]> git.mdlowis.com Git - proto/sclpl.git/commitdiff
attempted to implement precedence climbing
authorMichael D. Lowis <mike@mdlowis.com>
Fri, 5 Apr 2019 03:28:39 +0000 (23:28 -0400)
committerMichael D. Lowis <mike@mdlowis.com>
Fri, 5 Apr 2019 03:28:39 +0000 (23:28 -0400)
example.src
inc/sclpl.h
src/ast.c
src/parser.c

index 90a6ceee15ef76905e142fd22df133d874ad8fe7..d52d547f003aabe655a014cfcc4a772e15599469 100644 (file)
@@ -33,9 +33,9 @@ fun main(args string[]) int {
     var bar int = 123
     {123 321}
     123 (123)
-    foo()
-    bar(1)
-    baz(1,2)
+#    foo()
+#    bar(1)
+#    baz(1,2)
     if (1) {1}
     if 2 {2}
     if (3) {3} else {4}
@@ -46,9 +46,9 @@ fun main(args string[]) int {
         123
     }
     # UFCS call (call regular function like a method)
-    foo.bar()
-    foo.bar.baz()
-    # Struct/Union field access
-    let a int = foo.bar
-    let b int = foo.bar.baz
+#    foo.bar()
+#    foo.bar.baz()
+#    # Struct/Union field access
+#    let a int = foo.bar
+#    let b int = foo.bar.baz
 }
index 0e9996e2d34e6742073476ce5eb3bbe13a162844..9b27ce2e4cd3e4f5f8355105a5634764668c35f7 100644 (file)
@@ -98,7 +98,7 @@ Sym* sym_get(SymTable* syms, char* name);
 typedef enum {
     AST_VAR, AST_FUNC, AST_EXPLIST, AST_IF, AST_APPLY,
     AST_STRING, AST_SYMBOL, AST_CHAR, AST_INT,
-    AST_FLOAT, AST_BOOL, AST_IDENT
+    AST_FLOAT, AST_BOOL, AST_IDENT, AST_OPER
 } ASTType;
 
 typedef struct AST {
@@ -106,6 +106,11 @@ typedef struct AST {
     Type* datatype;
     union {
         struct AST* nodes[3];
+        struct {
+            int oper;
+            struct AST* left;
+            struct AST* right;
+        } op;
         /* Definition Node */
         struct {
             char* name;
@@ -174,6 +179,9 @@ AST* Apply(AST* func, AST* args);
 AST* apply_func(AST* apply);
 AST* apply_args(AST* apply);
 
+AST* OpCall(int oper, AST* left, AST* right);
+
+
 /* Package Definition
  *****************************************************************************/
 typedef struct Require {
index 0a58dd5f76295fa848056cc55016b585b7bcfffb..a2e48f5f3c15c1080ebef2cd047f207dc6e0d8a5 100644 (file)
--- a/src/ast.c
+++ b/src/ast.c
@@ -181,3 +181,11 @@ AST* apply_args(AST* apply) {
     assert(apply->nodetype == AST_APPLY);
     return apply->value.nodes[1];
 }
+
+AST* OpCall(int oper, AST* left, AST* right) {
+    AST* node = ast(AST_OPER);
+    node->value.op.oper = oper;
+    node->value.op.left = left;
+    node->value.op.right = right;
+    return node;
+}
index 4a26623cf7a6ff5b04e603a67976ca62a2096fbe..56828ad92e01f5f7106cbc26525392e9f916fe6a 100644 (file)
@@ -7,7 +7,7 @@ static void definition_list(Parser* p);
 static AST* definition(Parser* p);
 static AST* type_definition(Parser* p);
 static AST* func_definition(Parser* p);
-static AST* expression(Parser* p);
+static AST* expression(Parser* p, int level);
 static AST* constant(Parser* p);
 static AST* type_expression(Parser* p);
 static AST* struct_fields(Parser* p);
@@ -30,13 +30,13 @@ static int Indent = 0;
 #define parse_exit()
 #endif
 
-uint8_t PrefixOps[T_COUNT] = {
+int8_t PrefixOps[T_COUNT] = {
     [T_IF] = 1,
     ['{'] = 1,
     ['('] = 1,
 };
 
-uint8_t BinaryOps[T_COUNT] = {
+int8_t BinaryOps[T_COUNT] = {
     ['.'] = 1,
     ['('] = 1,
 };
@@ -154,7 +154,7 @@ static AST* definition(Parser* p) {
     char* str = strdup(expect_val(p, T_ID)->text);
     AST* type = type_expression(p);
     expect(p, '=');
-    AST* val = expression(p);
+    AST* val = expression(p, 1);
     parse_exit();
     return Var(str, val, type, SF_CONSTANT);
 }
@@ -191,26 +191,57 @@ static AST* func_definition(Parser* p) {
     return Var(name, func, type, SF_CONSTANT);
 }
 
-static AST* expression(Parser* p) {
-    parse_enter();
-    int precedence = PrefixOps[peek(p)->type];
+/*
+function parseExpressionAtPrecedence(currentPrecedence) {
+  expr = parseExpressionAtom()
+  while op = parseOperator() && op.precedence < currentPrecedence {
+    if op.rightAssociative {
+      b = parseExpressionAtPrecedence(op.precedence)
+    } else {
+      b = parseExpressionAtPrecedence(op.precedence + 1)
+    }
+    expr = OperatorExpression(op, expr, b)
+  }
+  return expr
+}
+*/
+
+static AST* expression(Parser* p, int level) {
     AST* left = prefix_expr(p);
-    int next = peek(p)->type;
-    while (BinaryOps[next] && BinaryOps[next] >= precedence) {
-        left = binary_expr(p, left);
-        next = peek(p)->type;
+    int oper = peek(p)->type;
+    while (BinaryOps[oper] && abs(BinaryOps[oper]) < level) {
+        AST* right;
+        expect(p, oper); // consume the operator
+        if (BinaryOps[oper] < 0)
+            right = expression(p, level+1);
+        else
+            right = expression(p, level);
+        left = OpCall(oper, left, right);
+        oper = peek(p)->type; // get next operator
     }
-    parse_exit();
     return left;
 }
 
+//static AST* expression(Parser* p) {
+//    parse_enter();
+//    int precedence = PrefixOps[peek(p)->type];
+//    AST* left = prefix_expr(p);
+//    int next = peek(p)->type;
+//    while (BinaryOps[next] && BinaryOps[next] >= precedence) {
+//        left = binary_expr(p, left);
+//        next = peek(p)->type;
+//    }
+//    parse_exit();
+//    return left;
+//}
+
 static AST* prefix_expr(Parser* p) {
     AST* tree = NULL;
     Tok* tok = peek(p);
     switch ((int)tok->type) {
         case '(':
             expect(p, '(');
-            tree = expression(p);
+            tree = expression(p, 1);
             expect(p, ')');
             break;
         case '[':
@@ -313,7 +344,7 @@ static AST* expression_block(Parser* p) {
         } else if (matches(p, T_FUN)) {
             expr = func_definition(p);
         } else {
-            expr = expression(p);
+            expr = expression(p, 1);
         }
         explist_append(list, expr);
     }
@@ -324,10 +355,10 @@ static AST* expression_block(Parser* p) {
 static AST* if_expression(Parser* p) {
     AST *cond = 0, *b1 = 0, *b2 = 0;
     expect(p, T_IF);
-    cond = expression(p); // condition
-    b1 = expression(p); // true branch
+    cond = expression(p, 1); // condition
+    b1 = expression(p, 1); // true branch
     if (accept(p, T_ELSE)) {
-        b2 = expression(p); // false branch
+        b2 = expression(p, 1); // false branch
     }
     return If(cond, b1, b2);
 }
@@ -348,7 +379,7 @@ static AST* expr_list(Parser* p, int firstc, int endc) {
     expect(p, firstc);
     AST* list = ExpList();
     while (!matches(p, endc)) {
-        explist_append(list, expression(p));
+        explist_append(list, expression(p, 1));
         if (!matches(p, endc)) {
             expect(p, ',');
             if (matches(p, endc))