mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-02-17 01:11:45 +00:00
expr.h:
nuke the ex_statement and estatement_[st] stuff add label_expr prototype expr.c: ex_statement nukage correct new_expr's decl add label_expr to ease label creation don't crash when printing a null expression (bare return) qc-parse.y: estatement_t nukage statement statements and statement_block are type expr generate `expressions' for statements a full parse tree for each function is now generated. there are several special expression opcodes for statements: d done \ r return -> unary: expression to return or null i if binary: evaluated expression, destination label n ifnot binary: evaluated expression, destination label c call binary: function def, args (expr list, rev order) s state binary: frame const, function def g goto unary: destination label l label unary: label number in a top level expression, l (label) defines the label, otherwise it is a reference.
This commit is contained in:
parent
2d87eeb57d
commit
1779a124c5
3 changed files with 219 additions and 34 deletions
|
@ -1,5 +1,4 @@
|
||||||
typedef enum {
|
typedef enum {
|
||||||
ex_statement,
|
|
||||||
ex_expr, // binary expression
|
ex_expr, // binary expression
|
||||||
ex_uexpr, // unary expression
|
ex_uexpr, // unary expression
|
||||||
ex_def,
|
ex_def,
|
||||||
|
@ -10,9 +9,6 @@ typedef enum {
|
||||||
ex_quaternion,
|
ex_quaternion,
|
||||||
} expr_type;
|
} expr_type;
|
||||||
|
|
||||||
typedef struct estatement_s {
|
|
||||||
} estatement_t;
|
|
||||||
|
|
||||||
typedef struct expr_s {
|
typedef struct expr_s {
|
||||||
struct expr_s *next;
|
struct expr_s *next;
|
||||||
expr_type type;
|
expr_type type;
|
||||||
|
@ -29,11 +25,11 @@ 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 *label_expr (void);
|
||||||
void print_expr (expr_t *e);
|
void print_expr (expr_t *e);
|
||||||
expr_t *binary_expr (int op, expr_t *e1, expr_t *e2);
|
expr_t *binary_expr (int op, expr_t *e1, expr_t *e2);
|
||||||
expr_t *unary_expr (int op, expr_t *e);
|
expr_t *unary_expr (int op, expr_t *e);
|
||||||
|
|
|
@ -13,7 +13,6 @@ static etype_t qc_types[] = {
|
||||||
ev_void,
|
ev_void,
|
||||||
ev_void,
|
ev_void,
|
||||||
ev_void,
|
ev_void,
|
||||||
ev_void,
|
|
||||||
ev_void, // FIXME ex_int
|
ev_void, // FIXME ex_int
|
||||||
ev_float, // ex_float
|
ev_float, // ex_float
|
||||||
ev_string, // ex_string
|
ev_string, // ex_string
|
||||||
|
@ -36,7 +35,6 @@ static etype_t
|
||||||
get_type (expr_t *e)
|
get_type (expr_t *e)
|
||||||
{
|
{
|
||||||
switch (e->type) {
|
switch (e->type) {
|
||||||
case ex_statement:
|
|
||||||
case ex_quaternion: //FIXME
|
case ex_quaternion: //FIXME
|
||||||
return ev_void;
|
return ev_void;
|
||||||
case ex_expr:
|
case ex_expr:
|
||||||
|
@ -58,18 +56,34 @@ get_type (expr_t *e)
|
||||||
}
|
}
|
||||||
|
|
||||||
expr_t *
|
expr_t *
|
||||||
new_expr ()
|
new_expr (void)
|
||||||
{
|
{
|
||||||
return calloc (1, sizeof (expr_t));
|
return calloc (1, sizeof (expr_t));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
expr_t *
|
||||||
|
label_expr (void)
|
||||||
|
{
|
||||||
|
static int label = 0;
|
||||||
|
|
||||||
|
expr_t *l = new_expr ();
|
||||||
|
l->type = ex_uexpr;
|
||||||
|
l->e.expr.op = 'l';
|
||||||
|
l->e.expr.e1 = new_expr ();
|
||||||
|
l->e.expr.e1->type = ex_int;
|
||||||
|
l->e.expr.e1->e.int_val = label++;
|
||||||
|
return l;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
print_expr (expr_t *e)
|
print_expr (expr_t *e)
|
||||||
{
|
{
|
||||||
printf (" ");
|
printf (" ");
|
||||||
|
if (!e) {
|
||||||
|
printf ("(nil)");
|
||||||
|
return;
|
||||||
|
}
|
||||||
switch (e->type) {
|
switch (e->type) {
|
||||||
case ex_statement:
|
|
||||||
break;
|
|
||||||
case ex_expr:
|
case ex_expr:
|
||||||
print_expr (e->e.expr.e1);
|
print_expr (e->e.expr.e1);
|
||||||
if (e->e.expr.op == 'c') {
|
if (e->e.expr.op == 'c') {
|
||||||
|
@ -420,8 +434,6 @@ unary_expr (int op, expr_t *e)
|
||||||
switch (op) {
|
switch (op) {
|
||||||
case '-':
|
case '-':
|
||||||
switch (e->type) {
|
switch (e->type) {
|
||||||
case ex_statement:
|
|
||||||
return ev_void;
|
|
||||||
case ex_uexpr:
|
case ex_uexpr:
|
||||||
if (e->e.expr.op == '-')
|
if (e->e.expr.op == '-')
|
||||||
return e->e.expr.e1;
|
return e->e.expr.e1;
|
||||||
|
@ -460,8 +472,6 @@ unary_expr (int op, expr_t *e)
|
||||||
break;
|
break;
|
||||||
case '!':
|
case '!':
|
||||||
switch (e->type) {
|
switch (e->type) {
|
||||||
case ex_statement:
|
|
||||||
return ev_void;
|
|
||||||
case ex_uexpr:
|
case ex_uexpr:
|
||||||
case ex_expr:
|
case ex_expr:
|
||||||
case ex_def:
|
case ex_def:
|
||||||
|
|
|
@ -21,6 +21,7 @@ void PR_PrintType(type_t*);
|
||||||
type_t *parse_params (def_t *parms);
|
type_t *parse_params (def_t *parms);
|
||||||
function_t *new_function (void);
|
function_t *new_function (void);
|
||||||
void build_function (function_t *f);
|
void build_function (function_t *f);
|
||||||
|
void emit_function (function_t *f, expr_t *e);
|
||||||
void build_scope (function_t *f, def_t *func);
|
void build_scope (function_t *f, def_t *func);
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -41,7 +42,6 @@ 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;
|
|
||||||
function_t *function;
|
function_t *function;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,7 +66,7 @@ typedef struct {
|
||||||
%type <type> type maybe_func
|
%type <type> type maybe_func
|
||||||
%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
|
||||||
%type <statement> statement statements statement_block
|
%type <expr> statement statements statement_block
|
||||||
%type <function> begin_function
|
%type <function> begin_function
|
||||||
|
|
||||||
%expect 1
|
%expect 1
|
||||||
|
@ -223,10 +223,29 @@ opt_initializer
|
||||||
| '=' begin_function statement_block end_function
|
| '=' begin_function statement_block end_function
|
||||||
{
|
{
|
||||||
build_function ($2);
|
build_function ($2);
|
||||||
|
emit_function ($2, $3);
|
||||||
}
|
}
|
||||||
| '=' begin_function '[' expr ',' expr ']' statement_block end_function
|
| '=' '[' const ','
|
||||||
{
|
{
|
||||||
build_function ($2);
|
$<def>$ = current_def;
|
||||||
|
}
|
||||||
|
def_name
|
||||||
|
{
|
||||||
|
current_def = $<def>5;
|
||||||
|
}
|
||||||
|
']' begin_function statement_block end_function
|
||||||
|
{
|
||||||
|
expr_t *e = new_expr ();
|
||||||
|
build_function ($9);
|
||||||
|
e->type = ex_expr;
|
||||||
|
e->e.expr.op = 's';
|
||||||
|
e->e.expr.e1 = $3;
|
||||||
|
e->e.expr.e2 = new_expr ();
|
||||||
|
e->e.expr.e2->type = ex_def;
|
||||||
|
e->e.expr.e2->e.def = $6;
|
||||||
|
e->next = $10;
|
||||||
|
|
||||||
|
emit_function ($9, e);
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
@ -262,34 +281,181 @@ statements
|
||||||
}
|
}
|
||||||
| statements statement
|
| statements statement
|
||||||
{
|
{
|
||||||
/* if ($1) {
|
if ($1) {
|
||||||
estatement_t *s = $1;
|
if ($2) {
|
||||||
while (s->next)
|
expr_t *s = $1;
|
||||||
s = s->next;
|
while (s->next)
|
||||||
s->next = $2;
|
s = s->next;
|
||||||
|
s->next = $2;
|
||||||
|
}
|
||||||
$$ = $1;
|
$$ = $1;
|
||||||
} else {
|
} else {
|
||||||
$$ = $2;
|
$$ = $2;
|
||||||
}*/
|
}
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
statement
|
statement
|
||||||
: ';' {}
|
: ';' { $$ = 0; }
|
||||||
| statement_block { $$ = $1; }
|
| statement_block { $$ = $1; }
|
||||||
| RETURN expr ';' {}
|
| RETURN expr ';'
|
||||||
| RETURN ';' {}
|
{
|
||||||
| WHILE '(' expr ')' statement {}
|
$$ = new_expr ();
|
||||||
| DO statement WHILE '(' expr ')' ';' {}
|
$$->type = ex_uexpr;
|
||||||
|
$$->e.expr.op = 'r';
|
||||||
|
$$->e.expr.e1 = $2;
|
||||||
|
}
|
||||||
|
| RETURN ';'
|
||||||
|
{
|
||||||
|
$$ = new_expr ();
|
||||||
|
$$->type = ex_uexpr;
|
||||||
|
$$->e.expr.op = 'r';
|
||||||
|
}
|
||||||
|
| WHILE '(' expr ')' statement
|
||||||
|
{
|
||||||
|
expr_t *e = new_expr ();
|
||||||
|
expr_t *l1 = label_expr ();
|
||||||
|
expr_t *l2 = label_expr ();
|
||||||
|
|
||||||
|
$$ = e;
|
||||||
|
|
||||||
|
e->type = ex_expr;
|
||||||
|
e->e.expr.op = 'n';
|
||||||
|
e->e.expr.e1 = $3;
|
||||||
|
e->e.expr.e2 = l2;
|
||||||
|
|
||||||
|
e->next = l1;
|
||||||
|
e = e->next;
|
||||||
|
|
||||||
|
e->next = $5;
|
||||||
|
while (e->next)
|
||||||
|
e = e->next;
|
||||||
|
|
||||||
|
e->next = new_expr ();
|
||||||
|
e = e->next;
|
||||||
|
e->type = ex_expr;
|
||||||
|
e->e.expr.op = 'i';
|
||||||
|
e->e.expr.e1 = $3;
|
||||||
|
e->e.expr.e2 = l1;
|
||||||
|
|
||||||
|
e->next = l2;
|
||||||
|
}
|
||||||
|
| DO statement WHILE '(' expr ')' ';'
|
||||||
|
{
|
||||||
|
expr_t *e;
|
||||||
|
expr_t *l1 = label_expr ();
|
||||||
|
|
||||||
|
$$ = e = l1;
|
||||||
|
|
||||||
|
e->next = $2;
|
||||||
|
while (e->next)
|
||||||
|
e = e->next;
|
||||||
|
|
||||||
|
e->next = new_expr ();
|
||||||
|
e = e->next;
|
||||||
|
e->type = ex_expr;
|
||||||
|
e->e.expr.op = 'i';
|
||||||
|
e->e.expr.e1 = $5;
|
||||||
|
e->e.expr.e2 = l1;
|
||||||
|
|
||||||
|
}
|
||||||
| LOCAL type
|
| LOCAL type
|
||||||
{
|
{
|
||||||
current_type = $2;
|
current_type = $2;
|
||||||
}
|
}
|
||||||
def_list ';' {}
|
def_list ';' { $$ = 0; }
|
||||||
| IF '(' expr ')' statement {}
|
| IF '(' expr ')' statement
|
||||||
| IF '(' expr ')' statement ELSE statement {}
|
{
|
||||||
| FOR '(' expr ';' expr ';' expr ')' statement {}
|
expr_t *e = new_expr ();
|
||||||
| expr ';' {}
|
expr_t *l1 = label_expr ();
|
||||||
|
|
||||||
|
$$ = e;
|
||||||
|
|
||||||
|
e->type = ex_expr;
|
||||||
|
e->e.expr.op = 'n';
|
||||||
|
e->e.expr.e1 = $3;
|
||||||
|
e->e.expr.e2 = l1;
|
||||||
|
|
||||||
|
e->next = $5;
|
||||||
|
while (e->next)
|
||||||
|
e = e->next;
|
||||||
|
|
||||||
|
e->next = l1;
|
||||||
|
}
|
||||||
|
| IF '(' expr ')' statement ELSE statement
|
||||||
|
{
|
||||||
|
expr_t *e = new_expr ();
|
||||||
|
expr_t *l1 = label_expr ();
|
||||||
|
expr_t *l2 = label_expr ();
|
||||||
|
|
||||||
|
$$ = e;
|
||||||
|
|
||||||
|
e->type = ex_expr;
|
||||||
|
e->e.expr.op = 'n';
|
||||||
|
e->e.expr.e1 = $3;
|
||||||
|
e->e.expr.e2 = l1;
|
||||||
|
|
||||||
|
e->next = $5;
|
||||||
|
while (e->next)
|
||||||
|
e = e->next;
|
||||||
|
|
||||||
|
e->next = new_expr ();
|
||||||
|
e = e->next;
|
||||||
|
e->type = ex_uexpr;
|
||||||
|
e->e.expr.op = 'g';
|
||||||
|
e->e.expr.e1 = l2;
|
||||||
|
|
||||||
|
e->next = l1;
|
||||||
|
e = e->next;
|
||||||
|
|
||||||
|
e->next = $7;
|
||||||
|
while (e->next)
|
||||||
|
e = e->next;
|
||||||
|
|
||||||
|
e->next = l2;
|
||||||
|
}
|
||||||
|
| FOR '(' expr ';' expr ';' expr ')' statement
|
||||||
|
{
|
||||||
|
expr_t *e;
|
||||||
|
expr_t *l1 = label_expr ();
|
||||||
|
expr_t *l2 = label_expr ();
|
||||||
|
|
||||||
|
$$ = e = $3;
|
||||||
|
if (e) {
|
||||||
|
e->next = new_expr ();
|
||||||
|
e = e->next;
|
||||||
|
} else {
|
||||||
|
e = new_expr ();
|
||||||
|
}
|
||||||
|
e->type = ex_expr;
|
||||||
|
e->e.expr.op = 'n';
|
||||||
|
e->e.expr.e1 = $5;
|
||||||
|
e->e.expr.e2 = l2;
|
||||||
|
|
||||||
|
e->next = l1;
|
||||||
|
e = e->next;
|
||||||
|
|
||||||
|
e->next = $9;
|
||||||
|
while (e->next)
|
||||||
|
e = e->next;
|
||||||
|
|
||||||
|
e->next = $7;
|
||||||
|
if (e->next)
|
||||||
|
e = e->next;
|
||||||
|
|
||||||
|
e->next = new_expr ();
|
||||||
|
e = e->next;
|
||||||
|
e->type = ex_expr;
|
||||||
|
e->e.expr.op = 'i';
|
||||||
|
e->e.expr.e1 = $5;
|
||||||
|
e->e.expr.e2 = l1;
|
||||||
|
|
||||||
|
e->next = l2;
|
||||||
|
}
|
||||||
|
| expr ';'
|
||||||
|
{
|
||||||
|
$$ = $1;
|
||||||
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
expr
|
expr
|
||||||
|
@ -454,3 +620,16 @@ build_function (function_t *f)
|
||||||
for (i = 0; i < df->numparms; i++)
|
for (i = 0; i < df->numparms; i++)
|
||||||
df->parm_size[i] = type_size[f->def->type->parm_types[i]->type];
|
df->parm_size[i] = type_size[f->def->type->parm_types[i]->type];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
emit_function (function_t *f, expr_t *e)
|
||||||
|
{
|
||||||
|
PR_PrintType (f->def->type);
|
||||||
|
printf (" %s =\n{\n", f->def->name);
|
||||||
|
while (e) {
|
||||||
|
print_expr (e);
|
||||||
|
puts("");
|
||||||
|
e = e->next;
|
||||||
|
}
|
||||||
|
printf ("}\n");
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue