From 4d825bf11ff3ba74c859de4e812e68fdea845c0e Mon Sep 17 00:00:00 2001 From: mike lowis Date: Mon, 19 Apr 2021 23:44:07 -0400 Subject: [PATCH] implemented basic constant folding ops.. --- cerise/cerise.h | 9 +-- cerise/codegen.c | 158 +++++++++++++++++++++++++++++++++++++++++++++-- cerise/parser.c | 1 + 3 files changed, 159 insertions(+), 9 deletions(-) diff --git a/cerise/cerise.h b/cerise/cerise.h index b819f93..87e5f5c 100644 --- a/cerise/cerise.h +++ b/cerise/cerise.h @@ -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); diff --git a/cerise/codegen.c b/cerise/codegen.c index b1bda04..b83c125 100644 --- a/cerise/codegen.c +++ b/cerise/codegen.c @@ -1,39 +1,187 @@ #include "cerise.h" +#include +#include -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) diff --git a/cerise/parser.c b/cerise/parser.c index 7e38a25..77dcd64 100644 --- a/cerise/parser.c +++ b/cerise/parser.c @@ -228,6 +228,7 @@ RULE(const_decl) expect(p, '='); expression(p); codegen_const(p, name, export); + codegen_print(p); if (!accept(p, ',')) { break; -- 2.49.0