work on type inference some more
[ccc.git] / ast.h
diff --git a/ast.h b/ast.h
index 13d3c58..635d0c8 100644 (file)
--- a/ast.h
+++ b/ast.h
 #include <stdio.h>
 #include <stdbool.h>
 
-enum binop {
-       binor,binand,
-       eq,neq,leq,le,geq,ge,
-       cons,plus,minus,times,divide,modulo,power
+#include "util.h"
+#include "type.h"
+struct ast;
+#include "parse.h"
+
+extern const char *fieldspec_str[];
+extern const char *binop_str[];
+extern const char *unop_str[];
+struct ast {
+       int ndecls;
+       struct decl **decls;
 };
-enum fieldspec {fst,snd,hd,tl};
-enum unop {negate,inverse};
-enum ast_type {
-       an_assign, an_binop, an_bool, an_char, an_cons, an_funcall, an_fundecl,
-       an_ident, an_if, an_int, an_list, an_nil, an_return, an_stmt_expr,
-       an_unop, an_vardecl, an_while
+
+struct vardecl {
+       struct type *type;
+       char *ident;
+       struct expr *expr;
 };
-struct ast {
-       enum ast_type type;
+struct fundecl {
+       char *ident;
+       int nargs;
+       char **args;
+       int natypes;
+       struct type **atypes;
+       struct type *rtype;
+       int nbody;
+       struct stmt **body;
+};
+
+struct decl {
+       //NOTE: DON'T CHANGE THIS ORDER
+       enum {dcomp, dvardecl, dfundecl} type;
        union {
                struct {
-                       struct ast *ident;
-                       struct ast *expr;
-               } an_assign;
-               bool an_bool;
-               struct {
-                       struct ast *l;
-                       enum binop op;
-                       struct ast *r;
-               } an_binop;
-               char an_char;
-               struct {
-                       struct ast *el;
-                       struct ast *tail;
-               } an_cons;
-               struct {
-                       char *ident;
-                       int nargs;
-                       struct ast **args;
-               } an_funcall;
+                       int ndecls;
+                       struct fundecl **decls;
+               } dcomp;
+               struct fundecl *dfun;
+               struct vardecl *dvar;
+       } data;
+};
+
+struct stmt {
+       enum {sassign, sif, sreturn, sexpr, svardecl, swhile} type;
+       union {
                struct {
                        char *ident;
-                       int nargs;
-                       char **args;
-                       int nbody;
-                       struct ast **body;
-               } an_fundecl;
+                       int nfields;
+                       char **fields;
+                       struct expr *expr;
+               } sassign;
                struct {
-                       struct ast *pred;
+                       struct expr *pred;
                        int nthen;
-                       struct ast **then;
+                       struct stmt **then;
                        int nels;
-                       struct ast **els;
-               } an_if;
-               int an_int;
+                       struct stmt **els;
+               } sif;
+               struct vardecl *svardecl;
+               struct expr *sreturn;
+               struct expr *sexpr;
+               struct {
+                       struct expr *pred;
+                       int nbody;
+                       struct stmt **body;
+               } swhile;
+       } data;
+};
+
+enum binop {
+       binor, binand, eq, neq, leq, le, geq, ge, cons, plus, minus, times,
+       divide, modulo, power,
+};
+enum fieldspec {fst,snd,hd,tl};
+enum unop {negate,inverse};
+struct expr {
+       enum {ebinop, ebool, echar, efuncall, eident, eint, enil, etuple,
+               estring, eunop} type;
+       union {
+               bool ebool;
+               struct {
+                       struct expr *l;
+                       enum binop op;
+                       struct expr *r;
+               } ebinop;
+               char echar;
                struct {
                        char *ident;
+                       int nargs;
+                       struct expr **args;
                        int nfields;
                        enum fieldspec *fields;
-               } an_ident;
+               } efuncall;
+               int eint;
                struct {
-                       int n;
-                       struct ast **ptr;
-               } an_list;
-               //struct { } an_nil;
-               struct ast *an_return;
-               struct ast *an_stmt_expr;
+                       char *ident;
+                       int nfields;
+                       enum fieldspec *fields;
+               } eident;
                struct {
-                       enum unop op;
-                       struct ast *l;
-               } an_unop;
+                       struct expr *left;
+                       struct expr *right;
+               } etuple;
                struct {
-                       char *ident;
-                       struct ast *l;
-               } an_vardecl;
+                       int nchars;
+                       char *chars;
+               } estring;
                struct {
-                       struct ast *pred;
-                       int nbody;
-                       struct ast **body;
-               } an_while;
+                       enum unop op;
+                       struct expr *l;
+               } eunop;
        } data;
 };
 
-struct ast *ast_assign(struct ast *ident, struct ast *expr);
-struct ast *ast_binop(struct ast *l, enum binop op, struct ast *tail);
-struct ast *ast_bool(bool b);
-struct ast *ast_char(const char *c);
-struct ast *ast_cons(struct ast *el, struct ast *tail);
-struct ast *ast_funcall(struct ast *ident, struct ast *args);
-struct ast *ast_fundecl(struct ast *ident, struct ast *args, struct ast *body);
-struct ast *ast_if(struct ast *pred, struct ast *then, struct ast *els);
-struct ast *ast_int(int integer);
-struct ast *ast_identc(char *ident);
-struct ast *ast_ident(struct ast *ident, struct ast *fields);
-struct ast *ast_list(struct ast *llist);
-struct ast *ast_nil();
-struct ast *ast_return(struct ast *rtrn);
-struct ast *ast_stmt_expr(struct ast *expr);
-struct ast *ast_unop(enum unop op, struct ast *l);
-struct ast *ast_vardecl(struct ast *ident, struct ast *l);
-struct ast *ast_while(struct ast *pred, struct ast *body);
+struct ast *ast(struct list *decls);
+
+struct vardecl *vardecl(struct type *type, char *ident, struct expr *expr);
+struct fundecl *fundecl(char *ident, struct list *args, struct list *atypes,
+       struct type *rtype, struct list *body);
+
+struct decl *decl_fun(struct fundecl *fundecl);
+struct decl *decl_var(struct vardecl *vardecl);
+
+struct stmt *stmt_assign(char *ident, struct list *fields, struct expr *expr);
+struct stmt *stmt_if(struct expr *pred, struct list *then, struct list *els);
+struct stmt *stmt_return(struct expr *rtrn);
+struct stmt *stmt_expr(struct expr *expr);
+struct stmt *stmt_vardecl(struct vardecl *vardecl);
+struct stmt *stmt_while(struct expr *pred, struct list *body);
+
+struct expr *expr_binop(struct expr *l, enum binop op, struct expr *r);
+struct expr *expr_bool(bool b);
+struct expr *expr_char(char *c);
+struct expr *expr_funcall(char *ident, struct list *args, struct list *fields);
+struct expr *expr_int(int integer);
+struct expr *expr_ident(char *ident, struct list *fields);
+struct expr *expr_nil();
+struct expr *expr_tuple(struct expr *left, struct expr *right);
+struct expr *expr_string(char *str);
+struct expr *expr_unop(enum unop op, struct expr *l);
 
-int ast_llistlength(struct ast *list);
+void ast_print(struct ast *, FILE *out);
+void vardecl_print(struct vardecl *decl, int indent, FILE *out);
+void fundecl_print(struct fundecl *decl, FILE *out);
+void decl_print(struct decl *ast, FILE *out);
+void stmt_print(struct stmt *ast, int indent, FILE *out);
+void expr_print(struct expr *ast, FILE *out);
 
-void ast_print(struct ast * ast, int indent, FILE *out);
-void ast_free(struct ast *ast);
+void ast_free(struct ast *);
+void vardecl_free(struct vardecl *decl);
+void fundecl_free(struct fundecl *fundecl);
+void decl_free(struct decl *ast);
+void stmt_free(struct stmt *ast);
+void expr_free(struct expr *ast);
 
 #endif