+include("util/mcgg/build.lua")
+
normalrule {
name = "ircodes",
outleaves = { "ircodes.h", "ircodes.c" },
}
}
+mcgg {
+ name = "mcgg_c",
+ srcs = { "./table" }
+}
+
cprogram {
name = "mcg",
srcs = {
"./*.c",
+ "+mcgg_c",
matching(filenamesof("+ircodes"), "%.c$")
},
deps = {
"modules/src/string+lib",
"modules/src/system+lib",
"./*.h",
- "util/mcgg+mcgg",
},
vars = {
["+cflags"] = {
--- /dev/null
+#include <stdio.h>
+#include <assert.h>
+#include <stdlib.h>
+#include <stdbool.h>
+#include <limits.h>
+#include <stdlib.h>
+
+#define TRACE
+
+#define STATE_TYPE void*
+typedef struct tree {
+ int op;
+ struct tree *kids[2];
+ STATE_TYPE state_label;
+} *NODEPTR_TYPE;
+#define OP_LABEL(p) ((p)->op)
+#define LEFT_CHILD(p) ((p)->kids[0])
+#define RIGHT_CHILD(p) ((p)->kids[1])
+#define STATE_LABEL(p) ((p)->state_label)
+#define PANIC printf
+
+static void burm_trace(NODEPTR_TYPE p, int eruleno, int cost, int bestcost) {
+#ifdef TRACE
+ extern const char *burm_string[];
+
+ fprintf(stderr, "0x%p matched %s with cost %d vs. %d\n", p,
+ burm_string[eruleno], cost, bestcost);
+#endif
+}
+
+#define burm_assert(b, s) assert(b && s)
+
--- /dev/null
+%{
+#if 0
+#include <stdio.h>
+#include <assert.h>
+#include <stdlib.h>
+#include <stdbool.h>
+
+#define TRACE
+
+#define STATE_TYPE void*
+typedef struct tree {
+ int op;
+ struct tree *kids[2];
+ STATE_TYPE state_label;
+} *NODEPTR_TYPE;
+#define OP_LABEL(p) ((p)->op)
+#define LEFT_CHILD(p) ((p)->kids[0])
+#define RIGHT_CHILD(p) ((p)->kids[1])
+#define STATE_LABEL(p) ((p)->state_label)
+#define PANIC printf
+
+static void burm_trace(NODEPTR_TYPE p, int eruleno, int cost, int bestcost) {
+#ifdef TRACE
+ extern const char *burm_string[];
+
+ fprintf(stderr, "0x%p matched %s with cost %d vs. %d\n", p,
+ burm_string[eruleno], cost, bestcost);
+#endif
+}
+#endif
+%}
+%term LOAD STORE LABEL CONST ADD FOO BAR BAZ BOO;
+%%
+
+ stm = STORE(addr:address, value:reg)
+ ins value:GPR
+ emit "str %value, %addr"
+ cost 4;
+
+ reg = LOAD(addr:address)
+ outs dest:ANY
+ emit "ld %dest, %addr"
+ cost 4;
+
+ address = ADD(addr:reg, offset:CONST)
+ ins addr:GPR
+ fragment "[%addr, #%offset.ivalue]";
+
+ address = addr:reg
+ ins addr:GPR
+ fragment "[%addr]";
+
+ stm = reg;
+
+ reg = ADD(left:reg, right:aluparam)
+ ins left:GPR, right:GPR
+ outs out:GPR
+ emit "add %out, %left, %right"
+ cost 4;
+
+ reg = ADD(left:aluparam, right:reg)
+ ins left:GPR, right:GPR
+ outs out:GPR
+ emit "add %out, %right, %left"
+ cost 4;
+
+ aluparam = value:CONST
+ when { return false; }
+ fragment "#%value.ivalue";
+
+ aluparam = reg;
+
+ reg = value:aluparam
+ outs out:GPR
+ emit "mov %out, %value"
+ cost 4;
+
+ reg = value:LABEL
+ outs out:GPR
+ emit "adr %out, #value.lvalue"
+ cost 4;
+
+ reg = value:CONST
+ outs out:GPR
+ emit "ldr %out, #value.lvalue"
+ cost 4;
"+yacc"
}
}
+
+definerule("mcgg",
+ {
+ srcs = { type="targets" }
+ },
+ function(e)
+ -- Remember this is executed from the caller's directory; local
+ -- target names will resolve there
+ if (#e.srcs ~= 1) then
+ error("you must supply exactly one input file")
+ end
+
+ local cpptable = cppfile {
+ name = e.name.."/cpptable",
+ outleaf = "cpptable",
+ srcs = e.srcs
+ }
+
+ return normalrule {
+ name = e.name,
+ cwd = e.cwd,
+ outleaves = {
+ "tables.c",
+ },
+ ins = {
+ "util/mcgg+mcgg",
+ cpptable
+ },
+ commands = {
+ "%{ins[1]} < %{ins[2]} > %{outs}",
+ }
+ }
+ end
+)
infp = stdin;
outfp = stdout;
+ emitheader();
+
yyin = infp;
yyparse();
for (p = nts; p; p = p->link)
if (!p->reached)
yyerror("can't reach non-terminal `%s'\n", p->name);
- emitheader();
+
emitdefs(nts, ntnumber);
emitstruct(nts, ntnumber);
emitnts(rules, nrules);
/* emitheader - emit initial definitions */
static void emitheader(void)
{
- print("#include <limits.h>\n#include <stdlib.h>\n");
- print("#ifndef STATE_TYPE\n#define STATE_TYPE int\n#endif\n");
- print("#ifndef ALLOC\n#define ALLOC(n) malloc(n)\n#endif\n"
- "#ifndef %Passert\n#define %Passert(x,y) if (!(x)) { y; abort(); }\n#endif\n\n");
+ print("#include \"mcgg_generated_header.h\"\n");
if (Tflag)
print("static NODEPTR_TYPE %Pnp;\n\n");
}
"%1struct %Pstate* r = (struct %Pstate *)right;\n"
"\n"
"%1assert(sizeof (STATE_TYPE) >= sizeof (void *));\n%1");
- print("%1p = ALLOC(sizeof *p);\n"
- "%1%Passert(p, PANIC(\"ALLOC returned NULL in %Pstate\\n\"));\n"
+ print("%1p = malloc(sizeof *p);\n"
"%1p->op = op;\n"
"%1p->left = l;\n"
"%1p->right = r;\n"