1
0
mirror of https://github.com/dschmenk/PLASMA.git synced 2025-03-17 14:29:28 +00:00

Short circuit AND/OR

This commit is contained in:
David Schmenk 2018-03-05 10:55:19 -08:00
parent 6de120ec89
commit eff01c5f12
10 changed files with 190 additions and 99 deletions

View File

@ -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;

View File

@ -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);

View File

@ -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

View File

@ -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

View File

@ -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
//

View File

@ -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);

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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.
*/