]> git.mdlowis.com Git - proto/sclpl.git/commitdiff
added support for constant and variable bindings at the top level
authorMichael D. Lowis <mike.lowis@gentex.com>
Wed, 30 May 2018 16:24:58 +0000 (12:24 -0400)
committerMichael D. Lowis <mike.lowis@gentex.com>
Wed, 30 May 2018 16:24:58 +0000 (12:24 -0400)
source/ast.c
source/lexer.l
source/parser.c
source/pprint.c
source/sclpl.h

index 7891139b75dd00450842e9db16caf1a4276ffbcb..76d0104419f4ac421dae2d1270117546dbc9121a 100644 (file)
@@ -3,7 +3,7 @@
 static AST* ast(ASTType type) {
     AST* tree = emalloc(sizeof(AST));
     memset(tree, 0, sizeof(AST));
-    tree->type = type;
+    tree->nodetype = type;
     return tree;
 }
 
@@ -14,7 +14,7 @@ AST* String(Tok* val) {
 }
 
 char* string_value(AST* val) {
-    assert(val->type == AST_STRING);
+    assert(val->nodetype == AST_STRING);
     return val->value.text;
 }
 
@@ -25,7 +25,7 @@ AST* Symbol(Tok* val) {
 }
 
 char* symbol_value(AST* val) {
-    assert(val->type == AST_SYMBOL);
+    assert(val->nodetype == AST_SYMBOL);
     return val->value.text;
 }
 
@@ -36,7 +36,7 @@ AST* Char(Tok* val) {
 }
 
 uint32_t char_value(AST* val) {
-    assert(val->type == AST_CHAR);
+    assert(val->nodetype == AST_CHAR);
     return val->value.character;
 }
 
@@ -47,7 +47,7 @@ AST* Integer(Tok* val) {
 }
 
 intptr_t integer_value(AST* val) {
-    assert(val->type == AST_INT);
+    assert(val->nodetype == AST_INT);
     return val->value.integer;
 }
 
@@ -58,7 +58,7 @@ AST* Float(Tok* val) {
 }
 
 double float_value(AST* val) {
-    assert(val->type == AST_FLOAT);
+    assert(val->nodetype == AST_FLOAT);
     return val->value.floating;
 }
 
@@ -69,7 +69,7 @@ AST* Bool(Tok* val) {
 }
 
 bool bool_value(AST* val) {
-    assert(val->type == AST_BOOL);
+    assert(val->nodetype == AST_BOOL);
     return val->value.boolean;
 }
 
@@ -80,23 +80,29 @@ AST* Ident(Tok* val) {
 }
 
 char* ident_value(AST* val) {
-    assert(val->type == AST_IDENT);
+    assert(val->nodetype == AST_IDENT);
     return val->value.text;
 }
 
-AST* Let(Tok* name, AST* value) {
-    AST* node = ast(AST_LET);
-    node->value.let.name = name->value.text;
-    node->value.let.value = value;
+AST* Var(Tok* name, AST* value, bool constant) {
+    AST* node = ast(AST_VAR);
+    node->value.var.name = name->value.text;
+    node->value.var.value = value;
+    node->value.var.constant = constant;
     return node;
 }
 
-char* let_name(AST* let) {
-    assert(let->type == AST_LET);
-    return let->value.let.name;
+char* var_name(AST* var) {
+    assert(var->nodetype == AST_VAR);
+    return var->value.var.name;
 }
 
-AST* let_value(AST* let) {
-    assert(let->type == AST_LET);
-    return let->value.let.value;
+AST* var_value(AST* var) {
+    assert(var->nodetype == AST_VAR);
+    return var->value.var.value;
+}
+
+bool var_const(AST* var) {
+    assert(var->nodetype == AST_VAR);
+    return var->value.var.constant;
 }
index 9105367226e408b367b4c34708f78f01b5cc13db..a34922f7ff8cf28655e387586cf386359951b67d 100644 (file)
@@ -30,9 +30,12 @@ NOSPACE [^ \t\r\n]
 
 %%
 
-<<EOF>> { return T_END_FILE; }
+[ \t\r\n] { /* whitespace is insignificant */ }
+<<EOF>>   { return T_END_FILE; }
 
 "let"  { return T_LET;    }
+"var"  { return T_VAR;    }
+
 "if"   { return T_IF;     }
 "then" { return T_THEN;   }
 "else" { return T_ELSE;   }
index 8e47f1c1062596472b697b633b1bcd12f9543993..3d3f04d38fd5ab17ddde2d4c0c63a0e6b1f35452 100644 (file)
@@ -1,6 +1,6 @@
 #include <sclpl.h>
 
-static AST* const_definition(Parser* p);
+static AST* const_definition(Parser* p, bool constant);
 static AST* const_expression(Parser* p);
 static AST* definition(Parser* p);
 static AST* expression(Parser* p);
@@ -62,26 +62,22 @@ static Tok* expect_val(Parser* parser, TokType type) {
 AST* toplevel(Parser* p) {
     AST* ret = NULL;
     if (!match(p, T_END_FILE)) {
-        if (accept(p, T_LET))
-            ret = const_definition(p);
+        TokType type = peek(p)->type;
+        if (accept(p, T_LET) || accept(p, T_VAR))
+            ret = const_definition(p, (type == T_LET));
         else
             error(p, "only definitions are allowed at the toplevel");
     }
     return ret;
 }
 
-static AST* const_definition(Parser* p) {
+static AST* const_definition(Parser* p, bool constant) {
     AST* expr;
     Tok* id = expect_val(p, T_ID);
-//    if (peek(p)->type == T_LPAR) {
-//        expr = function(p);
-//    } else {
-        type_annotation(p);
-        expect(p, T_ASSIGN);
-        expr = const_expression(p);
-        expect(p, T_END);
-//    }
-    return Let(id, expr);
+    type_annotation(p);
+    expect(p, T_ASSIGN);
+    expr = const_expression(p);
+    return Var(id, expr, constant);
 }
 
 static AST* const_expression(Parser* p) {
index 0140b4a1b886bb5238a6848b11a08a4432d8d528..f47fe8bf0e0ed5bc05c5071185df859fe875470f 100644 (file)
@@ -95,8 +95,8 @@ static const char* tree_type_to_string(ASTType type) {
 
 static void pprint_literal(FILE* file, AST* tree, int depth)
 {
-    printf("%s:", tree_type_to_string(tree->type));
-    switch(tree->type) {
+    printf("%s:", tree_type_to_string(tree->nodetype));
+    switch(tree->nodetype) {
         case AST_STRING: printf("\"%s\"", string_value(tree));  break;
         case AST_SYMBOL: printf("%s",     symbol_value(tree));  break;
         case AST_IDENT:  printf("%s",     ident_value(tree));   break;
@@ -116,11 +116,13 @@ void pprint_tree(FILE* file, AST* tree, int depth)
         return;
     }
     print_indent(file, depth);
-    switch (tree->type) {
-        case AST_LET:
-            printf("(let %s ", let_name(tree));
-            pprint_tree(file, let_value(tree), depth);
-            printf(")");
+    switch (tree->nodetype) {
+        case AST_VAR:
+            printf("(%s %s ",
+                (var_const(tree) ? "let" : "var"),
+                var_name(tree));
+            pprint_tree(file, var_value(tree), depth);
+            printf(")\n");
             break;
 
         default:
index d6393e6a7eb623ee710da52db72cbb8ddcccbf74..21784bfac05dc335890e59277837208233bad1a2 100644 (file)
@@ -40,9 +40,10 @@ void vec_set(vec_t* vec, size_t index, void* data);
 /* Token Types
  *****************************************************************************/
 typedef enum {
-    T_NONE, T_ERROR, T_END_FILE, T_ID, T_CHAR, T_INT, T_FLOAT, T_BOOL, T_STRING,
+    T_NONE, T_ERROR, T_END_FILE, T_LET, T_VAR,
+    T_ID, T_CHAR, T_INT, T_FLOAT, T_BOOL, T_STRING,
     T_LBRACE, T_RBRACE, T_LBRACK, T_RBRACK, T_LPAR, T_RPAR, T_COMMA, T_SQUOTE,
-    T_DQUOTE, T_END, T_COLON, T_AMP, T_LET, T_IF, T_THEN, T_ELSE, T_ASSIGN
+    T_DQUOTE, T_END, T_COLON, T_AMP, T_IF, T_THEN, T_ELSE, T_ASSIGN
 } TokType;
 
 typedef struct {
@@ -86,18 +87,19 @@ Type* PtrTo(Type* type);
 /* AST Types
  *****************************************************************************/
 typedef enum {
-    AST_LET, AST_STRING, AST_SYMBOL, AST_CHAR, AST_INT, AST_FLOAT, AST_BOOL, AST_IDENT
+    AST_VAR, AST_STRING, AST_SYMBOL, AST_CHAR, AST_INT, AST_FLOAT, AST_BOOL, AST_IDENT
 } ASTType;
 
 typedef struct AST {
-    ASTType type;
+    ASTType nodetype;
+    Type* datatype;
     union {
         /* Definition Node */
         struct {
             char* name;
-            struct AST* type;
             struct AST* value;
-        } let;
+            bool constant;
+        } var;
         /* String, Symbol, Identifier */
         char* text;
         /* Character */
@@ -140,9 +142,10 @@ AST* Ident(Tok* val);
 char* ident_value(AST* val);
 
 /* Definition */
-AST* Let(Tok* name, AST* value);
-char* let_name(AST* let);
-AST* let_value(AST* let);
+AST* Var(Tok* name, AST* value, bool constant);
+char* var_name(AST* var);
+AST* var_value(AST* var);
+bool var_const(AST* var);
 
 /* Pretty Printing
  *****************************************************************************/