3 source/interpret.c | 29 +++++++++++++
5 source/parse.y | 110 ++++++++++++++++-------------------------------------
6 3 files changed, 65 insertions(+), 75 deletions(-)
8 diff --quilt old/source/interpret.c new/source/interpret.c
9 --- old/source/interpret.c
10 +++ new/source/interpret.c
11 @@ -1974,6 +1974,30 @@ static int dupStack(void)
15 +** copy the value at stack postion index onto the stack
16 +** Before: Prog-> [index], next, ...
17 +** TheStack-> val0, ... valIndex, next, ...
18 +** After: Prog-> index, [next], ...
19 +** TheStack-> valIndex, val0, ... valIndex, next, ...
21 +static int peekPush(void)
30 + STACKDUMP(index + 1, 3);
39 ** if left and right arguments are arrays, then the result is a new array
40 ** in which all the keys from both the right and left are copied
41 ** the values from the right array are used in the result array when the
42 @@ -4534,6 +4558,11 @@ static void disasmInternal(Inst *inst, i
47 + printd(" peekIndex=%d", inst[i+1].val.immed);
54 diff --quilt old/source/ops.h new/source/ops.h
57 @@ -10,6 +10,7 @@ OP(PUSH_IMMED, pushImmed)
58 OP(PUSH_STRING, pushString) /* str */ /* push(str) */
59 OP(POP, popStack) /* pop(v) */
60 OP(DUP, dupStack) /* pop(v), push(v,v) */
61 +OP(PEEK_PUSH, peekPush) /* n */ /* peek(v, n), push(v) */
62 OP(ADD, add) /* pop(v2,v1), push(v1 + v2) */
63 OP(SUB, subtract) /* pop(v2,v1), push(v1 - v2) */
64 OP(MUL, multiply) /* pop(v2,v1), push(v1 * v2) */
65 diff --quilt old/source/parse.y new/source/parse.y
66 --- old/source/parse.y
67 +++ new/source/parse.y
68 @@ -108,15 +108,6 @@ static int nextSymIsField = 0;
69 /* set to 1 when we don't want a full symbol, just a name (string) for a
70 field name following a '.' */
73 -** Positions holder for instruction reordering of code generated for the
74 -** left-hand lvalue list in a multi-assignment statement.
76 -typedef struct LVinst {
77 - Inst *start, *mid, *next;
84 @@ -124,7 +115,6 @@ typedef struct LVinst {
92 @@ -141,7 +131,8 @@ typedef struct LVinst {
93 %type <oper> operassign incrdecr
94 %token <oper> '=' ADDEQ SUBEQ MULEQ DIVEQ MODEQ ANDEQ OREQ
95 %token <oper> INCR DECR
96 -%type <lvinst> lvlist lventry
102 @@ -438,12 +429,10 @@ simpstmt: /* simple variable assignmen
103 ** Below for lvlist, M0 is $$.start, M1 is $$.mid, M2 is $$.next. lventry's $$
104 ** gives the mid value between the P and A phases (M1).
106 -lvlistexpr: '(' lvlist ')' blank '=' blank expr {
107 - /* store expression value */
109 - ADD_SYM(LookupString("list assign expr", True));
110 +lvlistexpr: '(' mark lvlist mark ')' blank '=' blank expr {
111 /* swap expression evaluation code into position */
112 - SwapCode($2.mid, $2.next, GetPC());
113 + SwapCode($2, $4, GetPC());
114 + ADD_OP(OP_POP); /* pop expression */
118 @@ -453,76 +442,47 @@ lvlistexpr: '(' lvlist ')' blank '=' bla
119 ** Only then do we have the situation described for overall list assignment.
122 + Inst *this = GetPC();
125 - $$.nArgs = $1.nArgs;
128 /* add code to push the rvalue expression index needed */
129 - ADD_OP(OP_PUSH_IMMED); ADD_IMMED($$.nArgs);
130 - $$.start = $1.start;
132 + ADD_OP(OP_PUSH_IMMED); ADD_IMMED($$);
133 + ADD_OP(OP_ARRAY_REF); ADD_IMMED(1);
135 /* swap this code in front of the lvalue assignment code */
136 - $$.mid = SwapCode($1.mid, $1.next, $$.next);
137 + SwapCode($1, this, GetPC());
139 | lvlist ',' blank lventry {
140 - /* recursive step case - starts similarly */
141 - $$.nArgs = $1.nArgs + $4.nArgs;
142 + Inst *this = GetPC();
144 + /* the index for this entry into the rvalue array */
147 /* add code to push the rvalue expression index needed */
148 - ADD_OP(OP_PUSH_IMMED); ADD_IMMED($$.nArgs);
149 - $$.start = $1.start;
151 + ADD_OP(OP_PUSH_IMMED); ADD_IMMED($$);
152 + ADD_OP(OP_ARRAY_REF); ADD_IMMED(1);
154 /* swap this code in front of the lvalue assignment code */
155 - $4.mid = SwapCode($4.mid, $4.next, $$.next);
157 - ** now swap Px code to midpoint and change midpoint
158 - ** $1.start[P...]$1.mid[A...]$1.next[Px]$4.mid[Ax]$$.next --->
159 - ** $1.start[Px][P...]$1.mid[A...]$4.mid[Ax]$$.next
161 - SwapCode($1.start, $1.next, $4.mid);
162 - $$.start = $1.start; /* keep start point */
163 - $$.mid = $1.mid + ($4.mid - $1.next); /* adjust mid point */
164 + SwapCode($4, this, GetPC());
167 /* lventry's value is the PC position between the Px and Ax parts */
168 -lventry: mark SYMBOL {
171 - /* Push code: null */
173 - /* Assign code: stack: N, ... */
174 - ADD_OP(OP_PUSH_SYM);
175 - ADD_SYM(LookupString("list assign expr", True));
176 - /* stack: E, N, ... */
177 - ADD_OP(OP_SWAP_TOP2); /* stack: N, E, ... */
178 - ADD_OP(OP_ARRAY_REF); ADD_IMMED(1); /* stack: E[N] ... */
179 - ADD_OP(OP_ASSIGN); ADD_SYM($2);
182 - | mark initarraylv '[' arglist ']' {
185 - /* Push code dealt with in "initarraylv '[' arglist ']'" */
187 - /* Assign code: stack: N, ... */
188 - ADD_OP(OP_PUSH_SYM);
189 - ADD_SYM(LookupString("list assign expr", True));
190 - /* stack: E, N, ... */
191 - ADD_OP(OP_SWAP_TOP2); /* stack: N, E, ... */
192 - ADD_OP(OP_ARRAY_REF); ADD_IMMED(1); /* stack: E[N] ... */
193 - ADD_OP(OP_ARRAY_ASSIGN); ADD_IMMED($4);
196 - | mark initarraylv dot field {
199 - /* Push code dealt with in "initarraylv dot field" */
201 - /* Assign code: stack: N, ... */
202 - ADD_OP(OP_PUSH_SYM);
203 - ADD_SYM(LookupString("list assign expr", True));
204 - /* stack: E, N, ... */
205 - ADD_OP(OP_SWAP_TOP2); /* stack: N, E, ... */
206 - ADD_OP(OP_ARRAY_REF); ADD_IMMED(1); /* stack: E[N] ... */
208 + ADD_OP(OP_DUP); /* duplicate expression array */
209 + $$ = GetPC(); /* need to move the next op */
210 + ADD_OP(OP_ASSIGN); ADD_SYM($1);
212 + | initarraylv '[' arglist ']' {
213 + ADD_OP(OP_PEEK_PUSH); ADD_IMMED($3 + 1);
215 + ADD_OP(OP_ARRAY_ASSIGN); ADD_IMMED($3);
217 + | initarraylv dot field {
218 + ADD_OP(OP_PEEK_PUSH); ADD_IMMED(2);
220 ADD_OP(OP_ARRAY_ASSIGN); ADD_IMMED(1);