Skip to content

Commit 278727b

Browse files
committed
Implement absolute address for DATA statements.
This increases the parser size but is faster at run time, and allows the cross compiler to optimize datas away from code, making compiled code smaller.
1 parent aa0a680 commit 278727b

10 files changed

Lines changed: 118 additions & 86 deletions

File tree

src/actions.asm

Lines changed: 49 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -22,25 +22,25 @@
2222
.export E_REM, E_EOL, E_NUMBER_WORD, E_NUMBER_BYTE
2323
.export E_PUSH_LT, E_POP_LOOP, E_POP_REPEAT
2424
.export E_POP_IF, E_ELSEIF, E_EXIT_LOOP
25-
.export E_POP_WHILE, E_POP_FOR, E_POP_PROC_1, E_POP_PROC_2, E_POP_DATA
25+
.export E_POP_WHILE, E_POP_FOR, E_POP_PROC_DATA, E_POP_PROC_2
2626
.export E_CONST_STRING
2727
.export E_VAR_CREATE, E_VAR_WORD, E_VAR_SEARCH
28-
.export E_VAR_SET_TYPE
28+
.export E_VAR_SET_TYPE, E_LABEL_SET_TYPE
2929
.export E_LABEL, E_LABEL_DEF
3030
.export E_PUSH_VAR, E_POP_VAR
31-
.exportzp VT_WORD, VT_STRING, VT_FLOAT
31+
.exportzp VT_WORD, VT_STRING, VT_FLOAT, VT_UNDEF
3232
.exportzp VT_ARRAY_WORD, VT_ARRAY_BYTE, VT_ARRAY_STRING, VT_ARRAY_FLOAT
33-
.exportzp LT_PROC_1, LT_PROC_2, LT_DATA, LT_DO_LOOP, LT_REPEAT, LT_WHILE_1, LT_WHILE_2, LT_FOR_1, LT_FOR_2, LT_EXIT, LT_IF, LT_ELSE, LT_ELIF
33+
.exportzp LT_PROC_DATA, LT_PROC_2, LT_DO_LOOP, LT_REPEAT, LT_WHILE_1, LT_WHILE_2, LT_FOR_1, LT_FOR_2, LT_EXIT, LT_IF, LT_ELSE, LT_ELIF
3434
.importzp loop_sp, bpos, bptr, tmp1, tmp2, tmp3, opos
3535
; From runtime.asm
3636
.import read_word
3737
; From vars.asm
3838
.import var_search, name_new
39-
.import label_search
39+
.import list_search
4040
.importzp var_namelen, label_count, var_count
4141
; From alloc.asm
4242
.import alloc_laddr
43-
.importzp prog_ptr, laddr_ptr, laddr_buf, var_ptr, label_ptr
43+
.importzp prog_ptr, laddr_ptr, laddr_buf, var_ptr, label_ptr, label_buf
4444
; From parser.asm
4545
.import parser_error, parser_skipws, parser_emit_byte, parser_inc_opos
4646
; From error.asm
@@ -87,8 +87,7 @@ read_fp = AFP
8787
; ; EXIT? PUSH?
8888
; ; bit-7 bit-6
8989
LT_EXIT ; error yes
90-
LT_PROC_1 ; error yes
91-
LT_DATA ; error yes
90+
LT_PROC_DATA ; error yes
9291
LT_FOR_2 ; yes yes
9392
LT_LAST_JUMP = 63
9493
LT_PROC_2 ; yes no
@@ -402,13 +401,16 @@ no_float:
402401
xit: rts
403402
.endproc
404403

405-
; Support for labels (PROC/EXEC)
404+
; Support for labels (DATA/PROC/EXEC)
406405
; ------------------------------
407406
;
408407
; We keep two lists:
409408
; - label_buf/ptr: a list of all the labels, sorted by the label number.
410409
; one byte for each character in the name, last byte with
411410
; bit 7 set.
411+
; After the name there is one byte with the label type,
412+
; same as var-types.
413+
;
412414
; - laddr_buf/ptr: a list with each label reference:
413415
; byte 0: the label number,
414416
; byte 1: the type of reference,
@@ -433,14 +435,15 @@ xit: rts
433435
;
434436
; Label definition search/create
435437
.proc E_LABEL_DEF
438+
lda #0 ; Type of label: undefined
436439
jsr label_create
437440

438441
; Fills all undefined labels with current position:
439442
bcs nfound
440443

441444
; If we found a *definition* for the label, error out (label already
442445
; defined).
443-
cloop: bmi error
446+
cloop: bmi xit_label_err
444447

445448
; Write current codep to AX
446449
jsr patch_codep
@@ -460,25 +463,52 @@ nfound:
460463
jsr add_laddr_list
461464
; Ok, advance parsing pointer with the label length
462465
bcc advance_varn
463-
464-
error: sec
465466
rts
466467
.endproc
467468

469+
; Sets the type of the last label defined
470+
.proc E_LABEL_SET_TYPE
471+
jsr get_last_tok ; Get variable TYPE from last token
472+
473+
ldy #$FF
474+
dec label_ptr+1
475+
sta (label_ptr), y ; Store to (label_ptr - 1)
476+
inc label_ptr+1
477+
clc
478+
xit: rts
479+
.endproc
480+
468481
; Create a label if not exists and starts searching in the label
469482
; address list.
470483
;
471484
; This jumps to next_laddr, so it returns the same values.
472485
.proc label_create
473486
; Check if we have a valid name - this exits on error!
474-
jsr label_search
475-
bcc xit
487+
sta tmp3 ; Store label type
488+
ldx #label_buf - prog_ptr
489+
ldy label_count
490+
jsr list_search
491+
bcs do_create
492+
; Check if type is compatible
493+
cmp tmp3
494+
beq no_create ; Yes, search address
495+
xit_pop_2: ; Exit from caller with error
496+
pla
497+
pla
498+
::xit_label_err:
499+
sec
500+
rts
501+
502+
do_create:
503+
; See if we need to create it
504+
lda tmp3
505+
bne xit_pop_2
476506
; Create a new label
477507
ldx #label_ptr - prog_ptr
478508
jsr name_new
479509
ldx label_count
480510
inc label_count
481-
xit:
511+
no_create:
482512
lda laddr_buf
483513
ldy laddr_buf+1
484514
sty tmp1+1
@@ -560,6 +590,7 @@ xit: rts
560590

561591
; Label search / create (on use)
562592
.proc E_LABEL
593+
jsr get_last_tok ; Get label TYPE from last token
563594
jsr label_create
564595
; Emits a label, searching the label address in the label list
565596
bcs nfound
@@ -691,7 +722,7 @@ retry: dey
691722
bmi loop_error
692723
lda loop_stk, y
693724
bmi retry ; FOR(2)/WHILE(2)/IF/ELSE/ELIF are > 127
694-
cmp #LT_DATA+1 ; PROC(1)/DATA
725+
cmp #LT_PROC_DATA+1 ; PROC(1)/DATA
695726
bcc loop_error
696727
ok:
697728
; Store slot
@@ -788,14 +819,9 @@ no_elif:
788819
rts
789820
.endproc
790821

791-
.proc E_POP_DATA
792-
; Pop saved position, store
793-
lda #LT_DATA
794-
.byte $2C ; Skip 2 bytes over next "LDA"
795-
.endproc ; Fall through
796-
.proc E_POP_PROC_1
822+
.proc E_POP_PROC_DATA
797823
; Pop saved "jump to end" position
798-
lda #LT_PROC_1
824+
lda #LT_PROC_DATA
799825
.endproc ; Fall through
800826

801827
.proc pop_patch_codep

src/basic.syn

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -86,9 +86,9 @@ EXTERN {
8686
E_REM, E_NUMBER_WORD, E_NUMBER_BYTE, E_EOL
8787
E_PUSH_LT, E_POP_LOOP, E_POP_REPEAT
8888
E_POP_IF, E_ELSEIF, E_EXIT_LOOP
89-
E_POP_WHILE, E_POP_FOR, E_POP_PROC_1, E_POP_PROC_2, E_POP_DATA
89+
E_POP_WHILE, E_POP_FOR, E_POP_PROC_DATA, E_POP_PROC_2
9090
E_CONST_STRING
91-
E_VAR_CREATE, E_VAR_SET_TYPE
91+
E_VAR_CREATE, E_VAR_SET_TYPE, E_LABEL_SET_TYPE
9292
E_VAR_WORD, E_VAR_SEARCH
9393
E_LABEL, E_LABEL_DEF
9494
E_PUSH_VAR, E_POP_VAR
@@ -176,6 +176,8 @@ ADR_EXPR: string or variable
176176
STR_EXPR
177177
emit { TOK_VAR_LOAD, VT_ARRAY_WORD } E_VAR_SEARCH
178178
emit { TOK_VAR_LOAD, VT_ARRAY_BYTE } E_VAR_SEARCH
179+
emit { TOK_NUM, VT_ARRAY_WORD } E_LABEL
180+
emit { TOK_NUM, VT_ARRAY_BYTE } E_LABEL
179181
emit { TOK_VAR_LOAD, VT_ARRAY_STRING } E_VAR_SEARCH
180182
#@if FASTBASIC_FP
181183
emit { TOK_VAR_LOAD, VT_ARRAY_FLOAT } E_VAR_SEARCH "%"
@@ -388,9 +390,9 @@ VAR_CREATE_TYPE:
388390
# NOTE: the creation rule (E_VAR_SET_TYPE) always fails, so the parser uses the next
389391
# rules using the created variable.
390392
VAR_WORD_LVALUE_SADDR: integer variable
393+
ARRAY_WORD_ADDR emit TOK_SADDR
391394
E_VAR_CREATE VAR_CREATE_TYPE E_VAR_SET_TYPE
392395
emit TOK_VAR_SADDR E_VAR_WORD
393-
ARRAY_WORD_ADDR emit TOK_SADDR
394396

395397
VAR_STR_LVALUE_SADDR:
396398
emit { TOK_VAR_SADDR, VT_STRING } E_VAR_SEARCH "$"
@@ -441,6 +443,7 @@ SOUND_S1:
441443
# Word Arrays
442444
ARRAY_WORD_ADDR:
443445
emit { TOK_VAR_LOAD, VT_ARRAY_WORD } E_VAR_SEARCH emit TOK_PUSH PAR_EXPR emit { TOK_USHL, TOK_ADD }
446+
emit { TOK_NUM, VT_ARRAY_WORD } E_LABEL emit TOK_PUSH PAR_EXPR emit { TOK_USHL, TOK_ADD }
444447
445448
# String Arrays
446449
ARRAY_STRING_ADDR:
@@ -449,6 +452,7 @@ ARRAY_STRING_ADDR:
449452
# Byte Arrays
450453
ARRAY_BYTE_ADDR:
451454
emit { TOK_VAR_LOAD, VT_ARRAY_BYTE } E_VAR_SEARCH emit TOK_PUSH PAR_EXPR emit TOK_ADD
455+
emit { TOK_NUM, VT_ARRAY_BYTE } E_LABEL emit TOK_PUSH PAR_EXPR emit TOK_ADD
452456

453457
#@if FASTBASIC_FP
454458
# Float Arrays
@@ -559,16 +563,16 @@ DATA_BYTES: data byte
559563
DATA_TYPE: data type
560564
# Note: E_VAR_SET_TYPE skips white space, this allows spaces between
561565
# the data type and the "=".
562-
TYPE_BYTE E_VAR_SET_TYPE "=" E_NUMBER_BYTE DATA_BYTES
563-
TYPE_WORD E_VAR_SET_TYPE "=" E_NUMBER_WORD DATA_WORDS
566+
TYPE_BYTE EQUAL E_LABEL_SET_TYPE E_NUMBER_BYTE DATA_BYTES
567+
TYPE_WORD EQUAL E_LABEL_SET_TYPE E_NUMBER_WORD DATA_WORDS
564568

565569
DATA_END:
566570
","
567-
E_POP_DATA
571+
E_POP_PROC_DATA
568572

569-
DATA_VAR: new array name
570-
emit TOK_VAR_SADDR E_VAR_CREATE "()" emit { TOK_CDATA, LT_DATA } E_PUSH_LT
571-
pass
573+
DATA_VAR: new data array name
574+
DATA_TYPE
575+
emit { TOK_JUMP, LT_PROC_DATA } E_PUSH_LT E_LABEL_DEF "()" DATA_TYPE
572576

573577
# Parse a line
574578
PARSE_LINE_COMMAND:
@@ -619,10 +623,10 @@ PARSE_LINE_COMMAND:
619623
"PAuse" EXPR emit TOK_PAUSE
620624
"INC" VAR_WORD_LVALUE_SADDR emit TOK_INC
621625
"DEc" VAR_WORD_LVALUE_SADDR emit TOK_DEC
622-
"PROc" emit { TOK_JUMP, LT_PROC_1 } E_PUSH_LT E_LABEL_DEF emit LT_PROC_2 E_PUSH_LT
623-
"ENDProc" E_POP_PROC_2 emit TOK_RET E_POP_PROC_1
624-
"EXEc" emit TOK_CALL E_LABEL
625-
"DAta" DATA_VAR DATA_TYPE DATA_END
626+
"PROc" emit { TOK_JUMP, LT_PROC_DATA } E_PUSH_LT E_LABEL_DEF emit LT_PROC_2 E_PUSH_LT
627+
"ENDProc" E_POP_PROC_2 emit TOK_RET E_POP_PROC_DATA
628+
"EXEc" emit { TOK_CALL, VT_UNDEF } E_LABEL
629+
"DAta" DATA_VAR DATA_END
626630
"END" emit TOK_END
627631
#@if FASTBASIC_FP
628632
"DEG" emit { TOK_1, TOK_BYTE_POKE, DEGFLAG }

src/compiler/looptype.cc

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,10 @@ std::string get_loop_name(enum LoopType l)
2525
{
2626
switch( l )
2727
{
28-
case LT_PROC_1:
2928
case LT_PROC_2:
3029
return "PROC";
31-
case LT_DATA:
32-
return "DATA";
30+
case LT_PROC_DATA:
31+
return "PROC/DATA";
3332
case LT_EXIT:
3433
return "EXIT";
3534
case LT_DO_LOOP:
@@ -55,12 +54,10 @@ std::string get_loop_name(enum LoopType l)
5554

5655
LoopType get_looptype(std::string t)
5756
{
58-
if( t == "LT_PROC_1" )
59-
return LT_PROC_1;
57+
if( t == "LT_PROC_DATA" )
58+
return LT_PROC_DATA;
6059
if( t == "LT_PROC_2" )
6160
return LT_PROC_2;
62-
if( t == "LT_DATA" )
63-
return LT_DATA;
6461
if( t == "LT_DO_LOOP" )
6562
return LT_DO_LOOP;
6663
if( t == "LT_REPEAT" )

src/compiler/looptype.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,7 @@
2424

2525
enum LoopType {
2626
// First entries can't use "EXIT"
27-
LT_PROC_1 = 0,
28-
LT_DATA,
27+
LT_PROC_DATA = 0,
2928
LT_EXIT,
3029
// From here, loops don't push jump destinations
3130
LT_LAST_JUMP = 32,

src/compiler/main.cc

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ int main(int argc, char **argv)
168168
break;
169169
ln++;
170170
if( do_debug )
171-
std::cerr << iname << ": parsing line " << ln << "\n";
171+
std::cout << iname << ": parsing line " << ln << "\n";
172172
s.new_line(line, ln);
173173
while( s.pos != line.length() )
174174
{
@@ -204,8 +204,8 @@ int main(int argc, char **argv)
204204
}
205205
if( do_debug )
206206
{
207-
std::cerr << "parse end:\n";
208-
std::cerr << "MAX LEVEL: " << s.maxlvl << "\n";
207+
std::cout << "parse end:\n";
208+
std::cout << "MAX LEVEL: " << s.maxlvl << "\n";
209209
}
210210
// Check unclosed loops
211211
auto loop_error = s.check_loops();

0 commit comments

Comments
 (0)