locations
authorMart Lubbers <mart@martlubbers.net>
Mon, 8 Feb 2021 13:36:56 +0000 (14:36 +0100)
committerMart Lubbers <mart@martlubbers.net>
Mon, 8 Feb 2021 14:04:40 +0000 (15:04 +0100)
Makefile
ast.c
ast.h
parse.y
scan.l

index dfb7600..7cd4c61 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,16 +1,14 @@
-CFLAGS:=-Wall -Wextra -Werror -std=c99 -pedantic-errors -D_XOPEN_SOURCE=700 -ggdb
-YFLAGS:=-d --locations# -Wcounterexamples
-LFLAGS:=-X
+CFLAGS+=-Wall -Wextra -std=c99 -pedantic -D_XOPEN_SOURCE=700 -ggdb
+YFLAGS+=-Wall -Wno-empty-rule -Wyacc -Wdangling-alias -d --locations
+LFLAGS+=-X
 
 OBJECTS:=scan.o parse.o ast.o util.o
 
 all: expr
-
+expr: $(OBJECTS)
 scan.c: scan.l y.tab.h
 y.tab.h: parse.c
 expr.c: y.tab.h
 
-expr: $(OBJECTS)
-
 clean:
        $(RM) $(OBJECTS) y.tab.h scan.c parse.c expr
diff --git a/ast.c b/ast.c
index cb484c4..8b087f0 100644 (file)
--- a/ast.c
+++ b/ast.c
@@ -229,6 +229,14 @@ struct expr *expr_unop(enum unop op, struct expr *l)
        return res;
 }
 
+struct type *type_basic(enum basictype type)
+{
+       struct type *res = safe_malloc(sizeof(struct type));
+       res->type = tbasic;
+       res->data.tbasic = type;
+       return res;
+}
+
 struct type *type_list(struct type *type)
 {
        struct type *res = safe_malloc(sizeof(struct type));
diff --git a/ast.h b/ast.h
index ee9b840..6b31e0f 100644 (file)
--- a/ast.h
+++ b/ast.h
@@ -140,6 +140,7 @@ struct expr *expr_nil();
 struct expr *expr_tuple(struct expr *left, struct expr *right);
 struct expr *expr_unop(enum unop op, struct expr *l);
 
+struct type *type_basic(enum basictype type);
 struct type *type_list(struct type *type);
 struct type *type_tuple(struct type *l, struct type *r);
 struct type *type_var(char *ident);
diff --git a/parse.y b/parse.y
index 7cad6e5..dcfbad6 100644 (file)
--- a/parse.y
+++ b/parse.y
@@ -5,8 +5,8 @@
 #include "y.tab.h"
 
 int yylex(void);
-
 extern YYLTYPE yylloc;
+
 void yyerror(struct ast **result, const char *str)
 {
        fprintf(stderr, "%d-%d: %s\n", yylloc.first_line, yylloc.last_column, str);
@@ -35,11 +35,10 @@ int yywrap()
 %token <expr> BOOL CHAR INTEGER
 %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 VAR WHILE
+%token SCLOSE SOPEN TIMES TBOOL TCHAR TINT TVOID VAR WHILE
 
 %parse-param { struct ast **result }
 
-%right ARROW
 %right BINOR
 %right BINAND
 %nonassoc EQ NEQ LEQ LE GEQ GE
@@ -60,13 +59,12 @@ int yywrap()
 
 start : decls { *result = ast($1); } ;
 decls
-       : { $$ = NULL; }
+       : /* empty */ { $$ = NULL; }
        | decls vardecl { $$ = list_cons(decl_var($2), $1); }
        | decls fundecl { $$ = list_cons($2, $1); }
        ;
 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
@@ -75,21 +73,24 @@ fundecl
                { $$ = decl_fun($1, $3, NULL, NULL, $6, $7); }
        ;
 vardecls
-       : { $$ = NULL; }
+       : /* empty */ { $$ = NULL; }
        | vardecls vardecl { $$ = list_cons($2, $1); }
        ;
 funtype
-       : { $$ = NULL; }
+       : /* empty */ { $$ = NULL; }
        | funtype type { $$ = list_cons($2, $1); }
+       | funtype IDENT { $$ = list_cons(type_var($2), $1); }
        ;
 type
        : BOPEN type COMMA type BCLOSE { $$ = type_tuple($2, $4); }
-       | BOPEN type BCLOSE { $$ = $2; }
        | SOPEN type SCLOSE { $$ = type_list($2); }
-       | IDENT { $$ = type_var($1); }
+       | TBOOL { $$ = type_basic(btbool); }
+       | TCHAR { $$ = type_basic(btchar); }
+       | TINT { $$ = type_basic(btint); }
+       | TVOID { $$ = type_basic(btvoid); }
        ;
 args
-       : { $$ = NULL; }
+       : /* empty */ { $$ = NULL; }
        | nargs
        ;
 nargs
@@ -97,7 +98,7 @@ nargs
        | IDENT { $$ = list_cons($1, NULL); }
        ;
 fargs
-       : { $$ = NULL; }
+       : /* empty */ { $$ = NULL; }
        | fnargs
        ;
 fnargs
@@ -105,7 +106,7 @@ fnargs
        | expr { $$ = list_cons($1, NULL); }
        ;
 body
-       : { $$ = NULL; }
+       : /* empty */ { $$ = NULL; }
        | body stmt { $$ = list_cons($2, $1); }
        ;
 stmt
@@ -113,13 +114,13 @@ stmt
                { $$ = stmt_if($3, $6, $10); }
        | WHILE BOPEN expr BCLOSE COPEN body CCLOSE
                { $$ = 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); }
+       | expr SEMICOLON { $$ = stmt_expr($1); }
        ;
 field
-       : { $$ = NULL; }
+       : /* empty */ { $$ = NULL; }
        | field DOT IDENT { $$ = list_cons($3, $1); }
 expr
        : expr BINOR expr { $$ = expr_binop($1, binor, $3); }
@@ -139,9 +140,9 @@ expr
        | expr POWER expr { $$ = expr_binop($1, power, $3); }
        | MINUS expr %prec TIMES { $$ = expr_unop(negate, $2); }
        | INVERSE expr %prec TIMES { $$ = expr_unop(inverse, $2); }
+       | IDENT BOPEN fargs BCLOSE { $$ = expr_funcall($1, $3); }
        | BOPEN expr COMMA expr BCLOSE { $$ = expr_tuple($2, $4); }
        | BOPEN expr BCLOSE { $$ = $2; }
-       | IDENT BOPEN fargs BCLOSE { $$ = expr_funcall($1, $3); }
        | INTEGER
        | BOOL
        | CHAR
diff --git a/scan.l b/scan.l
index b1fb5be..23545c0 100644 (file)
--- a/scan.l
+++ b/scan.l
@@ -30,6 +30,10 @@ var         return VAR;
 true        { yylval.expr = expr_bool(true); return BOOL; }
 false       { yylval.expr = expr_bool(false); return BOOL; }
 return      return RETURN;
+Int         return TINT;
+Bool        return TBOOL;
+Char        return TCHAR;
+Void        return TVOID;
 ->          return ARROW;
 =           return ASSIGN;
 !           return INVERSE;