mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-01-31 05:00:35 +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_expr,
|
||||||
ex_def,
|
ex_def,
|
||||||
ex_int,
|
ex_int,
|
||||||
|
@ -6,10 +7,13 @@ enum expr_type {
|
||||||
ex_string,
|
ex_string,
|
||||||
ex_vector,
|
ex_vector,
|
||||||
ex_quaternion,
|
ex_quaternion,
|
||||||
};
|
} expr_type;
|
||||||
|
|
||||||
|
typedef struct estatement_s {
|
||||||
|
} estatement_t;
|
||||||
|
|
||||||
typedef struct expr_s {
|
typedef struct expr_s {
|
||||||
int type;
|
expr_type type;
|
||||||
union {
|
union {
|
||||||
struct {
|
struct {
|
||||||
int op;
|
int op;
|
||||||
|
@ -23,7 +27,10 @@ typedef struct expr_s {
|
||||||
string_t string_val;
|
string_t string_val;
|
||||||
float vector_val[3];
|
float vector_val[3];
|
||||||
float quaternion_val[4];
|
float quaternion_val[4];
|
||||||
|
estatement_t *statement;
|
||||||
} e;
|
} e;
|
||||||
} expr_t;
|
} expr_t;
|
||||||
|
|
||||||
expr_t *new_expr (void);
|
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 "qfcc.h"
|
||||||
#include "expr.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 *
|
expr_t *
|
||||||
new_expr ()
|
new_expr ()
|
||||||
{
|
{
|
||||||
return calloc (1, sizeof (expr_t));
|
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;
|
char *string_val;
|
||||||
float vector_val[3];
|
float vector_val[3];
|
||||||
float quaternion_val[4];
|
float quaternion_val[4];
|
||||||
|
estatement_t *statement;
|
||||||
}
|
}
|
||||||
|
|
||||||
%left OR AND
|
%left OR AND
|
||||||
|
@ -56,7 +57,8 @@ typedef struct {
|
||||||
|
|
||||||
%type <type> type
|
%type <type> type
|
||||||
%type <def> param param_list def_item def_list def_name
|
%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
|
%expect 1
|
||||||
|
|
||||||
|
@ -99,19 +101,14 @@ type
|
||||||
|
|
||||||
def_list
|
def_list
|
||||||
: def_list ',' def_item
|
: def_list ',' def_item
|
||||||
{
|
|
||||||
if ($3->next) {
|
|
||||||
$$ = $1;
|
|
||||||
} else {
|
|
||||||
$3->next = $1;
|
|
||||||
$$ = $3;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
| def_item
|
| def_item
|
||||||
;
|
;
|
||||||
|
|
||||||
def_item
|
def_item
|
||||||
: def_name opt_initializer { $$ = $1; }
|
: def_name opt_initializer
|
||||||
|
{
|
||||||
|
$$ = $1;
|
||||||
|
}
|
||||||
| '('
|
| '('
|
||||||
{
|
{
|
||||||
$<scope>$.scope = pr_scope;
|
$<scope>$.scope = pr_scope;
|
||||||
|
@ -206,20 +203,41 @@ param
|
||||||
|
|
||||||
opt_initializer
|
opt_initializer
|
||||||
: /*empty*/
|
: /*empty*/
|
||||||
|
{
|
||||||
|
$$ = 0;
|
||||||
|
}
|
||||||
| '=' const
|
| '=' const
|
||||||
|
{
|
||||||
|
$$ = $2;
|
||||||
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
opt_definition
|
opt_definition
|
||||||
: /*empty*/
|
: /*empty*/
|
||||||
|
{
|
||||||
|
$$ = 0;
|
||||||
|
}
|
||||||
| '=' '#' const
|
| '=' '#' const
|
||||||
{
|
{
|
||||||
if ($3->type != ex_int && $3->type != ex_float)
|
if ($3->type != ex_int && $3->type != ex_float) {
|
||||||
yyerror ("invalid constant for = #");
|
yyerror ("invalid constant for = #");
|
||||||
else {
|
$$ = 0;
|
||||||
|
} else {
|
||||||
|
$$ = $3;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
| '=' begin_function statement_block end_function
|
| '=' begin_function statement_block end_function
|
||||||
|
{
|
||||||
|
$$ = new_expr ();
|
||||||
|
$$->type = ex_statement;
|
||||||
|
$$->e.statement = $3;
|
||||||
|
}
|
||||||
| '=' '[' expr ',' expr ']' begin_function statement_block end_function
|
| '=' '[' expr ',' expr ']' begin_function statement_block end_function
|
||||||
|
{
|
||||||
|
$$ = new_expr ();
|
||||||
|
$$->type = ex_statement;
|
||||||
|
$$->e.statement = $8;
|
||||||
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
begin_function
|
begin_function
|
||||||
|
@ -238,55 +256,72 @@ end_function
|
||||||
|
|
||||||
statement_block
|
statement_block
|
||||||
: '{' statements '}'
|
: '{' statements '}'
|
||||||
|
{
|
||||||
|
$$ = $2;
|
||||||
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
statements
|
statements
|
||||||
: /*empty*/
|
: /*empty*/
|
||||||
|
{
|
||||||
|
$$ = 0;
|
||||||
|
}
|
||||||
| statements statement
|
| statements statement
|
||||||
|
{
|
||||||
|
/* if ($1) {
|
||||||
|
estatement_t *s = $1;
|
||||||
|
while (s->next)
|
||||||
|
s = s->next;
|
||||||
|
s->next = $2;
|
||||||
|
$$ = $1;
|
||||||
|
} else {
|
||||||
|
$$ = $2;
|
||||||
|
}*/
|
||||||
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
statement
|
statement
|
||||||
: ';'
|
: ';' {}
|
||||||
| statement_block
|
| statement_block { $$ = $1; }
|
||||||
| RETURN expr ';'
|
| RETURN expr ';' {}
|
||||||
| RETURN ';'
|
| RETURN ';' {}
|
||||||
| WHILE '(' expr ')' statement
|
| WHILE '(' expr ')' statement {}
|
||||||
| DO statement WHILE '(' expr ')' ';'
|
| DO statement WHILE '(' expr ')' ';' {}
|
||||||
| LOCAL type def_list ';'
|
| LOCAL type def_list ';' {}
|
||||||
| IF '(' expr ')' statement
|
| IF '(' expr ')' statement {}
|
||||||
| IF '(' expr ')' statement ELSE statement
|
| IF '(' expr ')' statement ELSE statement {}
|
||||||
| FOR '(' expr ';' expr ';' expr ')' statement
|
| FOR '(' expr ';' expr ';' expr ')' statement {}
|
||||||
| expr ';' {}
|
| expr ';' {}
|
||||||
;
|
;
|
||||||
|
|
||||||
expr
|
expr
|
||||||
: expr AND expr
|
: expr AND expr { $$ = binary_expr (AND, $1, $3); }
|
||||||
| expr OR expr
|
| expr OR expr { $$ = binary_expr (OR, $1, $3); }
|
||||||
| expr '=' expr
|
| expr '=' expr { $$ = binary_expr ('.', $1, $3); }
|
||||||
| expr EQ expr
|
| expr EQ expr { $$ = binary_expr (EQ, $1, $3); }
|
||||||
| expr NE expr
|
| expr NE expr { $$ = binary_expr (NE, $1, $3); }
|
||||||
| expr LE expr
|
| expr LE expr { $$ = binary_expr (LE, $1, $3); }
|
||||||
| expr GE expr
|
| expr GE expr { $$ = binary_expr (GE, $1, $3); }
|
||||||
| expr LT expr
|
| expr LT expr { $$ = binary_expr (LT, $1, $3); }
|
||||||
| expr GT expr
|
| expr GT expr { $$ = binary_expr (GT, $1, $3); }
|
||||||
| expr '+' expr
|
| expr '+' expr { $$ = binary_expr ('+', $1, $3); }
|
||||||
| expr '-' expr
|
| expr '-' expr { $$ = binary_expr ('-', $1, $3); }
|
||||||
| expr '*' expr
|
| expr '*' expr { $$ = binary_expr ('*', $1, $3); }
|
||||||
| expr '/' expr
|
| expr '/' expr { $$ = binary_expr ('/', $1, $3); }
|
||||||
| expr '&' expr
|
| expr '&' expr { $$ = binary_expr ('&', $1, $3); }
|
||||||
| expr '|' expr
|
| expr '|' expr { $$ = binary_expr ('!', $1, $3); }
|
||||||
| expr '.' expr
|
| expr '.' expr { $$ = binary_expr ('.', $1, $3); }
|
||||||
| expr '(' arg_list ')'
|
| expr '(' arg_list ')'
|
||||||
| expr '(' ')'
|
| expr '(' ')'
|
||||||
| '-' expr {}
|
| '-' expr { $$ = unary_expr ('-', $2); }
|
||||||
| '!' expr {}
|
| '!' expr { $$ = unary_expr ('!', $2); }
|
||||||
| NAME
|
| NAME
|
||||||
{
|
{
|
||||||
$$ = new_expr ();
|
$$ = new_expr ();
|
||||||
$$->type = ex_def;
|
$$->type = ex_def;
|
||||||
$$->e.def = PR_GetDef (NULL, $1, pr_scope, false);
|
$$->e.def = PR_GetDef (NULL, $1, pr_scope, false);
|
||||||
}
|
}
|
||||||
| const
|
| const { $$ = $1; }
|
||||||
| '(' expr ')' { $$ = $2; }
|
| '(' expr ')' { $$ = $2; }
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue