]> mj.ucw.cz Git - umpf.git/commitdiff
add more binary operators
authorAnicka Bernathova <anicka@anicka.net>
Wed, 15 Jul 2009 14:20:37 +0000 (16:20 +0200)
committerAnicka Bernathova <anicka@anicka.net>
Wed, 15 Jul 2009 14:20:37 +0000 (16:20 +0200)
code.c
cond.y
umpf.h

diff --git a/code.c b/code.c
index 04b41b3acfb3fb9310ada0627933f46e6342c7ac..070f7831615d86c5bb3f75c7f434a35e1f6997cd 100644 (file)
--- a/code.c
+++ b/code.c
@@ -80,14 +80,29 @@ new_instr(struct code c, struct list* where)
                list_add_last(&input_code, &p->car);
 }
 
                list_add_last(&input_code, &p->car);
 }
 
+static int
+new_3par_instr(int opcode, int left, int right, int pref_var, 
+                struct list* where)
+{
+       struct code ins;
+
+       ins.opcode = opcode;
+       ins.u.tpop.l = left;
+       ins.u.tpop.r = right;
+       if (pref_var >= 0)
+               ins.u.tpop.res = pref_var;
+       else
+               ins.u.tpop.res = current_varcode++;;
+       new_instr(ins, where);
+       return ins.u.tpop.res;
+}
+
 /* return number of variable where lies result 
  * pref_var < 0 => no preference
  */
 static int
 evaluate(struct tree* t, int pref_var, struct list* where)
 {
 /* return number of variable where lies result 
  * pref_var < 0 => no preference
  */
 static int
 evaluate(struct tree* t, int pref_var, struct list* where)
 {
-       struct code ins;
-
        if (t->st == ST_LEAF) { 
                return t->pt.leaf.n;
        } else if (t->st == ST_OP) {
        if (t->st == ST_LEAF) { 
                return t->pt.leaf.n;
        } else if (t->st == ST_OP) {
@@ -96,15 +111,8 @@ evaluate(struct tree* t, int pref_var, struct list* where)
                right = evaluate(t->pt.op.right, -1, where);
                switch (t->pt.op.op) {
                        case '.':
                right = evaluate(t->pt.op.right, -1, where);
                switch (t->pt.op.op) {
                        case '.':
-                               ins.opcode = CAT;
-                               ins.u.tpop.l = left;
-                               ins.u.tpop.r = right;
-                               if (pref_var >= 0)
-                                       ins.u.tpop.res = pref_var;
-                               else
-                                       ins.u.tpop.res = current_varcode++;;
-                               new_instr(ins, where);
-                               return ins.u.tpop.res;
+                               return new_3par_instr(OPC_CAT, left, 
+                                       right, pref_var, where);
                                break;
                        default:
                                die("evaluate: got to default");
                                break;
                        default:
                                die("evaluate: got to default");
@@ -122,30 +130,13 @@ do_ass(struct tree* t, struct list* where)
        var_l = t->pt.ass.left->pt.leaf.n;
        var_r = evaluate(t->pt.ass.right, -1, where);
        
        var_l = t->pt.ass.left->pt.leaf.n;
        var_r = evaluate(t->pt.ass.right, -1, where);
        
-       ins.opcode = SET;
+       ins.opcode = OPC_SET;
        ins.u.set.l = var_l;
        ins.u.set.r = var_r;
        new_instr(ins, where);
 
 }
 
        ins.u.set.l = var_l;
        ins.u.set.r = var_r;
        new_instr(ins, where);
 
 }
 
-static int
-new_cond_instr(int opcode, int left, int right, int pref_var, 
-                struct list* where)
-{
-       struct code ins;
-
-       ins.opcode = opcode;
-       ins.u.tpop.l = left;
-       ins.u.tpop.r = right;
-       if (pref_var >= 0)
-               ins.u.tpop.res = pref_var;
-       else
-               ins.u.tpop.res = current_varcode++;;
-       new_instr(ins, where);
-       return ins.u.tpop.res;
-}
-
 static int
 eval_cond(struct tree *t, int pref_var, struct list* where)
 {
 static int
 eval_cond(struct tree *t, int pref_var, struct list* where)
 {
@@ -165,7 +156,35 @@ eval_cond(struct tree *t, int pref_var, struct list* where)
 
                switch (t->pt.cond.op) {                
                        case '>':
 
                switch (t->pt.cond.op) {                
                        case '>':
-                               return new_cond_instr(GT, left, 
+                               return new_3par_instr (OPC_GT, left, 
+                                       right, pref_var, where);
+                               break;
+                       case '<':
+                               return new_3par_instr (OPC_LT, left, 
+                                       right, pref_var, where);
+                               break;
+                       case CC('<','='):
+                               return new_3par_instr (OPC_LE, left, 
+                                       right, pref_var, where);
+                               break;
+                       case CC('>','='):
+                               return new_3par_instr (OPC_GE, left, 
+                                       right, pref_var, where);
+                               break;
+                       case CC('!','~'):
+                               return new_3par_instr (OPC_NRE, left, 
+                                       right, pref_var, where);
+                               break;
+                       case CC('~','~'):
+                               return new_3par_instr (OPC_RE, left, 
+                                       right, pref_var, where);
+                               break;
+                       case CC('=','='):
+                               return new_3par_instr (OPC_EQ, left, 
+                                       right, pref_var, where);
+                               break;
+                       case CC('!','='):
+                               return new_3par_instr (OPC_NEQ, left, 
                                        right, pref_var, where);
                                break;
                        /* fixme: do more of them */
                                        right, pref_var, where);
                                break;
                        /* fixme: do more of them */
@@ -176,13 +195,34 @@ eval_cond(struct tree *t, int pref_var, struct list* where)
                }
        }
        if (t->pt.cond.type == OP_BOOL) {
                }
        }
        if (t->pt.cond.type == OP_BOOL) {
+               struct code ins;
+
                left = eval_cond(t->pt.cond.left, -1, where);
                left = eval_cond(t->pt.cond.left, -1, where);
-               right = eval_cond(t->pt.cond.right, -1, where);
+               if (t->pt.cond.op != '!') /* ! is unary */
+                       right = eval_cond(t->pt.cond.right, -1, where);
                switch (t->pt.cond.op) {
                        case '&':
                switch (t->pt.cond.op) {
                        case '&':
-                               return new_cond_instr(AND, left, 
+                               return new_3par_instr (OPC_AND, left, 
                                        right, pref_var, where);
                                break;
                                        right, pref_var, where);
                                break;
+                       case '|':
+                               return new_3par_instr (OPC_OR, left, 
+                                       right, pref_var, where);
+                               break;
+                       case '^':
+                               return new_3par_instr (OPC_XOR, left, 
+                                       right, pref_var, where);
+                               break;
+                       case '!':
+                               ins.opcode = OPC_NOT;
+                               ins.u.dpop.par = left;
+                               if (pref_var >= 0)
+                                       ins.u.dpop.res = pref_var;
+                               else
+                                       ins.u.dpop.res = current_varcode++;;
+                               new_instr(ins, where);
+                               return ins.u.dpop.res;
+                               break;
                        default:
                                die("eval_cond: unknown boolean op %c\n", 
                                t->pt.cond.op);
                        default:
                                die("eval_cond: unknown boolean op %c\n", 
                                t->pt.cond.op);
@@ -202,8 +242,8 @@ do_if(struct tree *t, struct list* where)
 
        list_init(if_branch);
        list_init(else_branch);
 
        list_init(if_branch);
        list_init(else_branch);
-       nop.opcode  = NOP;
-       jmp.opcode = JUMP;
+       nop.opcode  = OPC_NOP;
+       jmp.opcode = OPC_JUMP;
 
        c = eval_cond(t->pt.tif.c, -1, where);
 
 
        c = eval_cond(t->pt.tif.c, -1, where);
 
@@ -214,7 +254,7 @@ do_if(struct tree *t, struct list* where)
        jmp.u.jump.target = list_last(else_branch);
        new_instr(jmp, if_branch);
        
        jmp.u.jump.target = list_last(else_branch);
        new_instr(jmp, if_branch);
        
-       ins.opcode = JUMP_UNLESS;
+       ins.opcode = OPC_JUMP_UNLESS;
        ins.u.jump_unless.cond = c;
        ins.u.jump_unless.target = list_last(if_branch);
        new_instr(ins, where);
        ins.u.jump_unless.cond = c;
        ins.u.jump_unless.target = list_last(if_branch);
        new_instr(ins, where);
@@ -238,16 +278,16 @@ do_arrow(struct tree* t, struct list* where)
                ins.u.arrow.copy = 0;
        switch (t->pt.arrow.right) {
                case K_EMPTY:
                ins.u.arrow.copy = 0;
        switch (t->pt.arrow.right) {
                case K_EMPTY:
-                       ins.opcode = STORE;
+                       ins.opcode = OPC_STORE;
                        break;
                case K_PIPE:
                        break;
                case K_PIPE:
-                       ins.opcode = PIPE;
+                       ins.opcode = OPC_PIPE;
                        break;
                case K_MAIL:
                        break;
                case K_MAIL:
-                       ins.opcode = MAIL;
+                       ins.opcode = OPC_MAIL;
                        break;
                case K_DISCARD:
                        break;
                case K_DISCARD:
-                       ins.opcode = DISCARD;
+                       ins.opcode = OPC_DISCARD;
                        break;
                default:
                        die("do_arrow: This cannot happen ;-)");
                        break;
                default:
                        die("do_arrow: This cannot happen ;-)");
@@ -311,38 +351,38 @@ print_code(void)
 
        LIST_FOREACH(p, &input_code) {
                switch (p->opcode) {
 
        LIST_FOREACH(p, &input_code) {
                switch (p->opcode) {
-                       case SET:
+                       case OPC_SET:
                                printf("SET %d %d\n", p->u.set.l, p->u.set.r);
                                break; 
                                printf("SET %d %d\n", p->u.set.l, p->u.set.r);
                                break; 
-                       case CAT:
+                       case OPC_CAT:
                                printf("CAT %d %d %d\n", p->u.tpop.l,
                                p->u.tpop.r, p->u.tpop.res);
                                break;
                                printf("CAT %d %d %d\n", p->u.tpop.l,
                                p->u.tpop.r, p->u.tpop.res);
                                break;
-                       case JUMP:
+                       case OPC_JUMP:
                                printf("JUMP %d\n", (int) p->u.jump.target);
                                break;
                                printf("JUMP %d\n", (int) p->u.jump.target);
                                break;
-                       case JUMP_UNLESS:
+                       case OPC_JUMP_UNLESS:
                                printf("JUMP_UNLESS %d %d\n", p->u.jump_unless.cond,(int) p->u.jump_unless.target);
                                break;
                                printf("JUMP_UNLESS %d %d\n", p->u.jump_unless.cond,(int) p->u.jump_unless.target);
                                break;
-                       case GT:
+                       case OPC_GT:
                                printf("GT %d %d %d\n", p->u.tpop.l, p->u.tpop.r, p->u.tpop.res);
                                break;
                                printf("GT %d %d %d\n", p->u.tpop.l, p->u.tpop.r, p->u.tpop.res);
                                break;
-                       case AND:
+                       case OPC_AND:
                                printf("AND %d %d %d\n", p->u.tpop.l, p->u.tpop.r, p->u.tpop.res);
                                break;
                                printf("AND %d %d %d\n", p->u.tpop.l, p->u.tpop.r, p->u.tpop.res);
                                break;
-                       case NOP:
+                       case OPC_NOP:
                                puts("NOP");    
                                break;
                                puts("NOP");    
                                break;
-                       case PIPE:
+                       case OPC_PIPE:
                                printf("PIPE %d %d\n", p->u.arrow.what, p->u.arrow.copy);
                                break;
                                printf("PIPE %d %d\n", p->u.arrow.what, p->u.arrow.copy);
                                break;
-                       case STORE:
+                       case OPC_STORE:
                                printf("STORE %d %d\n", p->u.arrow.what, p->u.arrow.copy);
                                break;
                                printf("STORE %d %d\n", p->u.arrow.what, p->u.arrow.copy);
                                break;
-                       case MAIL:
+                       case OPC_MAIL:
                                printf("MAIL %d %d\n", p->u.arrow.what, p->u.arrow.copy);
                                break;
                                printf("MAIL %d %d\n", p->u.arrow.what, p->u.arrow.copy);
                                break;
-                       case DISCARD:
+                       case OPC_DISCARD:
                                puts("DISCARD");
                                break;
                        default:
                                puts("DISCARD");
                                break;
                        default:
diff --git a/cond.y b/cond.y
index 5d5751b3c32751bb3edf3c3af0245eae5164cc2b..ec5bc8e34a53b32580e55c56f46b705ef66d3360 100644 (file)
--- a/cond.y
+++ b/cond.y
@@ -27,9 +27,9 @@ static struct tree* tree_malloc(int type);
 %left ARROW
 %left <n> EQ NEQ GE LE '<' '>' RE NRE
 %left '='
 %left ARROW
 %left <n> EQ NEQ GE LE '<' '>' RE NRE
 %left '='
-%left '.'
-%left '+' '-' 
-%left '*' '/'
+%left <n> '.'
+%left <n> '+' '-' 
+%left <n> '*' '/'
 %left <n> '|'
 %left <n> '^'
 %left <n> '&'
 %left <n> '|'
 %left <n> '^'
 %left <n> '&'
@@ -43,6 +43,7 @@ static struct tree* tree_malloc(int type);
 %type <tr> arrow 
 %type <tr> cond
 %type <n> rop 
 %type <tr> arrow 
 %type <tr> cond
 %type <n> rop 
+%type <n> bop 
 %type <n> left
 %type <n> right 
 %type <tr> leaves 
 %type <n> left
 %type <n> right 
 %type <tr> leaves 
@@ -196,14 +197,21 @@ right:    /* empty */ { $$ = K_EMPTY; }
 ;
 
 ass_right:     leaves
 ;
 
 ass_right:     leaves
-               | ass_right '.' ass_right       {
+               | ass_right bop ass_right       {
                                        $$ = tree_malloc(ST_OP);
                                        $$ = tree_malloc(ST_OP);
-                                       $$->pt.op.op = '.';
+                                       $$->pt.op.op = $2;
                                        $$->pt.op.left = $1;    
                                        $$->pt.op.right = $3;   
                                }
 ;
 
                                        $$->pt.op.left = $1;    
                                        $$->pt.op.right = $3;   
                                }
 ;
 
+bop:   '.'   {$$ = $1} 
+       | '+' {$$ = $1}
+       | '-' {$$ = $1}
+       | '*' {$$ = $1}
+       | '/' {$$ = $1}
+;
+
 %%
 
 struct tree* 
 %%
 
 struct tree* 
diff --git a/umpf.h b/umpf.h
index c7d59a145ab3bff5b55c54a90df076ce063bb197..946279ebc8d0a84699ff8c20e84a8a915bfb6176 100644 (file)
--- a/umpf.h
+++ b/umpf.h
@@ -128,20 +128,34 @@ char* cat(char* l, char* r);
 struct code {
        struct node car;
        enum {
 struct code {
        struct node car;
        enum {
-               SET,
-               JUMP,
-               JUMP_IF,
-               JUMP_UNLESS,
-               DELIVER,
-               CALL_EXT,
-               NOP,
-               CAT,
-               GT,
-               AND,
-               PIPE,
-               MAIL,
-               STORE,
-               DISCARD
+               OPC_SET,
+               OPC_JUMP,
+               OPC_JUMP_IF,
+               OPC_JUMP_UNLESS,
+               OPC_DELIVER,
+               OPC_CALL_EXT,
+               OPC_NOP,
+               OPC_CAT,
+               OPC_GT,
+               OPC_LT,
+               OPC_LE,
+               OPC_GE,
+               OPC_EQ,
+               OPC_NEQ,
+               OPC_RE,
+               OPC_NRE,
+               OPC_AND,
+               OPC_OR,
+               OPC_XOR,
+               OPC_NOT,
+               OPC_PLUS,
+               OPC_MINUS,
+               OPC_MUL,
+               OPC_DIV,
+               OPC_PIPE,
+               OPC_MAIL,
+               OPC_STORE,
+               OPC_DISCARD
        } opcode;
 
        union {
        } opcode;
 
        union {
@@ -165,6 +179,10 @@ struct code {
                        int r;
                        int res; /* result */
                } tpop;
                        int r;
                        int res; /* result */
                } tpop;
+               struct {
+                       int par;
+                       int res; /* result */
+               } dpop;
                struct {
                        int copy;
                        int what;
                struct {
                        int copy;
                        int what;