else
{
char* export = (proc->export ? "" : "static");
- printf("\n%svoid %s_%s(void) {\n", export, p->name, proc->name);
+ printf("\n%s%s %s_%s(",
+ export,
+ TypeNames[proc->type->form],
+ p->name,
+ proc->name);
+ for (Symbol* arg = proc->desc; arg; arg = arg->next)
+ {
+ printf("%s %s", TypeNames[arg->type->form], arg->name);
+ }
+ printf(") {\n");
}
}
void codegen_prepcall(Parser* p, Item* item)
{
-// printf(" const %s _T%d = %lld;\n",
-// TypeNames[item->type->form], p->curr_reg, item->imm.i);
-// item->reg = p->curr_reg;
-// p->curr_reg++;
- printf(" const long _T%d = %s(", p->curr_reg, item->imm.s);
- item->reg = p->curr_reg;
- p->curr_reg++;
+ (void)p, (void)item;
}
-void codegen_call(Parser* p, Item* item)
+void codegen_call(Parser* p, Item* item, Item* args)
{
- (void)p, (void)item;
-
printf(" const long _T%d = %s(", p->curr_reg, item->imm.s);
+ while (args)
+ {
+ printf("_T%d", args->reg);
+ if (args->next)
+ {
+ printf(", ");
+ }
+ args = args->next;
+ }
item->reg = p->curr_reg;
p->curr_reg++;
printf(");\n");
void codegen_setarg(Parser* p, Item* item, bool firstarg)
{
load_var(p, item);
- (void)p, (void)item;
- if (item->mode == ITEM_CONST)
- {
- printf("%s%lld", (!firstarg ? ", " : ""), item->imm.i);
- }
- else
- {
- printf("%s_T%d", (!firstarg ? ", " : ""), item->reg);
- }
}
(void)p, (void)item;
}
-void codegen_call(Parser* p, Item* item)
+void codegen_call(Parser* p, Item* item, Item* args)
{
- (void)p, (void)item;
+ (void)p, (void)item, (void)args;
}
void codegen_setarg(Parser* p, Item* item, bool firstarg)
(void)p, (void)item;
}
-void codegen_call(Parser* p, Item* item)
+void codegen_call(Parser* p, Item* item, Item* args)
{
- (void)p, (void)item;
+ (void)p, (void)item, (void)args;
}
void codegen_setarg(Parser* p, Item* item, bool firstarg)
char* alias;
} Module;
-typedef struct {
+typedef struct Item {
+ struct Item* next;
enum {
ITEM_CONST, ITEM_VAR, ITEM_MVAR, ITEM_REG
} mode;
+ Symbol* sym;
Type* type;
int reg;
ImmValue imm;
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);
+void codegen_call(Parser* p, Item* item, Item* args);
void codegen_setarg(Parser* p, Item* item, bool firstarg);
/*
*****************************************************************************/
static void expression(Parser* p, Item* item);
-RULE(param_list)
-{
- (void)item;
- int nargs = 0;
- Item argdef = {0};
- (void)argdef;
- if (!matches(p, ')'))
- {
- Item arg = {0};
- expression(p, &arg);
- // if check_types()
- codegen_setarg(p, &arg, true);
- // else check_array_type()
- nargs++;
-
- while (!matches(p, ')'))
- {
- expect(p, ',');
- expression(p, &arg);
- // if check_types()
- codegen_setarg(p, &arg, false);
- // else check_array_type()
- nargs++;
- }
- }
-}
+//RULE(param_list)
+//{
+//// (void)item;
+//// int nargs = 0;
+//// Item argdef = {0};
+//// (void)argdef;
+//// if (!matches(p, ')'))
+//// {
+//// Item arg = {0};
+//// expression(p, &arg);
+//// // if check_types()
+//// codegen_setarg(p, &arg, true);
+//// // else check_array_type()
+//// nargs++;
+////
+//// while (!matches(p, ')'))
+//// {
+//// expect(p, ',');
+//// expression(p, &arg);
+//// // if check_types()
+//// codegen_setarg(p, &arg, false);
+//// // else check_array_type()
+//// nargs++;
+//// }
+//// }
+//
+// Symbol* args = item->sym;
+//
+//}
RULE(qualident)
{
char* name = expect_text(p, IDENT);
Symbol* sym = symbol_get(p, -1, name);
init_item(item, sym);
- if (sym->class == SYM_VAR)
+ if (sym->class == SYM_VAR || sym->class == SYM_PROC)
{
item->imm.s = sym->name;
}
designator(p, item);
if (accept(p, '('))
{
- // TODO: check item is a procedure
- codegen_prepcall(p, item);
- param_list(p, item);
- codegen_call(p, item);
+// codegen_prepcall(p, item);
+// param_list(p, item);
+ Symbol* proc = symbol_get(p, SYM_PROC, item->imm.s);
+ Symbol* args = proc->desc;
+ 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)
+ {
+ error(p, "too few arguments to function '%s'", proc->name);
+ }
+ else if (!matches(p, ')'))
+ {
+ error(p, "too many arguments to function '%s'", proc->name);
+ }
+ codegen_call(p, item, arglist.next);
expect(p, ')');
}
break;
proc->nargs++;
Symbol* arg = symbol_addfield(p, proc, name, SYM_VAR, false);
arg->type = item->type;
+ if (!matches(p, ')'))
+ {
+ expect(p, ',');
+ }
}
expect(p, ')');
if (accept(p, ':'))
{
// printf(" %s == %s\n", name, sym->name);
- if (sym->name && !strcmp(sym->name, name))
+ if (name && sym->name && !strcmp(sym->name, name))
{
if (class >= 0 && (int)sym->class != class)
{
error(p, "'%s' is not a type", name);
break;
+ case SYM_PROC:
+ error(p, "'%s' is not a procedure", name);
+ break;
+
default:
assert(!"unknown identifier type");
break;
return sym;
}
-
Symbol* symbol_get(Parser* p, int class, char* name)
{
for (Symbol* scope = p->scope; scope; scope = scope->next)
*****************************************************************************/
#ifdef CERISE_TESTS
#include "atf.h"
-
-
-
#endif
\ No newline at end of file
void check_types(Parser* p, Item* a, Item* b)
{
+// printf("%d %d\n", a->type->form, b->type->form);
if (a->type->form == FORM_REAL)
{
check_reals(p, a, b);
b : Int
c : Int
-procedure Foo*(e : Int) : Int
+procedure Foo*(e : Int, z : Int) : Int
const FOO = 2
type foo = Int
var z : Int
# c = 3;
# end
- c = c(1,a,3);
+ c = Foo(1,2);
end