Skip to content

Commit bcdfc01

Browse files
committed
COMMON: fix broken implementation to avoid appending multiple kwTYPE_EOCs
1 parent b5b794b commit bcdfc01

File tree

6 files changed

+86
-38
lines changed

6 files changed

+86
-38
lines changed

samples/distro-examples/tests/output/uds.out

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,4 @@ a.xfish.small=small
1010
a.xfish.big=big
1111
3
1212
2
13+
10

samples/distro-examples/tests/uds.bas

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,4 +141,27 @@ rem fill the var cache for testing in valgrind
141141
cache = {}
142142
for i = 0 to 8096
143143
cache[i] = "."
144-
next i
144+
next i
145+
146+
'
147+
' regression modifying kwTYPE_EOC
148+
'
149+
func GridClass()
150+
sub setCellValue(a)
151+
? a
152+
end
153+
local result = {}
154+
result.setCellValue = @setCellValue
155+
return result
156+
end
157+
func Game()
158+
sub start()
159+
self.grid.setCellValue(10)
160+
end
161+
local result = {}
162+
result.grid = GridClass()
163+
result.start = @start
164+
return result
165+
end
166+
g = Game()
167+
g.start()

src/common/bc.c

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,6 @@
99

1010
#include "common/bc.h"
1111
#include "common/smbas.h"
12-
#if defined(_UnixOS)
13-
#include <assert.h>
14-
#endif
1512

1613
/*
1714
* Create a bytecode segment
@@ -34,6 +31,8 @@ void bc_destroy(bc_t *bc) {
3431
bc->size = 0;
3532
bc->count = 0;
3633
bc->cp = 0;
34+
bc->eoc_position = 0;
35+
bc->line_position = 0;
3736
}
3837

3938
/*
@@ -60,13 +59,6 @@ void bc_add1(bc_t *bc, char code) {
6059
bc->count++;
6160
}
6261

63-
/*
64-
* change one command
65-
*/
66-
void bc_store1(bc_t *bc, bcip_t offset, byte code) {
67-
bc->ptr[offset] = code;
68-
}
69-
7062
/*
7163
* add one uint32_t
7264
*/
@@ -254,6 +246,20 @@ void bc_eoc(bc_t *bc) {
254246
}
255247
}
256248

249+
/*
250+
* pops any EOC mark at the current position
251+
*/
252+
int bc_pop_eoc(bc_t *bc) {
253+
int result;
254+
if (bc->eoc_position > 0 && bc->eoc_position == bc->count - 1) {
255+
bc->eoc_position = 0;
256+
result = (bc->ptr[--bc->count] == kwTYPE_EOC);
257+
} else {
258+
result = 0;
259+
}
260+
return result;
261+
}
262+
257263
/*
258264
* appends the src to dst
259265
*/

src/common/bc.h

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -81,16 +81,6 @@ void bc_resize(bc_t *bc, uint32_t newsize);
8181
*/
8282
void bc_add1(bc_t *bc, char code);
8383

84-
/**
85-
* @ingroup scan
86-
*
87-
* put 1 byte to specified offset
88-
*
89-
* @param bc the bc structure
90-
* @param code the byte
91-
*/
92-
void bc_store1(bc_t *bc, bcip_t offset, byte code);
93-
9484
/**
9585
* @ingroup scan
9686
*
@@ -128,6 +118,16 @@ char *bc_store_string(bc_t *bc, char *src);
128118
*/
129119
void bc_eoc(bc_t *bc);
130120

121+
/**
122+
* @ingroup scan
123+
*
124+
* pops any EOC mark at the current position
125+
*
126+
* @param bc the bc segment
127+
* @return whether kwTYPE_EOC was popped
128+
*/
129+
int bc_pop_eoc(bc_t *bc);
130+
131131
/**
132132
* @ingroup scan
133133
*

src/common/blib.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1009,6 +1009,9 @@ bcip_t cmd_push_args(int cmd, bcip_t goto_addr, bcip_t rvid) {
10091009
do {
10101010
byte code = code_peek(); // get next BC
10111011
switch (code) {
1012+
case kwTYPE_LINE:
1013+
ready = 1; // finish flag
1014+
break;
10121015
case kwTYPE_EOC: // end of an expression (parameter)
10131016
code_skipnext(); // ignore it
10141017
break;
@@ -1097,6 +1100,9 @@ void cmd_call_unit_udp(int cmd, int udp_tid, bcip_t goto_addr, bcip_t rvid) {
10971100
do {
10981101
byte code = code_peek(); // get next BC
10991102
switch (code) {
1103+
case kwTYPE_LINE:
1104+
ready = 1; // finish flag
1105+
break;
11001106
case kwTYPE_EOC: // end of an expression (parameter)
11011107
code_skipnext(); // ignore it
11021108
break;

src/common/scan.c

Lines changed: 29 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1849,7 +1849,12 @@ char *comp_array_params(char *src, char exitChar) {
18491849
*se = '\0';
18501850
bc_add_code(&comp_prog, kwTYPE_LEVEL_BEGIN);
18511851
comp_expression(ss, 0);
1852-
bc_store1(&comp_prog, comp_prog.count - 1, kwTYPE_LEVEL_END);
1852+
// overwrite kwTYPE_EOC with kwTYPE_LEVEL_END
1853+
if (!bc_pop_eoc(&comp_prog)) {
1854+
sc_raise(ERR_UNSUPPORTED);
1855+
}
1856+
bc_add_code(&comp_prog, kwTYPE_LEVEL_END);
1857+
comp_prog.eoc_position = 0;
18531858
*ss = ssSave;
18541859
*se = seSave;
18551860
ss = se = NULL;
@@ -2812,6 +2817,24 @@ int comp_text_line_command(bid_t idx, int decl, int sharp, char *last_cmd) {
28122817
return result;
28132818
}
28142819

2820+
void add_line_no() {
2821+
if (comp_prog.line_position == 0 ||
2822+
comp_prog.line_position != (comp_prog.count - KW_TYPE_LINE_BYTES)) {
2823+
// not an adjoining kwTYPE_LINE
2824+
if (!opt_autolocal && comp_prog.eoc_position == comp_prog.count - 1) {
2825+
// overwrite any adjoining kwTYPE_EOC (can't do this with autolocal)
2826+
if (!bc_pop_eoc(&comp_prog)) {
2827+
sc_raise(ERR_UNSUPPORTED);
2828+
}
2829+
}
2830+
2831+
// prevent adjoining kwTYPE_LINEs
2832+
comp_prog.line_position = comp_prog.count;
2833+
bc_add_code(&comp_prog, kwTYPE_LINE);
2834+
bc_add_addr(&comp_prog, comp_line);
2835+
}
2836+
}
2837+
28152838
/*
28162839
* Pass 1: scan source line
28172840
*/
@@ -2870,20 +2893,7 @@ void comp_text_line(char *text, int addLineNo) {
28702893
return;
28712894
}
28722895
if (addLineNo) {
2873-
// add debug info: line-number
2874-
if (comp_prog.line_position == 0 ||
2875-
comp_prog.line_position != (comp_prog.count - KW_TYPE_LINE_BYTES)) {
2876-
// not an adjoining kwTYPE_LINE
2877-
if (!opt_autolocal && comp_prog.eoc_position == comp_prog.count - 1) {
2878-
// overwrite any adjoining kwTYPE_EOC (can't do this with autolocal)
2879-
comp_prog.count--;
2880-
}
2881-
// prevent kwTYPE_EOC from being appended to this kwTYPE_LINE
2882-
comp_prog.eoc_position = comp_prog.count;
2883-
comp_prog.line_position = comp_prog.count;
2884-
bc_add_code(&comp_prog, kwTYPE_LINE);
2885-
bc_add_addr(&comp_prog, comp_line);
2886-
}
2896+
add_line_no();
28872897
}
28882898
if (idx == -1) {
28892899
idx = comp_is_proc(comp_bc_name);
@@ -3719,13 +3729,15 @@ bcip_t comp_optimise_let(bcip_t ip, byte kw_opr, char sep, byte opt_kw) {
37193729
bcip_t ip_next = ip + 1;
37203730
if (comp_prog.ptr[ip_next] == kwTYPE_VAR) {
37213731
ip_next += 1 + sizeof(bcip_t);
3722-
while (ip_next < comp_prog.count && comp_prog.ptr[ip_next] != kwTYPE_EOC) {
3732+
while (ip_next < comp_prog.count && comp_prog.ptr[ip_next] != kwTYPE_EOC
3733+
&& comp_prog.ptr[ip_next] != kwTYPE_LINE) {
37233734
if (comp_prog.ptr[ip_next] == kw_opr &&
37243735
comp_prog.ptr[ip_next + 1] == sep) {
37253736
ip_next += 2;
37263737
if (ip_next < comp_prog.count &&
37273738
comp_prog.ptr[ip_next] == kwTYPE_VAR &&
3728-
comp_prog.ptr[ip_next + 1 + sizeof(bcip_t)] == kwTYPE_EOC) {
3739+
(comp_prog.ptr[ip_next + 1 + sizeof(bcip_t)] == kwTYPE_EOC ||
3740+
comp_prog.ptr[ip_next + 1 + sizeof(bcip_t)] == kwTYPE_LINE)) {
37293741
comp_prog.ptr[ip] = opt_kw;
37303742
ip = ip_next;
37313743
}

0 commit comments

Comments
 (0)