ELSE,
ELSIF,
END,
+ EXTERN,
FOR,
+ FORWARD,
IF,
IMPORT,
IS,
size_t module;
int export : 1;
int global : 1;
+ int forward : 1;
} Symbol;
typedef struct {
Type* symbol_newtype(Parser* p);
Symbol* symbol_new(Parser* p, size_t scope, char* name, int class, bool export);
Symbol* symbol_get(Parser* p, size_t module, char* name, int class);
+Symbol* symbol_find(Parser* p, size_t module, char* name, int class);
size_t symbol_getid(Parser* p, size_t module, char* name, int class);
Symbol* symbol_getbyid(Parser* p, size_t id);
size_t symbol_openscope(Parser* p);
{
expect(p, '.');
char* name = expect_text(p, IDENT);
- symid = symbol_getid(p, symid, name, -1);
+ size_t qsymid = symbol_getid(p, symid, name, -1);
+ printf("%ld.%ld\n", symid, qsymid);
+ symid=qsymid;
}
/* make the identifier with the final index */
EXIT_RULE();
}
-void proc_decl(Parser* p)
+Symbol* proc_type(Parser* p)
{
- 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);
+ Symbol* proc = symbol_find(p, 0, name, SYM_PROC);
+ if (!proc)
+ {
+ proc = symbol_new(p, 0, name, SYM_PROC, export);
+ }
+ else if (!proc->forward)
+ {
+ error(p, "procedure '%s' multiply defined in scope", name);
+ }
+
Type* proctype = symbol_newtype(p);
proctype->form = FORM_PROC;
proc->type = proctype;
}
expect(p, ')');
proctype->base = (accept(p, ':') ? type(p) : &VoidType);
- codegen_symbol(p, proc);
-
- /* parse the private declarations */
- if (accept(p, CONST))
- {
- const_decl(p);
- }
- if (accept(p, TYPE))
+ if (proc->forward)
{
- type_decl(p);
- }
-
- if (accept(p, VAR))
- {
- var_decl(p);
+ // check the type here
+ proc->forward = 0;
}
+ codegen_symbol(p, proc);
+ return proc;
+}
+void proc_body(Parser* p, Type* proctype)
+{
expect(p, BEGIN);
SsaBlock* block = ssa_block(p);
p->curr_join = ssa_block(p);
}
expect(p, END);
codegen_block(p, block);
+}
+
+void proc_decl(Parser* p)
+{
+ ENTER_RULE();
+
+ Symbol* proc = proc_type(p);
+
+ /* parse the private declarations */
+ if (accept(p, CONST))
+ {
+ const_decl(p);
+ }
+
+ if (accept(p, TYPE))
+ {
+ type_decl(p);
+ }
+
+ if (accept(p, VAR))
+ {
+ var_decl(p);
+ }
+
+ if (accept(p, FORWARD))
+ {
+ proc->forward = 1;
+ }
+ else if (!accept(p, EXTERN))
+ {
+ proc_body(p, proc->type);
+ }
EXIT_RULE();
}
if (p.syms[i].export)
{
Symbol* sym = symbol_new(curr, 0, p.syms[i].name, p.syms[i].class, 0);
+ *sym = p.syms[i];
sym->module = modid;
}
}
return symbol_getbyid(p, id);
}
+Symbol* symbol_find(Parser* p, size_t module, char* name, int class)
+{
+ Symbol* sym = NULL;
+ size_t index = lookup(p, 0, module, name, class);
+ if (NIL_SYMBOL != index)
+ {
+ sym = symbol_getbyid(p, index);
+ }
+ return sym;
+}
+
size_t symbol_getid(Parser* p, size_t module, char* name, int class)
{
size_t index = lookup(p, 0, module, name, class);