{
case INT:
case BOOL:
- printf(" $%ld = %ld\n", op->u.args[0].i, op->u.args[1].i);
+ printf(" $%lld = %lld\n", op->u.args[0].i, op->u.args[1].i);
break;
case REAL:
- printf(" $%ld = %f\n", op->u.args[0].i, op->u.args[1].f);
+ printf(" $%lld = %f\n", op->u.args[0].i, op->u.args[1].f);
+ break;
+
+ default:
+ printf(" <unprintable op %d >\n", op->code);
break;
}
}
Ops[NumOps++] = op;
}
+static void ir_bool(Parser* p, bool val)
+{
+ Operation* op = calloc(1, sizeof(Operation));
+ op->code = BOOL;
+ op->mode = IR_MODE_CONST;
+ op->type = &BoolType;
+ op->u.args[0].i = p->curr_reg++;
+ op->u.args[1].i = (long)val;
+ ir_push(op);
+}
+
static void ir_int(Parser* p, long val)
{
Operation* op = calloc(1, sizeof(Operation));
op->code = INT;
- op->mode = IR_CONST;
+ op->mode = IR_MODE_CONST;
+ op->type = &IntType;
op->u.args[0].i = p->curr_reg++;
op->u.args[1].i = val;
- print_op(op);
ir_push(op);
}
{
Operation* op = calloc(1, sizeof(Operation));
op->code = REAL;
- op->mode = IR_CONST;
+ op->mode = IR_MODE_CONST;
+ op->type = &RealType;
op->u.args[0].i = p->curr_reg++;
op->u.args[1].f = val;
- print_op(op);
ir_push(op);
}
static void ir_getconst(Parser* p, Symbol* sym)
{
Operation* op = ir_pop();
- if (op->mode != IR_CONST)
+ print_op(op);
+ if (op->mode != IR_MODE_CONST)
{
error(p, "Constant definition is non-constant");
}
-// sym->type = op->type;
- if (op->code == INT)
- {
- sym->imm.i = op->u.args[1].i;
- }
- else
- {
- sym->imm.i = op->u.args[1].f;
- }
+ sym->type = op->type;
+ sym->imm = op->u.args[1];
}
static void ir_unop(Parser* p, int op)
{
Operation* a = ir_pop();
- if (a->mode == IR_CONST)
+ if (a->mode == IR_MODE_CONST)
{
if (a->code == INT)
{
{
case '+': a->u.args[1].i = +a->u.args[1].i; break;
case '-': a->u.args[1].i = -a->u.args[1].i; break;
- default: assert(!"not a valid op"); break;
+ default:
+ error(p, "invalid unary operation on integer value");
+ break;
}
}
else if (a->code == REAL)
{
case '+': a->u.args[1].f = +a->u.args[1].f; break;
case '-': a->u.args[1].f = -a->u.args[1].f; break;
- default: assert(!"not a valid op"); break;
+ default:
+ error(p, "invalid unary operation on real value");
+ break;
}
}
else if (a->code == BOOL)
switch (op)
{
case NOT: a->u.args[1].i = !a->u.args[1].i; break;
- default: assert(!"not a valid op"); break;
+ default:
+ error(p, "invalid unary operation on boolean value");
+ break;
}
}
}
else
{
- assert(!"unimplemented unary op");
+ error(p, "unimplemented unary operation");
}
- print_op(a);
ir_push(a);
}
+void ir_load(Parser* p, char* name)
+{
+ size_t id = symbol_getid(p, name, -1);
+ Symbol* sym = symbol_getbyid(p, id);
+
+ Operation* op = calloc(1, sizeof(Operation));
+ op->type = sym->type;
+ switch (sym->class)
+ {
+ case SYM_CONST:
+ op->mode = IR_MODE_CONST;
+ op->u.args[0].i = p->curr_reg++;
+ op->u.args[1] = sym->imm;
+ if (sym->type == &IntType)
+ {
+ op->code = INT;
+ }
+ else if (sym->type == &RealType)
+ {
+ op->code = REAL;
+ }
+ else if (sym->type == &BoolType)
+ {
+ op->code = BOOL;
+ }
+ else
+ {
+ error(p, "constant definition has unexpected type");
+ }
+ break;
+
+ case SYM_VAR:
+ op->code = VAR;
+ op->mode = IR_MODE_VAR;
+ op->u.args[0].i = p->curr_reg++;
+ op->u.args[1].i = id;
+ break;
+
+ case SYM_PROC:
+ op->code = VAR;
+ op->mode = IR_MODE_VAR;
+ op->u.args[0].i = p->curr_reg++;
+ op->u.args[1].i = id;
+ break;
+
+ case SYM_TYPE:
+ op->code = TYPE;
+ op->mode = IR_MODE_INFO;
+ break;
+
+ default:
+ break;
+ }
+ ir_push(op);
+}
+
/* Item Handling
*****************************************************************************/
Field* add_field(Parser* p, Type* type, char* name, bool export)
*****************************************************************************/
static void expression(Parser* p);
-//RULE(qualident, Item* item)
-//{
-// ENTER_RULE();
-// char* name = expect_text(p, IDENT);
-// Symbol* sym = symbol_get(p, name, -1);
-// init_item(item, sym);
-// (void)sym;
-//
-//// if (accept(p, '.'))
-//// {
-//// expect(p, IDENT);
-//// }
-// EXIT_RULE();
-//}
-//
-//RULE(designator, Item* item)
-//{
-// ENTER_RULE();
-// qualident(p, item);
+static void qualident(Parser* p)
+{
+ ENTER_RULE();
+
+ char* name = expect_text(p, IDENT);
+ ir_load(p, name);
+
+// if (accept(p, '.'))
+// {
+// expect(p, IDENT);
+// }
+
+ EXIT_RULE();
+}
+
+static void designator(Parser* p)
+{
+ ENTER_RULE();
+ qualident(p);
// /* selector */
// for (int done = 0; !done;)
// {
// break;
// }
// }
-// EXIT_RULE();
-//}
+ EXIT_RULE();
+}
static void factor(Parser* p)
{
// break;
case BOOL:
- ir_int(p, peek(p)->value.integer);
+ ir_bool(p, peek(p)->value.integer);
consume(p);
break;
-// case '(':
-// expect(p, '(');
-// expression(p, item);
-// expect(p, ')');
-// break;
+ case '(':
+ expect(p, '(');
+ expression(p);
+ expect(p, ')');
+ break;
-// case NOT:
-// consume(p);
-// factor(p, item);
-// check_bool(p, item);
-// codegen_unop(p, NOT, item);
-// break;
+ case NOT:
+ consume(p);
+ factor(p);
+ ir_unop(p, NOT);
+ break;
-// case IDENT:
-// designator(p, item);
+ case IDENT:
+ designator(p);
// if (accept(p, '('))
// {
// Symbol* proc = symbol_get(p, item->imm.s, SYM_PROC);
// codegen_call(p, item, arglist.next);
// expect(p, ')');
// }
-// break;
+ break;
default:
printf("unknown factor: %d\n", peek(p)->type);
int op = consume(p); // OP
term(p);
ir_unop(p, op);
-// check_num(p, item);
-// codegen_unop(p, op, item);
}
else
{