From f8c24dbfd0276fe80620433c800580fe5bceacad Mon Sep 17 00:00:00 2001 From: "Michael D. Lowis" Date: Sun, 3 Jun 2018 22:51:34 -0400 Subject: [PATCH] added primitive type cehcking --- source/parser.c | 37 ++++++++++++++++++++++++------------- source/sclpl.h | 1 + source/types.c | 12 ++++++++++++ 3 files changed, 37 insertions(+), 13 deletions(-) diff --git a/source/parser.c b/source/parser.c index 10f0a8d..1b36bd7 100644 --- a/source/parser.c +++ b/source/parser.c @@ -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; } } diff --git a/source/sclpl.h b/source/sclpl.h index 1549da5..f04531c 100644 --- a/source/sclpl.h +++ b/source/sclpl.h @@ -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 *****************************************************************************/ diff --git a/source/types.c b/source/types.c index 41db199..3aca206 100644 --- a/source/types.c +++ b/source/types.c @@ -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; + } +} + -- 2.52.0