From eff01c5f12f5b20d0ca3b666099e754c21a01fb9 Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Mon, 5 Mar 2018 10:55:19 -0800 Subject: [PATCH] Short circuit AND/OR --- src/toolsrc/codegen.c | 48 +++++++++++++++++++------------ src/toolsrc/codegen.h | 14 ++++++--- src/toolsrc/codegen.pla | 18 +++++++++--- src/toolsrc/codeopt.pla | 16 +++++------ src/toolsrc/codeseq.plh | 6 ++-- src/toolsrc/parse.c | 50 ++++++++++++++++++++++++++------ src/toolsrc/parse.pla | 27 +++++++++++------ src/toolsrc/plasm.pla | 8 +++--- src/vmsrc/apple/plvm02.s | 62 ++++++++++++++++++---------------------- src/vmsrc/plvm.c | 40 ++++++++++++++++++++------ 10 files changed, 190 insertions(+), 99 deletions(-) diff --git a/src/toolsrc/codegen.c b/src/toolsrc/codegen.c index 9ab4119..ade048e 100755 --- a/src/toolsrc/codegen.c +++ b/src/toolsrc/codegen.c @@ -806,10 +806,16 @@ void emit_brnch(int tag) printf("\t%s\t$50\t\t\t; BRNCH\t_B%03d\n", DB, tag); printf("\t%s\t_B%03d-*\n", DW, tag); } -void emit_brne(int tag) +void emit_brand(int tag) { emit_pending_seq(); - printf("\t%s\t$52\t\t\t; BRNE\t_B%03d\n", DB, tag); + printf("\t%s\t$8C\t\t\t; BRAND\t_B%03d\n", DB, tag); + printf("\t%s\t_B%03d-*\n", DW, tag); +} +void emit_bror(int tag) +{ + emit_pending_seq(); + printf("\t%s\t$8E\t\t\t; BROR\t_B%03d\n", DB, tag); printf("\t%s\t_B%03d-*\n", DW, tag); } void emit_brgt(int tag) @@ -991,12 +997,12 @@ int emit_op(t_token op) case LE_TOKEN: printf("\t%s\t$4A\t\t\t; ISLE\n", DB); break; - case LOGIC_OR_TOKEN: - printf("\t%s\t$22\t\t\t; LOR\n", DB); - break; - case LOGIC_AND_TOKEN: - printf("\t%s\t$24\t\t\t; LAND\n", DB); - break; +// case LOGIC_OR_TOKEN: +// printf("\t%s\t$22\t\t\t; LOR\n", DB); +// break; +// case LOGIC_AND_TOKEN: +// printf("\t%s\t$24\t\t\t; LAND\n", DB); +// break; case COMMA_TOKEN: break; default: @@ -1268,14 +1274,14 @@ int crunch_seq(t_opseq **seq, int pass) op->val = op->val <= opnext->val ? 1 : 0; freeops = 2; break; - case BINARY_CODE(LOGIC_OR_TOKEN): - op->val = op->val || opnext->val ? 1 : 0; - freeops = 2; - break; - case BINARY_CODE(LOGIC_AND_TOKEN): - op->val = op->val && opnext->val ? 1 : 0; - freeops = 2; - break; +// case BINARY_CODE(LOGIC_OR_TOKEN): +// op->val = op->val || opnext->val ? 1 : 0; +// freeops = 2; +// break; +// case BINARY_CODE(LOGIC_AND_TOKEN): +// op->val = op->val && opnext->val ? 1 : 0; +// freeops = 2; +// break; } // End of collapse constant operation if ((pass > 0) && (freeops == 0) && (op->val != 0)) @@ -1666,8 +1672,8 @@ int emit_pending_seq() case LT_CODE: case GT_CODE: case LE_CODE: - case LOGIC_OR_CODE: - case LOGIC_AND_CODE: +// case LOGIC_OR_CODE: +// case LOGIC_AND_CODE: emit_op(op->code); break; case CONST_CODE: @@ -1763,6 +1769,12 @@ int emit_pending_seq() case BRNCH_CODE: emit_brnch(op->tag); break; + case BRAND_CODE: + emit_brand(op->tag); + break; + case BROR_CODE: + emit_bror(op->tag); + break; case BRFALSE_CODE: emit_brfls(op->tag); break; diff --git a/src/toolsrc/codegen.h b/src/toolsrc/codegen.h index f8d3695..32b3dca 100755 --- a/src/toolsrc/codegen.h +++ b/src/toolsrc/codegen.h @@ -31,8 +31,8 @@ typedef struct _opseq { #define LT_CODE (0x0200|LT_TOKEN) #define GT_CODE (0x0200|GT_TOKEN) #define LE_CODE (0x0200|LE_TOKEN) -#define LOGIC_OR_CODE (0x0200|LOGIC_OR_TOKEN) -#define LOGIC_AND_CODE (0x0200|LOGIC_AND_TOKEN) +//#define LOGIC_OR_CODE (0x0200|LOGIC_OR_TOKEN) +//#define LOGIC_AND_CODE (0x0200|LOGIC_AND_TOKEN) #define CONST_CODE 0x0300 #define STR_CODE 0x0301 #define LB_CODE 0x0302 @@ -66,8 +66,10 @@ typedef struct _opseq { #define BRNCH_CODE 0x0320 #define BRFALSE_CODE 0x0321 #define BRTRUE_CODE 0x0322 -#define CODETAG_CODE 0x0323 -#define NOP_CODE 0x0324 +#define BRAND_CODE 0x323 +#define BROR_CODE 0x324 +#define CODETAG_CODE 0x0325 +#define NOP_CODE 0x0326 #define gen_uop(seq,op) gen_seq(seq,UNARY_CODE(op),0,0,0,0) #define gen_op(seq,op) gen_seq(seq,BINARY_CODE(op),0,0,0,0) @@ -83,6 +85,8 @@ typedef struct _opseq { #define gen_sw(seq) gen_seq(seq,SW_CODE,0,0,0,0) #define gen_icall(seq) gen_seq(seq,ICAL_CODE,0,0,0,0) #define gen_drop(seq) gen_seq(seq,DROP_CODE,0,0,0,0) +#define gen_brand(seq,tag) gen_seq(seq,BRAND_CODE,0,tag,0,0) +#define gen_bror(seq,tag) gen_seq(seq,BROR_CODE,0,tag,0,0) #define gen_brfls(seq,tag) gen_seq(seq,BRFALSE_CODE,0,tag,0,0) #define gen_brtru(seq,tag) gen_seq(seq,BRTRUE_CODE,0,tag,0,0) #define gen_brnch(seq,tag) gen_seq(seq,BRNCH_CODE,0,tag,0,0) @@ -136,6 +140,8 @@ int emit_unaryop(t_token op); int emit_op(t_token op); void emit_select(int tag); void emit_caseblock(int casecnt, int *caseof, int *casetag); +void emit_brand(int tag); +void emit_bror(int tag); void emit_brtru(int tag); void emit_brfls(int tag); void emit_brne(int tag); diff --git a/src/toolsrc/codegen.pla b/src/toolsrc/codegen.pla index da40fb7..f0c1130 100644 --- a/src/toolsrc/codegen.pla +++ b/src/toolsrc/codegen.pla @@ -190,6 +190,16 @@ def emit_branch(tag)#0 emit_byte($50) emit_reladdr(tag) end +def emit_brand(tag)#0 + emit_pending_seq + emit_byte($8C) + emit_reladdr(tag) +end +def emit_bror(tag)#0 + emit_pending_seq + emit_byte($8E) + emit_reladdr(tag) +end def emit_brgt(tag)#0 emit_pending_seq emit_byte($80) @@ -788,10 +798,10 @@ def gen_bop(seq, tkn) code = $44; break is LE_TKN code = $4A; break - is LOGIC_OR_TKN - code = $22; break - is LOGIC_AND_TKN - code = $24; break + //is LOGIC_OR_TKN + // code = $22; break + //is LOGIC_AND_TKN + // code = $24; break otherwise exit_err(ERR_INVAL|ERR_SYNTAX) wend diff --git a/src/toolsrc/codeopt.pla b/src/toolsrc/codeopt.pla index b49e37d..5978d22 100644 --- a/src/toolsrc/codeopt.pla +++ b/src/toolsrc/codeopt.pla @@ -200,14 +200,14 @@ def crunch_seq(seq, pass) op=>opval = op=>opval <= nextop=>opval freeops = 2 break - is LOGIC_OR_CODE - op=>opval = op=>opval or nextop=>opval - freeops = 2 - break - is LOGIC_AND_CODE - op=>opval = op=>opval and nextop=>opval - freeops = 2 - break +// is LOGIC_OR_CODE +// op=>opval = op=>opval or nextop=>opval +// freeops = 2 +// break +// is LOGIC_AND_CODE +// op=>opval = op=>opval and nextop=>opval +// freeops = 2 +// break wend // End of collapse constant operation fin if pass and not freeops and op=>opval diff --git a/src/toolsrc/codeseq.plh b/src/toolsrc/codeseq.plh index cf14e2d..5efa4c6 100644 --- a/src/toolsrc/codeseq.plh +++ b/src/toolsrc/codeseq.plh @@ -30,8 +30,8 @@ const SHL_CODE = $1A const SHR_CODE = $1C const INDEXW_CODE = $1E const LOGIC_NOT_CODE = $20 -const LOGIC_OR_CODE = $22 -const LOGIC_AND_CODE = $24 +//const LOGIC_OR_CODE = $22 +//const LOGIC_AND_CODE = $24 const DROP_CODE = $30 const DROP2_CODE = $32 const DUP_CODE = $34 @@ -79,6 +79,8 @@ const RELATIVE_GROUP = $05 const BRFALSE_CODE = $4C const BRTRUE_CODE = $4E const BRNCH_CODE = $50 +const BRAND_CODE = $8C +const BROR_CODE = $8E // // Code tag address group // diff --git a/src/toolsrc/parse.c b/src/toolsrc/parse.c index b315209..edd75c8 100755 --- a/src/toolsrc/parse.c +++ b/src/toolsrc/parse.c @@ -25,8 +25,8 @@ t_token binary_ops_table[] = { OR_TOKEN, GT_TOKEN, GE_TOKEN, LT_TOKEN, LE_TOKEN, EQ_TOKEN, NE_TOKEN, - LOGIC_AND_TOKEN, - LOGIC_OR_TOKEN +// LOGIC_AND_TOKEN, +// LOGIC_OR_TOKEN /* Lowest precedence */ }; t_token binary_ops_precedence[] = { @@ -39,8 +39,8 @@ t_token binary_ops_precedence[] = { 6, 7, 7, 7, 7, 8, 8, - 9, - 10 +// 9, +// 10 /* Lowest precedence */ }; @@ -730,14 +730,48 @@ t_opseq *parse_expr(t_opseq *codeseq, int *stackdepth) if (stackdepth) (*stackdepth)--; } - /* - * Look for ternary operator - */ - if (scantoken == TERNARY_TOKEN) + if (scantoken == LOGIC_AND_TOKEN) + { + int tag_and; + int stackdepth1; + + /* + * Short-circuit AND + */ + if (*stackdepth != 1) + parse_error("AND must evaluate to single value"); + tag_and = tag_new(BRANCH_TYPE); + codeseq = gen_brand(codeseq, tag_and); + codeseq = parse_expr(codeseq, &stackdepth1); + if (stackdepth1 != *stackdepth) + parse_error("Inconsistent AND value counts"); + codeseq = gen_codetag(codeseq, tag_and); + } + else if (scantoken == LOGIC_OR_TOKEN) + { + int tag_or; + int stackdepth1; + + /* + * Short-circuit OR + */ + if (*stackdepth != 1) + parse_error("OR must evaluate to single value"); + tag_or = tag_new(BRANCH_TYPE); + codeseq = gen_bror(codeseq, tag_or); + codeseq = parse_expr(codeseq, &stackdepth1); + if (stackdepth1 != *stackdepth) + parse_error("Inconsistent AND value counts"); + codeseq = gen_codetag(codeseq, tag_or); + } + else if (scantoken == TERNARY_TOKEN) { int tag_else, tag_endtri; int stackdepth1; + /* + * Look for ternary operator + */ if (*stackdepth != 1) parse_error("Ternary op must evaluate to single value"); tag_else = tag_new(BRANCH_TYPE); diff --git a/src/toolsrc/parse.pla b/src/toolsrc/parse.pla index 9c759f7..eadc9d9 100644 --- a/src/toolsrc/parse.pla +++ b/src/toolsrc/parse.pla @@ -494,7 +494,7 @@ end def parse_expr(codeseq)#2 byte stackdepth, matchdepth, stkdepth1, prevmatch, matchop, i word optos - word tag_else, tag_endtri + word tag_else, tag_endop stackdepth = 0 matchop = 0 @@ -524,21 +524,32 @@ def parse_expr(codeseq)#2 codeseq = gen_bop(codeseq, pop_op) stackdepth-- loop - // - // Look for ternary operator - // - if token == TERNARY_TKN + if token == LOGIC_AND_TKN + if stackdepth <> 1; exit_err(ERR_OVER|ERR_SYNTAX); fin + tag_endop = new_tag(RELATIVE_FIXUP) + codeseq = gen_oprel(codeseq, BRAND_CODE, tag_endop) + codeseq, stkdepth1 = parse_expr(codeseq) + if stkdepth1 <> stackdepth; exit_err(ERR_INVAL|ERR_CODE); fin + codeseq = gen_ctag(codeseq, tag_endop) + elsif token == LOGIC_OR_TKN + if stackdepth <> 1; exit_err(ERR_OVER|ERR_SYNTAX); fin + tag_endop = new_tag(RELATIVE_FIXUP) + codeseq = gen_oprel(codeseq, BROR_CODE, tag_endop) + codeseq, stkdepth1 = parse_expr(codeseq) + if stkdepth1 <> stackdepth; exit_err(ERR_INVAL|ERR_CODE); fin + codeseq = gen_ctag(codeseq, tag_endop) + elsif token == TERNARY_TKN if stackdepth <> 1; exit_err(ERR_OVER|ERR_SYNTAX); fin tag_else = new_tag(RELATIVE_FIXUP) - tag_endtri = new_tag(RELATIVE_FIXUP) + tag_endop = new_tag(RELATIVE_FIXUP) codeseq = gen_oprel(codeseq, BRFALSE_CODE, tag_else) codeseq, stkdepth1 = parse_expr(codeseq) if token <> TRIELSE_TKN; exit_err(ERR_MISS|ERR_SYNTAX); fin - codeseq = gen_oprel(codeseq, BRNCH_CODE, tag_endtri) + codeseq = gen_oprel(codeseq, BRNCH_CODE, tag_endop) codeseq = gen_ctag(codeseq, tag_else) codeseq, stackdepth = parse_expr(codeseq) if stkdepth1 <> stackdepth; exit_err(ERR_INVAL|ERR_CODE); fin - codeseq = gen_ctag(codeseq, tag_endtri) + codeseq = gen_ctag(codeseq, tag_endop) fin return codeseq, stackdepth end diff --git a/src/toolsrc/plasm.pla b/src/toolsrc/plasm.pla index fdb5aa2..7c6cf82 100644 --- a/src/toolsrc/plasm.pla +++ b/src/toolsrc/plasm.pla @@ -194,8 +194,8 @@ byte = EOR_TKN byte = OR_TKN byte = GT_TKN, GE_TKN, LT_TKN, LE_TKN byte = EQ_TKN, NE_TKN -byte = LOGIC_AND_TKN -byte = LOGIC_OR_TKN +//byte = LOGIC_AND_TKN +//byte = LOGIC_OR_TKN // Lowest precedence byte[] bops_prec // Highest precedence byte = 1, 1, 1 @@ -206,8 +206,8 @@ byte = 5 byte = 6 byte = 7, 7, 7, 7 byte = 8, 8 -byte = 9 -byte = 10 +//byte = 9 +//byte = 10 // Lowest precedence byte[16] opstack byte[16] precstack diff --git a/src/vmsrc/apple/plvm02.s b/src/vmsrc/apple/plvm02.s index b9f7d5a..54f7880 100755 --- a/src/vmsrc/apple/plvm02.s +++ b/src/vmsrc/apple/plvm02.s @@ -195,15 +195,15 @@ VMCORE = * !ALIGN 255,0 ;OPTBL !WORD CONST,CONST,CONST,CONST,CONST,CONST,CONST,CONST ; 00 02 04 06 08 0A 0C 0E ; !WORD CONST,CONST,CONST,CONST,CONST,CONST,CONST,CONST ; 10 12 14 16 18 1A 1C 1E -OPTBL !WORD ZERO,ADD,SUB,MUL,DIV,MOD,INCR,DECR ; 00 02 04 06 08 0A 0C 0E - !WORD NEG,COMP,BAND,IOR,XOR,SHL,SHR,IDXW ; 10 12 14 16 18 1A 1C 1E - !WORD LNOT,LOR,LAND,LA,LLA,CB,CW,CS ; 20 22 24 26 28 2A 2C 2E - !WORD DROP,DROP2,DUP,DIVMOD,ADDI,SUBI,ANDI,ORI ; 30 32 34 36 38 3A 3C 3E - !WORD ISEQ,ISNE,ISGT,ISLT,ISGE,ISLE,BRFLS,BRTRU ; 40 42 44 46 48 4A 4C 4E - !WORD BRNCH,SEL,CALL,ICAL,ENTER,LEAVE,RET,CFFB ; 50 52 54 56 58 5A 5C 5E - !WORD LB,LW,LLB,LLW,LAB,LAW,DLB,DLW ; 60 62 64 66 68 6A 6C 6E - !WORD SB,SW,SLB,SLW,SAB,SAW,DAB,DAW ; 70 72 74 76 78 7A 7C 7E - !WORD BRGT,BRLT,INCBRLE,ADDBRLE,DECBRGE,SUBBRGE ; 80 82 84 86 88 8A 8C 8E +OPTBL !WORD ZERO,ADD,SUB,MUL,DIV,MOD,INCR,DECR ; 00 02 04 06 08 0A 0C 0E + !WORD NEG,COMP,BAND,IOR,XOR,SHL,SHR,IDXW ; 10 12 14 16 18 1A 1C 1E + !WORD LNOT,LOR,LAND,LA,LLA,CB,CW,CS ; 20 22 24 26 28 2A 2C 2E + !WORD DROP,DROP2,DUP,DIVMOD,ADDI,SUBI,ANDI,ORI ; 30 32 34 36 38 3A 3C 3E + !WORD ISEQ,ISNE,ISGT,ISLT,ISGE,ISLE,BRFLS,BRTRU ; 40 42 44 46 48 4A 4C 4E + !WORD BRNCH,SEL,CALL,ICAL,ENTER,LEAVE,RET,CFFB ; 50 52 54 56 58 5A 5C 5E + !WORD LB,LW,LLB,LLW,LAB,LAW,DLB,DLW ; 60 62 64 66 68 6A 6C 6E + !WORD SB,SW,SLB,SLW,SAB,SAW,DAB,DAW ; 70 72 74 76 78 7A 7C 7E + !WORD BRGT,BRLT,INCBRLE,ADDBRLE,DECBRGE,SUBBRGE,BRAND,BROR ; 80 82 84 86 88 8A 8C 8E ;* ;* ;* ENTER INTO BYTECODE INTERPRETER @@ -406,15 +406,15 @@ LCDEFCMD = *-28 ; DEFCMD IN LC MEMORY !ALIGN 255,0 ;OPXTBL !WORD CONST,CONST,CONST,CONST,CONST,CONST,CONST,CONST ; 00 02 04 06 08 0A 0C 0E ; !WORD CONST,CONST,CONST,CONST,CONST,CONST,CONST,CONST ; 10 12 14 16 18 1A 1C 1E -OPXTBL !WORD ZERO,ADD,SUB,MUL,DIV,MOD,INCR,DECR ; 00 02 04 06 08 0A 0C 0E - !WORD NEG,COMP,BAND,IOR,XOR,SHL,SHR,IDXW ; 10 12 14 16 18 1A 1C 1E - !WORD LNOT,LOR,LAND,LA,LLA,CB,CW,CSX ; 20 22 24 26 28 2A 2C 2E - !WORD DROP,DROP2,DUP,DIVMOD,ADDI,SUBI,ANDI,ORI ; 30 32 34 36 38 3A 3C 3E - !WORD ISEQ,ISNE,ISGT,ISLT,ISGE,ISLE,BRFLS,BRTRU ; 40 42 44 46 48 4A 4C 4E - !WORD BRNCH,SEL,CALLX,ICALX,ENTER,LEAVEX,RETX,CFFB ; 50 52 54 56 58 5A 5C 5E - !WORD LBX,LWX,LLBX,LLWX,LABX,LAWX,DLB,DLW ; 60 62 64 66 68 6A 6C 6E - !WORD SB,SW,SLB,SLW,SAB,SAW,DAB,DAW ; 70 72 74 76 78 7A 7C 7E - !WORD BRGT,BRLT,INCBRLE,ADDBRLE,DECBRGE,SUBBRGE ; 80 82 84 86 88 8A 8C 8E +OPXTBL !WORD ZERO,ADD,SUB,MUL,DIV,MOD,INCR,DECR ; 00 02 04 06 08 0A 0C 0E + !WORD NEG,COMP,BAND,IOR,XOR,SHL,SHR,IDXW ; 10 12 14 16 18 1A 1C 1E + !WORD LNOT,LOR,LAND,LA,LLA,CB,CW,CSX ; 20 22 24 26 28 2A 2C 2E + !WORD DROP,DROP2,DUP,DIVMOD,ADDI,SUBI,ANDI,ORI ; 30 32 34 36 38 3A 3C 3E + !WORD ISEQ,ISNE,ISGT,ISLT,ISGE,ISLE,BRFLS,BRTRU ; 40 42 44 46 48 4A 4C 4E + !WORD BRNCH,SEL,CALLX,ICALX,ENTER,LEAVEX,RETX,CFFB ; 50 52 54 56 58 5A 5C 5E + !WORD LBX,LWX,LLBX,LLWX,LABX,LAWX,DLB,DLW ; 60 62 64 66 68 6A 6C 6E + !WORD SB,SW,SLB,SLW,SAB,SAW,DAB,DAW ; 70 72 74 76 78 7A 7C 7E + !WORD BRGT,BRLT,INCBRLE,ADDBRLE,DECBRGE,SUBBRGE,BRAND,BROR ; 80 82 84 86 88 8A 8C 8E ;* ;* ADD TOS TO TOS-1 ;* @@ -1362,22 +1362,16 @@ FIXNEXT TYA BCC ++ INC IPH ++ JMP NEXTOP -;BREQ INX -; LDA ESTKL-1,X -; CMP ESTKL,X -; BNE NOBRNCH -; LDA ESTKH-1,X -; CMP ESTKH,X -; BEQ BRNCH -; BNE NOBRNCH -;BRNE INX -; LDA ESTKL-1,X -; CMP ESTKL,X -; BNE BRNCH -; LDA ESTKH-1,X -; CMP ESTKH,X -; BEQ NOBRNCH -; BNE BRNCH +BRAND LDA ESTKL,X + ORA ESTKH,X + BEQ BRNCH + INX ; DROP LEFT HALF OF AND + BNE NOBRNCH +BROR LDA ESTKL,X + ORA ESTKH,X + BNE BRNCH + INX ; DROP LEFT HALF OF OR + BNE NOBRNCH BRTRU INX LDA ESTKH-1,X ORA ESTKL-1,X diff --git a/src/vmsrc/plvm.c b/src/vmsrc/plvm.c index ada061d..3beff8a 100755 --- a/src/vmsrc/plvm.c +++ b/src/vmsrc/plvm.c @@ -517,15 +517,15 @@ void call(uword pc) /* * OPCODE TABLE * -OPTBL: DW ZERO,ADD,SUB,MUL,DIV,MOD,INCR,DECR ; 00 02 04 06 08 0A 0C 0E - DW NEG,COMP,AND,IOR,XOR,SHL,SHR,IDXW ; 10 12 14 16 18 1A 1C 1E - DW NOT,LOR,LAND,LA,LLA,CB,CW,CS ; 20 22 24 26 28 2A 2C 2E - DW DROP,DROP2,DUP,DIVMOD,ADDI,SUBI,ANDI,ORI ; 30 32 34 36 38 3A 3C 3E - DW ISEQ,ISNE,ISGT,ISLT,ISGE,ISLE,BRFLS,BRTRU ; 40 42 44 46 48 4A 4C 4E - DW BRNCH,SEL,CALL,ICAL,ENTER,LEAVE,RET,CFFB ; 50 52 54 56 58 5A 5C 5E - DW LB,LW,LLB,LLW,LAB,LAW,DLB,DLW ; 60 62 64 66 68 6A 6C 6E - DW SB,SW,SLB,SLW,SAB,SAW,DAB,DAW ; 70 72 74 76 78 7A 7C 7E - DW ADDBRLE,INCBRLE,SUBBRGE,DECBRGE,BRGT,BRLT ; 80 82 84 86 88 8A 8C 8E +OPTBL: DW ZERO,ADD,SUB,MUL,DIV,MOD,INCR,DECR ; 00 02 04 06 08 0A 0C 0E + DW NEG,COMP,AND,IOR,XOR,SHL,SHR,IDXW ; 10 12 14 16 18 1A 1C 1E + DW NOT,LOR,LAND,LA,LLA,CB,CW,CS ; 20 22 24 26 28 2A 2C 2E + DW DROP,DROP2,DUP,DIVMOD,ADDI,SUBI,ANDI,ORI ; 30 32 34 36 38 3A 3C 3E + DW ISEQ,ISNE,ISGT,ISLT,ISGE,ISLE,BRFLS,BRTRU ; 40 42 44 46 48 4A 4C 4E + DW BRNCH,SEL,CALL,ICAL,ENTER,LEAVE,RET,CFFB ; 50 52 54 56 58 5A 5C 5E + DW LB,LW,LLB,LLW,LAB,LAW,DLB,DLW ; 60 62 64 66 68 6A 6C 6E + DW SB,SW,SLB,SLW,SAB,SAW,DAB,DAW ; 70 72 74 76 78 7A 7C 7E + DW ADDBRLE,INCBRLE,SUBBRGE,DECBRGE,BRGT,BRLT ; 80 82 84 86 88 8A 8C 8E DW BRGT,BRLT,INCBRLE,ADDBRLE,DECBRGE,SUBBRGE ; 80 82 84 86 88 8A 8C 8E */ void interp(code *ip) @@ -973,6 +973,28 @@ void interp(code *ip) ip += 2; } break; + case 0x8C: // BRAND : SHORT CIRCUIT AND + if (TOS) // EVALUATE RIGHT HAND OF AND + { + POP; + ip += 2; + } + else // MUST BE FALSE, SKIP RIGHT HAND + { + ip += WORD_PTR(ip); + } + break; + case 0x8E: // BROR : SHORT CIRCUIT OR + if (!TOS) // EVALUATE RIGHT HAND OF OR + { + POP; + ip += 2; + } + else // MUST BE TRUE, SKIP RIGHT HAND + { + ip += WORD_PTR(ip); + } + break; /* * Odd codes and everything else are errors. */