if (!term_hash)
term_hash = g_hash_table_new (g_str_hash , g_str_equal);
- g_hash_table_foreach (term_hash, (GHFunc) check_term_num, (gpointer) num);
+ g_hash_table_foreach (term_hash, (GHFunc) check_term_num, GINT_TO_POINTER (num));
term = g_new0 (Term, 1);
output ("#ifndef MBTREE_LEFT\n#define MBTREE_LEFT(t) ((t)->left)\n#endif\n");
output ("#ifndef MBTREE_RIGHT\n#define MBTREE_RIGHT(t) ((t)->right)\n#endif\n");
output ("#ifndef MBTREE_STATE\n#define MBTREE_STATE(t) ((t)->state)\n#endif\n");
+ output ("#ifndef MBREG_TYPE\n#define MBREG_TYPE gint32\n#endif\n");
output ("#ifndef MBCGEN_TYPE\n#define MBCGEN_TYPE int\n#endif\n");
output ("#ifndef MBALLOC_STATE\n#define MBALLOC_STATE g_new (MBState, 1)\n#endif\n");
output ("#ifndef MBCOST_DATA\n#define MBCOST_DATA gpointer\n#endif\n");
if (dag_mode) {
output ("\tMBTREE_TYPE\t *tree;\n");
- output ("\tgint32 reg1, reg2;\n");
+ output ("\tMBREG_TYPE\t reg1;\n");
+ output ("\tMBREG_TYPE\t reg2;\n");
}
output ("\tMBState\t\t*left, *right;\n");
for (l = nonterm_list; l; l = l->next) {
NonTerm *n = (NonTerm *)l->data;
- output ("const int mono_burg_decode_%s[] = {\n", n->name);
+ output ("const short mono_burg_decode_%s[] = {\n", n->name);
output ("\t0,\n");
for (rl = n->rules; rl; rl = rl->next) {
Rule *rule = (Rule *)rl->data;
emit_emitter_func ()
{
GList *l;
- int i, rulen;
+ int i;
GHashTable *cache = g_hash_table_new (g_str_hash, g_str_equal);
for (l = rule_list, i = 0; l; l = l->next) {
Rule *rule = (Rule *)l->data;
if (rule->code) {
- if ((rulen = GPOINTER_TO_INT (g_hash_table_lookup (cache, rule->code)))) {
- emit_rule_string (rule, "");
- output ("#define mono_burg_emit_%d mono_burg_emit_%d\n\n", i, rulen);
- i++;
- continue;
+ GList *cases;
+ if ((cases = g_hash_table_lookup (cache, rule->code))) {
+ cases = g_list_append (cases, GINT_TO_POINTER (i));
+ } else {
+ cases = g_list_append (NULL, GINT_TO_POINTER (i));
}
- output ("static void ");
-
- emit_rule_string (rule, "");
-
- if (dag_mode)
- output ("mono_burg_emit_%d (MBState *state, MBTREE_TYPE *tree, MBCGEN_TYPE *s)\n", i);
- else
- output ("mono_burg_emit_%d (MBTREE_TYPE *tree, MBCGEN_TYPE *s)\n", i);
- output ("{\n");
- output ("%s\n", rule->code);
- output ("}\n\n");
- g_hash_table_insert (cache, rule->code, GINT_TO_POINTER (i));
+ g_hash_table_insert (cache, rule->code, cases);
}
i++;
}
- g_hash_table_destroy (cache);
-
- output ("MBEmitFunc const mono_burg_func [] = {\n");
- output ("\tNULL,\n");
+ output ("void mono_burg_emit (int ern, MBState *state, MBTREE_TYPE *tree, MBCGEN_TYPE *s)\n {\n");
+ output ("\tswitch (ern) {");
for (l = rule_list, i = 0; l; l = l->next) {
Rule *rule = (Rule *)l->data;
- if (rule->code)
- output ("\tmono_burg_emit_%d,\n", i);
- else
- output ("\tNULL,\n");
+
+ if (rule->code) {
+ GList *cases, *tmp;
+ cases = g_hash_table_lookup (cache, rule->code);
+ if (cases && i != GPOINTER_TO_INT (cases->data)) {
+ i++;
+ continue;
+ }
+ emit_rule_string (rule, "");
+ for (tmp = cases; tmp; tmp = tmp->next) {
+ output ("\tcase %d:\n", GPOINTER_TO_INT (tmp->data) + 1);
+ }
+ output ("\t{\n");
+ output ("%s\n", rule->code);
+ output ("\t}\n\treturn;\n");
+ }
i++;
}
- output ("};\n\n");
+ output ("\t}\n}\n\n");
+ g_hash_table_destroy (cache);
}
static void
}
}
+static int
+count_nonterms (Tree *tree)
+{
+ if (!tree)
+ return 0;
+
+ if (tree->nonterm) {
+ return 1;
+ } else {
+ return count_nonterms (tree->left) + count_nonterms (tree->right);
+ }
+}
+
static void
emit_vardefs ()
{
GList *l;
int i, j, c, n, *si;
char **sa;
+ int *nts_offsets;
+ int current_offset;
+ output ("\n");
if (predefined_terms) {
+ output ("#if HAVE_ARRAY_ELEM_INIT\n");
+ output ("const guint8 mono_burg_arity [MBMAX_OPCODES] = {\n");
+ for (l = term_list, i = 0; l; l = l->next) {
+ Term *t = (Term *)l->data;
+ output ("\t [%s] = %d, /* %s */\n", t->name, t->arity, t->name);
+ }
+ output ("};\n\n");
+ output ("void\nmono_burg_init (void) {\n");
+ output ("}\n\n");
+ output ("#else\n");
output ("guint8 mono_burg_arity [MBMAX_OPCODES];\n");
output ("void\nmono_burg_init (void)\n{\n");
for (l = term_list, i = 0; l; l = l->next) {
Term *t = (Term *)l->data;
-
output ("\tmono_burg_arity [%s] = %d; /* %s */\n", t->name, t->arity, t->name);
-
}
-
output ("}\n\n");
+ output ("#endif /* HAVE_ARRAY_ELEM_INIT */\n");
} else {
output ("const guint8 mono_burg_arity [] = {\n");
output ("};\n\n");
}
+ output ("#if MONOBURG_LOG\n");
output ("const char * const mono_burg_rule_string [] = {\n");
output ("\tNULL,\n");
for (l = rule_list, i = 0; l; l = l->next) {
emit_tree_string (rule->tree);
output ("\",\n");
}
- output ("};\n\n");
+ output ("};\n");
+ output ("#endif /* MONOBURG_LOG */\n\n");
n = g_list_length (rule_list);
sa = g_new0 (char *, n);
si = g_new0 (int, n);
+ nts_offsets = g_new0 (int, n);
+ /* at offset 0 we store 0 to mean end of list */
+ current_offset = 1;
+ output ("const guint16 mono_burg_nts_data [] = {\n\t0,\n");
/* compress the _nts array */
for (l = rule_list, i = 0, c = 0; l; l = l->next) {
Rule *rule = (Rule *)l->data;
si [i++] = j;
if (j == c) {
- output ("static const guint16 mono_burg_nts_%d [] = { %s0 };\n", c, s);
+ output ("\t%s0,\n", s);
+ nts_offsets [c] = current_offset;
sa [c++] = s;
+ current_offset += count_nonterms (rule->tree) + 1;
}
}
- output ("\n");
+ output ("\t0\n};\n\n");
- output ("const guint16 *const mono_burg_nts [] = {\n");
+ output ("const guint8 mono_burg_nts [] = {\n");
output ("\t0,\n");
for (l = rule_list, i = 0; l; l = l->next) {
Rule *rule = (Rule *)l->data;
- output ("\tmono_burg_nts_%d, ", si [i++]);
+ output ("\t%d, /* %s */ ", nts_offsets [si [i]], sa [si [i]]);
+ ++i;
emit_rule_string (rule, "");
}
output ("};\n\n");
static void
emit_prototypes ()
{
- if (dag_mode)
- output ("typedef void (*MBEmitFunc) (MBState *state, MBTREE_TYPE *tree, MBCGEN_TYPE *s);\n\n");
- else
- output ("typedef void (*MBEmitFunc) (MBTREE_TYPE *tree, MBCGEN_TYPE *s);\n\n");
-
output ("extern const char * const mono_burg_term_string [];\n");
+ output ("#if MONOBURG_LOG\n");
output ("extern const char * const mono_burg_rule_string [];\n");
- output ("extern const guint16 *const mono_burg_nts [];\n");
- output ("extern MBEmitFunc const mono_burg_func [];\n");
+ output ("#endif /* MONOBURG_LOG */\n");
+ output ("extern const guint16 mono_burg_nts_data [];\n");
+ output ("extern const guint8 mono_burg_nts [];\n");
+ output ("extern void mono_burg_emit (int ern, MBState *state, MBTREE_TYPE *tree, MBCGEN_TYPE *s);\n\n");
output ("MBState *mono_burg_label (MBTREE_TYPE *tree, MBCOST_DATA *data);\n");
output ("int mono_burg_rule (MBState *state, int goal);\n");
output ("#include \"%s\"\n\n", deffile);
}
- emit_vardefs ();
- emit_cost_func ();
- emit_emitter_func ();
- emit_decoders ();
-
- emit_closure ();
- emit_label_func ();
-
- emit_kids ();
-
if (infiles) {
GList *l = infiles;
while (l) {
yyparsetail ();
}
+ emit_vardefs ();
+ emit_cost_func ();
+ emit_emitter_func ();
+ emit_decoders ();
+
+ emit_closure ();
+ emit_label_func ();
+
+ emit_kids ();
+
if (cfile)
fclose (cfd);