rewrite to union type, much better
[ccc.git] / parse.y
diff --git a/parse.y b/parse.y
index 4311833..3cc1d44 100644 (file)
--- a/parse.y
+++ b/parse.y
@@ -4,11 +4,9 @@
 #include <stdlib.h>
 
 #include "ast.h"
-#define YYSTYPE struct ast *
 
 #include "y.tab.h"
 
-int yylex_debug = 1;
 int yylex(void);
 
 void yyerror(struct ast **result, const char *str)
@@ -24,10 +22,21 @@ int yywrap()
 
 %}
 
+%union
+{
+       struct expr *expr;
+       struct stmt *stmt;
+       struct list *list;
+       struct vardecl vardecl;
+       struct decl *decl;
+       char *ident;
+}
+
 //%define parse.error verbose
-%token ASSIGN BCLOSE BINAND BINOR BOOL BOPEN CCLOSE CHAR COMMA CONS COPEN
-%token DIVIDE DOT ELSE IDENT IF INTEGER INVERSE MINUS MODULO NIL PLUS POWER
-%token RETURN SEMICOLON TIMES VAR WHILE
+%token <ident> IDENT
+%token <expr> BOOL CHAR INTEGER
+%token ASSIGN BCLOSE BINAND BINOR BOPEN CCLOSE COMMA CONS COPEN DIVIDE DOT ELSE
+%token IF INVERSE MINUS MODULO NIL PLUS POWER RETURN SEMICOLON TIMES VAR WHILE
 
 %parse-param { struct ast **result }
 
@@ -39,87 +48,86 @@ int yywrap()
 %left TIMES DIVIDE MODULO
 %right POWER
 
-%%
+%type <ast> start
+%type <expr> expr
+%type <list> args body decls fargs field fnargs nargs
+%type <decl> fundecl
+%type <vardecl> vardecl
+%type <stmt> stmt
 
-start : decls { *result = ast_list($1); } ;
+%%
 
+start : decls { *result = ast($1); } ;
 decls
        : { $$ = NULL; }
-       | decls vardecl SEMICOLON { $$ = ast_cons($2, $1); }
-       | decls fundecl { $$ = ast_cons($2, $1); }
+       | decls vardecl SEMICOLON { $$ = list_cons(decl_var($2), $1); }
+       | decls fundecl { $$ = list_cons($2, $1); }
        ;
-
 vardecl
-       : VAR IDENT ASSIGN expr { $$ = ast_vardecl($2, $4); }
+       : VAR IDENT ASSIGN expr { $$ = vardecl($2, $4); }
        ;
-
 fundecl
        : IDENT BOPEN args BCLOSE COPEN body CCLOSE
-               { $$ = ast_fundecl($1, ast_list($3), ast_list($6)); }
+               { $$ = decl_fun($1, $3, $6); }
        ;
-
 args
        : { $$ = NULL; }
        | nargs
        ;
 nargs
-       : nargs COMMA IDENT { $$ = ast_cons($3, $1); }
-       | IDENT { $$ = ast_cons($1, NULL); }
+       : nargs COMMA IDENT { $$ = list_cons($3, $1); }
+       | IDENT { $$ = list_cons($1, NULL); }
        ;
-
 fargs
        : { $$ = NULL; }
        | fnargs
        ;
 fnargs
-       : fnargs COMMA expr { $$ = ast_cons($3, $1); }
-       | expr { $$ = ast_cons($1, NULL); }
+       : fnargs COMMA expr { $$ = list_cons($3, $1); }
+       | expr { $$ = list_cons($1, NULL); }
        ;
 body
        : { $$ = NULL; }
-       | body vardecl SEMICOLON { $$ = ast_cons($2, $1); }
-       | body stmt { $$ = ast_cons($2, $1); }
+       | body stmt { $$ = list_cons($2, $1); }
        ;
-
 stmt
        : IF BOPEN expr BCLOSE COPEN body CCLOSE ELSE COPEN body CCLOSE
-               { $$ = ast_if($3, ast_list($6), ast_list($10)); }
+               { $$ = stmt_if($3, $6, $10); }
        | WHILE BOPEN expr BCLOSE COPEN body CCLOSE
-               { $$ = ast_while($3, ast_list($6)); }
-       | expr SEMICOLON { $$ = ast_stmt_expr($1); }
-       | IDENT ASSIGN expr SEMICOLON { $$ = ast_assign($1, $3); }
-       | RETURN expr SEMICOLON { $$ = ast_return($2); }
-       | RETURN SEMICOLON { $$ = ast_return(NULL); }
+               { $$ = stmt_while($3, $6); }
+       | expr SEMICOLON { $$ = stmt_expr($1); }
+       | IDENT ASSIGN expr SEMICOLON { $$ = stmt_assign($1, $3); }
+       | RETURN expr SEMICOLON { $$ = stmt_return($2); }
+       | RETURN SEMICOLON { $$ = stmt_return(NULL); }
+       | vardecl SEMICOLON { $$ = stmt_vardecl($1); }
        ;
-
 field
        : { $$ = NULL; }
-       | field DOT IDENT { $$ = ast_cons($3, $1); }
-
+       | field DOT IDENT { $$ = list_cons($3, $1); }
 expr
-       : expr BINOR expr { $$ = ast_binop($1, binor, $3); }
-       | expr BINAND expr { $$ = ast_binop($1, binand, $3); }
-       | expr EQ expr { $$ = ast_binop($1, eq, $3); }
-       | expr NEQ expr { $$ = ast_binop($1, neq, $3); }
-       | expr LEQ expr { $$ = ast_binop($1, leq, $3); }
-       | expr LE expr { $$ = ast_binop($1, le, $3); }
-       | expr GEQ expr { $$ = ast_binop($1, geq, $3); }
-       | expr GE expr { $$ = ast_binop($1, ge, $3); }
-       | expr CONS expr { $$ = ast_binop($1, cons, $3); }
-       | expr PLUS expr { $$ = ast_binop($1, plus, $3); }
-       | expr MINUS expr { $$ = ast_binop($1, minus, $3); }
-       | expr TIMES expr { $$ = ast_binop($1, times, $3); }
-       | expr DIVIDE expr { $$ = ast_binop($1, divide, $3); }
-       | expr MODULO expr { $$ = ast_binop($1, modulo, $3); }
-       | expr POWER expr { $$ = ast_binop($1, power, $3); }
-       | MINUS expr { $$ = ast_unop(negate, $2); }
-       | INVERSE expr %prec TIMES { $$ = ast_unop(inverse, $2); }
-       | BOPEN expr COMMA expr BCLOSE { $$ = ast_tuple($2, $4); }
+       : expr BINOR expr { $$ = expr_binop($1, binor, $3); }
+       | expr BINAND expr { $$ = expr_binop($1, binand, $3); }
+       | expr EQ expr { $$ = expr_binop($1, eq, $3); }
+       | expr NEQ expr { $$ = expr_binop($1, neq, $3); }
+       | expr LEQ expr { $$ = expr_binop($1, leq, $3); }
+       | expr LE expr { $$ = expr_binop($1, le, $3); }
+       | expr GEQ expr { $$ = expr_binop($1, geq, $3); }
+       | expr GE expr { $$ = expr_binop($1, ge, $3); }
+       | expr CONS expr { $$ = expr_binop($1, cons, $3); }
+       | expr PLUS expr { $$ = expr_binop($1, plus, $3); }
+       | expr MINUS expr { $$ = expr_binop($1, minus, $3); }
+       | expr TIMES expr { $$ = expr_binop($1, times, $3); }
+       | expr DIVIDE expr { $$ = expr_binop($1, divide, $3); }
+       | expr MODULO expr { $$ = expr_binop($1, modulo, $3); }
+       | expr POWER expr { $$ = expr_binop($1, power, $3); }
+       | MINUS expr { $$ = expr_unop(negate, $2); }
+       | INVERSE expr %prec TIMES { $$ = expr_unop(inverse, $2); }
+       | BOPEN expr COMMA expr BCLOSE { $$ = expr_tuple($2, $4); }
        | BOPEN expr BCLOSE { $$ = $2; }
-       | IDENT BOPEN fargs BCLOSE { $$ = ast_funcall($1, ast_list($3)); }
+       | IDENT BOPEN fargs BCLOSE { $$ = expr_funcall($1, $3); }
        | INTEGER
        | BOOL
        | CHAR
-       | IDENT field { $$ = ast_ident($1, ast_list($2)); }
-       | NIL { $$ = ast_nil(); }
+       | IDENT field { $$ = expr_ident($1, $2); }
+       | NIL { $$ = expr_nil(); }
        ;