]> git.mdlowis.com Git - proto/sclpl.git/commitdiff
switched to expression based syntax with no statements
authorMichael D. Lowis <mike@mdlowis.com>
Fri, 29 Jun 2018 01:18:15 +0000 (21:18 -0400)
committerMichael D. Lowis <mike@mdlowis.com>
Fri, 29 Jun 2018 01:18:15 +0000 (21:18 -0400)
example.src
source/parser.c

index f0ebb21c78ce77a95ca2df30402215e83ff25dde..b05e693a62672aa95913589eeb5a87e4fab26179 100644 (file)
@@ -1,47 +1,49 @@
 require ("fmt")
 provide (main)
 
-let const_true bool = true;
-let const_false bool = false;
-let const_uint int = 123;
-let const_string string = "";
+let const_true bool = true
+let const_false bool = false
+let const_uint int = 123
+let const_string string = ""
 
-var var_true bool = true;
-var var_false bool = false;
-var var_uint int = 123;
-var var_string string = "";
+var var_true bool = true
+var var_false bool = false
+var var_uint int = 123
+var var_string string = ""
 
-type type_int = int;
-type type_intary = int[];
-type type_intaryary = int[][];
-type type_intptrary = int*[];
-type type_intptr = int*;
-type type_intptrptr = int**;
+type type_int = int
+type type_intary = int[]
+type type_intaryary = int[][]
+type type_intptrary = int*[]
+type type_intptr = int*
+type type_intptrptr = int**
 type type_struct = struct {
-    foo = int;
-    bar = float;
-};
+    foo = int
+    bar = float
+}
 type type_union = union {
-    foo = int;
-    bar = float;
-};
+    foo = int
+    bar = float
+}
 
 fun main(args string[]) int {
-    let foo int = 123;
-    var bar int = 123;
-    {}
-    {123;}
-    123;
-    (123);
-    foo();
-    bar(1);
-    baz(1,2);
-    if (123) {}
-    if 123 {}
-    if (123) {} else {}
-    if (123) {} else if (123) {}
-    if (123) {} else if (123) {} else {}
-    if 123 {} else if 123 {} else {}
-    return bar;
+    let foo int = 123
+    var bar int = 123
+    {123}
+    123
+    (123)
+    foo()
+    bar(1)
+    baz(1,2)
+#    if (123) {}
+#    if 123 {}
+#    if (123) {} else {}
+#    if (123) {} else if (123) {}
+#    if (123) {} else if (123) {} else {}
+#    if 123 {} else if 123 {} else {}
+#
+#    fun main(args string[]) int {
+#        123
+#    }
 }
 
index 281a86c7f517d74873e4eb38e5bcf7eae053e5b4..2225da000d88d42bc17a551ead31767a4ac92789 100644 (file)
@@ -4,26 +4,19 @@
 static void require_list(Parser* p);
 static void provide_list(Parser* p);
 static AST* definition_list(Parser* p);
-static AST* const_definition(Parser* p, bool constant);
+static AST* definition(Parser* p);
 static AST* type_definition(Parser* p);
 static AST* func_definition(Parser* p);
+static AST* expression(Parser* p);
+static AST* constant(Parser* p);
 static AST* type_expression(Parser* p);
 static AST* struct_fields(Parser* p);
 static AST* expression_block(Parser* p);
-static AST* statement(Parser* p);
-static AST* expression(Parser* p);
-static AST* definition(Parser* p, bool constant);
-static AST* return_statement(Parser* p);
-static AST* if_statement(Parser* p);
-static AST* func_expr_list(Parser* p);
-
-static AST* const_expression(Parser* p);
+static AST* if_expression(Parser* p);
 static AST* identifier(Parser* p);
-static AST* function(Parser* p);
-static AST* literal(Parser* p);
-static AST* expr_block(Parser* p);
-static AST* if_stmnt(Parser* p);
-static AST* func_app(Parser* p, AST* fn);
+static AST* func_expr_list(Parser* p);
+static Type* get_typedef(Parser* p, char* typename);
+static AST* add_type(Parser* p, AST* ast, char* typename);
 static AST* token_to_tree(Parser* p, Tok* tok);
 
 /* Parsing Routines
@@ -108,28 +101,26 @@ static void provide_list(Parser* p) {
 
 static AST* definition_list(Parser* p) {
     while (!matches(p, T_END_FILE)) {
-        TokType type = peek(p)->type;
         if (matches(p, T_LET) || matches(p, T_VAR)) {
-            const_definition(p, (type == T_LET));
+            definition(p);
         } else if (matches(p, T_TYPE)) {
             type_definition(p);
         } else if (matches(p, T_FUN)) {
             func_definition(p);
         } else {
-            error(p, "only definitions are allowed at the toplevel");
+            error(p, "only definitions are allowed at the top level");
         }
     }
     return NULL;
 }
 
-static AST* const_definition(Parser* p, bool constant) {
+static AST* definition(Parser* p) {
     if (!accept(p, T_LET) && !accept(p, T_VAR))
         error(p, "constant or variable definition expected");
     expect(p, T_ID);
     type_expression(p);
     expect(p, '=');
-    const_expression(p);
-    expect(p, ';');
+    expression(p);
     return NULL;
 }
 
@@ -138,7 +129,6 @@ static AST* type_definition(Parser* p) {
     expect(p, T_ID);
     expect(p, '=');
     type_expression(p);
-    expect(p, ';');
     return NULL;
 }
 
@@ -162,19 +152,45 @@ static AST* func_definition(Parser* p) {
     return NULL;
 }
 
-static AST* const_expression(Parser* p) {
-    AST* expr = NULL;
-    if (accept(p, '(')) {
-        expr = const_expression(p);
+static AST* expression(Parser* p) {
+    if (matches(p, '(')) {
+        expect(p, '(');
+        expression(p);
         expect(p, ')');
+    } else if (matches(p, '{')) {
+        expression_block(p);
+    } else if (matches(p, T_IF)) {
+        if_expression(p);
     } else if (matches(p, T_ID)) {
-        expr = identifier(p);
+        identifier(p);
+        if (matches(p, '('))
+            func_expr_list(p);
     } else {
-        expr = literal(p);
+        constant(p);
     }
-    return expr;
+    return NULL;
 }
 
+static AST* constant(Parser* p) {
+    AST* ret = NULL;
+    Tok* tok = peek(p);
+    switch (tok->type) {
+        case T_BOOL:
+        case T_CHAR:
+        case T_STRING:
+        case T_INT:
+        case T_FLOAT:
+            ret = token_to_tree(p, tok);
+            tok->type = T_NONE;
+            break;
+        default:
+            error(p, "expected an expression");
+    }
+    return ret;
+}
+
+/* Type Expressions
+ ****************************************************************************/
 static AST* type_expression(Parser* p) {
     if (matches(p, T_STRUCT)) {
         expect(p, T_STRUCT);
@@ -202,89 +218,46 @@ static AST* struct_fields(Parser* p) {
         expect(p, T_ID);
         expect(p, '=');
         type_expression(p);
-        expect(p, ';');
     } while (!matches(p, '}'));
     expect(p, '}');
     return NULL;
 }
 
+/* Expression Blocks
+ ****************************************************************************/
 static AST* expression_block(Parser* p) {
     expect(p, '{');
     while (!matches(p, '}')) {
-        statement(p);
-    }
-    expect(p, '}');
-    return NULL;
-}
-
-static AST* statement(Parser* p) {
-    if (matches(p, '{')) {
-        expression_block(p);
-    } else {
         if (matches(p, T_LET) || matches(p, T_VAR)) {
-            definition(p, (peek(p)->type == T_LET));
-        } else if (matches(p, T_RETURN)) {
-            return_statement(p);
-        } else if (matches(p, T_IF)) {
-            if_statement(p);
-//        } else if (matches(p, T_WHILE)) {
-//        } else if (matches(p, T_FOR)) {
-//        } else if (matches(p, T_DO)) {
-//        } else if (matches(p, T_SWITCH)) {
-//        } else if (matches(p, T_MATCH)) {
+            definition(p);
         } else {
             expression(p);
-            expect(p, ';');
         }
     }
+    expect(p, '}');
     return NULL;
 }
 
-static AST* expression(Parser* p) {
-    AST* expr = NULL;
-    if (accept(p, '(')) {
-        expr = expression(p);
-        expect(p, ')');
-    } else if (matches(p, T_ID)) {
-        expr = identifier(p);
-        if (matches(p, '('))
-            func_expr_list(p);
-    } else {
-        expr = literal(p);
+static AST* if_expression(Parser* p) {
+    expect(p, T_IF);
+    expression(p); // condition
+    expression(p); // true branch
+    if (accept(p, T_ELSE)) {
+        expression(p); // false branch
     }
-    return expr;
-}
-
-static AST* definition(Parser* p, bool constant) {
-    if (!accept(p, T_LET) && !accept(p, T_VAR))
-        error(p, "constant or variable definition expected");
-    expect(p, T_ID);
-    type_expression(p);
-    expect(p, '=');
-    expression(p);
-    expect(p, ';');
     return NULL;
 }
 
-static AST* return_statement(Parser* p) {
-    expect(p, T_RETURN);
-    expression(p);
-    expect(p, ';');
-    return NULL;
-}
-
-static AST* if_statement(Parser* p) {
-    expect(p, T_IF);
-    expression(p);
-    expression_block(p);
-    if (accept(p, T_ELSE)) {
-        if (matches(p, T_IF)) {
-            if_statement(p);
-        } else {
-            expression_block(p);
-        }
+static AST* identifier(Parser* p) {
+    Tok* tok = peek(p);
+    if (tok->type == T_ID) {
+        AST* ast = Ident(tok);
+        tok->type = T_NONE;
+        return ast;
+    } else {
+        error(p, "Expected an identifier");
+        return NULL;
     }
-    return NULL;
 }
 
 static AST* func_expr_list(Parser* p) {
@@ -302,32 +275,14 @@ static AST* func_expr_list(Parser* p) {
     return NULL;
 }
 
-
-
+/* Helper Functions for Constants
+ ****************************************************************************/
 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 AST* literal(Parser* p) {
-    AST* ret = NULL;
-    Tok* tok = peek(p);
-    switch (tok->type) {
-        case T_BOOL:
-        case T_CHAR:
-        case T_STRING:
-        case T_INT:
-        case T_FLOAT:
-            ret = token_to_tree(p, tok);
-            tok->type = T_NONE;
-            break;
-        default:
-            error(p, "expected an expression");
-    }
-    return ret;
-}
-
 static AST* add_type(Parser* p, AST* ast, char* typename) {
     ast->datatype = get_typedef(p, typename);
     return ast;
@@ -345,14 +300,3 @@ static AST* token_to_tree(Parser* p, Tok* tok) {
     }
 }
 
-static AST* identifier(Parser* p) {
-    Tok* tok = peek(p);
-    if (tok->type == T_ID) {
-        AST* ast = Ident(tok);
-        tok->type = T_NONE;
-        return ast;
-    } else {
-        error(p, "Expected an identifier");
-        return NULL;
-    }
-}