static void print_ident(Parser* p, SsaVar* var)
{
Symbol* s = symbol_getbyid(p, var->symid);
+ assert(s);
+ assert(s->name);
char* name = (s->name[0] == '$' ? "" : s->name);
if ((s->global || s->class == SYM_PROC) && (s->class != SYM_TYPE))
{
print_oparg(p, expr->right);
puts("");
}
+ else if (expr->code == '.')
+ {
+ printf(" ");
+ print_ident(p, &(SSA_VAR(expr)));
+ printf(" = getelementptr ");
+ emit_type(SSA_LTYPE(expr));
+ printf(", ");
+ emit_type(SSA_LTYPE(expr));
+ printf("* ");
+ print_ident(p, &(SSA_LVAR(expr)));
+ printf(", i64 0");
+ int num = 0;
+ char* fname = ssa_asstring(expr->right);
+ struct Field* field = SSA_LTYPE(expr)->fields;
+ for (; field; field = field->next, num++)
+ {
+ if (!strcmp(fname, field->name))
+ {
+ break;
+ }
+ }
+ printf(", i32 %d", num);
+ puts("");
+ }
else
{
assert(!"not implemented");
SsaVar var;
SsaConst val;
struct SsaBlock* block;
+ char* str;
} SsaValue;
//typedef struct SsaNode {
bool ssa_asbool(SsaNode* node);
long long ssa_asint(SsaNode* node);
double ssa_asreal(SsaNode* node);
+char* ssa_asstring(SsaNode* node);
void ssa_join(Parser* p);
void ssa_reset_vars(Parser* p);
SsaNode* ssa_bool(Parser* p, bool val);
SsaNode* ssa_int(Parser* p, long long val);
SsaNode* ssa_real(Parser* p, double val);
+SsaNode* ssa_string(Parser* p, char* val);
SsaNode* ssa_op(Parser* p, int op, SsaNode* left, SsaNode* right);
SsaNode* ssa_store(Parser* p, SsaNode* dest, SsaNode* value);
return (SSA_VAL(node).f);
}
+char* ssa_asstring(SsaNode* node)
+{
+ assert(node->code == STRING);
+ return (SSA_VAL(node).s);
+}
+
/*
* store backup values for var versions, restore at the end of block
* popping a join node processes phis as stores propagating phis to outer join nodes
return node;
}
+SsaNode* ssa_string(Parser* p, char* val)
+{
+ (void)p;
+ SsaNode* node = ssa_node(STRING, MODE_CONST);
+ node->type = &StringType;
+ SSA_VAL(node).s = val;
+ return node;
+}
+
SsaNode* ssa_op(Parser* p, int op, SsaNode* left, SsaNode* right)
{
return (right != NULL)
SsaNode* ssa_store(Parser* p, SsaNode* dest, SsaNode* value)
{
value = load(p, value);
- if (dest->mode == MODE_MEMORY && dest->code == '[')
+ if (dest->mode == MODE_MEMORY && (dest->code == '[' || dest->code == '.'))
{
dest = load(p, dest);
}
SsaNode* ssa_fieldref(Parser* p, SsaNode* record, char* fname)
{
-#if 1
- (void)p, (void)record, (void)fname;
- assert(!"record field references unimplemented");
- return NULL;
-#else
- if (record->mode == MODE_MEMORY && record->code == '[')
+ if (record->mode == MODE_MEMORY && (record->code == '[' || record->code == '.'))
{
record = load(p, record);
}
- index = load(p, index);
- SsaNode* node = ssa_node('[', MODE_MEMORY);
- node->type = array->type->base;
- node->left = array;
- node->right = index;
+
+ /* make sure the referenced field exists */
+ struct Field* field = record->type->fields;
+ for (; field; field = field->next)
+ {
+ if (!strcmp(fname, field->name))
+ {
+ break;
+ }
+ }
+ if (!field)
+ {
+ error(p, "record has no field named '%s'", fname);
+ }
+
+ /* now create and return the node */
+ SsaNode* node = ssa_node('.', MODE_MEMORY);
+ node->type = field->type;
+ node->left = record;
+ node->right = ssa_string(p, fname);
return node;
-#endif
}
SsaNode* ssa_index(Parser* p, SsaNode* array, SsaNode* index)
{
- if (array->mode == MODE_MEMORY && array->code == '[')
+ if (array->mode == MODE_MEMORY && (array->code == '[' || array->code == '.'))
{
array = load(p, array);
}
static SsaNode* loadmem(Parser* p, SsaNode* node)
{
node = load(p, node);
- if (node->mode == MODE_MEMORY && node->code == '[')
+ if (node->mode == MODE_MEMORY && (node->code == '[' || node->code == '.'))
{
SsaNode* load_op = ssa_node(LOAD, MODE_MEMORY);
load_op->left = node;