mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-10 15:22:04 +00:00
new expression type: ex_block. forms a linked list of expressions for fast
appending and ease of manipulation.
This commit is contained in:
parent
d485ca1fb1
commit
e99796c4cf
3 changed files with 89 additions and 85 deletions
|
@ -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);
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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 ("");*/
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue