beginnings of expression and statement processing

This commit is contained in:
Bill Currie 2001-06-20 07:02:36 +00:00
parent 56aafce20c
commit 226b40483d
3 changed files with 171 additions and 45 deletions

View file

@ -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);

View file

@ -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;
}

View file

@ -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
%type <def> param param_list def_item def_list def_name
%type <expr> const expr arg_list
%type <expr> const expr arg_list opt_initializer opt_definition
%type <statement> 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>$.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