]> mj.ucw.cz Git - umpf.git/blobdiff - code.c
fix content length after filtering mail
[umpf.git] / code.c
diff --git a/code.c b/code.c
index 070f7831615d86c5bb3f75c7f434a35e1f6997cd..932bb9ab5d8766c3a43f508a43b5add5b27825ab 100644 (file)
--- a/code.c
+++ b/code.c
@@ -5,9 +5,6 @@
 
 #include "umpf.h"
 
-#define HASHSIZE 103
-#define MAGIC 19
-
 struct list* 
 new_var_hash(void)
 {
@@ -21,7 +18,7 @@ new_var_hash(void)
        return res;
 }
 
-static int
+int
 get_bucket_number(char* name)
 {
        unsigned int n = 0;
@@ -35,22 +32,36 @@ get_bucket_number(char* name)
         return n;
 }
 
-/* if not found, variable with value "" is created  */ 
+/* return var struct or NULL if not found */
+struct variable*
+get_var_struct(char* name, enum var_type type, struct list* hash)
+{
+       int n;
+       struct variable *p;
+
+       n = get_bucket_number(name);
+       LIST_FOREACH(p, hash + n)
+               if (!strcasecmp(p->name, name) && p->type == type)
+                       return p;
+
+       return NULL;
+}
+
 int
-find_var(char* name, struct list* hash)
+find_var(char* name, enum var_type type, struct list* hash)
 {
        int n;
        struct variable *p;
 
        n = get_bucket_number(name);
-       int nocase = isupper(*name);
        LIST_FOREACH(p, hash + n)
-               if (!(nocase ? strcasecmp : strcmp)(p->name,name))
+               if (!strcasecmp(p->name, name) && p->type == type)
                        return p->varcode;
 
        p = xmalloc(sizeof(struct variable));
        p->name = xstrdup(name);
        p->varcode = current_varcode++;
+       p->type = type;
        list_add_last(hash+n, &p->car);
 
        return p->varcode;
@@ -105,21 +116,33 @@ evaluate(struct tree* t, int pref_var, struct list* where)
 {
        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, where);
-               right = evaluate(t->pt.op.right, -1, where);
-               switch (t->pt.op.op) {
-                       case '.':
-                               return new_3par_instr(OPC_CAT, left, 
-                                       right, pref_var, where);
-                               break;
-                       default:
-                               die("evaluate: got to default");
-               }
-       } else
-               die("evaluate: I can evaluate only expressions but I got %d",
-                       t->st);
+       } 
+       int left, right;
+       left = evaluate(t->pt.op.left, -1, where);
+       right = evaluate(t->pt.op.right, -1, where);
+       switch (t->pt.op.op) {
+               case '.':
+                       return new_3par_instr(OPC_CAT, left, 
+                               right, pref_var, where);
+                       break;
+               case '+':
+                       return new_3par_instr(OPC_PLUS, left, 
+                               right, pref_var, where);
+                       break;
+               case '-':
+                       return new_3par_instr(OPC_MINUS, left, 
+                               right, pref_var, where);
+                       break;
+               case '*':
+                       return new_3par_instr(OPC_MUL, left, 
+                               right, pref_var, where);
+                       break;
+               case '/':
+                       return new_3par_instr(OPC_DIV, left, 
+                               right, pref_var, where);
+                       break;
+       }
+       die("evaluate: Never can get here :)");
 }
 
 static void
@@ -278,7 +301,7 @@ do_arrow(struct tree* t, struct list* where)
                ins.u.arrow.copy = 0;
        switch (t->pt.arrow.right) {
                case K_EMPTY:
-                       ins.opcode = OPC_STORE;
+                       ins.opcode = OPC_DELIVER;
                        break;
                case K_PIPE:
                        ins.opcode = OPC_PIPE;
@@ -289,6 +312,9 @@ do_arrow(struct tree* t, struct list* where)
                case K_DISCARD:
                        ins.opcode = OPC_DISCARD;
                        break;
+               case K_FILTER:
+                       ins.opcode = OPC_FILTER;
+                       break;
                default:
                        die("do_arrow: This cannot happen ;-)");
        }
@@ -304,6 +330,8 @@ do_arrow(struct tree* t, struct list* where)
 static void
 reset_temp_var_count(void)
 {
+       if (current_varcode > max_varcode)
+               max_varcode = current_varcode;
        current_varcode = temp_varcode_start;
 }
 
@@ -367,17 +395,62 @@ print_code(void)
                        case OPC_GT:
                                printf("GT %d %d %d\n", p->u.tpop.l, p->u.tpop.r, p->u.tpop.res);
                                break;
+                       case OPC_LT:
+                               printf("LT %d %d %d\n", p->u.tpop.l, p->u.tpop.r, p->u.tpop.res);
+                               break;
+                       case OPC_LE:
+                               printf("LE %d %d %d\n", p->u.tpop.l, p->u.tpop.r, p->u.tpop.res);
+                               break;
+                       case OPC_GE:
+                               printf("GE %d %d %d\n", p->u.tpop.l, p->u.tpop.r, p->u.tpop.res);
+                               break;
+                       case OPC_RE:
+                               printf("RE %d %d %d\n", p->u.tpop.l, p->u.tpop.r, p->u.tpop.res);
+                               break;
+                       case OPC_NRE:
+                               printf("NRE %d %d %d\n", p->u.tpop.l, p->u.tpop.r, p->u.tpop.res);
+                               break;
+                       case OPC_NEQ:
+                               printf("NEQ %d %d %d\n", p->u.tpop.l, p->u.tpop.r, p->u.tpop.res);
+                               break;
+                       case OPC_EQ:
+                               printf("EQ %d %d %d\n", p->u.tpop.l, p->u.tpop.r, p->u.tpop.res);
+                               break;
                        case OPC_AND:
                                printf("AND %d %d %d\n", p->u.tpop.l, p->u.tpop.r, p->u.tpop.res);
                                break;
+                       case OPC_OR:
+                               printf("OR %d %d %d\n", p->u.tpop.l, p->u.tpop.r, p->u.tpop.res);
+                               break;
+                       case OPC_XOR:
+                               printf("XOR %d %d %d\n", p->u.tpop.l, p->u.tpop.r, p->u.tpop.res);
+                               break;
+                       case OPC_PLUS:
+                               printf("PLUS %d %d %d\n", p->u.tpop.l, p->u.tpop.r, p->u.tpop.res);
+                               break;
+                       case OPC_MINUS:
+                               printf("MINUS %d %d %d\n", p->u.tpop.l, p->u.tpop.r, p->u.tpop.res);
+                               break;
+                       case OPC_MUL:
+                               printf("MUL %d %d %d\n", p->u.tpop.l, p->u.tpop.r, p->u.tpop.res);
+                               break;
+                       case OPC_DIV:
+                               printf("DIV %d %d %d\n", p->u.tpop.l, p->u.tpop.r, p->u.tpop.res);
+                               break;
+                       case OPC_NOT:
+                               printf("NOT %d %d\n", p->u.dpop.par, p->u.dpop.res);
+                               break;
                        case OPC_NOP:
                                puts("NOP");    
                                break;
                        case OPC_PIPE:
                                printf("PIPE %d %d\n", p->u.arrow.what, p->u.arrow.copy);
                                break;
-                       case OPC_STORE:
-                               printf("STORE %d %d\n", p->u.arrow.what, p->u.arrow.copy);
+                       case OPC_FILTER:
+                               printf("FILTER %d %d\n", p->u.arrow.what, p->u.arrow.copy);
+                               break;
+                       case OPC_DELIVER:
+                               printf("DELIVER %d %d\n", p->u.arrow.what, p->u.arrow.copy);
                                break;
                        case OPC_MAIL:
                                printf("MAIL %d %d\n", p->u.arrow.what, p->u.arrow.copy);