#define HASHSIZE 103
#define MAGIC 19
-#define BUFSIZE 1024
-static struct list*
+struct list*
new_var_hash(void)
{
struct list* res;
}
/* if not found, variable with value "" is created */
-static int
+int
find_var(char* name, struct list* hash)
{
int n;
p->name = xstrdup(name);
p->varcode = current_varcode++;
list_add_last(hash+n, &p->car);
- return p->varcode;
-}
-void
-init(void)
-{
- list_init(&input_code);
- var_hash = new_var_hash();
- const_tab = xmalloc(BUFSIZE);
- cur_const_s = BUFSIZE;
+ return p->varcode;
}
-static int
+int
store_const(char* c)
{
if (cur_const_n >= cur_const_s) {
list_add_last(&input_code, &p->car);
}
+/* return number of variable where lies result
+ * pref_var < 0 => no preference
+ */
+static int
+evaluate(struct tree* t, int pref_var)
+{
+ struct code ins;
+
+ if (t->st == ST_LEAF) {
+ return t->pt.leaf.n;
+ } else if (t->st == ST_OP) {
+ int left, right;
+ left = evaluate(t->pt.op.left, -1);
+ right = evaluate(t->pt.op.right, -1);
+ switch (t->pt.op.op) {
+ case '.':
+ ins.opcode = CAT;
+ ins.u.cat.l = left;
+ ins.u.cat.r = right;
+ if (pref_var >= 0)
+ ins.u.cat.res = pref_var;
+ else
+ ins.u.cat.res = current_varcode++;;
+ new_instr(ins);
+ return ins.u.cat.res;
+ break;
+ default:
+ die("evaluate: got to default");
+ }
+ } else
+ die("evaluate: I can evaluate only expressions but I got %d",
+ t->st);
+}
+
static void
do_ass(struct tree* t)
{
int var_l, var_r;
struct code ins;
- var_l = find_var(t->pt.ass.left->pt.leaf.value, var_hash);
+ var_l = t->pt.ass.left->pt.leaf.n;
+ var_r = evaluate(t->pt.ass.right, -1);
+
+ ins.opcode = SET;
+ ins.u.set.l = var_l;
+ ins.u.set.r = var_r;
+ new_instr(ins);
- if (t->st == ST_LEAF) {
- if (t->pt.leaf.type == L_VAR)
- var_r = find_var(t->pt.leaf.value, var_hash);
- else
- var_r = store_const(t->pt.leaf.value);
- ins.opcode = SET;
- ins.u.set.l = var_l;
- ins.u.set.r = var_r;
- new_instr(ins);
- }
+}
+
+static void
+reset_temp_var_count(void)
+{
+ current_varcode = temp_varcode_start;
}
void
return;
switch(t->st) {
case ST_BLOCK:
+ reset_temp_var_count();
compile(t->pt.block.head);
compile(t->pt.block.tail);
break;
case ST_ASS:
do_ass(t);
break;
+ case ST_OP:
+ break;
default:
die("compile: got to default");
}
}
void
-print_code(struct tree* t)
+print_code(void)
{
-
+ struct code* p;
+
+ LIST_FOREACH(p, &input_code) {
+ switch (p->opcode) {
+ case SET:
+ printf("SET %d %d\n", p->u.set.l, p->u.set.r);
+ break;
+ case CAT:
+ printf("CAT %d %d %d\n", p->u.cat.l,
+ p->u.cat.r, p->u.cat.res);
+ break;
+ default:
+ printf("not implemented, opcode: %d\n",
+ p->opcode);
+ }
+ }
}
$$->pt.ass.left = tree_malloc(ST_LEAF);
$$->pt.ass.left->pt.leaf.type = L_VAR;
$$->pt.ass.left->pt.leaf.value = $1;
-
+ $$->pt.ass.left->pt.leaf.n = find_var($1, var_hash);
$$->pt.ass.right = $3;
}
;
$$ = tree_malloc(ST_LEAF);
$$->pt.leaf.type = L_VAR;
$$->pt.leaf.value = $1;
+ $$->pt.leaf.n = find_var($1, var_hash);
}
| CONST {
$$ = tree_malloc(ST_LEAF);
$$->pt.leaf.type = L_CONST;
$$->pt.leaf.value = $1;
+ $$->pt.leaf.n = store_const($1);
}
;
#include "umpf.h"
+void
+init(void)
+{
+ list_init(&input_code);
+ var_hash = new_var_hash();
+ const_tab = xmalloc(BUFSIZE);
+ cur_const_n = 1;
+ cur_const_s = BUFSIZE;
+}
+
int
main(int argc, char** argv)
{
save_gids();
read_conf(argv[1]);
-
+ init();
// yydebug=1;
res = yyparse ();
if (res)
return res;
- init();
+ temp_varcode_start = current_varcode;
compile(input_tree);
- print_code(input_tree);
+ print_code();
// var_hash = new_var_hash();
// current_headers = make_hlist();
L_CONST,
} type;
char* value;
+ int n;
} leaf;
struct {
char* cat(char* l, char* r);
/* code.c */
-
+#define BUFSIZE 1024
struct code {
struct node car;
enum {
JUMP_UNLESS,
DELIVER,
CALL_EXT,
- NOP
+ NOP,
+ CAT
} opcode;
union {
int l;
int r;
} set;
+
+ struct {
+ int l;
+ int r;
+ int res; /* result */
+ } cat;
+
+ struct {
+ } nop;
} u;
};
struct list input_code;
struct list* var_hash;
int current_varcode;
+int temp_varcode_start;
char** var_tab;
char** const_tab;
-int cur_const_n, cur_const_s;
+int cur_const_n;
+int cur_const_s;
void init(void);
void compile(struct tree* t);
-void print_code(struct tree* t);
+int find_var(char* name, struct list* hash);
+int store_const(char* c);
+struct list* new_var_hash(void);
+void print_code(void);