-CFLAGS+=-Wall -Wextra -Werror -std=c99 -pedantic -ggdb
+CFLAGS+=-Wall -Wextra -Werror -std=c99 -pedantic -ggdb -O3
LDFLAGS+=-Wl,--gc-sections,--print-gc-sections
YFLAGS+=--locations -Wno-yacc --defines=parse.h
LFLAGS+=--header-file=scan.h
|| strcmp(t, "print") == 0;
}
-struct expr *expr_funcall_real(char *ident, struct array args, YYLTYPE l)
+static struct expr *expr_funcall_real(char *ident, struct array args, YYLTYPE l)
{
struct expr *res = xalloc(1, struct expr);
res->loc = l;
die("unresolved var type\n");
switch(type->type) {
case tbasic:
- fprintf(cout, "WORD ");
+ fprintf(cout, "%s ",
+ type->data.tbasic == btvoid ? "void" : "WORD");
break;
case tlist:
fprintf(cout, "struct splc_list *");
}
}
-void fundecl_genc(struct fundecl *decl, FILE *cout)
+void fundecl_sig(struct fundecl *decl, FILE *cout)
{
type_genc(decl->rtype, cout);
safe_fprintf(cout, "%s (", decl->ident);
ARRAY_ITER(char *, a, i, decl->args) {
if (i >= ARRAY_SIZE(decl->atypes))
die("function with unmatched type\n");
+ type_genc(ARRAY_EL(struct type *, decl->atypes, i), cout);
safe_fprintf(cout, "%s", a);
if (i < ARRAY_SIZE(decl->args) - 1)
safe_fprintf(cout, ", ");
} AIEND
- safe_fprintf(cout, ") /*");
- if (decl->rtype != NULL) {
- safe_fprintf(cout, " :: ");
- ARRAY_ITER(struct type *, t, i, decl->atypes) {
- type_print(t, cout);
- safe_fprintf(cout, " ");
- } AIEND
- safe_fprintf(cout, "-> ");
- type_print(decl->rtype, cout);
- }
- safe_fprintf(cout, "*/ {\n");
+ safe_fprintf(cout, ")");
+}
+
+void fundecl_genc(struct fundecl *decl, FILE *cout)
+{
+ fundecl_sig(decl, cout);
+ safe_fprintf(cout, "{\n");
ARRAY_ITER(struct stmt *, s, i, decl->body)
stmt_genc(s, 1, cout);
AIEND
{
switch (decl->type) {
case dcomp:
- //TODO generate prototypes?
+ if (ARRAY_SIZE(decl->data.dcomp) > 1) {
+ ARRAY_ITER(struct fundecl *, d, i, decl->data.dcomp)
+ fundecl_sig(d, cout);
+ safe_fprintf(cout, ";\n");
+ AIEND
+ }
ARRAY_ITER(struct fundecl *, d, i, decl->data.dcomp)
fundecl_genc(d, cout);
AIEND
break;
case dfundecl:
- fundecl_genc(decl->data.dfun, cout);
+ die("fundecls should be gone by now\n");
break;
case dvardecl:
vardecl_genc(decl->data.dvar, 0, cout);
void genc(struct ast *ast, FILE *cout)
{
- fprintf(cout,
- "#include <stdint.h>\n"
- "#include <stdlib.h>\n"
- "#define WORD intptr_t\n"
- "struct splc_tuple { WORD fst; WORD snd; };\n"
- "struct splc_list { WORD hd; struct splc_list *tl; };\n"
- "struct splc_tuple *splc_tuple(WORD fst, WORD snd) {\n"
- "\tstruct splc_tuple *res = malloc(sizeof(splc_tuple));\n"
- "\tres->fst = fst;\n"
- "\tres->snd = snd;\n"
- "\treturn res;\n"
- "}\n"
- "struct splc_list *splc_cons(WORD hd, struct splc_list *tl) {\n"
- "\tstruct splc_list *res = malloc(sizeof(splc_tuple));\n"
- "\tres->hd = hd;\n"
- "\tres->tl = tl;\n"
- "\treturn res;\n"
- "}\n"
- "WORD splc_power(WORD l, WORD r) {\n"
- "\tWORD res = 1;\n"
- "\twhile(l-- >= 0)\n"
- "\t\tres *= r;\n"
- "\treturn res;\n"
- "}\n"
- );
+ fprintf(cout, "#include \"rts.h\"\n");
for (int i = 0; i<ast->ndecls; i++) {
fprintf(cout, "\n");
decl_genc(ast->decls[i], cout);
--- /dev/null
+#include "rts.h"
+#include <stdlib.h>
+
+#define REFC(ptr) (*(int *)((ptr)-1))
+
+void *splc_malloc(size_t size)
+{
+ void *res = malloc(sizeof(void *)+size);
+ res++;
+ REFC(res) = 0;
+ return res;
+}
+
+void splc_free(void *ptr)
+{
+ REFC(ptr)--;
+ if (REFC(ptr) == 0)
+ free(ptr-1);
+}
+
+struct splc_tuple *splc_tuple(WORD fst, WORD snd) {
+ struct splc_tuple *res = splc_malloc(sizeof(splc_tuple));
+ res->fst = fst;
+ res->snd = snd;
+ return res;
+}
+struct splc_list *splc_cons(WORD hd, struct splc_list *tl) {
+ struct splc_list *res = splc_malloc(sizeof(splc_tuple));
+ res->hd = hd;
+ res->tl = tl;
+ return res;
+}
+WORD splc_power(WORD l, WORD r) {
+ WORD res = 1;
+ while(l-- >= 0)
+ res *= r;
+ return res;
+}
--- /dev/null
+#ifndef SPLC_RTS_H
+#define SPLC_RTS_H
+
+#include <stdint.h>
+#include <stddef.h>
+
+#define WORD intptr_t
+
+struct splc_tuple { WORD fst; WORD snd; };
+struct splc_list { WORD hd; struct splc_list *tl; };
+
+#endif
die("");
}
-void check_expr_constant(struct expr *expr)
+static void check_expr_constant(struct expr *expr)
{
switch (expr->type) {
case ebinop:
}
}
-struct vardecl *type_vardecl(struct gamma *gamma, struct vardecl *vardecl)
+static struct vardecl *type_vardecl(struct gamma *gamma, struct vardecl *vardecl)
{
struct type *t = vardecl->type == NULL
? gamma_fresh(gamma) : vardecl->type;
return vardecl;
}
-void type_comp(struct gamma *gamma, struct array decl)
+static void type_comp(struct gamma *gamma, struct array decl)
{
//Create a fresh variable for every function in the component
struct type **fs = xalloc(ARRAY_SIZE(decl), struct type *);
subst_free(s0);
}
-void gamma_preamble(struct gamma *gamma)
+static void gamma_preamble(struct gamma *gamma)
{
struct type *t = type_arrow(type_tuple(type_var_str("a")
, type_var_str("b")) ,type_var_str("a"));
type_free(t);
}
-bool check_return_stmt(struct stmt *stmt);
-bool check_return_body(struct array body)
+static bool check_return_stmt(struct stmt *stmt);
+static bool check_return_body(struct array body)
{
ARRAY_ITER(struct stmt *, s, i, body)
if (check_return_stmt(s))
}
-bool check_return_stmt(struct stmt *stmt)
+static bool check_return_stmt(struct stmt *stmt)
{
switch (stmt->type) {
case sassign:
}
}
-void check_return_comp(struct array decl)
+static void check_return_comp(struct array decl)
{
ARRAY_ITER(struct fundecl *, d, i, decl) {
if (d->rtype->type == tbasic && d->rtype->data.tbasic == btvoid)
} AIEND
}
-void add_return_if_none(struct array decl)
+static void add_return_if_none(struct array decl)
{
ARRAY_ITER(struct fundecl *, d, i, decl)
if (d->rtype == NULL && !check_return_body(d->body))
AIEND
}
+bool checkmain (struct fundecl *d)
+{
+ fprintf(stderr, "%s\n", d->ident);
+ if (strcmp(d->ident, "main") == 0) {
+ if (ARRAY_SIZE(d->args) != 0)
+ type_error(d->loc, true, "main cannot have arguments");
+ if (d->rtype->type != tbasic || d->rtype->data.tbasic != btvoid)
+ type_error(d->loc, true, "main must return void");
+ return true;
+ }
+ return false;
+}
+
struct ast *sem(struct ast *ast)
{
//Break up into strongly connected components
}
gamma_free(gamma);
+ //Check for a main function
+ bool found = false;
+ for (int i = 0; i<ast->ndecls && !found; i++) {
+ struct decl *decl = ast->decls[i];
+ if (decl->type == dcomp) {
+ ARRAY_ITER(struct fundecl *, d, i, decl->data.dcomp) {
+ if ((found = checkmain(d)))
+ break;
+ } AIEND
+ }
+ }
+ if (!found)
+ type_error(ast->loc, true, "no main function found\n");
+
return ast;
}
#include "../sem.h"
#include "../ast.h"
-bool occurs_check(struct ident ident, struct type *r)
+static bool occurs_check(struct ident ident, struct type *r)
{
int nftv = 0;
struct ident *ftv = NULL;
return NULL;
}
-struct subst *infer_binop(struct gamma *gamma, struct expr *l, struct expr *r,
+static struct subst *infer_binop(struct gamma *gamma, struct expr *l, struct expr *r,
struct type *a1, struct type *a2, struct type *rt, struct type *sigma)
{
struct subst *s1 = infer_expr(gamma, l, a1);
return subst_union(s4, s3);
}
-struct subst *infer_unop(struct gamma *gamma, struct expr *e,
+static struct subst *infer_unop(struct gamma *gamma, struct expr *e,
struct type *a, struct type *rt, struct type *sigma)
{
struct subst *s1 = infer_expr(gamma, e, a);
return NULL;
}
-struct subst *infer_body(struct gamma *gamma, struct array stmts, struct type *type)
+static struct subst *infer_body(struct gamma *gamma, struct array stmts, struct type *type)
{
gamma_increment_scope(gamma);
struct subst *s0 = subst_id(), *s1;
struct ast *infer(struct ast *ast);
-bool occurs_check(struct ident ident, struct type *r);
struct subst *unify(YYLTYPE loc, struct type *l, struct type *r);
struct subst *infer_expr(struct gamma *gamma, struct expr *expr, struct type *type);
struct subst *infer_stmt(struct gamma *gamma, struct stmt *stmt, struct type *type);
free(cfile);
switch(lang) {
case langc:
-// genc(result, cout);
+ genc(result, cout);
break;
default:
die("unsupported language\n");
#include "util.h"
-int fromHex(char c)
+static inline int fromHex(char c)
{
if (c >= '0' && c <= '9')
return c-'0';
return buf;
}
-bool isodigit(char c)
+static inline bool isodigit(char c)
{
return c >= '0' && c <= '7';
}
-int fromOctal(char c)
+static inline int fromOctal(char c)
{
if (isodigit(c))
return c-'0';