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:
parent
e1090c012c
commit
3ee19e86f6
@ -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)
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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));
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user