[qfcc] Move basic specifier creation into qc-lex

This simplifies type type_specifier rule significantly as now TYPE_SPEC
(was TYPE) includes all types and their basic modifiers (long, short,
signed, unsigned). This should allow me to make the type system closer
to gcc's (as of 3.4 as that seems to be the last version that used a
bison parser) and thus fix typeredef2.
This commit is contained in:
Bill Currie 2023-02-04 18:26:54 +09:00
parent 5f22a322df
commit 35f4f2e692
2 changed files with 58 additions and 76 deletions

View file

@ -340,13 +340,14 @@ yywrap (void)
typedef struct { typedef struct {
const char *name; const char *name;
int value; int value;
type_t *type; specifier_t spec;
} keyword_t; } keyword_t;
// These keywords are part of the Ruamoko language and require the QuakeForge // These keywords are part of the Ruamoko language and require the QuakeForge
// Ruamoko VM. // Ruamoko VM.
static keyword_t rua_keywords[] = { static keyword_t rua_keywords[] = {
#define VEC_TYPE(type_name, base_type) { #type_name, TYPE, &type_##type_name }, #define VEC_TYPE(type_name, base_type) \
{ #type_name, TYPE_SPEC, .spec = { .type = &type_##type_name } },
#include "tools/qfcc/include/vec_types.h" #include "tools/qfcc/include/vec_types.h"
}; };
@ -356,12 +357,12 @@ static keyword_t rua_keywords[] = {
// If not compiling for the QuakeForge VM, or if Ruamoko has been disabled, // If not compiling for the QuakeForge VM, or if Ruamoko has been disabled,
// then they will be unavailable as keywords. // then they will be unavailable as keywords.
static keyword_t obj_keywords[] = { static keyword_t obj_keywords[] = {
{"id", OBJECT, &type_id }, {"id", OBJECT, .spec = { .type = &type_id } },
{"Class", TYPE, &type_Class }, {"Class", TYPE_SPEC, .spec = { .type = &type_Class } },
{"Method", TYPE, &type_method }, {"Method", TYPE_SPEC, .spec = { .type = &type_method } },
{"Super", TYPE, &type_super }, {"Super", TYPE_SPEC, .spec = { .type = &type_super } },
{"SEL", TYPE, &type_SEL }, {"SEL", TYPE_SPEC, .spec = { .type = &type_SEL } },
{"IMP", TYPE, &type_IMP }, {"IMP", TYPE_SPEC, .spec = { .type = &type_IMP } },
{"@class", CLASS }, {"@class", CLASS },
{"@defs", DEFS }, {"@defs", DEFS },
@ -412,42 +413,42 @@ static keyword_t at_keywords[] = {
// These keywords require the QuakeForge VM to be of any use. ie, they cannot // These keywords require the QuakeForge VM to be of any use. ie, they cannot
// be supported (sanely) by v6 progs. // be supported (sanely) by v6 progs.
static keyword_t qf_keywords[] = { static keyword_t qf_keywords[] = {
{"quaternion", TYPE, &type_quaternion}, {"quaternion", TYPE_SPEC, .spec = { .type = &type_quaternion } },
{"double", TYPE, &type_double}, {"double", TYPE_SPEC, .spec = { .type = &type_double } },
{"int", TYPE, &type_int }, {"int", TYPE_SPEC, .spec = { .type = &type_int } },
{"unsigned", UNSIGNED, 0 }, {"unsigned", TYPE_SPEC, .spec = { .is_unsigned = 1 } },
{"signed", SIGNED, 0 }, {"signed", TYPE_SPEC, .spec = { .is_signed = 1 } },
{"long", LONG, 0 }, {"long", TYPE_SPEC, .spec = { .is_long = 1 } },
{"short", SHORT, 0 }, {"short", TYPE_SPEC, .spec = { .is_short = 1 } },
{"@function", TYPE, &type_func }, {"@function", TYPE_SPEC, .spec = { .type = &type_func } },
{"@args", ARGS, 0 }, {"@args", ARGS, },
{"@va_list", TYPE, &type_va_list }, {"@va_list", TYPE_SPEC, .spec = { .type = &type_va_list } },
{"@param", TYPE, &type_param }, {"@param", TYPE_SPEC, .spec = { .type = &type_param } },
{"@return", AT_RETURN, 0 }, {"@return", AT_RETURN, },
{"@cross", CROSS, 0 }, {"@cross", CROSS, },
{"@dot", DOT, 0 }, {"@dot", DOT, },
{"@hadamard", HADAMARD, 0 }, {"@hadamard", HADAMARD, },
}; };
// These keywors are always available. Other than the @ keywords, they // These keywors are always available. Other than the @ keywords, they
// form traditional QuakeC. // form traditional QuakeC.
static keyword_t keywords[] = { static keyword_t keywords[] = {
{"void", TYPE, &type_void }, {"void", TYPE_SPEC, .spec = { .type = &type_void } },
{"float", TYPE, &type_float }, {"float", TYPE_SPEC, .spec = { .type = &type_float } },
{"string", TYPE, &type_string}, {"string", TYPE_SPEC, .spec = { .type = &type_string } },
{"vector", TYPE, &type_vector}, {"vector", TYPE_SPEC, .spec = { .type = &type_vector } },
{"entity", TYPE, &type_entity}, {"entity", TYPE_SPEC, .spec = { .type = &type_entity } },
{"local", LOCAL, 0 }, {"local", LOCAL, },
{"return", RETURN, 0 }, {"return", RETURN, },
{"while", WHILE, 0 }, {"while", WHILE, },
{"do", DO, 0 }, {"do", DO, },
{"if", IF, 0 }, {"if", IF, },
{"else", ELSE, 0 }, {"else", ELSE, },
{"@system", SYSTEM, 0 }, {"@system", SYSTEM, },
{"@overload", OVERLOAD, 0 }, {"@overload", OVERLOAD, },
{"@attribute", ATTRIBUTE, 0 }, {"@attribute", ATTRIBUTE, },
}; };
static const char * static const char *
@ -474,12 +475,16 @@ process_keyword (keyword_t *keyword, const char *token)
return OBJECT; return OBJECT;
} else if (sym->sy_type == sy_type) { } else if (sym->sy_type == sy_type) {
// id has been redeclared via a typedef // id has been redeclared via a typedef
qc_yylval.spec = (specifier_t) {
.type = sym->type,
.sym = sym,
};
return TYPE_NAME; return TYPE_NAME;
} }
// id has been redelcared as a variable (hopefully) // id has been redelcared as a variable (hopefully)
return NAME; return NAME;
} else { } else {
qc_yylval.type = keyword->type; qc_yylval.spec = keyword->spec;
} }
return keyword->value; return keyword->value;
} }
@ -550,8 +555,13 @@ keyword_or_id (const char *token)
if (!sym) if (!sym)
sym = new_symbol (token); sym = new_symbol (token);
qc_yylval.symbol = sym; qc_yylval.symbol = sym;
if (sym->sy_type == sy_type) if (sym->sy_type == sy_type) {
qc_yylval.spec = (specifier_t) {
.type = sym->type,
.sym = sym,
};
return TYPE_NAME; return TYPE_NAME;
}
if (sym->sy_type == sy_class) if (sym->sy_type == sy_class)
return CLASS_NAME; return CLASS_NAME;
return NAME; return NAME;

View file

@ -153,10 +153,9 @@ int yylex (void);
%token RETURN AT_RETURN ELLIPSIS %token RETURN AT_RETURN ELLIPSIS
%token NIL GOTO SWITCH CASE DEFAULT ENUM %token NIL GOTO SWITCH CASE DEFAULT ENUM
%token ARGS TYPEDEF EXTERN STATIC SYSTEM OVERLOAD NOT ATTRIBUTE %token ARGS TYPEDEF EXTERN STATIC SYSTEM OVERLOAD NOT ATTRIBUTE
%token UNSIGNED SIGNED LONG SHORT
%token <op> STRUCT %token <op> STRUCT
%token <type> TYPE %token <spec> TYPE_SPEC TYPE_NAME
%token <symbol> OBJECT TYPE_NAME %token <symbol> OBJECT
%token CLASS DEFS ENCODE END IMPLEMENTATION INTERFACE PRIVATE %token CLASS DEFS ENCODE END IMPLEMENTATION INTERFACE PRIVATE
%token PROTECTED PROTOCOL PUBLIC SELECTOR REFERENCE SELF THIS %token PROTECTED PROTOCOL PUBLIC SELECTOR REFERENCE SELF THIS
@ -700,37 +699,10 @@ type_specifier_or_storage_class
; ;
type_specifier type_specifier
: TYPE : TYPE_SPEC
{
$$ = make_spec ($1, 0, 0, 0);
}
| UNSIGNED
{
$$ = make_spec (0, current_storage, 0, 0);
$$.is_unsigned = 1;
}
| SIGNED
{
$$ = make_spec (0, current_storage, 0, 0);
$$.is_signed = 1;
}
| LONG
{
$$ = make_spec (0, current_storage, 0, 0);
$$.is_long = 1;
}
| SHORT
{
$$ = make_spec (0, current_storage, 0, 0);
$$.is_short = 1;
}
| enum_specifier | enum_specifier
| struct_specifier | struct_specifier
| TYPE_NAME | TYPE_NAME
{
$$ = make_spec ($1->type, 0, 0, 0);
$$.sym = $1;
}
| OBJECT protocolrefs | OBJECT protocolrefs
{ {
if ($2) { if ($2) {
@ -1023,9 +995,9 @@ function_params
qc_func_params qc_func_params
: '(' ')' { $$ = 0; } : '(' ')' { $$ = 0; }
| '(' ps qc_var_list ')' { $$ = check_params ($3); } | '(' ps qc_var_list ')' { $$ = check_params ($3); }
| '(' ps TYPE ')' | '(' ps TYPE_SPEC ')'
{ {
if (!is_void ($3)) if (!is_void ($3.type))
PARSE_ERROR; PARSE_ERROR;
$$ = 0; $$ = 0;
} }
@ -1631,7 +1603,7 @@ unary_expr
ident_expr ident_expr
: OBJECT { $$ = new_symbol_expr ($1); } : OBJECT { $$ = new_symbol_expr ($1); }
| CLASS_NAME { $$ = new_symbol_expr ($1); } | CLASS_NAME { $$ = new_symbol_expr ($1); }
| TYPE_NAME { $$ = new_symbol_expr ($1); } | TYPE_NAME { $$ = new_symbol_expr ($1.sym); }
; ;
vector_expr vector_expr
@ -1742,7 +1714,7 @@ identifier
: NAME : NAME
| OBJECT | OBJECT
| CLASS_NAME | CLASS_NAME
| TYPE_NAME | TYPE_NAME { $$ = $1.sym; }
; ;
// Objective-QC stuff // Objective-QC stuff
@ -2241,8 +2213,8 @@ selector
: NAME { $$ = $1; } : NAME { $$ = $1; }
| CLASS_NAME { $$ = $1; } | CLASS_NAME { $$ = $1; }
| OBJECT { $$ = new_symbol (qc_yytext); } | OBJECT { $$ = new_symbol (qc_yytext); }
| TYPE { $$ = new_symbol (qc_yytext); } | TYPE_SPEC { $$ = new_symbol (qc_yytext); }
| TYPE_NAME { $$ = $1; } | TYPE_NAME { $$ = $1.sym; }
| reserved_word | reserved_word
; ;