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 {
ex_statement,
ex_expr, // binary expression
ex_uexpr, // unary expression
ex_def,
@ -10,9 +9,6 @@ typedef enum {
ex_quaternion,
} expr_type;
typedef struct estatement_s {
} estatement_t;
typedef struct expr_s {
struct expr_s *next;
expr_type type;
@ -29,11 +25,11 @@ 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 *label_expr (void);
void print_expr (expr_t *e);
expr_t *binary_expr (int op, expr_t *e1, expr_t *e2);
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, // FIXME ex_int
ev_float, // ex_float
ev_string, // ex_string
@ -36,7 +35,6 @@ static etype_t
get_type (expr_t *e)
{
switch (e->type) {
case ex_statement:
case ex_quaternion: //FIXME
return ev_void;
case ex_expr:
@ -58,18 +56,34 @@ get_type (expr_t *e)
}
expr_t *
new_expr ()
new_expr (void)
{
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
print_expr (expr_t *e)
{
printf (" ");
if (!e) {
printf ("(nil)");
return;
}
switch (e->type) {
case ex_statement:
break;
case ex_expr:
print_expr (e->e.expr.e1);
if (e->e.expr.op == 'c') {
@ -420,8 +434,6 @@ unary_expr (int op, expr_t *e)
switch (op) {
case '-':
switch (e->type) {
case ex_statement:
return ev_void;
case ex_uexpr:
if (e->e.expr.op == '-')
return e->e.expr.e1;
@ -460,8 +472,6 @@ unary_expr (int op, expr_t *e)
break;
case '!':
switch (e->type) {
case ex_statement:
return ev_void;
case ex_uexpr:
case ex_expr:
case ex_def:

View file

@ -21,6 +21,7 @@ void PR_PrintType(type_t*);
type_t *parse_params (def_t *parms);
function_t *new_function (void);
void build_function (function_t *f);
void emit_function (function_t *f, expr_t *e);
void build_scope (function_t *f, def_t *func);
typedef struct {
@ -41,7 +42,6 @@ typedef struct {
char *string_val;
float vector_val[3];
float quaternion_val[4];
estatement_t *statement;
function_t *function;
}
@ -66,7 +66,7 @@ typedef struct {
%type <type> type maybe_func
%type <def> param param_list def_item def_list def_name
%type <expr> const expr arg_list
%type <statement> statement statements statement_block
%type <expr> statement statements statement_block
%type <function> begin_function
%expect 1
@ -223,10 +223,29 @@ opt_initializer
| '=' begin_function statement_block end_function
{
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
{
/* if ($1) {
estatement_t *s = $1;
while (s->next)
s = s->next;
s->next = $2;
if ($1) {
if ($2) {
expr_t *s = $1;
while (s->next)
s = s->next;
s->next = $2;
}
$$ = $1;
} else {
$$ = $2;
}*/
}
}
;
statement
: ';' {}
: ';' { $$ = 0; }
| statement_block { $$ = $1; }
| RETURN expr ';' {}
| RETURN ';' {}
| WHILE '(' expr ')' statement {}
| DO statement WHILE '(' expr ')' ';' {}
| RETURN expr ';'
{
$$ = new_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
{
current_type = $2;
}
def_list ';' {}
| IF '(' expr ')' statement {}
| IF '(' expr ')' statement ELSE statement {}
| FOR '(' expr ';' expr ';' expr ')' statement {}
| expr ';' {}
def_list ';' { $$ = 0; }
| IF '(' expr ')' statement
{
expr_t *e = new_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
@ -454,3 +620,16 @@ build_function (function_t *f)
for (i = 0; i < df->numparms; i++)
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");
}