]> git.mdlowis.com Git - proto/obnc.git/commitdiff
implemented basic constant folding ops..
authormike lowis <mike@mdlowis.com>
Tue, 20 Apr 2021 03:44:07 +0000 (23:44 -0400)
committermike lowis <mike@mdlowis.com>
Tue, 20 Apr 2021 03:44:07 +0000 (23:44 -0400)
cerise/cerise.h
cerise/codegen.c
cerise/parser.c

index b819f93228b00b46bafdadbbd1a69e8f37bdaea1..87e5f5c170dcdf7eafee2a61f08908391602a9b1 100644 (file)
@@ -85,7 +85,7 @@ typedef struct LexFile {
 
 typedef struct {
     enum {
-        VAL_I8, VAL_I16, VAL_I32, VAL_I64, VAL_REAL, VAL_STRING
+        VAL_I8, VAL_I16, VAL_I32, VAL_I64, VAL_BOOL, VAL_REAL, VAL_STRING, VAL_NIL
     } type;
     union {
         long long integer;
@@ -108,8 +108,8 @@ typedef struct {
     Tok tok;
     Symbol globals;
     Symbol locals;
-    int valstack_idx;
-    Value valstack[1024];
+    int validx;
+    Value vals[1024];
 } Parser;
 
 void lexfile(Parser* ctx, char* path);
@@ -120,7 +120,8 @@ void module(Parser* p);
 
 /* Code Generation
  *****************************************************************************/
-void codegen_int(Parser* p, int val);
+void codegen_print(Parser* p);
+void codegen_int(Parser* p, long long val);
 void codegen_real(Parser* p, double val);
 void codegen_string(Parser* p, char* val);
 void codegen_bool(Parser* p, int val);
index b1bda04fec183fcd293dfe5f9c0dcad5be8fb2e1..b83c125422020d93bb12df3e6d2efbbb0ef8fa48 100644 (file)
 #include "cerise.h"
+#include <limits.h>
+#include <assert.h>
 
-void codegen_int(Parser* p, int val)
+static Value* peek_val(Parser* p)
 {
-    (void)p;
-    printf("%d ", val);
+    return &(p->vals[p->validx-1]);
+}
+
+static void push_int(Parser* p, int type, long long val)
+{
+    Value* v = &(p->vals[p->validx++]);
+    v->type = type;
+    v->value.integer = val;
+}
+
+static void push_float(Parser* p, double val)
+{
+    Value* v = &(p->vals[p->validx++]);
+    v->type = VAL_REAL;
+    v->value.floating = val;
+}
+
+static void push_string(Parser* p, char* val)
+{
+    Value* v = &(p->vals[p->validx++]);
+    v->type = VAL_STRING;
+    v->value.text = val;
+}
+
+static void push_nil(Parser* p)
+{
+    Value* v = &(p->vals[p->validx++]);
+    v->type = VAL_NIL;
+    v->value.integer = 0;
+}
+
+static void pop_val(Parser* p, Value* val)
+{
+    p->validx--;
+    *val = p->vals[p->validx];
+}
+
+
+static int is_int(Value* val)
+{
+    return (val->type <= VAL_I64);
+}
+
+
+
+
+void codegen_print(Parser* p)
+{
+    printf("DUMP: [ ");
+    for (int i = 0; i < p->validx; i++)
+    {
+        switch (p->vals[i].type)
+        {
+            case VAL_I8:
+            case VAL_I16:
+            case VAL_I32:
+            case VAL_I64:
+            case VAL_BOOL:
+                printf("%lld ", p->vals[i].value.integer);
+                break;
+            case VAL_REAL:
+                printf("%f ", p->vals[i].value.floating);
+                break;
+            case VAL_STRING:
+                printf("%s ", p->vals[i].value.text);
+                break;
+            case VAL_NIL:
+                printf("nil ");
+                break;
+        }
+    }
+    printf("]\n");
+}
+
+void codegen_int(Parser* p, long long val)
+{
+    printf("%lld ", val);
+
+    if (CHAR_MIN <= val && CHAR_MAX >= val)
+    {
+        push_int(p, VAL_I8, val);
+    }
+    else if (SHRT_MIN <= val && SHRT_MAX >= val)
+    {
+        push_int(p, VAL_I16, val);
+    }
+    else if (INT_MIN <= val && INT_MAX >= val)
+    {
+        push_int(p, VAL_I32, val);
+    }
+    else if (LONG_MIN <= val && LONG_MAX >= val)
+    {
+        push_int(p, VAL_I64, val);
+    }
+    else
+    {
+//        printf("unknown unary operator %d\n", val);
+    }
 }
 
 void codegen_real(Parser* p, double val)
 {
-    (void)p;
     printf("%f ", val);
+    push_float(p, val);
 }
 
 void codegen_string(Parser* p, char* val)
 {
-    (void)p;
     printf("\"%s\" ", val);
+    push_string(p, val);
 }
 
 void codegen_bool(Parser* p, int val)
 {
     (void)p;
     printf("%s ", val ? "true" : "false");
+    push_int(p, VAL_BOOL, val);
 }
 
 void codegen_nil(Parser* p)
 {
     (void)p;
     printf("nil ");
+    push_nil(p);
 }
 
 void codegen_unop(Parser* p, int val)
 {
     (void)p;
     if (val < 256) { printf("(%c) ", val); } else { printf("(%d) ", val); }
+    Value* v = peek_val(p);
+    switch (val)
+    {
+        case '+':
+            if (is_int(v))
+            {
+                v->value.integer = +v->value.integer;
+            }
+            else if (v->type == VAL_REAL)
+            {
+                v->value.floating = +v->value.floating;
+            }
+            else
+            {
+                assert(false);
+            }
+            break;
+
+        case '-':
+            if (is_int(v))
+            {
+                v->value.integer = -v->value.integer;
+            }
+            else if (v->type == VAL_REAL)
+            {
+                v->value.floating = -v->value.floating;
+            }
+            else
+            {
+                assert(false);
+            }
+            break;
+
+        case NOT:
+            if (v->type == VAL_BOOL)
+            {
+                v->value.integer = !v->value.integer;
+            }
+            else
+            {
+                assert(false);
+            }
+            break;
+
+        default:
+            printf("unknown unary operator %d\n", val);
+            break;
+    }
 }
 
 void codegen_binop(Parser* p, int val)
index 7e38a253a0e9aa3eecffa5bd55cbc44691f51bb5..77dcd64c4950c1f0f8789015406e1b36766b20ae 100644 (file)
@@ -228,6 +228,7 @@ RULE(const_decl)
         expect(p, '=');
         expression(p);
         codegen_const(p, name, export);
+        codegen_print(p);
         if (!accept(p, ','))
         {
             break;