Stupid stringlist is stupid. Use a proper data structure, properly abstracted
out (so other things can use it).
This commit is contained in:
parent
9f78e0b36b
commit
bcc74ba18d
9
modules/src/data/build.lua
Normal file
9
modules/src/data/build.lua
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
clibrary {
|
||||||
|
name = "lib",
|
||||||
|
srcs = { "./*.c" },
|
||||||
|
hdrs = { "./*.h" },
|
||||||
|
deps = {
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
|
43
modules/src/data/stringlist.c
Normal file
43
modules/src/data/stringlist.c
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "stringlist.h"
|
||||||
|
|
||||||
|
void stringlist_add(struct stringlist* list, const char* data)
|
||||||
|
{
|
||||||
|
struct stringfragment* f = calloc(1, sizeof *f);
|
||||||
|
f->data = data;
|
||||||
|
|
||||||
|
if (!list->last)
|
||||||
|
list->first = list->last = f;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
list->last->next = f;
|
||||||
|
list->last = f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void stringlist_addall(struct stringlist* list, struct stringlist* src)
|
||||||
|
{
|
||||||
|
struct stringfragment* f = src->first;
|
||||||
|
|
||||||
|
while (f)
|
||||||
|
{
|
||||||
|
stringlist_add(list, f->data);
|
||||||
|
f = f->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void stringlist_free(struct stringlist* list)
|
||||||
|
{
|
||||||
|
struct stringfragment* f = list->first;
|
||||||
|
|
||||||
|
while (f)
|
||||||
|
{
|
||||||
|
struct stringfragment* next = f->next;
|
||||||
|
free(f);
|
||||||
|
f = next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* vim: set sw=4 ts=4 expandtab : */
|
||||||
|
|
||||||
|
|
23
modules/src/data/stringlist.h
Normal file
23
modules/src/data/stringlist.h
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
#ifndef STRINGLIST_H
|
||||||
|
#define STRINGLIST_H
|
||||||
|
|
||||||
|
struct stringfragment
|
||||||
|
{
|
||||||
|
const char* data;
|
||||||
|
struct stringfragment* next;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct stringlist
|
||||||
|
{
|
||||||
|
struct stringfragment* first;
|
||||||
|
struct stringfragment* last;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern void stringlist_add(struct stringlist* list, const char* data);
|
||||||
|
extern void stringlist_addall(struct stringlist* list, struct stringlist* src);
|
||||||
|
extern void stringlist_free(struct stringlist* list);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* vim: set sw=4 ts=4 expandtab : */
|
||||||
|
|
|
@ -43,7 +43,8 @@ cprogram {
|
||||||
deps = {
|
deps = {
|
||||||
"./iburg.h",
|
"./iburg.h",
|
||||||
"+lib",
|
"+lib",
|
||||||
"+yacc"
|
"+yacc",
|
||||||
|
"modules/src/data+lib",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
%{
|
%{
|
||||||
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
@ -17,7 +18,7 @@ static int nextern = 1;
|
||||||
char* string;
|
char* string;
|
||||||
Tree tree;
|
Tree tree;
|
||||||
Rule rule;
|
Rule rule;
|
||||||
Stringlist stringlist;
|
struct stringlist* stringlist;
|
||||||
char* stringpair[2];
|
char* stringpair[2];
|
||||||
}
|
}
|
||||||
%term TERMINAL
|
%term TERMINAL
|
||||||
|
@ -58,7 +59,7 @@ patterns
|
||||||
pattern
|
pattern
|
||||||
: ID '=' rhs { nonterm($1); $$ = rule($1, $3, nextern++); }
|
: ID '=' rhs { nonterm($1); $$ = rule($1, $3, nextern++); }
|
||||||
| rhs { $$ = rule("stmt", $1, nextern++); }
|
| rhs { $$ = rule("stmt", $1, nextern++); }
|
||||||
| pattern WHEN cfragments { $$ = $1; $$->when = $3; }
|
| pattern WHEN cfragments { $$ = $1; stringlist_addall(&$$->when, $3); }
|
||||||
| pattern INS ins { $$ = $1; }
|
| pattern INS ins { $$ = $1; }
|
||||||
| pattern OUTS outs { $$ = $1; }
|
| pattern OUTS outs { $$ = $1; }
|
||||||
| emit { $$ = $1; }
|
| emit { $$ = $1; }
|
||||||
|
@ -77,8 +78,8 @@ labelledid
|
||||||
;
|
;
|
||||||
|
|
||||||
cfragments
|
cfragments
|
||||||
: /* nothing */ { $$ = NULL; }
|
: /* nothing */ { $$ = calloc(1, sizeof *$$); }
|
||||||
| CFRAGMENT cfragments { $$ = pushstring($1, $2); }
|
| cfragments CFRAGMENT { $$ = $1; stringlist_add($$, $2); }
|
||||||
;
|
;
|
||||||
|
|
||||||
ins
|
ins
|
||||||
|
@ -101,13 +102,22 @@ out
|
||||||
;
|
;
|
||||||
|
|
||||||
emit
|
emit
|
||||||
: pattern EMIT qfragments { $$ = $1; $$->code = $3; $$->is_fragment = false; }
|
: pattern EMIT qfragments {
|
||||||
| pattern FRAGMENT qfragments { $$ = $1; $$->code = $3; $$->is_fragment = true; }
|
$$ = $1;
|
||||||
|
stringlist_add($3, "\n");
|
||||||
|
stringlist_addall(&$$->code, $3);
|
||||||
|
$$->is_fragment = false;
|
||||||
|
}
|
||||||
|
| pattern FRAGMENT qfragments {
|
||||||
|
$$ = $1;
|
||||||
|
stringlist_addall(&$$->code, $3);
|
||||||
|
$$->is_fragment = true;
|
||||||
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
qfragments
|
qfragments
|
||||||
: QFRAGMENT { $$ = pushstring($1, NULL); }
|
: /* nothing */ { $$ = calloc(1, sizeof *$$); }
|
||||||
| QFRAGMENT qfragments { $$ = pushstring($1, $2); }
|
| qfragments QFRAGMENT { $$ = $1; stringlist_add($$, $2); }
|
||||||
;
|
;
|
||||||
|
|
||||||
%%
|
%%
|
||||||
|
|
|
@ -365,14 +365,6 @@ Rule rule(char* id, Tree pattern, int ern)
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
Stringlist pushstring(const char* data, Stringlist list)
|
|
||||||
{
|
|
||||||
Stringlist sl = calloc(1, sizeof *sl);
|
|
||||||
sl->payload = data;
|
|
||||||
sl->next = list;
|
|
||||||
return sl;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* print - formatted output */
|
/* print - formatted output */
|
||||||
static void print(char* fmt, ...)
|
static void print(char* fmt, ...)
|
||||||
{
|
{
|
||||||
|
@ -792,15 +784,15 @@ static void emitpredicatedefinitions(Rule r)
|
||||||
{
|
{
|
||||||
while (r)
|
while (r)
|
||||||
{
|
{
|
||||||
Stringlist s = r->when;
|
struct stringfragment* f = r->when.first;
|
||||||
if (s)
|
if (f)
|
||||||
{
|
{
|
||||||
print("/* %R */\n", r);
|
print("/* %R */\n", r);
|
||||||
print("static int %Ppredicate_%d(NODEPTR_TYPE n) {\n", r->ern);
|
print("static int %Ppredicate_%d(NODEPTR_TYPE n) {\n", r->ern);
|
||||||
while (s)
|
while (f)
|
||||||
{
|
{
|
||||||
print("%s", s->payload);
|
print("%s", f->data);
|
||||||
s = s->next;
|
f = f->next;
|
||||||
}
|
}
|
||||||
print("\n}\n\n");
|
print("\n}\n\n");
|
||||||
}
|
}
|
||||||
|
@ -866,32 +858,42 @@ static void emitemitters(Rule rules)
|
||||||
r = rules;
|
r = rules;
|
||||||
while (r)
|
while (r)
|
||||||
{
|
{
|
||||||
Stringlist s = r->code;
|
struct stringfragment* f = r->code.first;
|
||||||
if (s)
|
if (f)
|
||||||
{
|
{
|
||||||
print("/* %R */\n", r);
|
print("/* %R */\n", r);
|
||||||
print("static void %Pemitter_%d(NODEPTR_TYPE node, struct %Pemitter_data* data) {\n", r->ern);
|
print("static void %Pemitter_%d(NODEPTR_TYPE node, struct %Pemitter_data* data) {\n", r->ern);
|
||||||
emittreefetchers(0, r->pattern);
|
emittreefetchers(0, r->pattern);
|
||||||
print("%1NODEPTR_TYPE node_%s = node;\n", r->lhs->name);
|
print("%1NODEPTR_TYPE node_%s = node;\n", r->lhs->name);
|
||||||
|
|
||||||
while (s)
|
while (f)
|
||||||
{
|
{
|
||||||
if (s->payload[0] == '%')
|
switch (f->data[0])
|
||||||
{
|
{
|
||||||
const char* label = s->payload + 1;
|
case '%':
|
||||||
Tree t = find_label(r->pattern, label);
|
|
||||||
if (!t && (strcmp(label, r->lhs->name) != 0))
|
|
||||||
{
|
{
|
||||||
yylineno = r->lineno;
|
const char* label = f->data + 1;
|
||||||
yyerror("label '%s' not found", label);
|
Tree t = find_label(r->pattern, label);
|
||||||
exit(1);
|
if (!t && (strcmp(label, r->lhs->name) != 0))
|
||||||
|
{
|
||||||
|
yylineno = r->lineno;
|
||||||
|
yyerror("label '%s' not found", label);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
print("%1data->emit_ir(node_%s);\n", label);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
print("%1data->emit_ir(node_%s);\n", label);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
print("%1data->emit_string(\"%s\");\n", s->payload);
|
|
||||||
|
|
||||||
s = s->next;
|
case '\n':
|
||||||
|
assert(f->data[1] == 0);
|
||||||
|
print("%1data->emit_eoi();\n");
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
print("%1data->emit_string(\"%s\");\n", f->data);
|
||||||
|
}
|
||||||
|
|
||||||
|
f = f->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
print("}\n\n");
|
print("}\n\n");
|
||||||
|
@ -904,9 +906,10 @@ static void emitemitters(Rule rules)
|
||||||
print("%Pemitter_t* const %Pemitters[] = {\n");
|
print("%Pemitter_t* const %Pemitters[] = {\n");
|
||||||
while (r)
|
while (r)
|
||||||
{
|
{
|
||||||
Stringlist s = r->code;
|
struct stringfragment* f = r->code.first;
|
||||||
|
|
||||||
print("%1");
|
print("%1");
|
||||||
if (s)
|
if (f)
|
||||||
print("&%Pemitter_%d,", r->ern);
|
print("&%Pemitter_%d,", r->ern);
|
||||||
else
|
else
|
||||||
print("NULL,");
|
print("NULL,");
|
||||||
|
@ -920,7 +923,7 @@ static void emitemitters(Rule rules)
|
||||||
/* emitcost - emit a cost calculation via a predicate */
|
/* emitcost - emit a cost calculation via a predicate */
|
||||||
static void emitcostcalc(Rule r)
|
static void emitcostcalc(Rule r)
|
||||||
{
|
{
|
||||||
if (r->when)
|
if (r->when.first)
|
||||||
print("!%Ppredicate_%d(node) ? %d : ", r->ern, maxcost);
|
print("!%Ppredicate_%d(node) ? %d : ", r->ern, maxcost);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,16 +1,9 @@
|
||||||
#ifndef BURG_INCLUDED
|
#ifndef BURG_INCLUDED
|
||||||
#define BURG_INCLUDED
|
#define BURG_INCLUDED
|
||||||
|
|
||||||
/* $Id$ */
|
#include "stringlist.h"
|
||||||
/* iburg.c: */
|
|
||||||
extern char* stringf(char* fmt, ...);
|
|
||||||
|
|
||||||
typedef struct stringlist* Stringlist;
|
extern char* stringf(char* fmt, ...);
|
||||||
struct stringlist {
|
|
||||||
const char* payload;
|
|
||||||
Stringlist next;
|
|
||||||
};
|
|
||||||
extern Stringlist pushstring(const char* data, Stringlist list);
|
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
|
@ -56,20 +49,20 @@ extern Tree tree(const char* op, const char* label, Tree left, Tree right);
|
||||||
|
|
||||||
struct rule
|
struct rule
|
||||||
{ /* rules: */
|
{ /* rules: */
|
||||||
Nonterm lhs; /* lefthand side non-terminal */
|
Nonterm lhs; /* lefthand side non-terminal */
|
||||||
Tree pattern; /* rule pattern */
|
Tree pattern; /* rule pattern */
|
||||||
int lineno; /* line number where allocated */
|
int lineno; /* line number where allocated */
|
||||||
int ern; /* external rule number */
|
int ern; /* external rule number */
|
||||||
int packed; /* packed external rule number */
|
int packed; /* packed external rule number */
|
||||||
int cost; /* associated cost */
|
int cost; /* associated cost */
|
||||||
Rule link; /* next rule in ern order */
|
Rule link; /* next rule in ern order */
|
||||||
Rule next; /* next rule with same pattern root */
|
Rule next; /* next rule with same pattern root */
|
||||||
Rule chain; /* next chain rule with same rhs */
|
Rule chain; /* next chain rule with same rhs */
|
||||||
Rule decode; /* next rule with same lhs */
|
Rule decode; /* next rule with same lhs */
|
||||||
Rule kids; /* next rule with same burm_kids pattern */
|
Rule kids; /* next rule with same burm_kids pattern */
|
||||||
Stringlist when; /* C predicate string */
|
struct stringlist when; /* C predicate string */
|
||||||
Stringlist code; /* compiler output code strings */
|
struct stringlist code; /* compiler output code strings */
|
||||||
bool is_fragment; /* does this rule generate an instruction fragment? */
|
bool is_fragment; /* does this rule generate an instruction fragment? */
|
||||||
};
|
};
|
||||||
extern Rule rule(char* id, Tree pattern, int ern);
|
extern Rule rule(char* id, Tree pattern, int ern);
|
||||||
extern int maxcost; /* maximum cost */
|
extern int maxcost; /* maximum cost */
|
||||||
|
|
|
@ -30,6 +30,7 @@ struct burm_emitter_data
|
||||||
void* user;
|
void* user;
|
||||||
void (*emit_string)(const char* data);
|
void (*emit_string)(const char* data);
|
||||||
void (*emit_ir)(struct ir* ir);
|
void (*emit_ir)(struct ir* ir);
|
||||||
|
void (*emit_eoi)(void);
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef void burm_emitter_t(struct ir* ir, struct burm_emitter_data* data);
|
typedef void burm_emitter_t(struct ir* ir, struct burm_emitter_data* data);
|
||||||
|
|
Loading…
Reference in a new issue