mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-01-18 06:51:47 +00:00
beginnings of expression and statement processing
This commit is contained in:
parent
56aafce20c
commit
226b40483d
3 changed files with 171 additions and 45 deletions
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue