edgecases
[ccc.git] / parse.y
diff --git a/parse.y b/parse.y
index dcfbad6..dc85dac 100644 (file)
--- a/parse.y
+++ b/parse.y
@@ -32,7 +32,7 @@ int yywrap()
 
 %locations
 %token <ident> IDENT
-%token <expr> BOOL CHAR INTEGER
+%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
@@ -50,9 +50,9 @@ int yywrap()
 %type <ast> start
 %type <decl> fundecl
 %type <expr> expr
-%type <list> args body decls fargs field fnargs nargs funtype vardecls
+%type <list> args body decls fargs field fnargs nargs funtype vardecls bbody
 %type <stmt> stmt
-%type <type> type
+%type <type> type ftype
 %type <vardecl> vardecl
 
 %%
@@ -65,9 +65,10 @@ decls
        ;
 vardecl
        : VAR IDENT ASSIGN expr SEMICOLON { $$ = vardecl(NULL, $2, $4); }
+       | type IDENT ASSIGN expr SEMICOLON { $$ = vardecl($1, $2, $4); }
        ;
 fundecl
-       : IDENT BOPEN args BCLOSE CONS CONS funtype ARROW type COPEN vardecls body CCLOSE
+       : IDENT BOPEN args BCLOSE CONS CONS funtype ARROW ftype COPEN vardecls body CCLOSE
                { $$ = decl_fun($1, $3, $7, $9, $11, $12); }
        | IDENT BOPEN args BCLOSE COPEN vardecls body CCLOSE
                { $$ = decl_fun($1, $3, NULL, NULL, $6, $7); }
@@ -78,9 +79,16 @@ vardecls
        ;
 funtype
        : /* empty */ { $$ = NULL; }
-       | funtype type { $$ = list_cons($2, $1); }
-       | funtype IDENT { $$ = list_cons(type_var($2), $1); }
+       | funtype ftype { $$ = list_cons($2, $1); }
        ;
+ftype
+       : BOPEN ftype COMMA ftype BCLOSE { $$ = type_tuple($2, $4); }
+       | SOPEN ftype SCLOSE { $$ = type_list($2); }
+       | TBOOL { $$ = type_basic(btbool); }
+       | TCHAR { $$ = type_basic(btchar); }
+       | TINT { $$ = type_basic(btint); }
+       | TVOID { $$ = type_basic(btvoid); }
+    | IDENT { $$ = type_var($1); }
 type
        : BOPEN type COMMA type BCLOSE { $$ = type_tuple($2, $4); }
        | SOPEN type SCLOSE { $$ = type_list($2); }
@@ -109,19 +117,23 @@ body
        : /* empty */ { $$ = NULL; }
        | body stmt { $$ = list_cons($2, $1); }
        ;
+field
+       : /* empty */ { $$ = NULL; }
+       | field DOT IDENT { $$ = list_cons($3, $1); }
+       ;
+bbody
+       : COPEN body CCLOSE { $$ = $2; }
+       | stmt { $$ = list_cons($1, NULL); }
+       ;
 stmt
-       : IF BOPEN expr BCLOSE COPEN body CCLOSE ELSE COPEN body CCLOSE
-               { $$ = stmt_if($3, $6, $10); }
-       | WHILE BOPEN expr BCLOSE COPEN body CCLOSE
-               { $$ = stmt_while($3, $6); }
-       | IDENT ASSIGN expr SEMICOLON { $$ = stmt_assign($1, $3); }
+       : IF BOPEN expr BCLOSE bbody { $$ = stmt_if($3, $5, NULL); }
+       | IF BOPEN expr BCLOSE bbody ELSE bbody { $$ = stmt_if($3, $5, $7); }
+       | WHILE BOPEN expr BCLOSE bbody { $$ = stmt_while($3, $5); }
+       | IDENT field ASSIGN expr SEMICOLON { $$ = stmt_assign($1, $2, $4); }
        | RETURN expr SEMICOLON { $$ = stmt_return($2); }
        | RETURN SEMICOLON { $$ = stmt_return(NULL); }
        | expr SEMICOLON { $$ = stmt_expr($1); }
        ;
-field
-       : /* empty */ { $$ = NULL; }
-       | field DOT IDENT { $$ = list_cons($3, $1); }
 expr
        : expr BINOR expr { $$ = expr_binop($1, binor, $3); }
        | expr BINAND expr { $$ = expr_binop($1, binand, $3); }
@@ -146,6 +158,7 @@ expr
        | INTEGER
        | BOOL
        | CHAR
+       | STRING
        | IDENT field { $$ = expr_ident($1, $2); }
        | NIL { $$ = expr_nil(); }
        ;