struct AstNode* links[3];
} AstNode;
+
+
+typedef struct {
+ size_t symid;
+ size_t symver;
+} SsaVar;
+
+typedef union {
+ long long i;
+ double f;
+ char* s;
+} SsaConst;
+
+typedef union {
+ SsaVar var;
+ SsaConst val;
+} SsaValue;
+
+typedef struct SsaNode {
+ struct SsaNode* next;
+ int code : 27;
+ int mode : 4;
+ int loaded : 1;
+ Type* type;
+ SsaVar dest;
+ SsaValue left;
+ SsaValue right;
+} SsaNode;
+
+typedef struct {
+ size_t id;
+ SsaNode* head;
+ SsaNode* tail;
+} SsaBlock;
+
+enum {
+ MODE_CONST = 0,
+ MODE_VAR = 1,
+ MODE_OP = 2,
+ MODE_CONTROL = 3,
+};
+
+
+
+
typedef struct Symbol {
enum{
SYM_MODULE, SYM_CONST, SYM_VAR, SYM_TYPE, SYM_PROC
char* name;
Type* type;
struct Symbol* desc;
- AstNode* value;
+ SsaNode* value;
long nargs;
+ long version;
size_t module;
int export : 1;
int global : 1;
long curr_reg;
size_t scope;
+ SsaBlock* curr_block;
+ SsaBlock* curr_join;
+
+
size_t msyms;
size_t nsyms;
Symbol* syms;
bool ast_areconst(AstNode* left, AstNode* right);
AstNode* ast_ident(Parser* p, long long index);
-AstNode* ast_bool(bool val);
-AstNode* ast_int(long long val);
-AstNode* ast_real(double val);
+AstNode* ast_bool(Parser* p, bool val);
+AstNode* ast_int(Parser* p, long long val);
+AstNode* ast_real(Parser* p, double val);
bool ast_asbool(AstNode* node);
long long ast_asint(AstNode* node);
double ast_asreal(AstNode* node);
-AstNode* ast_op(int op, AstNode* left, AstNode* right);
+AstNode* ast_op(Parser* p, int op, AstNode* left, AstNode* right);
AstNode* ast_store(AstNode* dest, AstNode* value);
AstNode* ast_fieldref(Parser* p, AstNode* record, char* fname);
AstNode* ast_index(Parser* p, AstNode* array, AstNode* index);
void ast_print(Parser* p, AstNode* expr);
+
+
+
+
+bool ssa_asbool(SsaNode* node);
+long long ssa_asint(SsaNode* node);
+double ssa_asreal(SsaNode* node);
+
+SsaNode* ssa_ident(Parser* p, long long index);
+SsaNode* ssa_bool(Parser* p, bool val);
+SsaNode* ssa_int(Parser* p, long long val);
+SsaNode* ssa_real(Parser* p, double val);
+SsaNode* ssa_op(Parser* p, int op, SsaNode* left, SsaNode* right);
+
+SsaNode* ssa_store(Parser* p, SsaNode* dest, SsaNode* value);
+SsaNode* ssa_fieldref(Parser* p, SsaNode* record, char* fname);
+SsaNode* ssa_index(Parser* p, SsaNode* array, SsaNode* index);
+
+SsaBlock* ssa_block(void);
+void ssa_block_add(SsaBlock* blk, SsaNode* stmt);
+
+SsaNode* ssa_if(SsaNode* cond, SsaBlock* br1, SsaBlock* br2);
+SsaNode* ssa_return(SsaNode* expr);
+
+SsaNode* ssa_call(SsaNode* func);
+void ssa_call_add(SsaBlock* call, SsaNode* arg);
+
+void ssa_print(Parser* p, SsaNode* expr);
+void ssa_print_block(Parser* p, SsaBlock* block);
+
+
+
/* Backend Code Generation and Base Type Definitions
*****************************************************************************/
extern Type VoidType, BoolType, IntType, RealType, StringType;
return (AstNode*)node;
}
-AstNode* ast_bool(bool val)
+AstNode* ast_bool(Parser* p, bool val)
{
+ (void)p;
AstValue* node = (AstValue*)ast_new(BOOL, &BoolType, NULL, NULL, NULL);
node->val.i = val;
return (AstNode*)node;
}
-AstNode* ast_int(long long val)
+AstNode* ast_int(Parser* p, long long val)
{
+ (void)p;
AstValue* node = (AstValue*)ast_new(INT, &IntType, NULL, NULL, NULL);
node->val.i = val;
return (AstNode*)node;
}
-AstNode* ast_real(double val)
+AstNode* ast_real(Parser* p, double val)
{
+ (void)p;
AstValue* node = (AstValue*)ast_new(REAL, &RealType, NULL, NULL, NULL);
node->val.f = val;
return (AstNode*)node;
return ret;
}
-AstNode* ast_op(int op, AstNode* left, AstNode* right)
+AstNode* ast_op(Parser* p, int op, AstNode* left, AstNode* right)
{
+ (void)p;
return (right
? ast_binop(op, left, right)
: ast_unop(op, left));
AstNode* ast_fieldref(Parser* p, AstNode* record, char* fname)
{
Field* field = get_field(p, record->hdr.type, fname);
- AstNode* offset = ast_int(field->offset);
+ AstNode* offset = ast_int(p, field->offset);
if (record->hdr.code == '.')
{
/* accumulate the offset into an existing record access */
/* Grammar Definition
*****************************************************************************/
-static AstNode* expression(Parser* p);
+static SsaNode* expression(Parser* p);
-static AstNode* qualident(Parser* p)
+static SsaNode* qualident(Parser* p)
{
ENTER_RULE();
- AstNode* expr;
+ SsaNode* expr;
char* name = expect_text(p, IDENT);
size_t symid = symbol_getid(p, 0, name, -1);
Symbol* sym = symbol_getbyid(p, symid);
}
/* make the identifier with the final index */
- expr = ast_ident(p, symid);
+ expr = ssa_ident(p, symid);
EXIT_RULE();
return expr;
}
-static AstNode* designator(Parser* p)
+static SsaNode* designator(Parser* p)
{
ENTER_RULE();
- AstNode* expr = qualident(p);
+ SsaNode* expr = qualident(p);
/* selector */
for (int done = 0; !done;)
case '.':
{
expect(p, '.');
- if (expr->hdr.type->form != FORM_RECORD)
+ if (expr->type->form != FORM_RECORD)
{
error(p, "attempting to access field of non-array object");
}
char* name = expect_text(p, IDENT);
- expr = ast_fieldref(p, expr, name);
+ expr = ssa_fieldref(p, expr, name);
break;
}
case '[':
{
expect(p, '[');
- if (expr->hdr.type->form != FORM_ARRAY)
+ if (expr->type->form != FORM_ARRAY)
{
error(p, "attempting to index non-array value");
}
- AstNode* index = expression(p);
- check_int(p, index);
- expr = ast_index(p, expr, index);
+ SsaNode* index = expression(p);
+// check_int(p, index);
+ expr = ssa_index(p, expr, index);
expect(p, ']');
break;
}
return expr;
}
-static AstNode* factor(Parser* p)
+static SsaNode* factor(Parser* p)
{
ENTER_RULE();
- AstNode* expr = NULL;
+ SsaNode* expr = NULL;
switch ((int)peek(p)->type)
{
case INT:
- expr = ast_int(peek(p)->value.integer);
+ expr = ssa_int(p, peek(p)->value.integer);
consume(p);
break;
case REAL:
- expr = ast_real(peek(p)->value.floating);
+ expr = ssa_real(p, peek(p)->value.floating);
consume(p);
break;
case BOOL:
- expr = ast_bool(peek(p)->value.integer);
+ expr = ssa_bool(p, peek(p)->value.integer);
consume(p);
break;
case NOT:
consume(p);
- expr = ast_op(NOT, factor(p), NULL);
+ expr = ssa_op(p, NOT, factor(p), NULL);
break;
case IDENT:
expr = designator(p);
- if (accept(p, '('))
- {
- expr = ast_call(expr);
- if (expr->hdr.type->form != FORM_PROC)
- {
- error(p, "attempting to call a non-procedural value");
- }
-
- Field* args = expr->hdr.type->fields;
- while (args && !matches(p, ')'))
- {
- AstNode* val = expression(p);
- check_type(p, args->type, val);
- ast_call_add(expr, val);
- args = args->next;
- if (args)
- {
- expect(p, ',');
- }
- }
- if (args)
- {
- error(p, "too few arguments to function");
- }
- else if (!matches(p, ')'))
- {
- bool comma = accept(p, ',');
- if (comma && matches(p, ')'))
- {
- error(p, "trailing comma in argument list");
- }
- else
- {
- error(p, "too many arguments to function");
- }
- }
- expect(p, ')');
- }
+// if (accept(p, '('))
+// {
+// expr = ssa_call(expr);
+// if (expr->type->form != FORM_PROC)
+// {
+// error(p, "attempting to call a non-procedural value");
+// }
+//
+// Field* args = expr->type->fields;
+// while (args && !matches(p, ')'))
+// {
+// SsaNode* val = expression(p);
+// check_type(p, args->type, val);
+// ssa_call_add(expr, val);
+// args = args->next;
+// if (args)
+// {
+// expect(p, ',');
+// }
+// }
+// if (args)
+// {
+// error(p, "too few arguments to function");
+// }
+// else if (!matches(p, ')'))
+// {
+// bool comma = accept(p, ',');
+// if (comma && matches(p, ')'))
+// {
+// error(p, "trailing comma in argument list");
+// }
+// else
+// {
+// error(p, "too many arguments to function");
+// }
+// }
+// expect(p, ')');
+// }
break;
default:
return expr;
}
-
-static AstNode* term(Parser* p)
+static SsaNode* term(Parser* p)
{
ENTER_RULE();
- AstNode* expr = factor(p);
+ SsaNode* expr = factor(p);
while (matches_oneof(p, (int[]){'*', '/', '%', AND, 0}))
{
int op = consume(p);
- AstNode* right = factor(p);
+ SsaNode* right = factor(p);
switch(op)
{
case '*':
case '/':
case '%':
- check_nums(p, expr, right);
- expr = ast_op(op, expr, right);
+// check_nums(p, expr, right);
+ expr = ssa_op(p, op, expr, right);
break;
case AND:
- check_bools(p, expr, right);
- expr = ast_op(op, expr, right);
+// check_bools(p, expr, right);
+ expr = ssa_op(p, op, expr, right);
break;
default:
return expr;
}
-static AstNode* simple_expr(Parser* p)
+static SsaNode* simple_expr(Parser* p)
{
ENTER_RULE();
- AstNode* expr;
+ SsaNode* expr;
/* first term and +/- unary ops */
if (matches_oneof(p, (int[]){'+', '-', 0}))
{
int op = consume(p);
- AstNode* operand = term(p);
- check_num(p, operand);
- expr = ast_op(op, operand, NULL);
+ SsaNode* operand = term(p);
+// check_num(p, operand);
+ expr = ssa_op(p, op, operand, NULL);
}
else
{
while (matches_oneof(p, (int[]){'+', '-', OR, 0}))
{
int op = consume(p);
- AstNode* right = term(p);
+ SsaNode* right = term(p);
if (op == OR)
{
- check_bools(p, expr, right);
+// check_bools(p, expr, right);
}
else
{
- check_nums(p, expr, right);
+// check_nums(p, expr, right);
}
- expr = ast_op(op, expr, right);
+ expr = ssa_op(p, op, expr, right);
}
EXIT_RULE();
return expr;
}
-static AstNode* expression(Parser* p)
+static SsaNode* expression(Parser* p)
{
const int ops[] = { EQ, NEQ, '<', LTEQ, '>', GTEQ, 0 };
ENTER_RULE();
- AstNode* expr = simple_expr(p);
+ SsaNode* expr = simple_expr(p);
if (matches_oneof(p, ops))
{
int op = consume(p);
- AstNode* right = simple_expr(p);
- check_nums(p, expr, right);
- expr = ast_op(op, expr, right);
+ SsaNode* right = simple_expr(p);
+// check_nums(p, expr, right);
+ expr = ssa_op(p, op, expr, right);
}
EXIT_RULE();
}
else if (accept(p, ARRAY))
{
- AstNode* lnode = expression(p);
- if (!ast_isconst(lnode))
+ SsaNode* lnode = expression(p);
+ if (lnode->mode != MODE_CONST)
{
error(p, "non-constant array size");
}
- check_int(p, lnode);
- long long length = ast_asint(lnode);
+// check_int(p, lnode);
+ long long length = ssa_asint(lnode);
expect(p, OF);
Type* base = type(p);
ret = symbol_newtype(p);
return ret;
}
-static AstNode* statement_seq(Parser* p)
+static SsaBlock* statement_seq(Parser* p)
{
ENTER_RULE();
- AstNode* block = ast_block();
+ SsaBlock* block = ssa_block();
do
{
- if (matches(p, IF))
- {
- expect(p, IF);
- AstNode* cond = expression(p);
- check_bool(p, cond);
- expect(p, THEN);
- AstNode* blk1 = statement_seq(p);
- AstNode* blk2 = NULL;
- if (accept(p, ELSE))
- {
- blk2 = statement_seq(p);
- }
- ast_block_add(block, ast_if(cond, blk1, blk2));
- expect(p, END);
- }
- else /* assignments/expressions */
+// if (matches(p, IF))
+// {
+// expect(p, IF);
+// SsaNode* cond = expression(p);
+//// check_bool(p, cond);
+// expect(p, THEN);
+// SsaNode* blk1 = statement_seq(p);
+// SsaNode* blk2 = NULL;
+// if (accept(p, ELSE))
+// {
+// blk2 = statement_seq(p);
+// }
+// ssa_block_add(block, ssa_if(cond, blk1, blk2));
+// expect(p, END);
+// }
+// else /* assignments/expressions */
{
- AstNode* expr = expression(p);
+ SsaNode* expr = expression(p);
if (accept(p, '='))
{
- AstNode* right = expression(p);
- check_types(p, expr, right);
- expr = ast_store(expr, right);
+ SsaNode* right = expression(p);
+// check_types(p, expr, right);
+ expr = ssa_store(p, expr, right);
}
expect(p, ';');
- ast_block_add(block, expr);
+ ssa_block_add(block, expr);
}
}
while (!matches(p, END) && !matches(p, ELSE) && !matches(p, ELSIF) && !matches(p, RETURN));
export = accept(p, '*');
sym = symbol_new(p, 0, name, SYM_CONST, export);
expect(p, '=');
-// AstNode* block = ast_block();
-// expression(p, block);
-// sym->value = ast_lastval(block);
-// check_const(sym->value);
sym->value = expression(p);
- sym->type = sym->value->hdr.type;
+ sym->type = sym->value->type;
+ printf("%p\n", sym->value);
}
while (matches(p, IDENT));
/* parse the private declarations */
if (accept(p, CONST))
{
+ p->curr_block = ssa_block();
const_decl(p);
}
var_decl(p);
}
- /* parse the body of the procedure */
- expect(p, BEGIN);
- proc->value = ast_block();
- if (!matches(p, RETURN) && !matches(p, END))
- {
- ast_block_add(proc->value, statement_seq(p));
- }
- if (proctype->base != &VoidType)
- {
- expect(p, RETURN);
- AstNode* retval = expression(p);
- check_type(p, proctype->base, retval);
- ast_block_add(proc->value, ast_return(retval));
- expect(p, ';');
- }
- expect(p, END);
- symbol_closescope(p, scope);
-
- ast_print(p, proc->value);
- (void)proc->value;
+// /* parse the body of the procedure */
+// expect(p, BEGIN);
+// proc->value = ast_block();
+// if (!matches(p, RETURN) && !matches(p, END))
+// {
+// ast_block_add(proc->value, statement_seq(p));
+// }
+// if (proctype->base != &VoidType)
+// {
+// expect(p, RETURN);
+// AstNode* retval = expression(p);
+// check_type(p, proctype->base, retval);
+// ast_block_add(proc->value, ast_return(retval));
+// expect(p, ';');
+// }
+// expect(p, END);
+// symbol_closescope(p, scope);
+//
+// ast_print(p, proc->value);
+// (void)proc->value;
EXIT_RULE();
}
// }
if (!matches(p, END))
{
- AstNode* block = statement_seq(p);
- ast_print(p, block);
+ SsaBlock* block = statement_seq(p);
+// ast_print(p, block);
(void)block;
}
expect(p, END);
p->mtypes = 8;
p->types = calloc(p->mtypes, sizeof(Type*));
+ symbol_new(p, 0, "$", SYM_VAR, 0);
symbol_new(p, 0, "Bool", SYM_TYPE, 0)->type = &BoolType;
p->types[p->ntypes++] = &BoolType;
symbol_new(p, 0, "Int", SYM_TYPE, 0)->type = &IntType;
--- /dev/null
+#include <cerise.h>
+
+static SsaNode* ssa_node(int code, int mode);
+static SsaNode* binop(Parser* p, int op, SsaNode* left, SsaNode* right);
+static SsaNode* unop(Parser* p, int op, SsaNode* operand);
+static SsaNode* const_binop(Parser* p, int op, SsaNode* left, SsaNode* right);
+static SsaNode* const_unop(Parser* p, int op, SsaNode* operand);
+static SsaNode* load(Parser* p, SsaNode* node);
+
+bool ssa_asbool(SsaNode* node)
+{
+ assert(node->code == BOOL);
+ return (bool)(node->left.val.i);
+}
+
+long long ssa_asint(SsaNode* node)
+{
+ assert(node->code == INT);
+ return (bool)(node->left.val.i);
+}
+
+double ssa_asreal(SsaNode* node)
+{
+ assert(node->code == REAL);
+ return (bool)(node->left.val.f);
+}
+
+static SsaNode* ssa_node(int code, int mode)
+{
+ SsaNode* node = calloc(1, sizeof(SsaNode));
+ node->code = code;
+ node->mode = mode;
+ node->dest.symid = 0;
+ node->dest.symver = 0; /* TODO: increment temp ver */
+ return node;
+}
+
+SsaNode* ssa_ident(Parser* p, long long index)
+{
+ Symbol* sym = symbol_getbyid(p, index);
+ SsaNode* node = ssa_node(IDENT, MODE_VAR);
+ node->left.var.symid = index;
+ node->left.var.symver = sym->version;
+ return node;
+}
+
+SsaNode* ssa_bool(Parser* p, bool val)
+{
+ (void)p;
+ SsaNode* node = ssa_node(BOOL, MODE_CONST);
+ node->type = &BoolType;
+ node->left.val.i = val;
+ return node;
+}
+
+SsaNode* ssa_int(Parser* p, long long val)
+{
+ (void)p;
+ SsaNode* node = ssa_node(INT, MODE_CONST);
+ node->type = &IntType;
+ node->left.val.i = val;
+ return node;
+}
+
+SsaNode* ssa_real(Parser* p, double val)
+{
+ (void)p;
+ SsaNode* node = ssa_node(REAL, MODE_CONST);
+ node->type = &RealType;
+ node->left.val.f = val;
+ return node;
+}
+
+SsaNode* ssa_op(Parser* p, int op, SsaNode* left, SsaNode* right)
+{
+ return (right != NULL)
+ ? binop(p, op, left, right)
+ : unop(p, op, left);
+}
+
+SsaNode* ssa_store(Parser* p, SsaNode* dest, SsaNode* value)
+{
+ assert("!stores are not implemented");
+ load(p, value);
+ load(p, dest);
+ return NULL;
+}
+
+SsaNode* ssa_fieldref(Parser* p, SsaNode* record, char* fname)
+{
+ assert("!record field references unimplemented");
+ return NULL;
+}
+
+SsaNode* ssa_index(Parser* p, SsaNode* array, SsaNode* index)
+{
+ load(p, array);
+ load(p, index);
+ assert(!"array indexing unimplemented");
+ return NULL;
+}
+
+SsaBlock* ssa_block(void)
+{
+ return calloc(1, sizeof(SsaBlock));
+}
+
+void ssa_block_add(SsaBlock* blk, SsaNode* node)
+{
+ if (blk->head == 0)
+ {
+ blk->head = node;
+ blk->tail = node;
+ }
+ else
+ {
+ blk->tail->next = node;
+ blk->tail = node;
+ }
+}
+
+SsaNode* ssa_if(SsaNode* cond, SsaBlock* br1, SsaBlock* br2);
+SsaNode* ssa_return(SsaNode* expr);
+
+SsaNode* ssa_call(SsaNode* func);
+void ssa_call_add(SsaBlock* call, SsaNode* arg);
+
+
+
+
+
+void ssa_print_block(Parser* p, SsaBlock* block);
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+static SsaNode* binop(Parser* p, int op, SsaNode* left, SsaNode* right)
+{
+ SsaNode* node = NULL;
+ if (left->mode == MODE_CONST && right->mode == MODE_CONST)
+ {
+ node = const_binop(p, op, left, right);
+ }
+ else
+ {
+ left = load(p, left);
+ right = load(p, right);
+ node = ssa_node(op, MODE_OP);
+ node->type = left->type;
+ node->left.var = left->dest;
+ node->right.var = right->dest;
+ }
+ return node;
+}
+
+static SsaNode* unop(Parser* p, int op, SsaNode* operand)
+{
+ SsaNode* node = NULL;
+ if (operand->mode == MODE_CONST)
+ {
+ node = const_unop(p, op, operand);
+ }
+ else
+ {
+ operand = load(p, operand);
+ node = ssa_node(op, MODE_OP);
+ node->type = operand->type;
+ node->left.var = operand->dest;
+ }
+ return node;
+}
+
+static SsaNode* const_binop(Parser* p, int op, SsaNode* left, SsaNode* right)
+{
+ (void)p, (void)op, (void)left, (void)right;
+ /* perform the operation based on type and operator */
+ return NULL;
+}
+
+static SsaNode* const_unop(Parser* p, int op, SsaNode* operand)
+{
+ (void)p, (void)op, (void)operand;
+ /* perform the operation based on type and operator */
+ return NULL;
+}
+
+static SsaNode* load(Parser* p, SsaNode* node)
+{
+ if (!node->loaded)
+ {
+ ssa_block_add(p->curr_block, node);
+ node->loaded = 1;
+ }
+ return node;
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+//static void print_indent(int indent, char* str)
+//{
+// /* print the indent */
+// for (int i = 0; i < indent; i++)
+// {
+// printf(" ");
+// }
+// if (str)
+// {
+// printf("%s", str);
+// }
+//}
+//
+//static void print_opcode(SsaNode* node)
+//{
+// int op = node->code;
+// if (op < 256)
+// {
+// printf(" %c ", op);
+// }
+// else if (op == RETURN)
+// {
+// printf(" return ");
+// }
+// else if (op == IF)
+// {
+// printf("if ");
+// }
+// else
+// {
+// printf("(%d\n", op);
+// }
+//}
+//
+//static void print(Parser* p, AstNode* node, int indent)
+//{
+// assert(node);
+// print_indent(indent, NULL);
+//
+// /* now print the data */
+// switch(node->hdr.code)
+// {
+// case BOOL:
+// printf("B:%lld", ((AstValue*)node)->val.i);
+// break;
+//
+// case INT:
+// printf("I:%lld", ((AstValue*)node)->val.i);
+// break;
+//
+// case REAL:
+// printf("R:%f", ((AstValue*)node)->val.f);
+// break;
+//
+// case IDENT:
+// {
+// Symbol* s = symbol_getbyid(p, ((AstValue*)node)->val.i);
+// printf("%s.%lld", s->name, ((AstValue*)node)->tag);
+// }
+// break;
+//
+// case '.':
+// printf("(field-ref\n");
+// print(p, node->links[0], indent+1);
+// print(p, node->links[1], indent+1);
+// print_indent(indent, ")");
+// break;
+//
+// case '[':
+// printf("(array-index\n");
+// print(p, node->links[0], indent+1);
+// print(p, node->links[1], indent+1);
+// print_indent(indent, ")");
+// break;
+//
+// case BEGIN:
+// printf("(begin\n");
+// for (AstNode* curr = node->links[0]; curr; curr = curr->hdr.next)
+// {
+// print(p, curr, indent+1);
+// }
+// print_indent(indent, ")");
+// break;
+//
+// case CALL:
+// printf("(call\n");
+// print(p, node->links[0], indent+1);
+// for (AstNode* curr = node->links[1]; curr; curr = curr->hdr.next)
+// {
+// print(p, curr, indent+1);
+// }
+// print_indent(indent, ")");
+// break;
+//
+// case IF:
+// printf("(if\n");
+// print(p, node->links[0], indent+1);
+// print(p, node->links[1], indent+1);
+// if (node->links[2])
+// {
+// print(p, node->links[2], indent+1);
+// }
+// print_indent(indent, ")");
+// break;
+//
+// default:
+// if (node->links[1])
+// {
+// print_opcode(node);
+// print(p, node->links[0], indent+1);
+// print(p, node->links[1], indent+1);
+// print_indent(indent, ")");
+// }
+// else
+// {
+// print_opcode(node);
+// print(p, node->links[0], indent+1);
+// print_indent(indent, ")");
+// }
+// break;
+// }
+// puts("");
+//}
+//
+//void ast_print(Parser* p, AstNode* node)
+//{
+// print(p, node, 0);
+//}
+//
+void ssa_print(Parser* p, SsaNode* expr)
+{
+// switch (expr->code)
+// {
+// case
+// }
+}
/* TODO: read symbols from real symbol file */
// All of these should set ->module = modid
- Symbol* sym = symbol_new(p, 0, "testint", SYM_CONST, true);
+ Symbol* sym = symbol_new(p, 0, "testint", SYM_VAR, true);
sym->module = modid;
- sym->value = ast_int(42);
}
/* Symbol Table Unit Tests
B* = 42
C* = 42.0
D = -B
- E = -C
- F = not A
- G = B + 2 - 2 * 2
- H = false or A
+# E = -C
+# F = not A
+# G = B + 2 - 2 * 2
+# H = false or A
-type
- TypeA* = Int
- TypeB* = array 5*B of Int
- TypeC* = array 5 of array 10 of Int
- TypeD* = record
- x,y : Int
- label : array 10 of Int
- dim : record
- w,h : Int
- end
- end
- TypeE* = record
- i : Int
- a : array 5 of Int
- end
- TypeF* = array 5 of TypeE
+#type
+# TypeA* = Int
+# TypeB* = array 5*B of Int
+# TypeC* = array 5 of array 10 of Int
+# TypeD* = record
+# x,y : Int
+# label : array 10 of Int
+# dim : record
+# w,h : Int
+# end
+# end
+# TypeE* = record
+# i : Int
+# a : array 5 of Int
+# end
+# TypeF* = array 5 of TypeE
-var
- a* : Bool
- b* : Int
- c : Int
- d : Real
- e : array 5 of array 10 of Int
- f : TypeD
- g : array 5 of Int
- h : TypeF
+#var
+# a* : Bool
+# b* : Int
+# c : Int
+# d : Real
+# e : array 5 of array 10 of Int
+# f : TypeD
+# g : array 5 of Int
+# h : TypeF
#procedure Foo*(e : Int, z : Int, q1 : TypeD, q2 : array 5 of Int) : Int
# const FOO = 2
# end
#end
-begin
+#begin
# h[1].i = 42;
# a = true;
# a = A;
# Bar(Foo.testint);
# Bar(Bar2.testint);
# Bar(Bar3.testint);
-end
+#end