]> mj.ucw.cz Git - umpf.git/commitdiff
compile SET and CAT
authorAnicka Bernathova <anicka@anicka.net>
Tue, 14 Jul 2009 16:31:46 +0000 (18:31 +0200)
committerAnicka Bernathova <anicka@anicka.net>
Tue, 14 Jul 2009 16:31:46 +0000 (18:31 +0200)
code.c
cond.y
umpf.c
umpf.h

diff --git a/code.c b/code.c
index 7aff3defed7f79567fd5c22a7950014d31b58d74..af2348973efb31f07f733130576f46366003e908 100644 (file)
--- a/code.c
+++ b/code.c
@@ -7,9 +7,8 @@
 
 #define HASHSIZE 103
 #define MAGIC 19
-#define BUFSIZE 1024
 
-static struct list* 
+struct list* 
 new_var_hash(void)
 {
        struct list* res;
@@ -37,7 +36,7 @@ get_bucket_number(char* name)
 }
 
 /* if not found, variable with value "" is created  */ 
-static int
+int
 find_var(char* name, struct list* hash)
 {
        int n;
@@ -53,19 +52,11 @@ find_var(char* name, struct list* hash)
        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) {
@@ -86,23 +77,59 @@ new_instr(struct code c)
        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
@@ -112,6 +139,7 @@ compile(struct tree* t)
                return;
        switch(t->st) {
                case ST_BLOCK:
+                       reset_temp_var_count();
                        compile(t->pt.block.head);
                        compile(t->pt.block.tail);
                        break;
@@ -120,13 +148,30 @@ compile(struct tree* t)
                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);
+               }
+       }
 }
diff --git a/cond.y b/cond.y
index 6ae17e896e46ec27285a6f39fba878d38aa31001..b5e4bf612749309e73b00acd123b4ccfe71a0606 100644 (file)
--- a/cond.y
+++ b/cond.y
@@ -147,7 +147,7 @@ ass:
                                        $$->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;
                                }
 ;
@@ -156,11 +156,13 @@ leaves:           VAR     {
                                $$ = 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);
                        }
 ;
 
diff --git a/umpf.c b/umpf.c
index bb8ca58f0fa002dcb08e62a7d3e5733b17e76316..f868775a6183f6e3541ca53320be67c724c23327 100644 (file)
--- a/umpf.c
+++ b/umpf.c
@@ -3,6 +3,16 @@
 
 #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)
 {
@@ -19,17 +29,17 @@ 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();
diff --git a/umpf.h b/umpf.h
index a2d45766a4b514c74a93b03d7e13bfb88e4511b3..2da7f0019c3170fa2aafa2760a46f8c6bfe88f08 100644 (file)
--- a/umpf.h
+++ b/umpf.h
@@ -48,6 +48,7 @@ struct tree {
                                L_CONST,
                        } type;
                        char* value;
+                       int n;
                } leaf;
 
                struct {
@@ -114,7 +115,7 @@ int open_mailbox(char* path, int is_default_mailbox);
 char* cat(char* l, char* r);
 
 /* code.c */
-
+#define BUFSIZE 1024
 struct code {
        struct node car;
        enum {
@@ -124,7 +125,8 @@ struct code {
                JUMP_UNLESS,
                DELIVER,
                CALL_EXT,
-               NOP
+               NOP,
+               CAT
        } opcode;
 
        union {
@@ -132,6 +134,15 @@ struct code {
                        int l;
                        int r;
                } set;
+
+               struct {
+                       int l;
+                       int r;
+                       int res; /* result */
+               } cat;
+
+               struct {
+               } nop;
        } u;
 };
 
@@ -144,10 +155,15 @@ struct variable {
 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);