constant globals checking
[ccc.git] / type.c
diff --git a/type.c b/type.c
index f1828bc..3325de8 100644 (file)
--- a/type.c
+++ b/type.c
@@ -1,5 +1,34 @@
 #include "ast.h"
 
+void type_error(const char *msg, ...)
+{
+       va_list ap;
+       va_start(ap, msg);
+       fprintf(stderr, "type error: ");
+       vfprintf(stderr, msg, ap);
+       va_end(ap);
+       die("");
+}
+
+void check_expr_constant(struct expr *expr)
+{
+       switch (expr->type) {
+       case ebinop:
+               check_expr_constant(expr->data.ebinop.l);
+               check_expr_constant(expr->data.ebinop.r);
+               break;
+       case eunop:
+               check_expr_constant(expr->data.eunop.l);
+               break;
+       case efuncall:
+       case eident:
+               type_error("Initialiser is not constant\n");
+               break;
+       default:
+               break;
+       }
+}
+
 struct vardecl *type_vardecl(struct vardecl *vardecl)
 {
        return vardecl;
@@ -23,7 +52,13 @@ struct decl *type_decl(struct decl *decl)
 
 struct ast *type(struct ast *ast)
 {
-       for (int i = 0; i<ast->ndecls; i++)
-               ast->decls[i] = type_decl(ast->decls[i]);
+       for (int i = 0; i<ast->ndecls; i++) {
+               if (ast->decls[i]->type == dvardecl) {
+                       //Check globals
+                       check_expr_constant(ast->decls[i]->data.dvar->expr);
+                       break;
+               }
+       }
        return ast;
 }
+