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
*****************************************************************************/
--- /dev/null
+#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 ? '*' : ' '));
+}
#include "cerise.h"
#include <stdarg.h>
-#define TRACE
+//#define TRACE
#ifdef TRACE
static int Indent = 0;
#define RULE(name) \
{
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)
/* first term and +/- */
if (matches_oneof(p, (int[]){'+', '-', 0}))
{
- consume(p); // OP
+ int op = consume(p); // OP
term(p);
+ codegen_unop(p, op);
}
else
{
/* optional second term and op */
while (matches_oneof(p, (int[]){'+', '-', OR, 0}))
{
- consume(p);
+ int op = consume(p);
term(p);
+ codegen_binop(p, op);
}
}
factor(p);
while (matches_oneof(p, (int[]){'*', '/', AND, 0}))
{
- consume(p);
+ int op = consume(p);
factor(p);
+ codegen_binop(p, op);
}
}
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;
case NOT:
consume(p);
factor(p);
+ codegen_unop(p, NOT);
break;
case IDENT: