printf("}\n");
}
-void codegen_startproc(Parser* p, char* name, bool exported)
+void codegen_startproc(Parser* p, Symbol* proc)
{
- char* export = (exported ? "" : "static");
- if (!name)
+ if (!proc)
{
- printf("\n%svoid %s(void) {\n", export, p->name);
+ printf("\nvoid %s(void) {\n", p->name);
}
else
{
- printf("\n%svoid %s_%s(void) {\n", export, p->name, name);
+ char* export = (proc->export ? "" : "static");
+ printf("\n%svoid %s_%s(void) {\n", export, p->name, proc->name);
}
}
(void)p;
}
-void codegen_startproc(Parser* p, char* name, bool exported)
+void codegen_startproc(Parser* p, Symbol* proc)
{
- (void)p, (void)name, (void)exported;
+ (void)p, (void)proc;
}
void codegen_endproc(Parser* p)
printf(" ret\n");
}
-void codegen_startproc(Parser* p, char* name, bool exported)
+void codegen_startproc(Parser* p, Symbol* proc)
{
- (void)exported;
printf(" .text\n");
- if (name)
+ if (proc)
{
- printf(" .globl %s_%s\n", p->name, name);
- printf("%s_%s:\n", p->name, name);
+ printf(" .globl %s_%s\n", p->name, proc->name);
+ printf("%s_%s:\n", p->name, proc->name);
}
else
{
// src/sym.c
Symbol* symbol_new(Parser* p, char* name, int class, bool export);
+Symbol* symbol_addfield(Parser* p, Symbol* parent, char* name, int class, bool export);
Symbol* symbol_get(Parser* p, int class, char* name);
void symbol_openscope(Parser* p);
void symbol_closescope(Parser* p);
void codegen_imports(Parser* p);
void codegen_var(Parser* p, Symbol* sym);
void codegen_main(Parser* p);
-void codegen_startproc(Parser* p, char* name, bool exported);
+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);
expect(p, PROCEDURE);
char* name = expect_text(p, IDENT);
bool export = accept(p, '*');
- Symbol* sym = symbol_new(p, name, SYM_PROC, export);
- Symbol** args = &(sym->desc);
- symbol_openscope(p);
- codegen_startproc(p, name, export);
- (void)args;
+ Symbol* proc = symbol_new(p, name, SYM_PROC, export);
+// Symbol** args = &(sym->desc);
+// (void)args;
/* construct the proc type */
expect(p, '(');
char* name = expect_text(p, IDENT);
expect(p, ':');
type(p, item);
- sym->nargs++;
- // TODO: Added argument symbol here...
- (void)name;
+ proc->nargs++;
+ Symbol* arg = symbol_addfield(p, proc, name, SYM_VAR, false);
+ arg->type = item->type;
}
expect(p, ')');
if (accept(p, ':'))
{
type(p, item);
- sym->type = item->type;
+ proc->type = item->type;
}
+ codegen_startproc(p, proc);
+ symbol_openscope(p);
+
/* parse the declarations */
if (accept(p, CONST))
{
expect(p, ';');
}
expect(p, END);
+
symbol_closescope(p);
codegen_endproc(p);
}
-
RULE(import_list)
{
(void)item;
proc_decl(p, item);
}
- codegen_startproc(p, NULL, true);
+ codegen_startproc(p, NULL);
if (accept(p, BEGIN))
{
codegen_imports(p);
fprintf(file, "%s:%zu:%zu:", tok->file, line, col);
}
+char* TokTypes[] = {
+ ['"'] = "\"",
+ ['='] = "=",
+ ['.'] = ".",
+ ['<'] = "<",
+ ['>'] = ">",
+ ['!'] = "!",
+ ['('] = "(",
+ [')'] = ")",
+ ['['] = "[",
+ [']'] = "]",
+ ['{'] = "{",
+ ['}'] = "}",
+ [','] = ",",
+ [':'] = ":",
+ [';'] = ";",
+ ['^'] = "^",
+ ['+'] = "+",
+ ['-'] = "-",
+ ['*'] = "*",
+ ['/'] = "/",
+ ['|'] = "|",
+ ['%'] = "%",
+ [EQ] = "==",
+ [NEQ] = "!=",
+ [LTEQ] = "<=",
+ [GTEQ] = ">=",
+ [DOTDOT] = "..",
+ [AND] = "and",
+ [ARRAY] = "array",
+ [BEGIN] = "begin",
+ [BY] = "by",
+ [CASE] = "case",
+ [CONST] = "const",
+ [DIV] = "div",
+ [DO] = "do",
+ [ELSE] = "else",
+ [ELSIF] = "elsif",
+ [END] = "end",
+ [FOR] = "for",
+ [IF] = "if",
+ [IMPORT] = "import",
+ [IS] = "is",
+ [MOD] = "mod",
+ [MODULE] = "module",
+ [NIL] = "nil",
+ [NOT] = "not",
+ [OF] = "of",
+ [OR] = "or",
+ [POINTER] = "pointer",
+ [PROCEDURE] = "procedure",
+ [RECORD] = "record",
+ [REPEAT] = "repeat",
+ [RETURN] = "return",
+ [THEN] = "then",
+ [TO] = "to",
+ [TYPE] = "type",
+ [UNTIL] = "until",
+ [VAR] = "var",
+ [WHILE] = "while",
+};
+
#ifdef CERISE_TESTS
#include "atf.h"
#include "cerise.h"
+/* for token mismatch errors */
+extern char* TokTypes[];
+
Tok* peek(Parser* p)
{
if (NONE == p->tok.type)
void expect(Parser* p, TokType type)
{
if (!accept(p, type))
- error(p, "Unexpected token");
+ {
+ char* expect = TokTypes[type];
+ char* recv = TokTypes[peek(p)->type];
+
+ if (expect && recv)
+ {
+ error(p, "expected '%s', recieved '%s'", expect, recv);
+ }
+ else if (expect)
+ {
+ error(p, "expected '%s'", expect);
+ }
+ else
+ {
+ error(p, "Unexpected token");
+ }
+ }
}
Tok* expect_val(Parser* p, TokType type)
{
p->scope->desc = sym;
}
-// p->scope->desc = sym;
- assert(sym);
return sym;
}
+Symbol* symbol_addfield(Parser* p, Symbol* parent, char* name, int class, bool export)
+{
+ Symbol* prev = NULL;
+ Symbol* curr = parent->desc;
+
+// printf("\nsymbol_addfield(%s)\n", name);
+ while (curr)
+ {
+// printf(" %s <- %s\n", curr->name, name);
+ if (curr->name && !strcmp(curr->name, name))
+ {
+ error(p, "multiple definitions of '%s' in scope", name);
+ }
+ prev = curr;
+ curr = curr->next;
+ }
+
+ Symbol* sym = calloc(1, sizeof(Symbol));
+ sym->name = name;
+ sym->class = class;
+ sym->export = export;
+ if (prev)
+ {
+ prev->next = sym;
+ }
+ else
+ {
+ parent->desc = sym;
+ }
+ return sym;
+}
+
+
Symbol* symbol_get(Parser* p, int class, char* name)
{
for (Symbol* scope = p->scope; scope; scope = scope->next)
{
// printf("SCOPE(n: %p):\n", scope->next);
-
if (sym_matches(p, class, name, scope))
{
return scope;
var
a : Bool
- z : Int
b : Int
c : Int
procedure Foo*(e : Int) : Int
const FOO = 2
-# type foo : Int
+ type foo = Int
var z : Int
begin
c = b * b;