From: mike lowis Date: Mon, 19 Apr 2021 03:35:47 +0000 (-0400) Subject: added codegen module X-Git-Url: https://git.mdlowis.com/?a=commitdiff_plain;h=022e922c40a61ea7ac4cadd5efe1506e6b075b39;p=proto%2Fobnc.git added codegen module --- diff --git a/cerise/cerise.h b/cerise/cerise.h index af6cc55..e085def 100644 --- a/cerise/cerise.h +++ b/cerise/cerise.h @@ -95,6 +95,17 @@ void lexprintpos(Parser* p, FILE* file, Tok* tok); void gettoken(Parser* ctx); void module(Parser* p); +/* Code Generation + *****************************************************************************/ +void codegen_int(Parser* p, int val); +void codegen_real(Parser* p, double val); +void codegen_string(Parser* p, char* val); +void codegen_bool(Parser* p, int val); +void codegen_nil(Parser* p); +void codegen_unop(Parser* p, int val); +void codegen_binop(Parser* p, int val); +void codegen_const(Parser* p, char* name, int export); + /* Option Parsing *****************************************************************************/ diff --git a/cerise/codegen.c b/cerise/codegen.c new file mode 100644 index 0000000..b1bda04 --- /dev/null +++ b/cerise/codegen.c @@ -0,0 +1,49 @@ +#include "cerise.h" + +void codegen_int(Parser* p, int val) +{ + (void)p; + printf("%d ", val); +} + +void codegen_real(Parser* p, double val) +{ + (void)p; + printf("%f ", val); +} + +void codegen_string(Parser* p, char* val) +{ + (void)p; + printf("\"%s\" ", val); +} + +void codegen_bool(Parser* p, int val) +{ + (void)p; + printf("%s ", val ? "true" : "false"); +} + +void codegen_nil(Parser* p) +{ + (void)p; + printf("nil "); +} + +void codegen_unop(Parser* p, int val) +{ + (void)p; + if (val < 256) { printf("(%c) ", val); } else { printf("(%d) ", val); } +} + +void codegen_binop(Parser* p, int val) +{ + (void)p; + if (val < 256) { printf("(%c) ", val); } else { printf("(%d) ", val); } +} + +void codegen_const(Parser* p, char* name, int export) +{ + (void)p; + printf(" -> const %s%c\n", name, (export ? '*' : ' ')); +} diff --git a/cerise/parser.c b/cerise/parser.c index 7aecee8..4b0816b 100644 --- a/cerise/parser.c +++ b/cerise/parser.c @@ -1,7 +1,7 @@ #include "cerise.h" #include -#define TRACE +//#define TRACE #ifdef TRACE static int Indent = 0; #define RULE(name) \ @@ -223,15 +223,16 @@ RULE(const_decl) { while (1) { - /*char* name =*/ expect_text(p, IDENT); + char* name = expect_text(p, IDENT); + bool export = accept(p, '*'); expect(p, '='); expression(p); + codegen_const(p, name, export); if (!accept(p, ',')) { break; } } - (void)p; } RULE(expression) @@ -256,8 +257,9 @@ RULE(simple_expr) /* first term and +/- */ if (matches_oneof(p, (int[]){'+', '-', 0})) { - consume(p); // OP + int op = consume(p); // OP term(p); + codegen_unop(p, op); } else { @@ -267,8 +269,9 @@ RULE(simple_expr) /* optional second term and op */ while (matches_oneof(p, (int[]){'+', '-', OR, 0})) { - consume(p); + int op = consume(p); term(p); + codegen_binop(p, op); } } @@ -279,8 +282,9 @@ RULE(term) factor(p); while (matches_oneof(p, (int[]){'*', '/', AND, 0})) { - consume(p); + int op = consume(p); factor(p); + codegen_binop(p, op); } } @@ -300,10 +304,27 @@ RULE(factor) switch ((int)peek(p)->type) { case INT: + codegen_int(p, peek(p)->value.integer); + consume(p); + break; + case REAL: + codegen_real(p, peek(p)->value.floating); + consume(p); + break; + case STRING: + codegen_string(p, peek(p)->text); + consume(p); + break; + case NIL: + codegen_nil(p); + consume(p); + break; + case BOOL: + codegen_bool(p, peek(p)->value.integer); consume(p); break; @@ -316,6 +337,7 @@ RULE(factor) case NOT: consume(p); factor(p); + codegen_unop(p, NOT); break; case IDENT: