MultipleAssignment redux
[nedit-bw.git] / MultipleAssignment-redux.patch
blob8938573831ade829a5a4c59b8d9056e6f2232b73
1 ---
3 source/interpret.c | 29 +++++++++++++
4 source/ops.h | 1
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, ...
20 +*/
21 +static int peekPush(void)
23 + DataValue value;
24 + int index;
26 + DISASM_RT();
28 + GET_IMMED(index);
30 + STACKDUMP(index + 1, 3);
32 + PEEK(value, index);
33 + PUSH(value);
35 + return STAT_OK;
38 +/*
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
44 break;
46 + case OP_PEEK_PUSH:
47 + printd(" peekIndex=%d", inst[i+1].val.immed);
48 + ++i;
49 + break;
51 case OP_BRANCH:
52 case OP_BRANCH_TRUE:
53 case OP_BRANCH_FALSE:
54 diff --quilt old/source/ops.h new/source/ops.h
55 --- old/source/ops.h
56 +++ 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 '.' */
72 -/*
73 -** Positions holder for instruction reordering of code generated for the
74 -** left-hand lvalue list in a multi-assignment statement.
75 -*/
76 -typedef struct LVinst {
77 - Inst *start, *mid, *next;
78 - int nArgs;
79 -} LVinst;
83 %union {
84 @@ -124,7 +115,6 @@ typedef struct LVinst {
85 Inst *inst;
86 int num;
87 enum operations oper;
88 - LVinst lvinst;
89 struct {
90 AccumulatorData *acc;
91 Symbol *sym;
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
97 +%type <num> lvlist
98 +%type <inst> lventry
99 %token ARGSEP
101 %nonassoc IF_NO_ELSE
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 */
108 - ADD_OP(OP_ASSIGN);
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.
121 lvlist: lventry {
122 + Inst *this = GetPC();
124 /* start case */
125 - $$.nArgs = $1.nArgs;
126 + $$ = 1;
128 /* add code to push the rvalue expression index needed */
129 - ADD_OP(OP_PUSH_IMMED); ADD_IMMED($$.nArgs);
130 - $$.start = $1.start;
131 - $$.next = GetPC();
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 */
145 + $$ = $1 + 1;
147 /* add code to push the rvalue expression index needed */
148 - ADD_OP(OP_PUSH_IMMED); ADD_IMMED($$.nArgs);
149 - $$.start = $1.start;
150 - $$.next = GetPC();
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);
156 - /*
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
160 - */
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 {
169 - $$.nArgs = 1;
170 - $$.start = $1;
171 - /* Push code: null */
172 - $$.mid = GetPC();
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);
180 - $$.next = GetPC();
182 - | mark initarraylv '[' arglist ']' {
183 - $$.nArgs = 1;
184 - $$.start = $1;
185 - /* Push code dealt with in "initarraylv '[' arglist ']'" */
186 - $$.mid = GetPC();
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);
194 - $$.next = GetPC();
196 - | mark initarraylv dot field {
197 - $$.nArgs = 1;
198 - $$.start = $1;
199 - /* Push code dealt with in "initarraylv dot field" */
200 - $$.mid = GetPC();
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] ... */
207 +lventry: SYMBOL {
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);
214 + $$ = GetPC();
215 + ADD_OP(OP_ARRAY_ASSIGN); ADD_IMMED($3);
217 + | initarraylv dot field {
218 + ADD_OP(OP_PEEK_PUSH); ADD_IMMED(2);
219 + $$ = GetPC();
220 ADD_OP(OP_ARRAY_ASSIGN); ADD_IMMED(1);
221 - $$.next = GetPC();