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:
Bill Currie 2001-06-25 20:52:04 +00:00
parent 2d87eeb57d
commit 1779a124c5
3 changed files with 219 additions and 34 deletions

View file

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

View file

@ -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:

View file

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