]> mj.ucw.cz Git - umpf.git/commitdiff
part of conditions, printing variables
authorAnicka Bernathova <anicka@anicka.net>
Thu, 10 Jul 2008 11:51:29 +0000 (13:51 +0200)
committerAnicka Bernathova <anicka@anicka.net>
Thu, 10 Jul 2008 11:51:29 +0000 (13:51 +0200)
brum.c
brum.h
cond.y
int.c
lex.c

diff --git a/brum.c b/brum.c
index 21ebff6f3e48450c799e6144a2ceee66dbf16c94..5172d69b3229f84345bc79dec2b6eba4726787a7 100644 (file)
--- a/brum.c
+++ b/brum.c
@@ -16,6 +16,8 @@ main(void)
 
        var_hash = new_var_hash();
        interp(input_tree, var_hash);
+       
+       print_vars(var_hash);
 
        return 0;
 }
diff --git a/brum.h b/brum.h
index 7cb6fdebae2614d03fab7e38b91868cc68443241..16e4b9e5acb8acb50c30eb74b9f9191b4d5f408e 100644 (file)
--- a/brum.h
+++ b/brum.h
@@ -22,6 +22,10 @@ struct tree {
 
                struct {
                        int op;
+                       enum {
+                               OP_REL,
+                               OP_BOOL 
+                       } type;
                        struct tree* left;
                        struct tree* right;
                } cond; /* binary operator */
@@ -62,6 +66,7 @@ struct tree {
 struct tree* input_tree;
 
 /* lex.c */
+#define CC(a,b) ((a<<8)|b)
 void* xmalloc(size_t size);
 char* xstrdup(char* s);
 void __attribute__ ((noreturn)) die(char* msg, ...);
@@ -79,3 +84,4 @@ struct variable** var_hash;
 void print_tree(struct tree* t, int ind);
 void interp(struct tree* t, struct variable** hash);
 struct variable** new_var_hash(void);
+void print_vars(struct variable** hash);
diff --git a/cond.y b/cond.y
index 9f42a4be6581a8d3eaecb1faa1371c7d0caf4017..42a663d1f9947ac78f022f867e894d51d4e71437 100644 (file)
--- a/cond.y
+++ b/cond.y
@@ -93,29 +93,30 @@ cif:        KW_IF cond command KW_ELSE command      {
 cond:  '!' cond {
                                $$ = tree_malloc(ST_COND);
                                $$->pt.cond.left = $2;  
-                               $$->pt.cond.right = tree_malloc(ST_EMPTY)
+                               $$->pt.cond.right = NULL
                                $$->pt.cond.op = $1;    
-
+                               $$->pt.cond.type = OP_BOOL;     
                }
        | cond '|' cond {
                                $$ = tree_malloc(ST_COND);
                                $$->pt.cond.left = $1;  
                                $$->pt.cond.right = $3; 
                                $$->pt.cond.op = $2;    
-
+                               $$->pt.cond.type = OP_BOOL;     
                        }
        | cond '&' cond {
                                $$ = tree_malloc(ST_COND);
                                $$->pt.cond.left = $1;  
                                $$->pt.cond.right = $3; 
                                $$->pt.cond.op = $2;    
-
+                               $$->pt.cond.type = OP_BOOL;     
                        }
        | cond '^' cond {
                                $$ = tree_malloc(ST_COND);
                                $$->pt.cond.left = $1;  
                                $$->pt.cond.right = $3; 
                                $$->pt.cond.op = $2;    
+                               $$->pt.cond.type = OP_BOOL;     
 
                        }
        | '(' cond ')' { $$ = $2; }
@@ -124,6 +125,7 @@ cond:       '!' cond {
                                                $$->pt.cond.left = $1;  
                                                $$->pt.cond.right = $3; 
                                                $$->pt.cond.op = $2;    
+                                               $$->pt.cond.type = OP_REL;      
                                        }
 ;
 
diff --git a/int.c b/int.c
index 6403e11094b9baea6accac26186e04c534b30781..73e34ff5f613834fc906bf3805020efc94bb0b26 100644 (file)
--- a/int.c
+++ b/int.c
@@ -50,7 +50,9 @@ find_var(char* name, char* value, struct variable** hash)
        if (p && value){
                free(p->value);
                p->value = value;
-       } else {
+       } else if (p && !value)
+               return p;
+       else {
                p = xmalloc(sizeof(struct variable));
                p->next = hash[n];
                hash[n] = p;
@@ -179,6 +181,49 @@ interp_ass_right(struct tree* t, struct variable** hash)
                }
 }      
 
+int
+interp_cond(struct tree* t, struct variable** hash)
+{
+       if (t->st != ST_COND)
+               die("Muhehehechlemst?");
+
+       if (t->pt.cond.type == OP_REL){
+               if (t->pt.cond.left->st != ST_LEAF || t->pt.cond.right->st != ST_LEAF)
+       die("Chlemst");
+
+               char* left = (t->pt.cond.left->pt.leaf.type == L_VAR ? find_var(t->pt.cond.left->pt.leaf.value,NULL,hash)->value : t->pt.cond.left->pt.leaf.value);
+       char* right = (t->pt.cond.right->pt.leaf.type == L_VAR ? find_var(t->pt.cond.right->pt.leaf.value,NULL,hash)->value : t->pt.cond.right->pt.leaf.value);
+               switch (t->pt.cond.op){
+                       case CC('=','='):
+                               return !strcmp(left,right);
+                       case CC('!','='):
+                               return strcmp(left,right);
+                       case CC('~','~'):
+                               return regex_cmp(left,right);
+                       case CC('!','~'):
+                               return !regex_cmp(left,right);
+               }
+
+       } else {
+               int left = interp_cond(t->pt.cond.left, hash);
+               int right;
+
+               if (t->pt.cond.op != '!')
+                       right = interp_cond(t->pt.cond.right, hash);
+
+               switch (t->pt.cond.op){
+                       case '&':
+                               return left && right;
+                       case '|':
+                               return left || right;
+                       case '^':
+                               return (left || right) && !(left && right);
+                       case '!':
+                               return !left;
+               }
+       }
+}
+
 void
 interp(struct tree* t, struct variable** hash)
 {
@@ -189,12 +234,35 @@ interp(struct tree* t, struct variable** hash)
                case ST_BLOCK:
                        interp(t->pt.block.head, hash);
                        interp(t->pt.block.tail, hash);
-               break;
+                       break;
                case ST_ASS:
                        find_var(t->pt.ass.left->pt.leaf.value, interp_ass_right(t->pt.ass.right, hash), hash);
-               break;
+                       break;
+               case ST_IF:
+                       if (interp_cond(t->pt.tif.c, hash))
+                               interp(t->pt.tif.i, hash);
+                       else 
+                               interp(t->pt.tif.e, hash);
+                       break;
+               case ST_EMPTY:
+                       break;  
                default:
                        die("interp: got to default");
        }
 
-};
+}
+
+void
+print_vars(struct variable** hash)
+{
+       int i;
+       struct variable* p;
+
+       for (i=0; i<HASHSIZE; i++){
+               p = hash[i];
+               while(p){
+                       printf("%s=%s\n",p->name, p->value);
+                       p = p->next;
+               }               
+       }
+}
diff --git a/lex.c b/lex.c
index 8710763bd9417da6dbd4907b84a7ad335707d273..07d86b3e79645dc76275e5d5e34c6ed14cd912bf 100644 (file)
--- a/lex.c
+++ b/lex.c
@@ -123,7 +123,6 @@ yylex(void)
        if (c == EOF)
                return 0;
        
-#define CC(a,b) ((a<<8)|b)
        int d = getchar();
        if (d >= 0) {
                switch (CC(c,d)) {
@@ -153,6 +152,9 @@ yylex(void)
                case '=':
                case ';':
                case '.':
+               case '|':
+               case '&':
+               case '^':
                        yylval.n = c;
                        return c;