From 226b40483d2b97064eb70033a11e734a2a4cef75 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Wed, 20 Jun 2001 07:02:36 +0000 Subject: [PATCH] beginnings of expression and statement processing --- tools/qfcc/include/expr.h | 13 +++- tools/qfcc/source/expr.c | 84 +++++++++++++++++++++++++ tools/qfcc/source/qc-parse.y | 119 ++++++++++++++++++++++------------- 3 files changed, 171 insertions(+), 45 deletions(-) diff --git a/tools/qfcc/include/expr.h b/tools/qfcc/include/expr.h index 24c16b64e..c14629dae 100644 --- a/tools/qfcc/include/expr.h +++ b/tools/qfcc/include/expr.h @@ -1,4 +1,5 @@ -enum expr_type { +typedef enum { + ex_statement, ex_expr, ex_def, ex_int, @@ -6,10 +7,13 @@ enum expr_type { ex_string, ex_vector, ex_quaternion, -}; +} expr_type; + +typedef struct estatement_s { +} estatement_t; typedef struct expr_s { - int type; + expr_type type; union { struct { int op; @@ -23,7 +27,10 @@ typedef struct expr_s { string_t string_val; float vector_val[3]; float quaternion_val[4]; + estatement_t *statement; } e; } expr_t; expr_t *new_expr (void); +expr_t *binary_expr (int op, expr_t *e1, expr_t *e2); +expr_t *unary_expr (int op, expr_t *e); diff --git a/tools/qfcc/source/expr.c b/tools/qfcc/source/expr.c index 3f476eef4..9b3b38d61 100644 --- a/tools/qfcc/source/expr.c +++ b/tools/qfcc/source/expr.c @@ -3,8 +3,92 @@ #include "qfcc.h" #include "expr.h" +static etype_t qc_types[] = { + ev_void, + ev_void, + ev_void, + ev_void, // FIXME ex_int + ev_float, // ex_float + ev_string, // ex_string + ev_vector, // ex_vector + ev_void, // FIXME ex_quaternion +}; + +static type_t *types[] = { + &type_void, + &type_string, + &type_float, + &type_vector, + &type_entity, + &type_field, + &type_function, + &type_pointer, +}; + expr_t * new_expr () { return calloc (1, sizeof (expr_t)); } + +static expr_t * +binary_const (int op, expr_t *e1, expr_t *e2) +{ + return 0; +} + +static etype_t +get_type (expr_t *e) +{ + switch (e->type) { + case ex_statement: + case ex_quaternion: //FIXME + return ev_void; + case ex_expr: + return e->e.expr.type->type; + case ex_def: + return e->e.def->type->type; + case ex_int: //FIXME? + e->type = ex_float; + e->e.float_val = e->e.int_val; + return ev_float; + case ex_float: + case ex_string: + case ex_vector: + //FIXME case ex_quaternion: + return qc_types[e->type]; + } + return ev_void; +} + +expr_t * +binary_expr (int op, expr_t *e1, expr_t *e2) +{ + etype_t t1, t2; + + if (e1->type >= ex_int && e2->type >= ex_int) + return binary_const (op, e1, e2); + + t1 = get_type (e1); + t2 = get_type (e2); + if (t1 == ev_void || t2 == ev_void) + return 0; + + if (t1 == t2) { + expr_t *e = new_expr (); + e->type = ex_expr; + e->e.expr.op = op; + e->e.expr.type = types[t1]; + e->e.expr.e1 = e1; + e->e.expr.e2 = e2; + return e; + } else { + return 0; + } +} + +expr_t * +unary_expr (int op, expr_t *e) +{ + return 0; +} diff --git a/tools/qfcc/source/qc-parse.y b/tools/qfcc/source/qc-parse.y index eacaf0afd..ed4cd194d 100644 --- a/tools/qfcc/source/qc-parse.y +++ b/tools/qfcc/source/qc-parse.y @@ -36,6 +36,7 @@ typedef struct { char *string_val; float vector_val[3]; float quaternion_val[4]; + estatement_t *statement; } %left OR AND @@ -56,7 +57,8 @@ typedef struct { %type type %type param param_list def_item def_list def_name -%type const expr arg_list +%type const expr arg_list opt_initializer opt_definition +%type statement statements statement_block %expect 1 @@ -99,19 +101,14 @@ type def_list : def_list ',' def_item - { - if ($3->next) { - $$ = $1; - } else { - $3->next = $1; - $$ = $3; - } - } | def_item ; def_item - : def_name opt_initializer { $$ = $1; } + : def_name opt_initializer + { + $$ = $1; + } | '(' { $$.scope = pr_scope; @@ -206,20 +203,41 @@ param opt_initializer : /*empty*/ + { + $$ = 0; + } | '=' const + { + $$ = $2; + } ; opt_definition : /*empty*/ + { + $$ = 0; + } | '=' '#' const { - if ($3->type != ex_int && $3->type != ex_float) + if ($3->type != ex_int && $3->type != ex_float) { yyerror ("invalid constant for = #"); - else { + $$ = 0; + } else { + $$ = $3; } } | '=' begin_function statement_block end_function + { + $$ = new_expr (); + $$->type = ex_statement; + $$->e.statement = $3; + } | '=' '[' expr ',' expr ']' begin_function statement_block end_function + { + $$ = new_expr (); + $$->type = ex_statement; + $$->e.statement = $8; + } ; begin_function @@ -238,56 +256,73 @@ end_function statement_block : '{' statements '}' + { + $$ = $2; + } ; statements : /*empty*/ + { + $$ = 0; + } | statements statement + { +/* if ($1) { + estatement_t *s = $1; + while (s->next) + s = s->next; + s->next = $2; + $$ = $1; + } else { + $$ = $2; + }*/ + } ; statement - : ';' - | statement_block - | RETURN expr ';' - | RETURN ';' - | WHILE '(' expr ')' statement - | DO statement WHILE '(' expr ')' ';' - | LOCAL type def_list ';' - | IF '(' expr ')' statement - | IF '(' expr ')' statement ELSE statement - | FOR '(' expr ';' expr ';' expr ')' statement + : ';' {} + | statement_block { $$ = $1; } + | RETURN expr ';' {} + | RETURN ';' {} + | WHILE '(' expr ')' statement {} + | DO statement WHILE '(' expr ')' ';' {} + | LOCAL type def_list ';' {} + | IF '(' expr ')' statement {} + | IF '(' expr ')' statement ELSE statement {} + | FOR '(' expr ';' expr ';' expr ')' statement {} | expr ';' {} ; expr - : expr AND expr - | expr OR expr - | expr '=' expr - | expr EQ expr - | expr NE expr - | expr LE expr - | expr GE expr - | expr LT expr - | expr GT expr - | expr '+' expr - | expr '-' expr - | expr '*' expr - | expr '/' expr - | expr '&' expr - | expr '|' expr - | expr '.' expr + : expr AND expr { $$ = binary_expr (AND, $1, $3); } + | expr OR expr { $$ = binary_expr (OR, $1, $3); } + | expr '=' expr { $$ = binary_expr ('.', $1, $3); } + | expr EQ expr { $$ = binary_expr (EQ, $1, $3); } + | expr NE expr { $$ = binary_expr (NE, $1, $3); } + | expr LE expr { $$ = binary_expr (LE, $1, $3); } + | expr GE expr { $$ = binary_expr (GE, $1, $3); } + | expr LT expr { $$ = binary_expr (LT, $1, $3); } + | expr GT expr { $$ = binary_expr (GT, $1, $3); } + | expr '+' expr { $$ = binary_expr ('+', $1, $3); } + | expr '-' expr { $$ = binary_expr ('-', $1, $3); } + | expr '*' expr { $$ = binary_expr ('*', $1, $3); } + | expr '/' expr { $$ = binary_expr ('/', $1, $3); } + | expr '&' expr { $$ = binary_expr ('&', $1, $3); } + | expr '|' expr { $$ = binary_expr ('!', $1, $3); } + | expr '.' expr { $$ = binary_expr ('.', $1, $3); } | expr '(' arg_list ')' | expr '(' ')' - | '-' expr {} - | '!' expr {} + | '-' expr { $$ = unary_expr ('-', $2); } + | '!' expr { $$ = unary_expr ('!', $2); } | NAME { $$ = new_expr (); $$->type = ex_def; $$->e.def = PR_GetDef (NULL, $1, pr_scope, false); } - | const - | '(' expr ')' { $$ = $2; } + | const { $$ = $1; } + | '(' expr ')' { $$ = $2; } ; arg_list