From eeaab95be5819ab4534d00a2f7a65e34f2596f8a Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Fri, 15 Jun 2001 19:38:43 +0000 Subject: [PATCH] beginnings of expression and def handling. --- tools/qfcc/include/expr.h | 29 +++++++++++ tools/qfcc/source/Makefile.am | 2 +- tools/qfcc/source/expr.c | 10 ++++ tools/qfcc/source/qc-lex.l | 4 +- tools/qfcc/source/qc-parse.y | 91 +++++++++++++++++++++++++++++------ tools/qfcc/source/qfcc.c | 2 +- 6 files changed, 120 insertions(+), 18 deletions(-) create mode 100644 tools/qfcc/include/expr.h create mode 100644 tools/qfcc/source/expr.c diff --git a/tools/qfcc/include/expr.h b/tools/qfcc/include/expr.h new file mode 100644 index 000000000..24c16b64e --- /dev/null +++ b/tools/qfcc/include/expr.h @@ -0,0 +1,29 @@ +enum expr_type { + ex_expr, + ex_def, + ex_int, + ex_float, + ex_string, + ex_vector, + ex_quaternion, +}; + +typedef struct expr_s { + int type; + union { + struct { + int op; + type_t *type; + struct expr_s *e1; + struct expr_s *e2; + } expr; + def_t *def; + int int_val; + float float_val; + string_t string_val; + float vector_val[3]; + float quaternion_val[4]; + } e; +} expr_t; + +expr_t *new_expr (void); diff --git a/tools/qfcc/source/Makefile.am b/tools/qfcc/source/Makefile.am index acab70246..98a49b3e0 100644 --- a/tools/qfcc/source/Makefile.am +++ b/tools/qfcc/source/Makefile.am @@ -33,5 +33,5 @@ YFLAGS = -d bin_PROGRAMS= qfcc -qfcc_SOURCES= cmdlib.c pr_comp.c pr_def.c pr_imm.c pr_lex.c pr_opcode.c qfcc.c #qc-parse.y qc-lex.l +qfcc_SOURCES= cmdlib.c pr_comp.c pr_def.c pr_imm.c pr_lex.c pr_opcode.c qfcc.c #qc-parse.y qc-lex.l expr.c qfcc_LDADD= -lQFutil diff --git a/tools/qfcc/source/expr.c b/tools/qfcc/source/expr.c new file mode 100644 index 000000000..3f476eef4 --- /dev/null +++ b/tools/qfcc/source/expr.c @@ -0,0 +1,10 @@ +#include + +#include "qfcc.h" +#include "expr.h" + +expr_t * +new_expr () +{ + return calloc (1, sizeof (expr_t)); +} diff --git a/tools/qfcc/source/qc-lex.l b/tools/qfcc/source/qc-lex.l index 4b878b6f0..d6cf6b333 100644 --- a/tools/qfcc/source/qc-lex.l +++ b/tools/qfcc/source/qc-lex.l @@ -1,6 +1,7 @@ %{ #include #include "qfcc.h" +#include "expr.h" #include "qc-parse.h" #define YY_NO_UNPUT @@ -60,7 +61,7 @@ m ([\-+]?) {ID} return type_or_name(yytext); \"(\\.|[^"])*\" { - //yylval.string_val = strdup (yytext); + yylval.string_val = strdup (yytext); return STRING_VAL; } @@ -170,6 +171,7 @@ type_or_name (char *token) yylval.type = keyword->type; return keyword->value; } + yylval.string_val = strdup (token); return NAME; } diff --git a/tools/qfcc/source/qc-parse.y b/tools/qfcc/source/qc-parse.y index 5123df58b..dc86ba61a 100644 --- a/tools/qfcc/source/qc-parse.y +++ b/tools/qfcc/source/qc-parse.y @@ -1,5 +1,7 @@ %{ #include "qfcc.h" +#include "expr.h" + #define YYDEBUG 1 #define YYERROR_VERBOSE 1 void @@ -18,6 +20,7 @@ type_t *PR_FindType (type_t *new); %union { def_t *def; type_t *type; + expr_t *expr; int int_val; float float_val; char *string_val; @@ -42,13 +45,15 @@ type_t *PR_FindType (type_t *new); %token TYPE %type type -%type param param_list def_item def_list expr arg_list +%type param param_list def_item def_list def_name +%type const expr arg_list %expect 1 %{ -type_t *current_type; +type_t *current_type; +def_t *current_def; %} @@ -85,14 +90,19 @@ def_list ; def_item + : def_name opt_initializer + | '(' param_list ')' def_name opt_definition {} + | '(' ')' def_name opt_definition {} + | '(' ELIPSIS ')' def_name opt_definition {} + ; + +def_name : NAME { + printf ("%s\n", $1); $$ = PR_GetDef (current_type, $1, pr_scope, pr_scope ? &pr_scope->num_locals : &numpr_globals); + current_def = $$; } - opt_initializer - | '(' param_list ')' NAME opt_initializer {} - | '(' ')' NAME opt_initializer {} - | '(' ELIPSIS ')' NAME opt_initializer {} ; param_list @@ -114,10 +124,34 @@ param opt_initializer : /*empty*/ - | '=' '#' const - | '=' statement_block | '=' const - | '=' '[' expr ',' expr ']' statement_block + ; + +opt_definition + : /*empty*/ + | '=' '#' const + { + if ($3->type != ex_int && $3->type != ex_float) + yyerror ("invalid constant for = #"); + else { + } + } + | '=' begin_function statement_block end_function + | '=' '[' expr ',' expr ']' begin_function statement_block end_function + ; + +begin_function + : /*empty*/ + { + pr_scope = current_def; + } + ; + +end_function + : /*empty*/ + { + pr_scope = 0; + } ; statement_block @@ -140,7 +174,7 @@ statement | IF '(' expr ')' statement | IF '(' expr ')' statement ELSE statement | FOR '(' expr ';' expr ';' expr ')' statement - | expr ';' + | expr ';' {} ; expr @@ -162,13 +196,15 @@ expr | expr '.' expr | expr '(' arg_list ')' | expr '(' ')' - | '-' expr - | '!' expr + | '-' expr {} + | '!' expr {} | NAME { - $$ = PR_GetDef (NULL, $1, pr_scope, false); + $$ = new_expr (); + $$->type = ex_def; + $$->e.def = PR_GetDef (NULL, $1, pr_scope, false); } - | const {} + | const | '(' expr ')' { $$ = $2; } ; @@ -178,11 +214,36 @@ arg_list ; const - : FLOAT_VAL {} + : FLOAT_VAL + { + $$ = new_expr (); + $$->type = ex_float; + $$->e.float_val = $1; + } | STRING_VAL {} + { + $$ = new_expr (); + $$->type = ex_string; + $$->e.string_val = ReuseString ($1); + } | VECTOR_VAL {} + { + $$ = new_expr (); + $$->type = ex_vector; + memcpy ($$->e.vector_val, $1, sizeof ($$->e.vector_val)); + } | QUATERNION_VAL {} + { + $$ = new_expr (); + $$->type = ex_quaternion; + memcpy ($$->e.quaternion_val, $1, sizeof ($$->e.quaternion_val)); + } | INT_VAL {} + { + $$ = new_expr (); + $$->type = ex_int; + $$->e.int_val = $1; + } ; %% diff --git a/tools/qfcc/source/qfcc.c b/tools/qfcc/source/qfcc.c index 6b51e819a..7fec34a80 100644 --- a/tools/qfcc/source/qfcc.c +++ b/tools/qfcc/source/qfcc.c @@ -832,7 +832,6 @@ int main (int argc, char **argv) { char *src; - char *src2; char filename[1024]; int p, crc; double start, stop; @@ -924,6 +923,7 @@ Options: \n\ } fclose (yyin); #else + char *src2; sprintf (filename, "%s/%s", sourcedir, com_token); printf ("compiling %s\n", filename); LoadFile (filename, (void *) &src2);