*.o
y.output
a.c
+
+callgrind.out.*
+massif.out.*
CFLAGS+=-Wall -Wextra -Werror -std=c99 -pedantic -ggdb
-YFLAGS+=-d --locations -v --defines=parse.h
+LDFLAGS+=-Wl,--gc-sections,--print-gc-sections
+YFLAGS+=--locations -Wno-yacc --defines=parse.h
LFLAGS+=--header-file=scan.h
OBJECTS:=scan.o parse.o ast.o type.o util.o list.o sem.o genc.o ident.o\
parse.h: parse.c
expr.c: y.tab.h
-scan.o: CFLAGS+=-D_XOPEN_SOURCE=700
-
-.PHONY: test
-
-test:
- CFLAGS="$(CFLAGS)" $(MAKE) -C test test
+$(filter-out scan.o parse.o,$(OBJECTS)): CFLAGS+=-ffunction-sections
clean:
$(RM) $(OBJECTS) y.output parse.h scan.h scan.c parse.c expr a.c
return (struct ident) {.type=istr, .data={.istr=s}};
}
-struct ident ident_int(int i)
-{
- return (struct ident) {.type=iint, .data={.iint=i}};
-}
-
int ident_cmp(struct ident l, struct ident r)
{
- //int > buf == str
- switch (l.type) {
- case iint:
- switch (r.type) {
- case iint:
- return l.data.iint - r.data.iint;
- default:
- return 1;
- }
- break;
- case istr:
- switch (r.type) {
- case iint:
- return -1;
- case istr:
- return strcmp(l.data.istr, r.data.istr);
- }
- break;
- }
- return 0;
+ //int > str
+ if (l.type == iint)
+ return r.type == iint ? l.data.iint - r.data.iint : 1;
+ else
+ return r.type == istr ? strcmp(l.data.istr, r.data.istr) : -1;
}
int ident_cmpv(const void *l, const void *r)
return ident_cmp(*(struct ident *)l, *(struct ident *)r);
}
-int ident_stricmp(char *l, struct ident r)
-{
- return ident_cmp((struct ident){.type=istr, .data={.istr=l}}, r);
-}
-
-int ident_stricmpv(const void *l, const void *r)
-{
- return ident_stricmp((char *)l, *(struct ident *)r);
-}
-
-int ident_istrcmp(struct ident l, char *r)
-{
- return ident_cmp(l, (struct ident){.type=istr, .data={.istr=r}});
-}
-
-int ident_istrcmpv(const void *l, const void *r)
-{
- return ident_istrcmp(*(struct ident *)l, (char *)r);
-}
-
struct ident ident_dup(struct ident i)
{
if (i.type == istr)
return i;
}
-char *ident_tostr(struct ident i)
-{
- if (i.type == istr)
- return i.data.istr;
- char buf[10] = {0};
- sprintf(buf, "%d", i.data.iint);
- return safe_strdup(buf);
-}
-
void ident_print(struct ident i, FILE *out)
{
if (i.type == istr)
};
struct ident ident_str(char *istr);
-struct ident ident_int(int iint);
int ident_cmp(struct ident, struct ident);
int ident_cmpv(const void *, const void *);
-int ident_stricmp(char *, struct ident);
-int ident_stricmpv(const void *, const void *);
-int ident_istrcmp(struct ident, char *);
-int ident_istrcmpv(const void *, const void *);
struct ident ident_dup(struct ident);
-char *ident_tostr(struct ident);
void ident_print(struct ident, FILE *);
void ident_free(struct ident);
#include "list.h"
#include "util.h"
-struct list *list_append(void *el, struct list *head)
-{
- if (head == NULL)
- return list_cons(el, NULL);
- struct list *tail = head;
- while (tail->tail != NULL)
- tail = tail->tail;
- tail->tail = list_cons(el, NULL);
- return head;
-}
-
struct list *list_cons(void *el, struct list *tail)
{
struct list *res = xalloc(1, struct list);
struct list *tail;
};
-struct list *list_append(void *el, struct list *head);
struct list *list_cons(void *el, struct list *tail);
void list_free(struct list *head, void (*freefun)(void *));
void **list_to_array(struct list *list, int *num, bool reverse, int extra);
%}
-%define parse.lac full
%define parse.error verbose
+// Dangling else
+//%expect 1
+// Tuples and parenthesis
+//%expect-rr 1
+%glr-parser
+%locations
+%parse-param { struct ast **result }
%union {
struct expr *expr;
char *ident;
}
-%locations
%token <ident> IDENT
%token <expr> BOOL CHAR INTEGER STRING
%token ARROW ASSIGN BCLOSE BINAND BINOR BOPEN CCLOSE COMMA CONS COPEN DIVIDE
%token DOT ELSE ERROR IF INVERSE MINUS MODULO NIL PLUS POWER RETURN SEMICOLON
%token SCLOSE SOPEN TIMES TBOOL TCHAR TINT TVOID VAR WHILE
-%parse-param { struct ast **result }
-
%right BINOR
%right BINAND
%nonassoc EQ NEQ LEQ LE GEQ GE
%right POWER
%type <ast> start
-%type <expr> expr
+%type <expr> expr tuply
%type <list> args body decls fargs field fnargs nargs funtype bbody
%type <stmt> stmt
%type <type> type ftype
| vardecl { $$ = stmt_vardecl($1, @$); }
| expr SEMICOLON { $$ = stmt_expr($1, @$); }
;
+tuply
+ : BCLOSE { $$ = NULL; }
+ | COMMA expr BCLOSE { $$ = $2; }
+ ;
expr
: expr BINOR expr { $$ = expr_binop($1, binor, $3, @$); }
| expr BINAND expr { $$ = expr_binop($1, binand, $3, @$); }
| MINUS expr %prec TIMES { $$ = expr_unop(negate, $2, @$); }
| INVERSE expr %prec TIMES { $$ = expr_unop(inverse, $2, @$); }
| IDENT BOPEN fargs BCLOSE field { $$ = expr_funcall($1, $3, $5, @$); }
- | BOPEN expr COMMA expr BCLOSE { $$ = expr_tuple($2, $4, @$); }
- | BOPEN expr BCLOSE { $$ = $2; }
+ | BOPEN expr tuply { $$ = $3 == NULL ? $2 : expr_tuple($2, $3, @$); }
| INTEGER
| BOOL
| CHAR
%option noinput
%option nounput
+%option never-interactive
%{
#define YY_USER_ACTION \
return vardecl;
}
-void type_fundecl(struct gamma *gamma, struct fundecl *decl)
-{
- struct type *f1 = gamma_fresh(gamma);
- struct subst *s1 = infer_fundecl(gamma, decl, f1);
- f1 = subst_apply_t(s1, f1);
-
- gamma_insert(gamma, ident_str(decl->ident), scheme_generalise(gamma, f1));
- subst_free(s1);
- type_free(f1);
-}
-
void type_comp(struct gamma *gamma, int ndecls, struct fundecl **decl)
{
//Create a fresh variable for every function in the component
}
}
gamma_free(gamma);
- subst_free_queue();
return ast;
}
#define KEEP_LIST
-#ifdef KEEP_LIST
-#define BUFCAP 100
-struct subst *buf[BUFCAP] = {NULL};
-int bufi = 0;
-#endif
-
struct subst *subst_id()
{
struct subst *res;
-#ifdef KEEP_LIST
- if (bufi == 0 || bufi >= BUFCAP) {
-#endif
- res = xalloc(1, struct subst);
- res->capacity = INCAP;
- res->nvar = 0;
- res->entries = xalloc(INCAP, struct subst_entry);
-#ifdef KEEP_LIST
- } else {
- res = buf[--bufi];
- res->nvar = 0;
- }
-#endif
+ res = xalloc(1, struct subst);
+ res->capacity = INCAP;
+ res->nvar = 0;
+ res->entries = xalloc(INCAP, struct subst_entry);
return res;
}
}
static const void *bsearchfail;
-int idententrycmp(const void *l, const void *r)
+static int idententrycmp(const void *l, const void *r)
{
bsearchfail = r;
return ident_cmp(*(struct ident *)l, ((struct subst_entry *)r)->var);
return gamma;
}
-void subst_print(struct subst *s, FILE *out)
-{
- if (s == NULL) {
- fprintf(out, "(nil)");
- } else {
- fprintf(out, "[");
- for (size_t i = 0; i<s->nvar; i++) {
- ident_print(s->entries[i].var, out);
- fprintf(out, "->");
- type_print(s->entries[i].type, out);
- if (i + 1 < s->nvar)
- fprintf(out, ", ");
- }
- fprintf(out, "]");
- }
-}
-
-static void subst_really_free(void *sp)
-{
- struct subst *s = (struct subst *)sp;
- if (s != NULL) {
- free(s->entries);
- free(s);
- }
-}
+//void subst_print(struct subst *s, FILE *out)
+//{
+// if (s == NULL) {
+// fprintf(out, "(nil)");
+// } else {
+// fprintf(out, "[");
+// for (size_t i = 0; i<s->nvar; i++) {
+// ident_print(s->entries[i].var, out);
+// fprintf(out, "->");
+// type_print(s->entries[i].type, out);
+// if (i + 1 < s->nvar)
+// fprintf(out, ", ");
+// }
+// fprintf(out, "]");
+// }
+//}
void subst_free(struct subst *s)
{
ident_free(s->entries[i].var);
type_free(s->entries[i].type);
}
-#ifdef KEEP_LIST
- if (bufi < BUFCAP) {
- buf[bufi++] = s;
- } else {
- subst_really_free(s);
- }
-#else
- subst_really_free(s);
-#endif
-}
-
-void subst_free_queue()
-{
-#ifdef KEEP_LIST
- while (--bufi >= 0) {
- free(buf[bufi]->entries);
- free(buf[bufi]);
- }
-#endif
+ free(s->entries);
+ free(s);
}
struct scheme *subst_apply_s(struct subst *subst, struct scheme *scheme);
struct gamma *subst_apply_g(struct subst *subst, struct gamma *gamma);
-void subst_print(struct subst *s, FILE *out);
+//void subst_print(struct subst *s, FILE *out);
void subst_free(struct subst *s);
-void subst_free_queue();
#endif
return tj.head;
}
-int iddeclcmp(const void *l, const void *r)
-{
- fprintf(stderr, "iddeclcmp: %s %s\n", (char *)l, (*(struct decl **)r)->data.dfun->ident);
- return strcmp((char *)l, (*(struct decl **)r)->data.dfun->ident);
-}
-
struct list *edges_expr(int ndecls, struct decl **decls, void *parent,
struct expr *expr, struct list *l)
{
struct type *type_var(struct ident ident)
{
struct type *res = xalloc(1, struct type);
- if (ident_istrcmp(ident, "Int") == 0) {
+ if (ident_cmp(ident, ident_str("Int")) == 0) {
res->type = tbasic;
res->data.tbasic = btint;
ident_free(ident);
- } else if (ident_istrcmp(ident, "Char") == 0) {
+ } else if (ident_cmp(ident, ident_str("Char")) == 0) {
res->type = tbasic;
res->data.tbasic = btchar;
ident_free(ident);
- } else if (ident_istrcmp(ident, "Bool") == 0) {
+ } else if (ident_cmp(ident, ident_str("Bool")) == 0) {
res->type = tbasic;
res->data.tbasic = btbool;
ident_free(ident);
- } else if (ident_istrcmp(ident, "Void") == 0) {
+ } else if (ident_cmp(ident, ident_str("Void")) == 0) {
res->type = tbasic;
res->data.tbasic = btvoid;
ident_free(ident);