From: Michael D. Lowis Date: Thu, 10 Jun 2021 20:44:21 +0000 (-0400) Subject: commented out a bunch of code in preparation for IR overhaul X-Git-Url: https://git.mdlowis.com/?a=commitdiff_plain;h=a54ee78fb16d4ad0ee93dba664603363e4782b91;p=proto%2Fobnc.git commented out a bunch of code in preparation for IR overhaul --- diff --git a/cerise/backend/ssa/codegen.c b/cerise/backend/ssa/codegen.c index 1ddc6db..056efd7 100644 --- a/cerise/backend/ssa/codegen.c +++ b/cerise/backend/ssa/codegen.c @@ -21,207 +21,207 @@ Type StringType = { .form = FORM_STRING, .size = -1 }; - - -static size_t MaxBlocks = 0; -static size_t NumBlocks = 0; -static Block* Blocks = NULL; -static size_t Level = 0; -static struct { - size_t curr; - size_t join; -} Levels[32] = {0}; - -static size_t block_new(void) -{ - if (NumBlocks == MaxBlocks) - { - MaxBlocks = (MaxBlocks ? 16u : (MaxBlocks << 1u)); - Blocks = realloc(Blocks, MaxBlocks * sizeof(Block)); - } - memset(&Blocks[NumBlocks], 0, sizeof(Block)); - NumBlocks++; - return (NumBlocks-1); -} - -static void put_op(Operation* op) -{ - Block* block = &Blocks[Levels[Level].curr]; - if (block->nops == block->mops) - { - block->mops = (block->mops ? 4u : (block->mops << 1u)); - block->ops = realloc(block->ops, block->mops * sizeof(Operation)); - } - block->ops[block->nops++] = *op; -} - -static void load_var(Parser* p, Item* item) -{ - if (!item->reg) - { - switch (item->mode) - { - case ITEM_CONST: - /* TODO: range check the constant */ - item->reg = p->curr_reg++; - printf(" $%d = %lld;\n", item->reg, item->imm.i); - break; - -// case ITEM_VAR: -// item->reg = declare_temp(p, item->type, isref); -// if (item->type->form == FORM_RECORD) -// { -// printf(" = (Byte*)&%s[0];\n", item->imm.s); -// } -// else -// { -// printf(" = %c%s;\n", (isref ? '&' : ' '), item->imm.s); -// } -// item->imm.i = 0; -// break; // -// case ITEM_MVAR: -// item->reg = declare_temp(p, item->type, isref); -// if (item->type->form == FORM_RECORD) -// { -// printf(" = &%s_%s[0];\n", p->name, item->imm.s); -// } -// else -// { -// printf(" = %c%s_%s;\n", (isref ? '&' : ' '), p->name, item->imm.s); -// } -// item->imm.i = 0; +// +//static size_t MaxBlocks = 0; +//static size_t NumBlocks = 0; +//static Block* Blocks = NULL; +//static size_t Level = 0; +//static struct { +// size_t curr; +// size_t join; +//} Levels[32] = {0}; +// +//static size_t block_new(void) +//{ +// if (NumBlocks == MaxBlocks) +// { +// MaxBlocks = (MaxBlocks ? 16u : (MaxBlocks << 1u)); +// Blocks = realloc(Blocks, MaxBlocks * sizeof(Block)); +// } +// memset(&Blocks[NumBlocks], 0, sizeof(Block)); +// NumBlocks++; +// return (NumBlocks-1); +//} +// +//static void put_op(Operation* op) +//{ +// Block* block = &Blocks[Levels[Level].curr]; +// if (block->nops == block->mops) +// { +// block->mops = (block->mops ? 4u : (block->mops << 1u)); +// block->ops = realloc(block->ops, block->mops * sizeof(Operation)); +// } +// block->ops[block->nops++] = *op; +//} +// +//static void load_var(Parser* p, Item* item) +//{ +// if (!item->reg) +// { +// switch (item->mode) +// { +// case ITEM_CONST: +// /* TODO: range check the constant */ +// item->reg = p->curr_reg++; +// printf(" $%d = %lld;\n", item->reg, item->imm.i); // break; - - default: - assert(!"bad load_var()"); - } - } -} - - - - -void codegen_startmod(Parser* p) -{ - (void)p; -} - -void codegen_endmod(Parser* p) -{ - (void)p; -} - -void codegen_setint(Item* item, Type* type, long long val) -{ - item->mode = ITEM_CONST; - item->type = type; - item->reg = 0; - item->imm.i = val; -} - -void codegen_setreal(Item* item, double val) -{ - item->mode = ITEM_CONST; - item->type = &RealType; - item->reg = 0; - item->imm.f = val; -} - -void codegen_setstr(Item* item, char* val) -{ - item->mode = ITEM_CONST; - item->type = &StringType; - item->reg = 0; - item->imm.s = val; -} - -void codegen_imports(Parser* p) -{ - (void)p; -} - -void codegen_var(Parser* p, Symbol* sym) -{ - (void)p, (void)sym; -} - -void codegen_main(Parser* p) -{ - (void)p; -} - -void codegen_startproc(Parser* p, Symbol* proc) -{ - (void)p, (void)proc; - printf("func %s(){\n", (proc ? proc->name : p->name)); - printf("L%lu:\n", block_new()); -} - -void codegen_endproc(Parser* p) -{ - (void)p; - printf("}\n"); -} - -void codegen_unop(Parser* p, int op, Item* a) -{ - (void)p, (void)op, (void)a; -} - -void codegen_binop(Parser* p, int op, Item* a, Item* b) -{ - (void)p, (void)op, (void)a, (void)b; -} - -void codegen_store(Parser* p, Item* a, Item* b) -{ - (void)p, (void)a, (void)b; - load_var(p, b); -} - -void codegen_if(Parser* p, Item* item) -{ - (void)p, (void)item; -} - -void codegen_else(Parser* p, Item* item) -{ - (void)p, (void)item; -} - -void codegen_endif(Parser* p, long elsifs, Item* item) -{ - (void)p, (void)elsifs, (void)item; -} - -void codegen_prepcall(Parser* p, Item* item) -{ - (void)p, (void)item; -} - -void codegen_call(Parser* p, Item* item, Item* args) -{ - (void)p, (void)item, (void)args; -} - -void codegen_setarg(Parser* p, Item* item, bool firstarg) -{ - (void)p, (void)item, (void)firstarg; -} - -void codegen_return(Parser* p, Item* item) -{ - (void)p, (void)item; -} - -void codegen_index(Parser* p, Item* array, Item* index) -{ - (void)p, (void)array, (void)index; -} - -void codegen_field(Parser* p, Item* record, char* name) -{ - (void)p, (void)record, (void)name; -} - +// +//// case ITEM_VAR: +//// item->reg = declare_temp(p, item->type, isref); +//// if (item->type->form == FORM_RECORD) +//// { +//// printf(" = (Byte*)&%s[0];\n", item->imm.s); +//// } +//// else +//// { +//// printf(" = %c%s;\n", (isref ? '&' : ' '), item->imm.s); +//// } +//// item->imm.i = 0; +//// break; +//// +//// case ITEM_MVAR: +//// item->reg = declare_temp(p, item->type, isref); +//// if (item->type->form == FORM_RECORD) +//// { +//// printf(" = &%s_%s[0];\n", p->name, item->imm.s); +//// } +//// else +//// { +//// printf(" = %c%s_%s;\n", (isref ? '&' : ' '), p->name, item->imm.s); +//// } +//// item->imm.i = 0; +//// break; +// +// default: +// assert(!"bad load_var()"); +// } +// } +//} +// +// +// +// +//void codegen_startmod(Parser* p) +//{ +// (void)p; +//} +// +//void codegen_endmod(Parser* p) +//{ +// (void)p; +//} +// +//void codegen_setint(Item* item, Type* type, long long val) +//{ +// item->mode = ITEM_CONST; +// item->type = type; +// item->reg = 0; +// item->imm.i = val; +//} +// +//void codegen_setreal(Item* item, double val) +//{ +// item->mode = ITEM_CONST; +// item->type = &RealType; +// item->reg = 0; +// item->imm.f = val; +//} +// +//void codegen_setstr(Item* item, char* val) +//{ +// item->mode = ITEM_CONST; +// item->type = &StringType; +// item->reg = 0; +// item->imm.s = val; +//} +// +//void codegen_imports(Parser* p) +//{ +// (void)p; +//} +// +//void codegen_var(Parser* p, Symbol* sym) +//{ +// (void)p, (void)sym; +//} +// +//void codegen_main(Parser* p) +//{ +// (void)p; +//} +// +//void codegen_startproc(Parser* p, Symbol* proc) +//{ +// (void)p, (void)proc; +// printf("func %s(){\n", (proc ? proc->name : p->name)); +// printf("L%lu:\n", block_new()); +//} +// +//void codegen_endproc(Parser* p) +//{ +// (void)p; +// printf("}\n"); +//} +// +//void codegen_unop(Parser* p, int op, Item* a) +//{ +// (void)p, (void)op, (void)a; +//} +// +//void codegen_binop(Parser* p, int op, Item* a, Item* b) +//{ +// (void)p, (void)op, (void)a, (void)b; +//} +// +//void codegen_store(Parser* p, Item* a, Item* b) +//{ +// (void)p, (void)a, (void)b; +// load_var(p, b); +//} +// +//void codegen_if(Parser* p, Item* item) +//{ +// (void)p, (void)item; +//} +// +//void codegen_else(Parser* p, Item* item) +//{ +// (void)p, (void)item; +//} +// +//void codegen_endif(Parser* p, long elsifs, Item* item) +//{ +// (void)p, (void)elsifs, (void)item; +//} +// +//void codegen_prepcall(Parser* p, Item* item) +//{ +// (void)p, (void)item; +//} +// +//void codegen_call(Parser* p, Item* item, Item* args) +//{ +// (void)p, (void)item, (void)args; +//} +// +//void codegen_setarg(Parser* p, Item* item, bool firstarg) +//{ +// (void)p, (void)item, (void)firstarg; +//} +// +//void codegen_return(Parser* p, Item* item) +//{ +// (void)p, (void)item; +//} +// +//void codegen_index(Parser* p, Item* array, Item* index) +//{ +// (void)p, (void)array, (void)index; +//} +// +//void codegen_field(Parser* p, Item* record, char* name) +//{ +// (void)p, (void)record, (void)name; +//} +// diff --git a/cerise/inc/cerise.h b/cerise/inc/cerise.h index 716389a..ce835a5 100644 --- a/cerise/inc/cerise.h +++ b/cerise/inc/cerise.h @@ -141,7 +141,7 @@ typedef struct { Tok tok; Module* imports; char* name; - int curr_reg; + long curr_reg; size_t msyms; size_t nsyms; Symbol* syms; @@ -229,15 +229,20 @@ void codegen_return(Parser* p, Item* item); void codegen_index(Parser* p, Item* array, Item* index); void codegen_field(Parser* p, Item* record, char* name); +enum { + IR_CONST +}; + typedef union { long i; double f; char* s; } Operand; -typedef struct { +typedef struct Operation { +// struct Operation* next; int code : 28; - int type : 4; + int mode : 4; union { Operand args[3]; struct { diff --git a/cerise/src/const_ops.c b/cerise/src/const_ops.c index eedd955..532f8f3 100644 --- a/cerise/src/const_ops.c +++ b/cerise/src/const_ops.c @@ -1,142 +1,142 @@ #include "cerise.h" - -int items_const(Item* a, Item* b) -{ - return ((a->mode == ITEM_CONST) && (b->mode == ITEM_CONST)); -} - -void const_binop(int op, Item* a, Item* b) -{ - if (a->type->form == FORM_INT || a->type->form == FORM_BOOL) - { - switch (op) - { - case '+': a->imm.i = a->imm.i + b->imm.i; break; - case '-': a->imm.i = a->imm.i - b->imm.i; break; - case '*': a->imm.i = a->imm.i * b->imm.i; break; - case '/': a->imm.i = a->imm.i / b->imm.i; break; - case '%': a->imm.i = a->imm.i % b->imm.i; break; - case AND: a->imm.i = a->imm.i && b->imm.i; break; - case OR: a->imm.i = a->imm.i || b->imm.i; break; - - case EQ: - a->imm.i = a->imm.i == b->imm.i; - a->type = &BoolType; - break; - - case NEQ: - a->imm.i = a->imm.i != b->imm.i; - a->type = &BoolType; - break; - - case '<': - a->imm.i = a->imm.i < b->imm.i; - a->type = &BoolType; - break; - - case LTEQ: - a->imm.i = a->imm.i <= b->imm.i; - a->type = &BoolType; - break; - - case '>': - a->imm.i = a->imm.i > b->imm.i; - a->type = &BoolType; - break; - - case GTEQ: - a->imm.i = a->imm.i >= b->imm.i; - a->type = &BoolType; - break; - -// case IS: break; - - default: - assert(!"not a valid op"); - break; - } - } - else if (a->type->form == FORM_REAL) - { - switch (op) - { - case '+': a->imm.f = a->imm.f + b->imm.f; break; - case '-': a->imm.f = a->imm.f - b->imm.f; break; - case '*': a->imm.f = a->imm.f * b->imm.f; break; - case '/': a->imm.f = a->imm.f / b->imm.f; break; - - case EQ: - a->imm.f = a->imm.f == b->imm.f; - a->type = &BoolType; - break; - - case NEQ: - a->imm.f = a->imm.f != b->imm.f; - a->type = &BoolType; - break; - - case '<': - a->imm.f = a->imm.f < b->imm.f; - a->type = &BoolType; - break; - - case LTEQ: - a->imm.f = a->imm.f <= b->imm.f; - a->type = &BoolType; - break; - - case '>': - a->imm.f = a->imm.f > b->imm.f; - a->type = &BoolType; - break; - - case GTEQ: - a->imm.f = a->imm.f >= b->imm.f; - a->type = &BoolType; - break; - - default: - assert(!"not a valid op"); - break; - } - } - else - { - assert(!"not a valid form"); - } -} - -void const_unop(Parser* p, int op, Item* a) -{ - (void)p; - if (a->type->form == FORM_INT) - { - switch (op) - { - case '+': a->imm.i = +a->imm.i; break; - case '-': a->imm.i = -a->imm.i; break; - default: assert(!"not a valid op"); break; - } - } - else if (a->type->form == FORM_REAL) - { - switch (op) - { - case '+': a->imm.f = +a->imm.f; break; - case '-': a->imm.f = -a->imm.f; break; - default: assert(!"not a valid op"); break; - } - } - else if (a->type->form == FORM_BOOL) - { - switch (op) - { - case NOT: a->imm.i = !a->imm.i; break; - default: assert(!"not a valid op"); break; - } - } - else - { - assert(!"not a valid form"); - } -} +// +//int items_const(Item* a, Item* b) +//{ +// return ((a->mode == ITEM_CONST) && (b->mode == ITEM_CONST)); +//} +// +//void const_binop(int op, Item* a, Item* b) +//{ +// if (a->type->form == FORM_INT || a->type->form == FORM_BOOL) +// { +// switch (op) +// { +// case '+': a->imm.i = a->imm.i + b->imm.i; break; +// case '-': a->imm.i = a->imm.i - b->imm.i; break; +// case '*': a->imm.i = a->imm.i * b->imm.i; break; +// case '/': a->imm.i = a->imm.i / b->imm.i; break; +// case '%': a->imm.i = a->imm.i % b->imm.i; break; +// case AND: a->imm.i = a->imm.i && b->imm.i; break; +// case OR: a->imm.i = a->imm.i || b->imm.i; break; +// +// case EQ: +// a->imm.i = a->imm.i == b->imm.i; +// a->type = &BoolType; +// break; +// +// case NEQ: +// a->imm.i = a->imm.i != b->imm.i; +// a->type = &BoolType; +// break; +// +// case '<': +// a->imm.i = a->imm.i < b->imm.i; +// a->type = &BoolType; +// break; +// +// case LTEQ: +// a->imm.i = a->imm.i <= b->imm.i; +// a->type = &BoolType; +// break; +// +// case '>': +// a->imm.i = a->imm.i > b->imm.i; +// a->type = &BoolType; +// break; +// +// case GTEQ: +// a->imm.i = a->imm.i >= b->imm.i; +// a->type = &BoolType; +// break; +// +//// case IS: break; +// +// default: +// assert(!"not a valid op"); +// break; +// } +// } +// else if (a->type->form == FORM_REAL) +// { +// switch (op) +// { +// case '+': a->imm.f = a->imm.f + b->imm.f; break; +// case '-': a->imm.f = a->imm.f - b->imm.f; break; +// case '*': a->imm.f = a->imm.f * b->imm.f; break; +// case '/': a->imm.f = a->imm.f / b->imm.f; break; +// +// case EQ: +// a->imm.f = a->imm.f == b->imm.f; +// a->type = &BoolType; +// break; +// +// case NEQ: +// a->imm.f = a->imm.f != b->imm.f; +// a->type = &BoolType; +// break; +// +// case '<': +// a->imm.f = a->imm.f < b->imm.f; +// a->type = &BoolType; +// break; +// +// case LTEQ: +// a->imm.f = a->imm.f <= b->imm.f; +// a->type = &BoolType; +// break; +// +// case '>': +// a->imm.f = a->imm.f > b->imm.f; +// a->type = &BoolType; +// break; +// +// case GTEQ: +// a->imm.f = a->imm.f >= b->imm.f; +// a->type = &BoolType; +// break; +// +// default: +// assert(!"not a valid op"); +// break; +// } +// } +// else +// { +// assert(!"not a valid form"); +// } +//} +// +//void const_unop(Parser* p, int op, Item* a) +//{ +// (void)p; +// if (a->type->form == FORM_INT) +// { +// switch (op) +// { +// case '+': a->imm.i = +a->imm.i; break; +// case '-': a->imm.i = -a->imm.i; break; +// default: assert(!"not a valid op"); break; +// } +// } +// else if (a->type->form == FORM_REAL) +// { +// switch (op) +// { +// case '+': a->imm.f = +a->imm.f; break; +// case '-': a->imm.f = -a->imm.f; break; +// default: assert(!"not a valid op"); break; +// } +// } +// else if (a->type->form == FORM_BOOL) +// { +// switch (op) +// { +// case NOT: a->imm.i = !a->imm.i; break; +// default: assert(!"not a valid op"); break; +// } +// } +// else +// { +// assert(!"not a valid form"); +// } +//} diff --git a/cerise/src/grammar.c b/cerise/src/grammar.c index d90d4b9..812f8c9 100644 --- a/cerise/src/grammar.c +++ b/cerise/src/grammar.c @@ -7,40 +7,148 @@ //#define TRACE #ifdef TRACE static int Indent = 0; - #define RULE(name) \ - static void name##_actual(Parser* p, Item* item); \ - static void name(Parser* p, Item* item) { \ - printf("%*c-> %s\n", ++Indent * 2, ' ', __func__); \ - name##_actual(p, item); \ - Indent--; } \ - static void name##_actual(Parser* p, Item* item) + #define ENTER_RULE() \ + printf("%*c-> %s\n", ++Indent * 2, ' ', __func__) + + #define EXIT_RULE() \ + Indent-- #else - #define RULE(name) \ - static void name(Parser* p, Item* item) + #define ENTER_RULE() ((void)0) + #define EXIT_RULE() ((void)0) #endif -/* Item Handling +/* Basic Blocks and Operations *****************************************************************************/ -static void init_item(Item* item, Symbol* sym) +#define MAX_OPS (256) +static size_t NumOps = 0; +static Operation* Ops[MAX_OPS] = {0}; + +static void print_op(Operation* op) { - item->type = sym->type; - if (SYM_VAR == sym->class) + switch (op->code) { - item->mode = (sym->global ? ITEM_MVAR : ITEM_VAR); - item->imm.s = sym->name; + case INT: + case BOOL: + printf(" $%ld = %ld\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); + break; } - else if (SYM_PROC == sym->class) +} + +/* Intermediate Representation + *****************************************************************************/ +//void codegen_startproc(Parser* p, Symbol* func); +//void codegen_endproc(Parser* p); +//void codegen_unop(Parser* p, int op, Item* a); +//void codegen_binop(Parser* p, int op, Item* a, Item* b); +//void codegen_store(Parser* p, Item* a, Item* b); +//void codegen_if(Parser* p, Item* item); +//void codegen_else(Parser* p, Item* item); +//void codegen_endif(Parser* p, long elsifs, Item* item); +//void codegen_prepcall(Parser* p, Item* item); +//void codegen_call(Parser* p, Item* item, Item* args); +//void codegen_setarg(Parser* p, Item* item, bool firstarg); +//void codegen_return(Parser* p, Item* item); +//void codegen_index(Parser* p, Item* array, Item* index); +//void codegen_field(Parser* p, Item* record, char* name); + +static Operation* ir_pop(void) +{ + assert(NumOps > 0); + return Ops[--NumOps]; +} + +static void ir_push(Operation* op) +{ + assert(NumOps < MAX_OPS); + Ops[NumOps++] = op; +} + +static void ir_int(Parser* p, long val) +{ + Operation* op = calloc(1, sizeof(Operation)); + op->code = INT; + op->mode = IR_CONST; + op->u.args[0].i = p->curr_reg++; + op->u.args[1].i = val; + print_op(op); + ir_push(op); +} + +static void ir_real(Parser* p, double val) +{ + Operation* op = calloc(1, sizeof(Operation)); + op->code = REAL; + op->mode = IR_CONST; + 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) + { + 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; + } +} + +static void ir_unop(Parser* p, int op) +{ + Operation* a = ir_pop(); + if (a->mode == IR_CONST) { - item->mode = ITEM_MVAR; - item->imm.s = sym->name; + if (a->code == INT) + { + switch (op) + { + 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; + } + } + else if (a->code == REAL) + { + switch (op) + { + 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; + } + } + 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; + } + } } else { - item->mode = ITEM_CONST; - item->imm = sym->imm; + assert(!"unimplemented unary op"); } + print_op(a); + ir_push(a); } +/* Item Handling + *****************************************************************************/ Field* add_field(Parser* p, Type* type, char* name, bool export) { Field* prev = NULL; @@ -73,403 +181,428 @@ Field* add_field(Parser* p, Type* type, char* name, bool export) /* Grammar Definition *****************************************************************************/ -static void expression(Parser* p, Item* item); - -RULE(qualident) -{ - char* name = expect_text(p, IDENT); - Symbol* sym = symbol_get(p, name, -1); - init_item(item, sym); - -// if (accept(p, '.')) +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); +// /* selector */ +// for (int done = 0; !done;) // { -// expect(p, IDENT); +// switch ((int)peek(p)->type) +// { +// case '.': +// { +// expect(p, '.'); +// char* name = expect_text(p, IDENT); +// if (item->type->form == FORM_RECORD) +// { +// codegen_field(p, item, name); +// } +// else +// { +// error(p, "attempting to access field of non-array object"); +// } +// break; +// } +// +// case '[': +// { +// Item index = {0}; +// expect(p, '['); +// expression(p, &index); +// if (item->type->form == FORM_ARRAY) +// { +// codegen_index(p, item, &index); +// } +// else +// { +// error(p, "attempting to index non-array value"); +// } +// expect(p, ']'); +// break; +// } +// +// // case '^': +// // expect(p, '^'); +// // break; +// +// // case '(': +// // qualident(p); +// // expect(p, ')'); +// // break; +// +// default: +// done = 1; +// break; +// } // } -} +// EXIT_RULE(); +//} -RULE(designator) -{ - qualident(p, item); - /* selector */ - for (int done = 0; !done;) - { - switch ((int)peek(p)->type) - { - case '.': - { - expect(p, '.'); - char* name = expect_text(p, IDENT); - if (item->type->form == FORM_RECORD) - { - codegen_field(p, item, name); - } - else - { - error(p, "attempting to access field of non-array object"); - } - break; - } - - case '[': - { - Item index = {0}; - expect(p, '['); - expression(p, &index); - if (item->type->form == FORM_ARRAY) - { - codegen_index(p, item, &index); - } - else - { - error(p, "attempting to index non-array value"); - } - expect(p, ']'); - break; - } - - // case '^': - // expect(p, '^'); - // break; - - // case '(': - // qualident(p); - // expect(p, ')'); - // break; - - default: - done = 1; - break; - } - } -} - -RULE(factor) +static void factor(Parser* p) { + ENTER_RULE(); switch ((int)peek(p)->type) { case INT: - codegen_setint(item, &IntType, peek(p)->value.integer); + ir_int(p, peek(p)->value.integer); consume(p); break; case REAL: - codegen_setreal(item, peek(p)->value.floating); + ir_real(p, peek(p)->value.floating); consume(p); break; - case STRING: - codegen_setstr(item, peek(p)->text); - consume(p); - break; - -// case NIL: -// codegen_nil(item); +// case STRING: +// codegen_setstr(item, peek(p)->text); // consume(p); // break; case BOOL: - codegen_setint(item, &BoolType, peek(p)->value.integer); + ir_int(p, peek(p)->value.integer); consume(p); break; - case '(': - expect(p, '('); - expression(p, item); - expect(p, ')'); - break; +// case '(': +// expect(p, '('); +// expression(p, item); +// 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, item); +// check_bool(p, item); +// codegen_unop(p, NOT, item); +// break; - case IDENT: - designator(p, item); - if (accept(p, '(')) - { - Symbol* proc = symbol_get(p, item->imm.s, SYM_PROC); - item->type = proc->type->base; - Field* args = proc->type->fields; - Item arglist = {0}; - Item** currarg = &(arglist.next); - while (args && !matches(p, ')')) - { - Item argdef = { .type = args->type }; - Item* argval = calloc(1, sizeof(Item)); - expression(p, argval); - check_types(p, &argdef, argval); - codegen_setarg(p, argval, (arglist.next == 0)); - *currarg = argval; - currarg = &(argval->next); - args = args->next; - if (args) - { - expect(p, ','); - } - } - if (args) - { - error(p, "too few arguments to function '%s'", proc->name); - } - 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 '%s'", proc->name); - } - } - codegen_call(p, item, arglist.next); - expect(p, ')'); - } - break; +// case IDENT: +// designator(p, item); +// if (accept(p, '(')) +// { +// Symbol* proc = symbol_get(p, item->imm.s, SYM_PROC); +// item->type = proc->type->base; +// Field* args = proc->type->fields; +// Item arglist = {0}; +// Item** currarg = &(arglist.next); +// while (args && !matches(p, ')')) +// { +// Item argdef = { .type = args->type }; +// Item* argval = calloc(1, sizeof(Item)); +// expression(p, argval); +// check_types(p, &argdef, argval); +// codegen_setarg(p, argval, (arglist.next == 0)); +// *currarg = argval; +// currarg = &(argval->next); +// args = args->next; +// if (args) +// { +// expect(p, ','); +// } +// } +// if (args) +// { +// error(p, "too few arguments to function '%s'", proc->name); +// } +// 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 '%s'", proc->name); +// } +// } +// codegen_call(p, item, arglist.next); +// expect(p, ')'); +// } +// break; default: printf("unknown factor: %d\n", peek(p)->type); break; } + EXIT_RULE(); } -RULE(term) + +static void term(Parser* p) { - factor(p, item); + ENTER_RULE(); - while (matches_oneof(p, (int[]){'*', '/', '%', AND, 0})) - { - Item right = { 0 }; - int op = consume(p); - factor(p, &right); - switch(op) - { - case '*': - case '/': - case '%': - check_nums(p, item, &right); - codegen_binop(p, op, item, &right); - break; - - case AND: - check_bools(p, item, &right); - codegen_binop(p, op, item, &right); - break; - - default: - assert(!"not supported"); - break; - } - } + factor(p); + +// while (matches_oneof(p, (int[]){'*', '/', '%', AND, 0})) +// { +// Item right = { 0 }; +// int op = consume(p); +// factor(p, &right); +// switch(op) +// { +// case '*': +// case '/': +// case '%': +// check_nums(p, item, &right); +// codegen_binop(p, op, item, &right); +// break; +// +// case AND: +// check_bools(p, item, &right); +// codegen_binop(p, op, item, &right); +// break; +// +// default: +// assert(!"not supported"); +// break; +// } +// } + + EXIT_RULE(); } -RULE(simple_expr) +static void simple_expr(Parser* p) { + ENTER_RULE(); + /* first term and +/- */ if (matches_oneof(p, (int[]){'+', '-', 0})) { int op = consume(p); // OP - term(p, item); - check_num(p, item); - codegen_unop(p, op, item); + term(p); + ir_unop(p, op); +// check_num(p, item); +// codegen_unop(p, op, item); } else { - term(p, item); + term(p); } - /* optional second term and op */ - while (matches_oneof(p, (int[]){'+', '-', OR, 0})) - { - Item right = { 0 }; - int op = consume(p); - term(p, &right); - if (op == OR) - { - check_bools(p, item, &right); - } - else - { - check_nums(p, item, &right); - } - codegen_binop(p, op, item, &right); - } -} - -RULE(expression) -{ - int ops[] = { EQ, NEQ, '<', LTEQ, '>', GTEQ, IS, 0 }; - simple_expr(p, item); +// /* optional second term and op */ +// while (matches_oneof(p, (int[]){'+', '-', OR, 0})) +// { +// Item right = { 0 }; +// int op = consume(p); +// term(p, &right); +// if (op == OR) +// { +// check_bools(p, item, &right); +// } +// else +// { +// check_nums(p, item, &right); +// } +// codegen_binop(p, op, item, &right); +// } - if (matches_oneof(p, ops)) - { - Item right = { 0 }; - int op = consume(p); - simple_expr(p, &right); - check_nums(p, item, &right); - codegen_binop(p, op, item, &right); - } + EXIT_RULE(); } -RULE(type) +static void expression(Parser* p) { - (void)item; - if (matches(p, IDENT)) - { - char* text = expect_text(p, IDENT); - Symbol* sym = symbol_get(p, text, SYM_TYPE); - item->type = sym->type; - } - else if (accept(p, ARRAY)) - { - expression(p, item); - if (item->mode != ITEM_CONST) - { - error(p, "non-constant array size"); - } - expect(p, OF); - Item base = {0}; - type(p, &base); - item->type = calloc(1, sizeof(Type)); - item->type->form = FORM_ARRAY; - item->type->size = item->imm.i; - item->type->base = base.type; - } - else if (accept(p, RECORD)) - { - long offset = 0; - item->type = calloc(1, sizeof(Type)); - item->type->form = FORM_RECORD; + ENTER_RULE(); +// int ops[] = { EQ, NEQ, '<', LTEQ, '>', GTEQ, IS, 0 }; - while (peek(p)->type != END) - { - /* parse the field name list */ - Field* first = NULL; - int nfields = 0; - do - { - char* name = expect_text(p, IDENT); - bool export = accept(p, '*'); - Field* f = add_field(p, item->type, name, export); - nfields++; - if (!first) - { - first = f; - } - } - while (accept(p, ',')); - - /* now parse the type designation */ - Item field_type = {0}; - expect(p, ':'); - type(p, &field_type); - - /* apply the type to the newly created symbols */ - for (int i = 0; i < nfields; i++) - { - offset = align_item(offset, field_type.type->size); - first->type = field_type.type; - first->offset = offset; - offset += size_of(first->type); - first = first->next; - } - } - item->type->size = offset; - - expect(p, END); - } - else - { - error(p, "expected a type"); - } -} + simple_expr(p); -RULE(statement_seq) -{ - do - { - if (matches(p, IF)) - { - expect(p, IF); - expression(p, item); - check_bool(p, item); - codegen_if(p, item); - expect(p, THEN); - statement_seq(p, &(Item){0}); - int elsifs = 0; - while (accept(p, ELSIF)) - { - elsifs++; - codegen_else(p, item); - expression(p, item); - check_bool(p, item); - codegen_if(p, item); - expect(p, THEN); - statement_seq(p, &(Item){0}); - } - if (accept(p, ELSE)) - { - codegen_else(p, item); - statement_seq(p, &(Item){0}); - } - codegen_endif(p, elsifs, item); - expect(p, END); - } - else /* assignments/expressions */ - { - expression(p, item); - if (accept(p, '=')) - { - Item right = { 0 }; - expression(p, &right); - check_types(p, item, &right); - codegen_store(p, item, &right); - } - expect(p, ';'); - } - } - while (!matches(p, END) && !matches(p, ELSE) && !matches(p, ELSIF) && !matches(p, RETURN)); -} +// if (matches_oneof(p, ops)) +// { +// Item right = { 0 }; +// int op = consume(p); +// simple_expr(p, &right); +// check_nums(p, item, &right); +// codegen_binop(p, op, item, &right); +// } -RULE(var_decl) -{ - (void)item; - do - { - char* name = expect_text(p, IDENT); - bool export = accept(p, '*'); - Symbol* sym = symbol_new(p, 0, name, SYM_VAR, export); - Item base_type = {0}; - expect(p, ':'); - type(p, &base_type); - sym->type = base_type.type; - } - while (matches(p, IDENT)); + EXIT_RULE(); } -RULE(type_decl) -{ - char* name = NULL; - bool export = false; - Symbol* sym = NULL; +//RULE(type, Item* item) +//{ +// ENTER_RULE(); +// (void)item; +// if (matches(p, IDENT)) +// { +// char* text = expect_text(p, IDENT); +// Symbol* sym = symbol_get(p, text, SYM_TYPE); +// item->type = sym->type; +// } +// else if (accept(p, ARRAY)) +// { +// expression(p, item); +// if (item->mode != ITEM_CONST) +// { +// error(p, "non-constant array size"); +// } +// expect(p, OF); +// Item base = {0}; +// type(p, &base); +// item->type = calloc(1, sizeof(Type)); +// item->type->form = FORM_ARRAY; +// item->type->size = item->imm.i; +// item->type->base = base.type; +// } +// else if (accept(p, RECORD)) +// { +// long offset = 0; +// item->type = calloc(1, sizeof(Type)); +// item->type->form = FORM_RECORD; +// +// while (peek(p)->type != END) +// { +// /* parse the field name list */ +// Field* first = NULL; +// int nfields = 0; +// do +// { +// char* name = expect_text(p, IDENT); +// bool export = accept(p, '*'); +// Field* f = add_field(p, item->type, name, export); +// nfields++; +// if (!first) +// { +// first = f; +// } +// } +// while (accept(p, ',')); +// +// /* now parse the type designation */ +// Item field_type = {0}; +// expect(p, ':'); +// type(p, &field_type); +// +// /* apply the type to the newly created symbols */ +// for (int i = 0; i < nfields; i++) +// { +// offset = align_item(offset, field_type.type->size); +// first->type = field_type.type; +// first->offset = offset; +// offset += size_of(first->type); +// first = first->next; +// } +// } +// item->type->size = offset; +// +// expect(p, END); +// } +// else +// { +// error(p, "expected a type"); +// } +// EXIT_RULE(); +//} - do - { - name = expect_text(p, IDENT); - export = accept(p, '*'); - sym = symbol_new(p, 0, name, SYM_TYPE, export); - expect(p, '='); - type(p, item); - sym->type = item->type; - } - while (matches(p, IDENT)); -} +//RULE(statement_seq, Item* item) +//{ +// ENTER_RULE(); +// do +// { +// if (matches(p, IF)) +// { +// expect(p, IF); +// expression(p, item); +// check_bool(p, item); +// codegen_if(p, item); +// expect(p, THEN); +// statement_seq(p, &(Item){0}); +// int elsifs = 0; +// while (accept(p, ELSIF)) +// { +// elsifs++; +// codegen_else(p, item); +// expression(p, item); +// check_bool(p, item); +// codegen_if(p, item); +// expect(p, THEN); +// statement_seq(p, &(Item){0}); +// } +// if (accept(p, ELSE)) +// { +// codegen_else(p, item); +// statement_seq(p, &(Item){0}); +// } +// codegen_endif(p, elsifs, item); +// expect(p, END); +// } +// else /* assignments/expressions */ +// { +// expression(p, item); +// if (accept(p, '=')) +// { +// Item right = { 0 }; +// expression(p, &right); +// check_types(p, item, &right); +// codegen_store(p, item, &right); +// } +// expect(p, ';'); +// } +// } +// while (!matches(p, END) && !matches(p, ELSE) && !matches(p, ELSIF) && !matches(p, RETURN)); +// EXIT_RULE(); +//} + +//RULE(var_decl, Item* item) +//{ +// ENTER_RULE(); +// (void)item; +// do +// { +// char* name = expect_text(p, IDENT); +// bool export = accept(p, '*'); +// Symbol* sym = symbol_new(p, 0, name, SYM_VAR, export); +// Item base_type = {0}; +// expect(p, ':'); +// type(p, &base_type); +// sym->type = base_type.type; +// } +// while (matches(p, IDENT)); +// EXIT_RULE(); +//} +// +//RULE(type_decl, Item* item) +//{ +// ENTER_RULE(); +// char* name = NULL; +// bool export = false; +// Symbol* sym = NULL; +// +// do +// { +// name = expect_text(p, IDENT); +// export = accept(p, '*'); +// sym = symbol_new(p, 0, name, SYM_TYPE, export); +// expect(p, '='); +// type(p, item); +// sym->type = item->type; +// } +// while (matches(p, IDENT)); +// EXIT_RULE(); +//} -RULE(const_decl) +static void const_decl(Parser* p) { +// ENTER_RULE(); char* name = NULL; bool export = false; Symbol* sym = NULL; @@ -479,91 +612,94 @@ RULE(const_decl) name = expect_text(p, IDENT); export = accept(p, '*'); sym = symbol_new(p, 0, name, SYM_CONST, export); - expect(p, '='); - expression(p, item); - sym->imm = item->imm; - sym->type = item->type; + expression(p); + ir_getconst(p, sym); +// sym->imm = item->imm; +// sym->type = item->type; } while (matches(p, IDENT)); +// EXIT_RULE(); } -RULE(proc_decl) -{ - expect(p, PROCEDURE); - char* name = expect_text(p, IDENT); - bool export = accept(p, '*'); - Symbol* proc = symbol_new(p, 0, name, SYM_PROC, export); - Type* proctype = calloc(1, sizeof(Type)); - proctype->form = FORM_PROC; - proc->type = proctype; - size_t scope = symbol_openscope(p); - - /* construct the proc type */ - expect(p, '('); - while (!matches(p, ')')) - { - char* name = expect_text(p, IDENT); - expect(p, ':'); - type(p, item); - proc->nargs++; - add_field(p, proctype, name, false)->type = item->type; - symbol_new(p, scope, name, SYM_VAR, export)->type = item->type; - if (!matches(p, ')')) - { - expect(p, ','); - } - } - expect(p, ')'); - if (accept(p, ':')) - { - type(p, item); - proctype->base = item->type; - } - - codegen_startproc(p, proc); - - /* parse the declarations */ - if (accept(p, CONST)) - { - const_decl(p, item); - } - - if (accept(p, TYPE)) - { - type_decl(p, item); - } - - if (accept(p, VAR)) - { - var_decl(p, item); - } - - /* parse the body of the procedure */ - expect(p, BEGIN); - if (!matches(p, RETURN) && !matches(p, END)) - { - statement_seq(p, item); - } - if (accept(p, RETURN)) - { - expression(p, item); - codegen_return(p, item); - expect(p, ';'); - } - else - { - codegen_return(p, NULL); - } - expect(p, END); - - codegen_endproc(p); - symbol_closescope(p, scope); -} - -RULE(import_list) +//RULE(proc_decl, Item* item) +//{ +// ENTER_RULE(); +// expect(p, PROCEDURE); +// char* name = expect_text(p, IDENT); +// bool export = accept(p, '*'); +// Symbol* proc = symbol_new(p, 0, name, SYM_PROC, export); +// Type* proctype = calloc(1, sizeof(Type)); +// proctype->form = FORM_PROC; +// proc->type = proctype; +// size_t scope = symbol_openscope(p); +// +// /* construct the proc type */ +// expect(p, '('); +// while (!matches(p, ')')) +// { +// char* name = expect_text(p, IDENT); +// expect(p, ':'); +// type(p, item); +// proc->nargs++; +// add_field(p, proctype, name, false)->type = item->type; +// symbol_new(p, scope, name, SYM_VAR, export)->type = item->type; +// if (!matches(p, ')')) +// { +// expect(p, ','); +// } +// } +// expect(p, ')'); +// if (accept(p, ':')) +// { +// type(p, item); +// proctype->base = item->type; +// } +// +// codegen_startproc(p, proc); +// +// /* parse the declarations */ +// if (accept(p, CONST)) +// { +// const_decl(p, item); +// } +// +// if (accept(p, TYPE)) +// { +// type_decl(p, item); +// } +// +// if (accept(p, VAR)) +// { +// var_decl(p, item); +// } +// +// /* parse the body of the procedure */ +// expect(p, BEGIN); +// if (!matches(p, RETURN) && !matches(p, END)) +// { +// statement_seq(p, item); +// } +// if (accept(p, RETURN)) +// { +// expression(p, item); +// codegen_return(p, item); +// expect(p, ';'); +// } +// else +// { +// codegen_return(p, NULL); +// } +// expect(p, END); +// +// codegen_endproc(p); +// symbol_closescope(p, scope); +// EXIT_RULE(); +//} + +static void import_list(Parser* p) { - (void)item; +// ENTER_RULE(); expect(p, IMPORT); do { @@ -589,49 +725,51 @@ RULE(import_list) m->next = p->imports; p->imports = m; } +// EXIT_RULE(); } -RULE(module) +static void module(Parser* p) { + ENTER_RULE(); size_t scope = symbol_openscope(p); expect(p, MODULE); p->name = expect_text(p, IDENT); - /* TODO: Check that it matches filename here */ + /* TODO: Check that it matches filename here */ if (matches(p, IMPORT)) { - import_list(p, item); + import_list(p); } if (accept(p, CONST)) { - const_decl(p, item); + const_decl(p); } - if (accept(p, TYPE)) - { - type_decl(p, item); - } - - if (accept(p, VAR)) - { - var_decl(p, item); - } +// if (accept(p, TYPE)) +// { +// type_decl(p); +// } +// +// if (accept(p, VAR)) +// { +// var_decl(p); +// } - while (matches(p, PROCEDURE)) - { - proc_decl(p, item); - } +// while (matches(p, PROCEDURE)) +// { +// proc_decl(p); +// } - codegen_startproc(p, NULL); - if (accept(p, BEGIN)) - { - codegen_imports(p); - statement_seq(p, item); - expect(p, END); - } - codegen_endproc(p); +// codegen_startproc(p, NULL); +// if (accept(p, BEGIN)) +// { +// codegen_imports(p); +// statement_seq(p, item); +// expect(p, END); +// } +// codegen_endproc(p); if (!matches(p, END_FILE)) { @@ -639,6 +777,7 @@ RULE(module) } symbol_closescope(p, scope); + EXIT_RULE(); } static inline char* file_load(char* path) @@ -680,10 +819,10 @@ void compile(char* fname) symbol_new(p, 0, "Real", SYM_TYPE, 0)->type = &RealType; symbol_new(p, 0, "String", SYM_TYPE, 0)->type = &StringType; - codegen_startmod(p); - module(p, &(Item){0}); - codegen_main(p); - codegen_endmod(p); +// codegen_startmod(p); + module(p); +// codegen_main(p); +// codegen_endmod(p); } /* Grammar Unit Tests @@ -691,112 +830,112 @@ void compile(char* fname) #ifdef CERISE_TESTS #include "atf.h" -Parser Ctx = {0}; - -static void parse_init(char* fname, char* string) -{ - memset(&Ctx, 0, sizeof(Ctx)); - symbol_new(&Ctx, 0, "Bool", SYM_TYPE, 0)->type = &BoolType; - symbol_new(&Ctx, 0, "Int", SYM_TYPE, 0)->type = &IntType; - symbol_new(&Ctx, 0, "Real", SYM_TYPE, 0)->type = &RealType; - symbol_new(&Ctx, 0, "String", SYM_TYPE, 0)->type = &StringType; - LexFile* file = calloc(sizeof(LexFile), 1u); - file->path = strdup(fname); - file->fbeg = file->fpos = strdup(string); - file->next = Ctx.file; - Ctx.file = file; -} - -static void parse_rule(void (*rule)(Parser*, Item*), Item* item, char* string) -{ -// puts(""); -// printf("%s\n", string); - parse_init("test_input", string); - rule(&Ctx, (item ? item : &(Item){0})); -} - -static void parse_module(char* fname, char* string) -{ - parse_init(fname, string); - module(&Ctx, &(Item){0}); -} +//Parser Ctx = {0}; +// +//static void parse_init(char* fname, char* string) +//{ +// memset(&Ctx, 0, sizeof(Ctx)); +// symbol_new(&Ctx, 0, "Bool", SYM_TYPE, 0)->type = &BoolType; +// symbol_new(&Ctx, 0, "Int", SYM_TYPE, 0)->type = &IntType; +// symbol_new(&Ctx, 0, "Real", SYM_TYPE, 0)->type = &RealType; +// symbol_new(&Ctx, 0, "String", SYM_TYPE, 0)->type = &StringType; +// LexFile* file = calloc(sizeof(LexFile), 1u); +// file->path = strdup(fname); +// file->fbeg = file->fpos = strdup(string); +// file->next = Ctx.file; +// Ctx.file = file; +//} +// +//static void parse_rule(void (*rule)(Parser*, Item*), Item* item, char* string) +//{ +//// puts(""); +//// printf("%s\n", string); +// parse_init("test_input", string); +// rule(&Ctx, (item ? item : &(Item){0})); +//} +// +//static void parse_module(char* fname, char* string) +//{ +// parse_init(fname, string); +// module(&Ctx, &(Item){0}); +//} TEST_SUITE(Grammar) { - TEST(Should parse basic module syntax) - { - parse_module("Empty", "module Empty"); - parse_module("ModA", "module ModA import ModB"); - parse_module("ModA", "module ModA const FOO = 42"); - parse_module("ModA", "module ModA var foo : Int"); - } - - TEST(Should parse imports) - { - parse_rule(import_list, 0, "import A;"); - parse_rule(import_list, 0, "import A = ModA;"); - parse_rule(import_list, 0, "import A, B;"); - parse_rule(import_list, 0, "import A, B = ModB, C;"); - } - - TEST(Should parse constant declarations and expressions) - { - parse_rule(const_decl, 0, "FOO = 123"); - parse_rule(const_decl, 0, "FOO = 123.123"); - parse_rule(const_decl, 0, "FOO = \"\""); - parse_rule(const_decl, 0, "FOO = true"); - parse_rule(const_decl, 0, "FOO = false"); -// parse_rule(const_decl, 0, "FOO = nil"); - parse_rule(const_decl, 0, "FOO = not true"); - parse_rule(const_decl, 0, "FOO = (not false)"); - parse_rule(const_decl, 0, "FOO = +1"); - parse_rule(const_decl, 0, "FOO = -1"); - parse_rule(const_decl, 0, "FOO = +1.0"); - parse_rule(const_decl, 0, "FOO = -1.0"); - parse_rule(const_decl, 0, "FOO = 1 + 2"); - parse_rule(const_decl, 0, "FOO = 1.0 + 2.0"); - parse_rule(const_decl, 0, "FOO = 1 - 2"); - parse_rule(const_decl, 0, "FOO = 1.0 - 2.0"); - parse_rule(const_decl, 0, "FOO = 3 * 2"); - parse_rule(const_decl, 0, "FOO = 3.0 * 2.0"); - parse_rule(const_decl, 0, "FOO = 4 / 2"); - parse_rule(const_decl, 0, "FOO = 3.0 / 4.0"); - parse_rule(const_decl, 0, "FOO = 5 % 3"); - parse_rule(const_decl, 0, "FOO = 5 == 3"); - parse_rule(const_decl, 0, "FOO = 5 != 3"); - parse_rule(const_decl, 0, "FOO = 5 < 3"); - parse_rule(const_decl, 0, "FOO = 5 <= 3"); - parse_rule(const_decl, 0, "FOO = 5 > 3"); - parse_rule(const_decl, 0, "FOO = 5 >= 3"); - parse_rule(const_decl, 0, "FOO = 5, BAR = FOO - 3"); - } - - TEST(Should parse module level type declarations) - { - parse_rule(type_decl, 0, "a = Int"); - parse_rule(type_decl, 0, "a = Real"); - parse_rule(type_decl, 0, "a = Bool"); - parse_rule(type_decl, 0, "a = array 42 of Int"); - parse_rule(type_decl, 0, "a = array 42 of array 42 of Int"); - parse_rule(type_decl, 0, "a = record end"); - } - - TEST(Should parse module level variable declarations) - { - parse_rule(var_decl, 0, "i : Int"); - parse_rule(var_decl, 0, "i : Real"); - parse_rule(var_decl, 0, "i : Bool"); -// parse_rule(var_decl, 0, "x,y,z : Int"); - } - - TEST(Should parse module level procedure declarations) - { - parse_rule(proc_decl, 0, - "procedure Foo*() : Int\n" - "begin\n" - " return 1;\n" - "end" - ); - } +// TEST(Should parse basic module syntax) +// { +// parse_module("Empty", "module Empty"); +// parse_module("ModA", "module ModA import ModB"); +// parse_module("ModA", "module ModA const FOO = 42"); +// parse_module("ModA", "module ModA var foo : Int"); +// } +// +// TEST(Should parse imports) +// { +// parse_rule(import_list, 0, "import A;"); +// parse_rule(import_list, 0, "import A = ModA;"); +// parse_rule(import_list, 0, "import A, B;"); +// parse_rule(import_list, 0, "import A, B = ModB, C;"); +// } +// +// TEST(Should parse constant declarations and expressions) +// { +// parse_rule(const_decl, 0, "FOO = 123"); +// parse_rule(const_decl, 0, "FOO = 123.123"); +// parse_rule(const_decl, 0, "FOO = \"\""); +// parse_rule(const_decl, 0, "FOO = true"); +// parse_rule(const_decl, 0, "FOO = false"); +//// parse_rule(const_decl, 0, "FOO = nil"); +// parse_rule(const_decl, 0, "FOO = not true"); +// parse_rule(const_decl, 0, "FOO = (not false)"); +// parse_rule(const_decl, 0, "FOO = +1"); +// parse_rule(const_decl, 0, "FOO = -1"); +// parse_rule(const_decl, 0, "FOO = +1.0"); +// parse_rule(const_decl, 0, "FOO = -1.0"); +// parse_rule(const_decl, 0, "FOO = 1 + 2"); +// parse_rule(const_decl, 0, "FOO = 1.0 + 2.0"); +// parse_rule(const_decl, 0, "FOO = 1 - 2"); +// parse_rule(const_decl, 0, "FOO = 1.0 - 2.0"); +// parse_rule(const_decl, 0, "FOO = 3 * 2"); +// parse_rule(const_decl, 0, "FOO = 3.0 * 2.0"); +// parse_rule(const_decl, 0, "FOO = 4 / 2"); +// parse_rule(const_decl, 0, "FOO = 3.0 / 4.0"); +// parse_rule(const_decl, 0, "FOO = 5 % 3"); +// parse_rule(const_decl, 0, "FOO = 5 == 3"); +// parse_rule(const_decl, 0, "FOO = 5 != 3"); +// parse_rule(const_decl, 0, "FOO = 5 < 3"); +// parse_rule(const_decl, 0, "FOO = 5 <= 3"); +// parse_rule(const_decl, 0, "FOO = 5 > 3"); +// parse_rule(const_decl, 0, "FOO = 5 >= 3"); +// parse_rule(const_decl, 0, "FOO = 5, BAR = FOO - 3"); +// } +// +// TEST(Should parse module level type declarations) +// { +// parse_rule(type_decl, 0, "a = Int"); +// parse_rule(type_decl, 0, "a = Real"); +// parse_rule(type_decl, 0, "a = Bool"); +// parse_rule(type_decl, 0, "a = array 42 of Int"); +// parse_rule(type_decl, 0, "a = array 42 of array 42 of Int"); +// parse_rule(type_decl, 0, "a = record end"); +// } +// +// TEST(Should parse module level variable declarations) +// { +// parse_rule(var_decl, 0, "i : Int"); +// parse_rule(var_decl, 0, "i : Real"); +// parse_rule(var_decl, 0, "i : Bool"); +//// parse_rule(var_decl, 0, "x,y,z : Int"); +// } +// +// TEST(Should parse module level procedure declarations) +// { +// parse_rule(proc_decl, 0, +// "procedure Foo*() : Int\n" +// "begin\n" +// " return 1;\n" +// "end" +// ); +// } } #endif diff --git a/cerise/tests/Module.m b/cerise/tests/Module.m index e067986..b862ea7 100644 --- a/cerise/tests/Module.m +++ b/cerise/tests/Module.m @@ -6,34 +6,34 @@ module Module const A = true - B = 42 + B = -42 -type - TypeA = Int - TypeB = array 5 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 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 @@ -53,7 +53,7 @@ var # return a; #end -begin +#begin # h[1].i = 42; # a = true; # a = A; @@ -134,8 +134,6 @@ begin # e[0][9] = 42; # c = Bar(42); - - c = 42; - c = 24; - -end +# c = 42; +# c = 24; +#end