--- parrot/languages/imcc/imcc.y Mon Oct 21 13:56:24 2002 +++ parrot-leo/languages/imcc/imcc.y Mon Oct 21 17:34:18 2002 @@ -240,6 +240,100 @@ } +static Instruction * +multi_keyed(char *name, SymReg ** regs, int nr, int emit) +{ + int i, keys, kv, n; + char buf[16]; + static int p = 0; + SymReg *preg[IMCC_MAX_REGS]; /* px,py,pz */ + SymReg *nreg[IMCC_MAX_REGS]; + Instruction * ins, *last; + + /* count keys in keyvec */ + kv = keyvec; + for (i = keys = 0; i < nr; i++, kv >>= 1) + if (kv & 1) + keys++; + if (keys <= 1) + return 0; + /* XXX what to do, if we don't emit instruction? */ + assert(emit); + /* OP _p_k _p_k_p_k => + * set py, p_k + * set pz, p_k + * new px, .PerlUndef + * OP px, py, pz + * set _p_k_px + */ + + kv = keyvec; + for (i = n = 0; i < nr; i++, kv >>= 1, n++) { + if (kv & 1) { + fataly(EX_SOFTWARE, "multi_keyed", line,"illegal key operand\n"); + } + /* make a new P symbol */ + while (1) { + sprintf(buf, "$P%d", ++p); + if (get_sym(buf) == 0) + break; + } + preg[n] = mk_symreg(buf, 'P'); + kv >>= 1; + if (kv & 1) { + /* we have a keyed operand */ + if (regs[i]->set != 'P') { + fataly(EX_SOFTWARE, "multi_keyed", line,"not an aggregate\n"); + } + nargs = 3; + /* don't emit LHS yet */ + if (i == 0) { + keyvec = 1 << 1; + nreg[0] = regs[i]; + nreg[1] = regs[i+1]; + nreg[2] = preg[n]; + /* set p_k px */ + ins = iANY(str_dup("set"), 0, nreg, 0); + } + else { + keyvec = 1 << 2; + nreg[0] = preg[n]; + nreg[1] = regs[i]; + nreg[2] = regs[i+1]; + /* set py|z p_k */ + iANY(str_dup("set"), 0, nreg, 1); + } + i++; + } + /* non keyed */ + else { + nargs = 2; + keyvec = 0; + if (i == 0) { + nreg[0] = regs[i]; + nreg[1] = preg[n]; + /* set n, px */ + ins = iANY(str_dup("set"), 0, nreg, 0); + } + else { + nreg[0] = preg[n]; + nreg[1] = regs[i]; + /* set px, n */ + iANY(str_dup("set"), 0, nreg, 1); + } + } + } + /* make a new undef */ + iNEW(preg[0], str_dup("PerlUndef"), 1); + /* emit the operand */ + nargs = 3; + keyvec = 0; + iANY(name, 0, preg, 1); + /* emit the LHS op */ + emitb(ins); + return ins; +} + Instruction * iANY(char * name, char *fmt, SymReg **regs, int emit) { char fullname[64]; int i; @@ -247,6 +341,10 @@ int op; Instruction * ins; + ins = multi_keyed(name, regs, nargs, emit); + if (ins) + return ins; + op_fullname(fullname, name, regs, nargs); op = interpreter->op_lib->op_code(fullname, 1); if (op >= 0) { @@ -332,7 +430,6 @@ fataly(EX_SOFTWARE, "iANY", line,"op not found '%s' (%s<%d>)\n", fullname, name, nargs); } - clear_state(); return ins; } @@ -384,7 +481,8 @@ pasmline: labels pasm_inst '\n' { $$ = 0; } ; -pasm_inst: PARROT_OP pasm_args { $$ = iANY($1,0,regs,1); free($1); } +pasm_inst: {clear_state();} + PARROT_OP pasm_args { $$ = iANY($2,0,regs,1); free($2); } | /* none */ { $$ = 0;} ; @@ -427,7 +525,8 @@ | statements statement ; -statement: instruction +statement: {clear_state(); } + instruction ; labels: /* none */ { $$ = NULL; } --- parrot/3key.imc Mon Oct 21 17:34:24 2002 +++ parrot-leo/3key.imc Mon Oct 21 15:57:17 2002 @@ -0,0 +1,14 @@ +.sub _main + P0 = new PerlArray + P1 = new PerlArray + P2 = new PerlArray + set P1[0], 100 + set P2[1], 200 + set I2, 1 + add P0[2], P1[0], P2[I2] + set I0, P0[2] + print I0 + print "\n" + end +ret + --- parrot/a.pasm Mon Oct 21 17:34:24 2002 +++ parrot-leo/a.pasm Mon Oct 21 17:14:05 2002 @@ -0,0 +1,19 @@ +_main: + new P0, 10 # .PerlArray + new P1, 10 # .PerlArray + new P2, 10 # .PerlArray + set P1[0], 100 + set P2[1], 200 + set I2, 1 + set P4, P1[0] + set P3, P2[I2] + new P1, 15 # .PerlUndef + add P1, P4, P3 + set P0[2], P1 + set I0, P0[2] + print I0 + print "\n" + end + ret + +