int size;
} Type;
-typedef struct {
- int code : 28;
- int mode : 4;
- struct AstNode* next;
- Type* type;
-} AstNodeHeader;
-
-typedef struct AstNode {
- AstNodeHeader hdr;
- struct AstNode* links[3];
-} AstNode;
-
-
-
typedef struct {
size_t symid;
size_t symver;
enum {
MODE_CONST = 0,
MODE_VAR = 1,
- MODE_OP = 2,
- MODE_CONTROL = 3,
-};
+ MODE_CONTROL = 2,
+ MODE_UNOP = 3,
+ MODE_BINOP = 4,
+/*
+ MODE_UV = 3,
+ MODE_UC = 4,
+ MODE_BVV = 5,
+ MODE_BVC = 6,
+ MODE_BCV = 7,
+*/
+};
typedef struct Symbol {
enum{
long align_item(long offset, long size);
long size_of(Type* type);
-// src/ast.c
-bool ast_isconst(AstNode* node);
-bool ast_areconst(AstNode* left, AstNode* right);
-
-AstNode* ast_ident(Parser* p, long long index);
-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(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);
-
-AstNode* ast_block(void);
-void ast_block_add(AstNode* blk, AstNode* stmt);
-AstNode* ast_call(AstNode* func);
-void ast_call_add(AstNode* func, AstNode* arg);
-AstNode* ast_if(AstNode* cond, AstNode* br1, AstNode* br2);
-AstNode* ast_return(AstNode* expr);
-
-void ast_print(Parser* p, AstNode* expr);
-
-
-
-
-
+// src/ssa.c
bool ssa_asbool(SsaNode* node);
long long ssa_asint(SsaNode* node);
double ssa_asreal(SsaNode* node);
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;
{
// p->curr_block = ssa_block();
SsaBlock* block = statement_seq(p);
-// ssa_print_block(block);
+ ssa_print_block(p, block);
(void)block;
}
expect(p, END);
else
{
node = ssa_node(IDENT, MODE_VAR);
+ node->type = sym->type;
node->left.var.symid = index;
node->left.var.symver = sym->version;
}
-void ssa_print_block(Parser* p, SsaBlock* block);
{
left = load(p, left);
right = load(p, right);
- node = ssa_node(op, MODE_OP);
+ node = ssa_node(op, MODE_BINOP);
node->type = left->type;
node->left.var = left->dest;
node->right.var = right->dest;
else
{
operand = load(p, operand);
- node = ssa_node(op, MODE_OP);
+ node = ssa_node(op, MODE_UNOP);
node->type = operand->type;
node->left.var = operand->dest;
}
static SsaNode* load(Parser* p, SsaNode* node)
{
+// if (!node->loaded && (node->mode != MODE_CONST) && (node->mode != MODE_VAR))
if (!node->loaded)
{
+// if (node->dest.symid == 0)
+// {
+// node->dest.symver++;
+// }
ssa_block_add(p->curr_block, node);
node->loaded = 1;
}
// print(p, node, 0);
//}
+
+static void print_ident(Parser* p, SsaVar* var)
+{
+ Symbol* s = symbol_getbyid(p, var->symid);
+ printf("%s.%lu", s->name, var->symver);
+}
+
+static void print_dest(Parser* p, SsaNode* node)
+{
+ print_ident(p, &(node->dest));
+ printf(" = ");
+}
+
void ssa_print(Parser* p, SsaNode* expr)
{
(void)p;
switch(expr->code)
{
+ case IDENT:
+ print_ident(p, &(expr->left.var));
+ break;
+
case BOOL:
- printf("(Bool)%d\n", ssa_asbool(expr));
+ printf("(Bool)%d", ssa_asbool(expr));
break;
case INT:
- printf("(Int)%lld\n", ssa_asint(expr));
+ printf("(Int)%lld", ssa_asint(expr));
break;
case REAL:
- printf("(Real)%f\n", ssa_asreal(expr));
+ printf("(Real)%f", ssa_asreal(expr));
break;
default:
- printf("???\n");
+ if (expr->mode == MODE_VAR)
+ {
+ print_ident(p, &(expr->left.var));
+ }
+ else if (expr->mode == MODE_UNOP)
+ {
+ printf("unary op");
+ }
+ else if (expr->mode == MODE_BINOP)
+ {
+ printf("binary op");
+ }
+ else
+ {
+ printf("??? M:%d C:%d\n", expr->mode, expr->code);
+ }
break;
}
}
+
+void ssa_print_block(Parser* p, SsaBlock* block)
+{
+ printf("L%lu:\n", block->id);
+ for (SsaNode* node = block->head; node; node = node->next)
+ {
+ printf(" ");
+ print_dest(p, node);
+ ssa_print(p, node);
+ puts("");
+ }
+}
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;
# b = -b;
#
# # Arithmetic ops
-# c = b + 1;
+ c = b + 1;
# c = b - 1;
# c = b * 1;
# c = b / 1;
# Bar(Foo.testint);
# Bar(Bar2.testint);
# Bar(Bar3.testint);
-#end
+end