]> git.mdlowis.com Git - proto/sclpl.git/commitdiff
added primitive type cehcking
authorMichael D. Lowis <mike@mdlowis.com>
Mon, 4 Jun 2018 02:51:34 +0000 (22:51 -0400)
committerMichael D. Lowis <mike@mdlowis.com>
Mon, 4 Jun 2018 02:51:34 +0000 (22:51 -0400)
source/parser.c
source/sclpl.h
source/types.c

index 10f0a8dc24b40013b611a1a9e88cb8b86cb66964..1b36bd716f37f2311b2ee51a2f6e07088cda3a12 100644 (file)
@@ -11,8 +11,8 @@ static Type* type_annotation(Parser* p);
 static AST* literal(Parser* p);
 static AST* expr_block(Parser* p);
 static AST* if_stmnt(Parser* p);
-static AST* token_to_tree(Tok* tok);
 static AST* func_app(Parser* p, AST* fn);
+static AST* token_to_tree(Parser* p, Tok* tok);
 
 /* Parsing Routines
  *****************************************************************************/
@@ -87,6 +87,8 @@ static AST* const_definition(Parser* p, bool constant) {
     expect(p, T_ASSIGN);
     AST* expr = const_expression(p);
     sym_add(&(p->syms), (constant ? SF_CONSTANT : 0), id->value.text, type);
+    if (!types_equal(type, expr->datatype))
+        error(p, "type mismatch");
     return Var(id, expr, constant);
 }
 
@@ -103,11 +105,15 @@ static AST* const_expression(Parser* p) {
     return expr;
 }
 
+static Type* get_typedef(Parser* p, char* typename) {
+   Sym* sym = sym_get(&(p->syms), typename);
+    if (!sym) error(p, "unknown type '%s'", typename);
+    return sym->type;
+}
+
 static Type* type_annotation(Parser* p) {
     Tok* id = expect_val(p, T_ID);
-    Sym* sym = sym_get(&(p->syms), id->value.text);
-    if (!sym) error(p, "unknown type '%s'", id->value.text);
-    return sym->type;
+    return get_typedef(p, id->value.text);
 }
 
 static AST* literal(Parser* p) {
@@ -119,23 +125,28 @@ static AST* literal(Parser* p) {
         case T_STRING:
         case T_INT:
         case T_FLOAT:
-            ret = token_to_tree(tok);
+            ret = token_to_tree(p, tok);
             tok->type = T_NONE;
             break;
         default:
-            error(p, "Expected a literal");
+            error(p, "not a valid literal");
     }
     return ret;
 }
 
-static AST* token_to_tree(Tok* tok) {
+static AST* add_type(Parser* p, AST* ast, char* typename) {
+    ast->datatype = get_typedef(p, typename);
+    return ast;
+}
+
+static AST* token_to_tree(Parser* p, Tok* tok) {
     switch (tok->type) {
-        case T_BOOL:   return Bool(tok);
-        case T_CHAR:   return Char(tok);
-        case T_STRING: return String(tok);
-        case T_INT:    return Integer(tok);
-        case T_FLOAT:  return Float(tok);
-        case T_ID:     return Ident(tok);
+        case T_BOOL:   return add_type(p, Bool(tok), "bool");
+        case T_CHAR:   return add_type(p, Char(tok), "char");
+        case T_STRING: return add_type(p, String(tok), "string");
+        case T_INT:    return add_type(p, Integer(tok), "int");
+        case T_FLOAT:  return add_type(p, Float(tok), "float");
+        case T_ID:     return add_type(p, Ident(tok), tok->value.text);
         default:       return NULL;
     }
 }
index 1549da571573727522317b48f71b4d697a14672c..f04531c1047cc02c212064833837418a60e5630a 100644 (file)
@@ -84,6 +84,7 @@ Type* UIntType(size_t nbits);
 Type* ArrayOf(Type* type, size_t count);
 Type* RefTo(Type* type);
 Type* PtrTo(Type* type);
+bool types_equal(Type* type1, Type* type2);
 
 /* Symbol Table
  *****************************************************************************/
index 41db199c6b0efda5f8a4f6022ded13613c57e473..3aca20664f0264cdd1fa8b27560d11b9870aa73b 100644 (file)
@@ -37,3 +37,15 @@ Type* RefTo(Type* type) {
 Type* PtrTo(Type* type) {
     return NULL;
 }
+
+bool types_equal(Type* type1, Type* type2) {
+    if (type1->kind != type2->kind) return false;
+    switch (type1->kind) {
+        case ARRAY:
+            return (types_equal(type1->value.array.type, type2->value.array.type) &&
+                    (type1->value.array.count == type1->value.array.count));
+        default:
+            return true;
+    }
+}
+