Skip to content

Commit a89cb15

Browse files
committed
Implement support for multiple PROC parameters.
Parameters are pushed to the stack in the EXEC and popped in the PROC start in the oposite order. Implement a stack for storing the parameter variables, needed to reorder parameters.
1 parent 12e6591 commit a89cb15

File tree

8 files changed

+49
-37
lines changed

8 files changed

+49
-37
lines changed

src/actions.asm

+11-7
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
.exportzp VT_WORD, VT_STRING, VT_FLOAT, VT_UNDEF
3232
.exportzp VT_ARRAY_WORD, VT_ARRAY_BYTE, VT_ARRAY_STRING, VT_ARRAY_FLOAT
3333
.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
34-
.importzp loop_sp, bpos, bptr, tmp1, tmp2, tmp3, opos
34+
.importzp var_sp, loop_sp, bpos, bptr, tmp1, tmp2, tmp3, opos
3535
.exportzp reloc_addr
3636
; From runtime.asm
3737
.import read_word
@@ -104,9 +104,9 @@ read_fp = AFP
104104

105105
;----------------------------------------------------------
106106
; Use cassette buffer for loop stack, max 128 bytes
107-
; Note that at $480 we store the interpreter stack.
108107
loop_stk = $400
109-
108+
; And at $480 store the "variable" stack, used procedure parameters
109+
var_stk = $480
110110

111111
;----------------------------------------------------------
112112
.zeropage
@@ -627,27 +627,31 @@ do_create:
627627
ldx label_count
628628
inc label_count
629629
set_var:
630-
stx E_POP_VAR+1
630+
stx E_DO_EXEC+1
631631
clc
632632
rts
633633
.endproc
634634

635635
.proc E_DO_EXEC
636-
ldx E_POP_VAR+1
636+
ldx #0
637637
jsr label_create::no_create
638638
jmp E_LABEL::cloop
639639
.endproc
640640

641641
; PUSH/POP variables
642642
.proc E_PUSH_VAR
643643
jsr get_last_tok ; Get variable ID from last token
644-
sta E_POP_VAR+1
644+
ldx var_sp
645+
sta var_stk, x
646+
inc var_sp
645647
clc
646648
rts
647649
.endproc
648650

649651
.proc E_POP_VAR
650-
lda #0
652+
dec var_sp
653+
ldx var_sp
654+
lda var_stk, x
651655
jmp parser_emit_byte
652656
.endproc
653657

src/basic.syn

+8-4
Original file line numberDiff line numberDiff line change
@@ -630,13 +630,17 @@ PAUSE_OPT:
630630
E_EOL emit { TOK_0 }
631631

632632
# Optional expression for EXEC
633-
OPT_EXPR:
634-
EXPR emit { TOK_PUSH }
633+
OPT_EXEC_PARAM:
634+
EXPR EXEC_PARAM_MORE emit { TOK_PUSH }
635+
pass
636+
637+
EXEC_PARAM_MORE:
638+
C_EXPR
635639
pass
636640

637641
# Optional variable in PROC
638642
OPT_PROC_VAR:
639-
VAR_WORD_SAVE emit { TOK_POP, TOK_VAR_STORE } E_POP_VAR
643+
VAR_WORD_SAVE OPT_PROC_VAR emit { TOK_POP, TOK_VAR_STORE } E_POP_VAR
640644
pass
641645

642646
# Parse a line
@@ -690,7 +694,7 @@ PARSE_LINE_COMMAND: statement
690694
"DEc" VAR_WORD_LVALUE_SADDR emit TOK_DEC
691695
"PRoc" emit { TOK_JUMP, LT_PROC_DATA } E_PUSH_LT E_LABEL_DEF emit LT_PROC_2 E_PUSH_LT OPT_PROC_VAR
692696
"ENDProc" E_POP_PROC_2 emit TOK_RET E_POP_PROC_DATA
693-
"EXEc" E_LABEL_EXEC OPT_EXPR emit { TOK_CALL } E_DO_EXEC
697+
"EXEc" E_LABEL_EXEC OPT_EXEC_PARAM emit { TOK_CALL } E_DO_EXEC
694698
"DAta" DATA_VAR DATA_END
695699
"END" emit TOK_END
696700
#@if FASTBASIC_FP

src/compiler/parser.cc

+5-8
Original file line numberDiff line numberDiff line change
@@ -255,20 +255,17 @@ bool SMB_E_PUSH_VAR(parse &s)
255255
{
256256
// nothing to do!
257257
s.debug("E_PUSH_VAR");
258-
s.sto_var = s.remove_last().get_val();
258+
s.var_stk.push_back(s.remove_last().get_val());
259259
return true;
260260
}
261261

262262
bool SMB_E_POP_VAR(parse &s)
263263
{
264264
s.debug("E_POP_VAR");
265-
if (s.sto_var < 0)
266-
{
267-
s.debug("---------->ERROR: no variable stored!\n");
268-
return false;
269-
}
270-
s.emit_byte( s.sto_var );
271-
s.sto_var = -1;
265+
if (s.var_stk.empty())
266+
throw parse_error("variable stack empty", s.pos);
267+
s.emit_byte( s.var_stk.back() );
268+
s.var_stk.pop_back();
272269
return true;
273270
}
274271

src/compiler/parser.h

+2-3
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ class parse {
5858
int linenum;
5959
};
6060
std::string in_fname;
61-
int sto_var;
61+
std::vector<int> var_stk;
6262
int lvl, maxlvl;
6363
std::string str;
6464
size_t pos;
@@ -130,7 +130,6 @@ class parse {
130130
} expand;
131131

132132
parse():
133-
sto_var(-1),
134133
lvl(0), maxlvl(0), pos(0),
135134
max_pos(0), linenum(0), label_num(0),
136135
finalized(false),
@@ -211,7 +210,7 @@ class parse {
211210
void new_line(std::string l, int ln)
212211
{
213212
pos = max_pos = 0;
214-
sto_var = -1;
213+
var_stk.clear();
215214
str = l;
216215
saved_errors.clear();
217216
expand.text.clear();

src/parse.asm

+17-9
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
.export parser_start, parser_error, parser_skipws, parser_emit_byte, parser_inc_opos
2323
; Parser state
2424
.exportzp bptr, bpos, bmax, linenum, buf_ptr, end_ptr
25-
.exportzp loop_sp
25+
.exportzp loop_sp, var_sp
2626
; Output state
2727
.exportzp opos
2828
; From actions.asm
@@ -34,7 +34,7 @@
3434
.import alloc_prog
3535
.importzp prog_ptr, BASIC_TOP
3636
; From vars.asm
37-
.importzp var_count, label_count
37+
.exportzp var_count, label_count
3838
; From runtime.asm
3939
.importzp IOCHN, COLOR, IOERROR
4040
.import putc
@@ -53,8 +53,15 @@ end_ptr:.res 2
5353
bmax: .res 1
5454
opos: .res 1
5555
pptr: .res 2
56-
linenum:.res 2
57-
loop_sp:.res 1
56+
57+
; This variables are cleared in one loop:
58+
zp_clear_start:
59+
linenum: .res 2
60+
loop_sp: .res 1
61+
var_sp: .res 1
62+
label_count: .res 1
63+
var_count: .res 1
64+
zp_clear_end:
5865

5966
.code
6067
.include "atari.inc"
@@ -177,11 +184,12 @@ parser_start:
177184
tsx
178185
stx saved_cpu_stack
179186
lda #0
180-
sta linenum
181-
sta linenum+1
182-
sta loop_sp
183-
sta var_count
184-
sta label_count
187+
ldx #zp_clear_end - zp_clear_start
188+
zp_clear:
189+
sta zp_clear_start, x
190+
dex
191+
bpl zp_clear
192+
185193
parse_line:
186194
ldx #0
187195
stx bpos

src/vars.asm

+2-4
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,10 @@
2020
; --------------------------------------------
2121

2222
.export var_search, list_search, name_new
23-
.exportzp var_namelen, label_count, var_count
23+
.exportzp var_namelen
2424

2525
; From alloc.asm
26-
.importzp var_buf, prog_ptr
26+
.importzp var_buf, prog_ptr, label_count, var_count
2727
.import alloc_area_8
2828
; From parser.asm
2929
.import parser_skipws
@@ -44,8 +44,6 @@ INBUFF = $F3
4444
name: .res 2
4545
var: .res 2
4646
len: .res 1
47-
label_count: .res 1
48-
var_count: .res 1
4947

5048
; Use a longer name for external references
5149
var_namelen= len

testsuite/tests/testproc.bas

+3-2
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,10 @@ endproc
2020

2121
exec before
2222

23-
exec param 123
23+
exec param 123, i * i * i
2424

2525
' Proc with a parameter
26-
proc param x
26+
proc param x y
2727
? "X="; x
28+
? "Y="; y
2829
endproc

testsuite/tests/testproc.chk

+1
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,4 @@ Loop: 9
1414
Loop: 10
1515
-- test --
1616
X=123
17+
Y=1331

0 commit comments

Comments
 (0)