new expression type: ex_block. forms a linked list of expressions for fast

appending and ease of manipulation.
This commit is contained in:
Bill Currie 2001-06-26 03:33:01 +00:00
parent d485ca1fb1
commit e99796c4cf
3 changed files with 89 additions and 85 deletions

View file

@ -1,5 +1,6 @@
typedef enum {
ex_label,
ex_block,
ex_expr, // binary expression
ex_uexpr, // unary expression
ex_def,
@ -16,11 +17,17 @@ typedef struct {
char *name;
} label_t;
typedef struct {
struct expr_s *head;
struct expr_s **tail;
} block_t;
typedef struct expr_s {
struct expr_s *next;
expr_type type;
union {
label_t *label;
label_t label;
block_t block;
struct {
int op;
type_t *type;
@ -38,8 +45,12 @@ typedef struct expr_s {
expr_t *new_expr (void);
expr_t *new_label_expr (void);
expr_t *new_block_expr (void);
expr_t *new_binary_expr (int op, expr_t *e1, expr_t *e2);
expr_t *new_unary_expr (int op, expr_t *e1);
expr_t *append_expr (expr_t *block, expr_t *e);
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

@ -12,6 +12,7 @@ extern function_t *current_func;
static etype_t qc_types[] = {
ev_void, // ex_label
ev_void, // ex_block
ev_void, // ex_expr
ev_void, // ex_uexpr
ev_void, // ex_def
@ -38,6 +39,7 @@ get_type (expr_t *e)
{
switch (e->type) {
case ex_label:
case ex_block:
case ex_quaternion: //FIXME
return ev_void;
case ex_expr:
@ -73,12 +75,22 @@ new_label_expr (void)
expr_t *l = new_expr ();
l->type = ex_label;
l->e.label = calloc (1, sizeof (label_t));
l->e.label->name = malloc (1 + strlen (fname) + 1 + ceil (log10 (lnum)) + 1);
sprintf (l->e.label->name, "$%s_%d", fname, lnum);
l->e.label.name = malloc (1 + strlen (fname) + 1 + ceil (log10 (lnum)) + 1);
sprintf (l->e.label.name, "$%s_%d", fname, lnum);
return l;
}
expr_t *
new_block_expr (void)
{
expr_t *b = new_expr ();
b->type = ex_block;
b->e.block.head = 0;
b->e.block.tail = &b->e.block.head;
return b;
}
expr_t *
new_binary_expr (int op, expr_t *e1, expr_t *e2)
{
@ -102,6 +114,21 @@ new_unary_expr (int op, expr_t *e1)
return e;
}
expr_t *
append_expr (expr_t *block, expr_t *e)
{
if (block->type != ex_block)
abort ();
if (!e)
return block;
*block->e.block.tail = e;
block->e.block.tail = &e->next;
return block;
}
void
print_expr (expr_t *e)
{
@ -112,7 +139,15 @@ print_expr (expr_t *e)
}
switch (e->type) {
case ex_label:
printf ("%s", e->e.label->name);
printf ("%s", e->e.label.name);
break;
case ex_block:
printf ("{\n");
for (e = e->e.block.head; e; e = e->next) {
print_expr (e);
puts("");
}
printf ("}");
break;
case ex_expr:
print_expr (e->e.expr.e1);
@ -465,6 +500,7 @@ unary_expr (int op, expr_t *e)
case '-':
switch (e->type) {
case ex_label:
case ex_block:
abort ();
case ex_uexpr:
if (e->e.expr.op == '-')
@ -505,6 +541,7 @@ unary_expr (int op, expr_t *e)
case '!':
switch (e->type) {
case ex_label:
case ex_block:
abort ();
case ex_uexpr:
case ex_expr:

View file

@ -278,21 +278,13 @@ statement_block
statements
: /*empty*/
{
$$ = 0;
//printf("statements: /* empty */\n");
$$ = new_block_expr ();
}
| statements statement
{
if ($1) {
if ($2) {
expr_t *s = $1;
while (s->next)
s = s->next;
s->next = $2;
}
$$ = $1;
} else {
$$ = $2;
}
//printf("statements: statements statement\n");
$$ = append_expr ($1, $2);
}
;
@ -312,33 +304,23 @@ statement
expr_t *l1 = new_label_expr ();
expr_t *l2 = new_label_expr ();
expr_t *e = new_binary_expr ('n', $3, l2);
$$ = new_block_expr ();
$$ = e;
e = (e->next = l1);
e->next = $5;
while (e->next)
e = e->next;
e = (e->next = new_binary_expr ('i', $3, l1));
e->next = l2;
append_expr ($$, new_binary_expr ('n', $3, l2));
append_expr ($$, l1);
append_expr ($$, $5);
append_expr ($$, new_binary_expr ('i', $3, l1));
append_expr ($$, l2);
}
| DO statement WHILE '(' expr ')' ';'
{
expr_t *l1 = new_label_expr ();
expr_t *e = l1;
$$ = new_block_expr ();
$$ = e;
e->next = $2;
while (e->next)
e = e->next;
e->next = new_binary_expr ('i', $5, l1);
append_expr ($$, l1);
append_expr ($$, $2);
append_expr ($$, new_binary_expr ('i', $5, l1));
}
| LOCAL type
{
@ -349,66 +331,40 @@ statement
{
expr_t *l1 = new_label_expr ();
expr_t *e = new_binary_expr ('n', $3, l1);
$$ = new_block_expr ();
$$ = e;
e->next = $5;
while (e->next)
e = e->next;
e->next = l1;
append_expr ($$, new_binary_expr ('n', $3, l1));
append_expr ($$, $5);
append_expr ($$, l1);
}
| IF '(' expr ')' statement ELSE statement
{
expr_t *l1 = new_label_expr ();
expr_t *l2 = new_label_expr ();
expr_t *e = new_binary_expr ('n', $3, l1);
$$ = new_block_expr ();
$$ = e;
e->next = $5;
while (e->next)
e = e->next;
e = (e->next = new_unary_expr ('g', l2));
e = (e->next = l1);
e->next = $7;
while (e->next)
e = e->next;
e->next = l2;
append_expr ($$, new_binary_expr ('n', $3, l1));
append_expr ($$, $5);
append_expr ($$, new_unary_expr ('g', l2));
append_expr ($$, l1);
append_expr ($$, $7);
append_expr ($$, l2);
}
| FOR '(' expr ';' expr ';' expr ')' statement
{
expr_t *l1 = new_label_expr ();
expr_t *l2 = new_label_expr ();
expr_t *e = new_binary_expr ('n', $5, l2);
$$ = new_block_expr ();
$$ = $3;
if ($$) {
$$->next = e;
} else {
$$ = e;
}
e = (e->next = l1);
e->next = $9;
while (e->next)
e = e->next;
e->next = $7;
if (e->next)
e = e->next;
e = (e->next = new_binary_expr ('i', $5, l1));
e->next = l2;
append_expr ($$, $3);
append_expr ($$, new_binary_expr ('n', $5, l2));
append_expr ($$, l1);
append_expr ($$, $9);
append_expr ($$, $7);
append_expr ($$, new_binary_expr ('i', $5, l1));
append_expr ($$, l2);
}
| expr ';'
{
@ -582,12 +538,12 @@ build_function (function_t *f)
void
emit_function (function_t *f, expr_t *e)
{
/* PR_PrintType (f->def->type);
printf (" %s =\n{\n", f->def->name);
/*PR_PrintType (f->def->type);
printf (" %s =\n", f->def->name);
while (e) {
print_expr (e);
puts("");
e = e->next;
}
printf ("}\n");*/
puts ("");*/
}