*.o
y.output
a.c
+a.out
callgrind.out.*
massif.out.*
res->type = efuncall;
res->data.efuncall.ident = ident;
res->data.efuncall.args = args;
+ res->data.efuncall.type = NULL;
return res;
}
escape_char(expr->data.echar, buf, false));
break;
case efuncall:
- safe_fprintf(out, "%s(", expr->data.efuncall.ident);
+ safe_fprintf(out, "%s", expr->data.efuncall.ident);
+ if (expr->data.efuncall.type != NULL) {
+ safe_fprintf(out, " /* ");
+ type_print(expr->data.efuncall.type, out);
+ safe_fprintf(out, " */ ");
+ }
+ safe_fprintf(out, "(");
ARRAY_ITER(struct expr *, e, i, expr->data.efuncall.args) {
expr_print2(e, out, nfctx);
if (i+1 < ARRAY_SIZE(expr->data.efuncall.args))
break;
case efuncall:
free(expr->data.efuncall.ident);
+ if (expr->data.efuncall.type != NULL)
+ type_free(expr->data.efuncall.type);
array_free(expr->data.efuncall.args, (void (*)(void *))expr_free);
break;
case eint:
struct {
char *ident;
struct array args; // struct expr *
+ struct type *type; // type for overloaded functions
} efuncall;
int eint;
char *eident;
#include <stdbool.h>
+#include <string.h>
#include "ast.h"
safe_fprintf(cout, ")");
}
+static void call_print_type(struct type *type, FILE *cout)
+{
+ switch(type->type) {
+ case tarrow:
+ die("cannot print functions???");
+ break;
+ case tbasic:
+ safe_fprintf(cout, "%s", basictype_str[type->data.tbasic]);
+ break;
+ case tlist:
+ safe_fprintf(cout, "l");
+ call_print_type(type->data.tlist, cout);
+ break;
+ case ttuple:
+ safe_fprintf(cout, "t");
+ type_print(type->data.ttuple.l, cout);
+ type_print(type->data.ttuple.r, cout);
+ safe_fprintf(cout, "t");
+ break;
+ case tvar:
+ die("cannot print overloaded types???");
+ break;
+ }
+}
+
void expr_genc(struct expr *expr, FILE *cout)
{
char buf[] = "\\x55";
escape_char(expr->data.echar, buf, false));
break;
case efuncall:
- safe_fprintf(cout, "%s(", expr->data.efuncall.ident);
+ if (strcmp(expr->data.efuncall.ident, "print") == 0) {
+ fprintf(cout, "print_");
+ call_print_type(expr->data.efuncall.type, cout);
+ } else {
+ safe_fprintf(cout, "%s", expr->data.efuncall.ident);
+ }
+ safe_fprintf(cout, "(");
ARRAY_ITER(struct expr *, e, i, expr->data.efuncall.args) {
expr_genc(e, cout);
if (i+1 < ARRAY_SIZE(expr->data.efuncall.args))
#include "rts.h"
#include <stdlib.h>
+#include <stdio.h>
#define REFC(ptr) (*(int *)((ptr)-1))
res *= r;
return res;
}
+void print_Int(WORD l)
+{
+ printf("%ld", l);
+}
+void print_Char(WORD l)
+{
+ printf("%c", l);
+}
+void print_Bool(WORD l)
+{
+ printf("%s", l ? "true" : "false");
+}
struct splc_tuple { WORD fst; WORD snd; };
struct splc_list { WORD hd; struct splc_list *tl; };
+void print_Int(WORD l);
+void print_Char(WORD l);
+void print_Bool(WORD l);
+
#endif
return vardecl;
}
+static void patch_overload_stmt(struct subst *subst, struct stmt *s);
+static void patch_overload_body(struct subst *subst, struct array body)
+{
+ ARRAY_ITER(struct stmt *, s, j, body)
+ patch_overload_stmt(subst, s);
+ AIEND
+}
+
+static void patch_overload_expr(struct subst *subst, struct expr *expr)
+{
+ if (expr == NULL)
+ return;
+ switch (expr->type) {
+ case ebinop:
+ patch_overload_expr(subst, expr->data.ebinop.l);
+ patch_overload_expr(subst, expr->data.ebinop.r);
+ break;
+ case efuncall:
+ if (strcmp(expr->data.efuncall.ident, "print") == 0)
+ expr->data.efuncall.type = subst_apply_t(subst,
+ expr->data.efuncall.type);
+ break;
+ case etuple:
+ patch_overload_expr(subst, expr->data.etuple.left);
+ patch_overload_expr(subst, expr->data.etuple.right);
+ break;
+ default:
+ break;
+ }
+
+}
+static void patch_overload_stmt(struct subst *subst, struct stmt *stmt)
+{
+ switch (stmt->type) {
+ case sassign:
+ patch_overload_expr(subst, stmt->data.sassign.expr);
+ break;
+ case sif:
+ patch_overload_expr(subst, stmt->data.sif.pred);
+ patch_overload_body(subst, stmt->data.sif.then);
+ patch_overload_body(subst, stmt->data.sif.els);
+ break;
+ case sreturn:
+ patch_overload_expr(subst, stmt->data.sreturn);
+ break;
+ case sexpr:
+ patch_overload_expr(subst, stmt->data.sexpr);
+ break;
+ case svardecl:
+ patch_overload_expr(subst, stmt->data.svardecl->expr);
+ break;
+ case swhile:
+ patch_overload_expr(subst, stmt->data.swhile.pred);
+ patch_overload_body(subst, stmt->data.swhile.body);
+ break;
+ }
+}
+
static void type_comp(struct gamma *gamma, struct array decl)
{
//Create a fresh variable for every function in the component
for (size_t i = 0; i<ARRAY_SIZE(decl); i++)
type_free(fs[i]);
free(fs);
+
+ //Patch all overloaded functions
+ ARRAY_ITER(struct fundecl *, d, i, decl) {
+ patch_overload_body(s0, d->body);
+ } AIEND
subst_free(s0);
}
//Infer return type
s1 = unify(expr->loc, t, type);
s0 = subst_union(s1, s0);
+ if (strcmp(expr->data.efuncall.ident, "print") == 0)
+ expr->data.efuncall.type = type_dup(ft->data.tarrow.l);
type_free(ft);
return s0;
case eint:
#include "type.h"
#include "ident.h"
-static const char *basictype_str[] = {
+const char *basictype_str[] = {
[btbool] = "Bool", [btchar] = "Char", [btint] = "Int",
[btvoid] = "Void",
};
#include "ast.h"
#include "ident.h"
+extern const char *basictype_str[];
enum basictype {btbool, btchar, btint, btvoid};
struct type {
enum {tarrow,tbasic,tlist,ttuple,tvar} type;