From 35f4f2e6923c20ac2089b00a5220218741f72424 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sat, 4 Feb 2023 18:26:54 +0900 Subject: [PATCH] [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. --- tools/qfcc/source/qc-lex.l | 88 ++++++++++++++++++++---------------- tools/qfcc/source/qc-parse.y | 46 ++++--------------- 2 files changed, 58 insertions(+), 76 deletions(-) diff --git a/tools/qfcc/source/qc-lex.l b/tools/qfcc/source/qc-lex.l index 5e50ef5d5..99b3b3842 100644 --- a/tools/qfcc/source/qc-lex.l +++ b/tools/qfcc/source/qc-lex.l @@ -340,13 +340,14 @@ yywrap (void) typedef struct { const char *name; int value; - type_t *type; + specifier_t spec; } keyword_t; // These keywords are part of the Ruamoko language and require the QuakeForge // Ruamoko VM. 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" }; @@ -356,12 +357,12 @@ static keyword_t rua_keywords[] = { // If not compiling for the QuakeForge VM, or if Ruamoko has been disabled, // then they will be unavailable as keywords. static keyword_t obj_keywords[] = { - {"id", OBJECT, &type_id }, - {"Class", TYPE, &type_Class }, - {"Method", TYPE, &type_method }, - {"Super", TYPE, &type_super }, - {"SEL", TYPE, &type_SEL }, - {"IMP", TYPE, &type_IMP }, + {"id", OBJECT, .spec = { .type = &type_id } }, + {"Class", TYPE_SPEC, .spec = { .type = &type_Class } }, + {"Method", TYPE_SPEC, .spec = { .type = &type_method } }, + {"Super", TYPE_SPEC, .spec = { .type = &type_super } }, + {"SEL", TYPE_SPEC, .spec = { .type = &type_SEL } }, + {"IMP", TYPE_SPEC, .spec = { .type = &type_IMP } }, {"@class", CLASS }, {"@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 // be supported (sanely) by v6 progs. static keyword_t qf_keywords[] = { - {"quaternion", TYPE, &type_quaternion}, - {"double", TYPE, &type_double}, - {"int", TYPE, &type_int }, - {"unsigned", UNSIGNED, 0 }, - {"signed", SIGNED, 0 }, - {"long", LONG, 0 }, - {"short", SHORT, 0 }, + {"quaternion", TYPE_SPEC, .spec = { .type = &type_quaternion } }, + {"double", TYPE_SPEC, .spec = { .type = &type_double } }, + {"int", TYPE_SPEC, .spec = { .type = &type_int } }, + {"unsigned", TYPE_SPEC, .spec = { .is_unsigned = 1 } }, + {"signed", TYPE_SPEC, .spec = { .is_signed = 1 } }, + {"long", TYPE_SPEC, .spec = { .is_long = 1 } }, + {"short", TYPE_SPEC, .spec = { .is_short = 1 } }, - {"@function", TYPE, &type_func }, - {"@args", ARGS, 0 }, - {"@va_list", TYPE, &type_va_list }, - {"@param", TYPE, &type_param }, - {"@return", AT_RETURN, 0 }, + {"@function", TYPE_SPEC, .spec = { .type = &type_func } }, + {"@args", ARGS, }, + {"@va_list", TYPE_SPEC, .spec = { .type = &type_va_list } }, + {"@param", TYPE_SPEC, .spec = { .type = &type_param } }, + {"@return", AT_RETURN, }, - {"@cross", CROSS, 0 }, - {"@dot", DOT, 0 }, - {"@hadamard", HADAMARD, 0 }, + {"@cross", CROSS, }, + {"@dot", DOT, }, + {"@hadamard", HADAMARD, }, }; // These keywors are always available. Other than the @ keywords, they // form traditional QuakeC. static keyword_t keywords[] = { - {"void", TYPE, &type_void }, - {"float", TYPE, &type_float }, - {"string", TYPE, &type_string}, - {"vector", TYPE, &type_vector}, - {"entity", TYPE, &type_entity}, - {"local", LOCAL, 0 }, - {"return", RETURN, 0 }, - {"while", WHILE, 0 }, - {"do", DO, 0 }, - {"if", IF, 0 }, - {"else", ELSE, 0 }, - {"@system", SYSTEM, 0 }, - {"@overload", OVERLOAD, 0 }, - {"@attribute", ATTRIBUTE, 0 }, + {"void", TYPE_SPEC, .spec = { .type = &type_void } }, + {"float", TYPE_SPEC, .spec = { .type = &type_float } }, + {"string", TYPE_SPEC, .spec = { .type = &type_string } }, + {"vector", TYPE_SPEC, .spec = { .type = &type_vector } }, + {"entity", TYPE_SPEC, .spec = { .type = &type_entity } }, + {"local", LOCAL, }, + {"return", RETURN, }, + {"while", WHILE, }, + {"do", DO, }, + {"if", IF, }, + {"else", ELSE, }, + {"@system", SYSTEM, }, + {"@overload", OVERLOAD, }, + {"@attribute", ATTRIBUTE, }, }; static const char * @@ -474,12 +475,16 @@ process_keyword (keyword_t *keyword, const char *token) return OBJECT; } else if (sym->sy_type == sy_type) { // id has been redeclared via a typedef + qc_yylval.spec = (specifier_t) { + .type = sym->type, + .sym = sym, + }; return TYPE_NAME; } // id has been redelcared as a variable (hopefully) return NAME; } else { - qc_yylval.type = keyword->type; + qc_yylval.spec = keyword->spec; } return keyword->value; } @@ -550,8 +555,13 @@ keyword_or_id (const char *token) if (!sym) sym = new_symbol (token); 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; + } if (sym->sy_type == sy_class) return CLASS_NAME; return NAME; diff --git a/tools/qfcc/source/qc-parse.y b/tools/qfcc/source/qc-parse.y index 4939f7c90..beecbaae2 100644 --- a/tools/qfcc/source/qc-parse.y +++ b/tools/qfcc/source/qc-parse.y @@ -153,10 +153,9 @@ int yylex (void); %token RETURN AT_RETURN ELLIPSIS %token NIL GOTO SWITCH CASE DEFAULT ENUM %token ARGS TYPEDEF EXTERN STATIC SYSTEM OVERLOAD NOT ATTRIBUTE -%token UNSIGNED SIGNED LONG SHORT %token STRUCT -%token TYPE -%token OBJECT TYPE_NAME +%token TYPE_SPEC TYPE_NAME +%token OBJECT %token CLASS DEFS ENCODE END IMPLEMENTATION INTERFACE PRIVATE %token PROTECTED PROTOCOL PUBLIC SELECTOR REFERENCE SELF THIS @@ -700,37 +699,10 @@ type_specifier_or_storage_class ; type_specifier - : TYPE - { - $$ = 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; - } + : TYPE_SPEC | enum_specifier | struct_specifier | TYPE_NAME - { - $$ = make_spec ($1->type, 0, 0, 0); - $$.sym = $1; - } | OBJECT protocolrefs { if ($2) { @@ -1023,9 +995,9 @@ function_params qc_func_params : '(' ')' { $$ = 0; } | '(' ps qc_var_list ')' { $$ = check_params ($3); } - | '(' ps TYPE ')' + | '(' ps TYPE_SPEC ')' { - if (!is_void ($3)) + if (!is_void ($3.type)) PARSE_ERROR; $$ = 0; } @@ -1631,7 +1603,7 @@ unary_expr ident_expr : OBJECT { $$ = 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 @@ -1742,7 +1714,7 @@ identifier : NAME | OBJECT | CLASS_NAME - | TYPE_NAME + | TYPE_NAME { $$ = $1.sym; } ; // Objective-QC stuff @@ -2241,8 +2213,8 @@ selector : NAME { $$ = $1; } | CLASS_NAME { $$ = $1; } | OBJECT { $$ = new_symbol (qc_yytext); } - | TYPE { $$ = new_symbol (qc_yytext); } - | TYPE_NAME { $$ = $1; } + | TYPE_SPEC { $$ = new_symbol (qc_yytext); } + | TYPE_NAME { $$ = $1.sym; } | reserved_word ;