1
0
mirror of https://github.com/dschmenk/PLASMA.git synced 2025-03-27 18:35:06 +00:00

SWITCH/CASE table optimization

This commit is contained in:
David Schmenk 2018-03-04 21:36:23 -08:00
parent e1090c012c
commit 3ee19e86f6
7 changed files with 170 additions and 58 deletions

View File

@ -194,15 +194,15 @@ export def fight(player, enemy)
if enemy=>prev_other
enemy=>prev_other=>next_other = enemy=>next_other
fin
if player->health > e_atck
player->health = player->health - e_atck
else
player->energy = 0
player->health = 0
fin
if player->energy >= 4
player->energy = player->energy - 4
fin
fin
if player->health > e_atck
player->health = player->health - e_atck
else
player->energy = 0
player->health = 0
fin
if player->energy >= 4
player->energy = player->energy - 4
fin
until player->health == 0 or enemy->life == 0
conio:echo(ECHO_OFF)

View File

@ -773,6 +773,23 @@ void emit_indexword(void)
{
printf("\t%s\t$1E\t\t\t; IDXW\n", DB);
}
void emit_select(int tag)
{
emit_pending_seq();
printf("\t%s\t$52\t\t\t; SEL\n", DB);
printf("\t%s\t_B%03d-*\n", DW, tag);
}
void emit_caseblock(int casecnt, int *caseof, int *casetag)
{
int i;
printf("\t%s\t$%02lX\t\t\t; CASEBLOCK\n", DB, casecnt & 0xFF);
for (i = 0; i < casecnt; i++)
{
printf("\t%s\t$%04lX\n", DW, caseof[i] & 0xFFFF);
printf("\t%s\t_B%03d-*\n", DW, casetag[i]);
}
}
void emit_brfls(int tag)
{
printf("\t%s\t$4C\t\t\t; BRFLS\t_B%03d\n", DB, tag);

View File

@ -134,6 +134,8 @@ void emit_indexbyte(void);
void emit_indexword(void);
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_brtru(int tag);
void emit_brfls(int tag);
void emit_brne(int tag);

View File

@ -1,5 +1,6 @@
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "plasm.h"
#define LVALUE 0
#define RVALUE 1
@ -798,7 +799,9 @@ t_opseq *parse_set(t_opseq *codeseq)
int parse_stmnt(void)
{
int tag_prevbrk, tag_prevcnt, tag_else, tag_endif, tag_while, tag_wend, tag_repeat, tag_for, tag_choice, tag_of;
int type, addr, step, cfnvals, prev_for;
int type, addr, step, cfnvals, prev_for, constsize, casecnt;
int *caseval, *casetag;
long constval;
char *idptr;
t_opseq *seq, *fromseq, *toseq;
@ -913,9 +916,9 @@ int parse_stmnt(void)
infor = prev_for;
break;
case FOR_TOKEN:
stack_loop += 2;
prev_for = infor;
infor = 1;
stack_loop += 2;
tag_prevbrk = break_tag;
break_tag = tag_new(BRANCH_TYPE);
tag_for = tag_new(BRANCH_TYPE);
@ -996,17 +999,19 @@ int parse_stmnt(void)
}
emit_codetag(break_tag);
break_tag = tag_prevbrk;
stack_loop -= 2;
infor = prev_for;
stack_loop -= 2;
break;
case CASE_TOKEN:
prev_for = infor;
infor = 0;
stack_loop++;
tag_prevbrk = break_tag;
break_tag = tag_new(BRANCH_TYPE);
tag_choice = tag_new(BRANCH_TYPE);
tag_of = tag_new(BRANCH_TYPE);
caseval = malloc(sizeof(int)*256);
casetag = malloc(sizeof(int)*256);
casecnt = 0;
//stack_loop++;
if (!(seq = parse_expr(NULL, &cfnvals)))
parse_error("Bad CASE expression");
if (cfnvals > 1)
@ -1015,33 +1020,53 @@ int parse_stmnt(void)
while (cfnvals-- > 1) seq = gen_drop(seq);
}
emit_seq(seq);
emit_select(tag_choice);
next_line();
while (scantoken != ENDCASE_TOKEN)
{
if (scantoken == OF_TOKEN)
{
if (!(seq = parse_expr(NULL, &cfnvals)))
parse_error("Bad CASE OF expression");
if (cfnvals > 1)
{
parse_warn("Expression value overflow");
while (cfnvals-- > 1) seq = gen_drop(seq);
}
emit_seq(seq);
emit_brne(tag_choice);
constval = 0;
parse_constexpr(&constval, &constsize);
//if (!(seq = parse_expr(NULL, &cfnvals)))
// parse_error("Bad CASE OF expression");
//if (cfnvals > 1)
//{
// parse_warn("Expression value overflow");
// while (cfnvals-- > 1) seq = gen_drop(seq);
//}
//emit_seq(seq);
//emit_brne(tag_choice);
//tag_choice = tag_new(BRANCH_TYPE);
tag_of = tag_new(BRANCH_TYPE);
caseval[casecnt] = constval;
casetag[casecnt] = tag_of;
casecnt++;
if (casecnt > 255)
parse_error("CASE clause overflow");
emit_codetag(tag_of);
while (parse_stmnt()) next_line();
tag_of = tag_new(BRANCH_TYPE);
if (prevstmnt != BREAK_TOKEN) // Fall through to next OF if no break
emit_brnch(tag_of);
emit_codetag(tag_choice);
tag_choice = tag_new(BRANCH_TYPE);
//tag_of = tag_new(BRANCH_TYPE);
//if (prevstmnt != BREAK_TOKEN) // Fall through to next OF if no break
// emit_brnch(tag_of);
//emit_codetag(tag_choice);
//tag_choice = tag_new(BRANCH_TYPE);
}
else if (scantoken == DEFAULT_TOKEN)
{
emit_codetag(tag_of);
tag_of = 0;
if (prevstmnt != BREAK_TOKEN) // Fall through to next OF if no break
{
tag_of = tag_new(BRANCH_TYPE);
emit_brnch(tag_of);
}
else
tag_of = 0;
emit_codetag(tag_choice);
emit_caseblock(casecnt, caseval, casetag);
tag_choice = 0;
scan();
if (tag_of)
emit_codetag(tag_of);
while (parse_stmnt()) next_line();
if (scantoken != ENDCASE_TOKEN)
parse_error("Bad CASE DEFAULT clause");
@ -1051,13 +1076,21 @@ int parse_stmnt(void)
else
parse_error("Bad CASE clause");
}
if (tag_of)
emit_codetag(tag_of);
if (tag_choice)
{
emit_brnch(break_tag);
emit_codetag(tag_choice);
emit_caseblock(casecnt, caseval, casetag);
}
free(caseval);
free(casetag);
//if (tag_of)
// emit_codetag(tag_of);
emit_codetag(break_tag);
emit_drop();
//emit_drop();
//stack_loop--;
break_tag = tag_prevbrk;
stack_loop--;
infor = prev_for;
infor = prev_for;
break;
case BREAK_TOKEN:
if (break_tag)
@ -1079,7 +1112,14 @@ int parse_stmnt(void)
if (infunc)
{
int i;
for (i = 0; i < stack_loop; i++)
i = stack_loop;
while (i >= 2)
{
emit_drop2();
i -= 2;
}
if (i)
emit_drop();
cfnvals = 0;
emit_seq(parse_list(NULL, &cfnvals));

View File

@ -858,9 +858,14 @@ def parse_stmnt
break
is RETURN_TKN
if infunc
for i = 1 to stack_loop
i = stack_loop
while i >= 2
emit_code(DROP2_CODE)
i = i - 2
loop
if i
emit_code(DROP_CODE)
next
fin
seq, cfnvals = parse_list
emit_seq(seq)
if cfnvals > infuncvals

View File

@ -200,7 +200,7 @@ OPTBL !WORD ZERO,ADD,SUB,MUL,DIV,MOD,INCR,DECR ; 00 02 04 06 08
!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,BRNE,CALL,ICAL,ENTER,LEAVE,RET,CFFB ; 50 52 54 56 58 5A 5C 5E
!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
@ -411,7 +411,7 @@ OPXTBL !WORD ZERO,ADD,SUB,MUL,DIV,MOD,INCR,DECR ; 00 02 04 06 08
!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,BRNE,CALLX,ICALX,ENTER,LEAVEX,RETX,CFFB ; 50 52 54 56 58 5A 5C 5E
!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
@ -1309,6 +1309,50 @@ ISLT LDA ESTKL+1,X
;*
;* BRANCHES
;*
SEL INX
TYA ; FLATTEN IP
SEC
ADC IPL
STA TMPL
LDA #$00
TAY
ADC IPH
STA TMPH ; ADD BRANCH OFFSET
LDA (TMP),Y
;CLC ; BETTER NOT CARRY OUT OF IP+Y
ADC TMPL
STA IPL
INY
LDA (TMP),Y
ADC TMPH
STA IPH
DEY
LDA (IP),Y
STA TMPL ; CASE COUNT
INC IPL
BNE +
INC IPH
+ LDA ESTKL-1,X
CASELP CMP (IP),Y
BNE +
LDA ESTKH-1,X
INY
CMP (IP),Y
BEQ BRNCH
LDA ESTKL-1,X
DEY
+ DEC TMPL
BEQ +
INY
INY
INY
INY
BNE CASELP
INC IPH
BNE CASELP
+ INY
INY
INY
FIXNEXT TYA
LDY #$00
CLC
@ -1325,14 +1369,14 @@ FIXNEXT TYA
; 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
;BRNE INX
; LDA ESTKL-1,X
; CMP ESTKL,X
; BNE BRNCH
; LDA ESTKH-1,X
; CMP ESTKH,X
; BEQ NOBRNCH
; BNE BRNCH
BRTRU INX
LDA ESTKH-1,X
ORA ESTKL-1,X

View File

@ -522,7 +522,7 @@ OPTBL: DW ZERO,ADD,SUB,MUL,DIV,MOD,INCR,DECR ; 00 02 04 06 08 0A 0C 0
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,BRNE,CALL,ICAL,ENTER,LEAVE,RET,CFFB ; 50 52 54 56 58 5A 5C 5E
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
@ -748,17 +748,21 @@ void interp(code *ip)
case 0x50: // BRNCH : IP += (IP)
ip += WORD_PTR(ip);
break;
case 0x52: // BRNE : TOS != TOS-1 ? IP += (IP)
case 0x52: // SELECT
val = POP;
if (TOS != val)
ip += WORD_PTR(ip);
parmcnt = BYTE_PTR(ip);
ip++;
while (parmcnt--)
{
PUSH(val);
ip += WORD_PTR(ip);
}
else
{
PUSH(val);
ip += 2;
if (WORD_PTR(ip) == val)
{
ip += 2;
ip += WORD_PTR(ip);
parmcnt = 0;
}
else
ip += 4;
}
break;
case 0x54: // CALL : TOFP = IP, IP = (IP) ; call