diff lwcc/cc-parse.c @ 501:f3e9732973f1

Add basic integer operations to lwcc Add +, -, *, and / to lwcc parser and code generator. Multiplication and division require helper functions in a yet to be created support library. These operations are integer only for the moment.
author William Astle <lost@l-w.ca>
date Tue, 24 Sep 2019 22:07:56 -0600
parents 1bd2d590d734
children 14a40f8bb4eb
line wrap: on
line diff
--- a/lwcc/cc-parse.c	Thu Aug 29 17:00:17 2019 -0600
+++ b/lwcc/cc-parse.c	Tue Sep 24 22:07:56 2019 -0600
@@ -169,19 +169,69 @@
 
 }
 
-node_t *parse_expr(struct parser_state *ps)
+node_t *parse_term_real(struct parser_state *ps)
 {
     node_t *rv;
-    if (ps -> curtok -> ttype == TOK_CONST_INT)
+
+    switch (ps -> curtok -> ttype)
     {
+    case TOK_CONST_INT:
         rv = node_create(NODE_CONST_INT, ps -> curtok -> strval);
         parse_next(ps);
         return rv;
     }
-    parse_generr(ps, "expr");
+
+    parse_generr(ps, "term");
     return NULL;
 }
 
+node_t *parse_expr_real(struct parser_state *ps, int prec)
+{
+    static struct { int tok; int nodetype; int prec; } operlist[] = {
+        { TOK_STAR, NODE_OPER_TIMES, 150 },
+        { TOK_DIV, NODE_OPER_DIVIDE, 150 },
+        { TOK_ADD, NODE_OPER_PLUS, 100 },
+        { TOK_SUB, NODE_OPER_MINUS, 100 },
+        { 0, 0, 0 }
+    };
+    node_t *term1, *term2;
+    int i;
+    
+    term1 = parse_term_real(ps);
+    if (!term1)
+        return NULL;
+
+nextoper:
+    for (i = 0; operlist[i].tok; i++)
+        if (operlist[i].tok == ps -> curtok -> ttype)
+            break;
+    fprintf(stderr, "Matched operator: %d, %d\n", operlist[i].tok, operlist[i].prec);
+    // if we hit the end of the expression, return
+    if (operlist[i].tok == 0)
+        return term1;
+
+    // is the next operator less or same precedence?
+    if (operlist[i].prec <= prec)
+        return term1;
+
+    parse_next(ps);
+    term2 = parse_expr_real(ps, operlist[i].prec);
+    if (!term2)
+    {
+        parse_generr(ps, "expr");
+        node_destroy(term2);
+    }
+    
+    term1 = node_create(operlist[i].nodetype, term1, term2);
+    term2 = NULL;
+    goto nextoper;
+}
+
+node_t *parse_expr(struct parser_state *ps)
+{
+    return parse_expr_real(ps, 0);
+}
+
 node_t *parse_statement(struct parser_state *ps)
 {
     node_t *rv;