1%token	NAME INTEGER SC_FLOAT ACCIDENTAL SYMBOL STRING ASCII PRIMITIVENAME CLASSNAME CURRYARG
2%token  VAR ARG CLASSVAR SC_CONST
3%token	NILOBJ TRUEOBJ FALSEOBJ
4%token	PSEUDOVAR
5%token  ELLIPSIS DOTDOT PIE BEGINCLOSEDFUNC
6%token  BADTOKEN INTERPRET
7%token  BEGINGENERATOR LEFTARROW WHILE
8%left	':'
9%right  '='
10%left	BINOP KEYBINOP '-' '<' '>' '*' '+' '|' READWRITEVAR
11%left	'.'
12%right  '`'
13%right  UMINUS
14%start  root
15
16%{
17
18#include <stdlib.h>
19#include <string.h>
20#include "PyrLexer.h"
21#include "PyrParseNode.h"
22#include "SC_Constants.h"
23#include "SC_InlineUnaryOp.h"
24#include "SC_InlineBinaryOp.h"
25#include "InitAlloc.h"
26#include "PredefinedSymbols.h"
27#include "SimpleStack.h"
28
29void bcopy(void *src, void *dst, size_t size) ;
30int yyparse();
31extern bool compilingCmdLine;
32extern LongStack generatorStack;
33
34
35%}
36%error-verbose
37%%
38
39root	: classes
40			{ gRootParseNode = (PyrParseNode*)$1; gParserResult = 1; }
41		| classextensions
42			{ gRootParseNode = (PyrParseNode*)$1; gParserResult = 1; }
43		| INTERPRET cmdlinecode
44			{ gRootParseNode = (PyrParseNode*)$2; gParserResult = 2; }
45		;
46
47classes : { $$ = 0; }
48		|	classes classdef
49			{ $$ = (intptr_t)linkNextNode((PyrParseNode*)$1, (PyrParseNode*)$2); }
50		;
51
52classextensions : classextension
53				| classextensions classextension
54				{ $$ = (intptr_t)linkNextNode((PyrParseNode*)$1, (PyrParseNode*)$2); }
55				;
56
57classdef	: classname superclass '{' classvardecls methods '}'
58				{ $$ = (intptr_t)newPyrClassNode((PyrSlotNode*)$1, (PyrSlotNode*)$2,
59					(PyrVarListNode*)$4, (PyrMethodNode*)$5, 0);
60				}
61			| classname '[' optname ']' superclass '{' classvardecls methods '}'
62				{ $$ = (intptr_t)newPyrClassNode((PyrSlotNode*)$1, (PyrSlotNode*)$5,
63					(PyrVarListNode*)$7, (PyrMethodNode*)$8,
64					(PyrSlotNode*)$3);
65				}
66			;
67
68classextension : '+' classname '{' methods '}'
69				{
70					$$ = (intptr_t)newPyrClassExtNode((PyrSlotNode*)$2, (PyrMethodNode*)$4);
71				}
72			;
73
74optname		: { $$ = 0; }
75			| name
76			;
77
78superclass	: { $$ = 0; }
79			| ':' classname
80				{ $$ = $2; }
81			;
82
83classvardecls	: { $$ = 0; }
84				| classvardecls classvardecl
85					{ $$ = (intptr_t)linkNextNode((PyrParseNode*)$1, (PyrParseNode*)$2); }
86				;
87
88classvardecl	: CLASSVAR rwslotdeflist ';'
89					{ $$ = (intptr_t)newPyrVarListNode((PyrVarDefNode*)$2, varClass); }
90				| VAR rwslotdeflist ';'
91					{ $$ = (intptr_t)newPyrVarListNode((PyrVarDefNode*)$2, varInst); }
92				| SC_CONST constdeflist ';'
93					{ $$ = (intptr_t)newPyrVarListNode((PyrVarDefNode*)$2, varConst); }
94				;
95
96methods		: { $$ = 0; }
97			| methods methoddef
98				{ $$ = (intptr_t)linkNextNode((PyrParseNode*)$1, (PyrParseNode*)$2); }
99			;
100
101methoddef	: name '{' argdecls funcvardecls primitive methbody '}'
102				{ $$ = (intptr_t)newPyrMethodNode((PyrSlotNode*)$1, (PyrSlotNode*)$5,
103					(PyrArgListNode*)$3, (PyrVarListNode*)$4, (PyrParseNode*)$6, 0); }
104			| '*' name '{' argdecls funcvardecls primitive methbody '}'
105				{ $$ = (intptr_t)newPyrMethodNode((PyrSlotNode*)$2, (PyrSlotNode*)$6,
106					(PyrArgListNode*)$4, (PyrVarListNode*)$5, (PyrParseNode*)$7, 1); }
107			| binop '{' argdecls funcvardecls primitive methbody '}'
108				{ $$ = (intptr_t)newPyrMethodNode((PyrSlotNode*)$1, (PyrSlotNode*)$5,
109					(PyrArgListNode*)$3, (PyrVarListNode*)$4, (PyrParseNode*)$6, 0); }
110			| '*' binop '{' argdecls funcvardecls primitive methbody '}'
111				{ $$ = (intptr_t)newPyrMethodNode((PyrSlotNode*)$2, (PyrSlotNode*)$6,
112					(PyrArgListNode*)$4, (PyrVarListNode*)$5, (PyrParseNode*)$7, 1); }
113			;
114
115optsemi		:
116			| ';'
117			;
118
119optcomma	:
120			| ','
121			;
122
123optequal	:
124			| '='
125			;
126
127funcbody	: funretval
128			| exprseq funretval
129				{ $$ = (intptr_t)newPyrDropNode((PyrParseNode*)$1, (PyrParseNode*)$2); }
130			;
131
132cmdlinecode	: '(' funcvardecls1 funcbody ')'
133				{ $$ = (intptr_t)newPyrBlockNode(NULL, (PyrVarListNode*)$2, (PyrParseNode*)$3, false); }
134			| funcvardecls1 funcbody
135				{ $$ = (intptr_t)newPyrBlockNode(NULL, (PyrVarListNode*)$1, (PyrParseNode*)$2, false); }
136			| funcbody
137				{ $$ = (intptr_t)newPyrBlockNode(NULL, NULL, (PyrParseNode*)$1, false); }
138			;
139
140methbody	: retval
141			| exprseq retval
142				{ $$ = (intptr_t)newPyrDropNode((PyrParseNode*)$1, (PyrParseNode*)$2); }
143			;
144
145primitive	: { $$ = 0; }
146			| primname optsemi
147				{ $$ = $1; }
148			;
149
150retval	:
151			{ $$ = (intptr_t)newPyrReturnNode(NULL); }
152		| '^' expr optsemi
153			{ $$ = (intptr_t)newPyrReturnNode((PyrParseNode*)$2); }
154		;
155
156funretval	:
157			{ $$ = (intptr_t)newPyrBlockReturnNode(); }
158		| '^' expr optsemi
159			{ $$ = (intptr_t)newPyrReturnNode((PyrParseNode*)$2); }
160		;
161
162blocklist1	: blocklistitem
163		| blocklist1 blocklistitem
164				{
165					$$ = (intptr_t)linkNextNode((PyrParseNode*)$1, (PyrParseNode*)$2);
166				}
167			;
168
169blocklistitem : blockliteral
170				| generator
171				;
172
173blocklist	:	{ $$ = 0; }
174			| blocklist1
175			;
176
177msgsend : name blocklist1
178			{
179				$$ = (intptr_t)newPyrCallNode((PyrSlotNode*)$1, (PyrParseNode*)$2, 0, 0);
180			}
181		| '(' binop2 ')' blocklist1
182			{
183				$$ = (intptr_t)newPyrCallNode((PyrSlotNode*)$2, (PyrParseNode*)$4, 0, 0);
184			}
185		| name '(' ')' blocklist1
186			{
187				$$ = (intptr_t)newPyrCallNode((PyrSlotNode*)$1, NULL, NULL, (PyrParseNode*)$4);
188			}
189		| name '(' arglist1 optkeyarglist ')' blocklist
190			{
191				$$ = (intptr_t)newPyrCallNode((PyrSlotNode*)$1, (PyrParseNode*)$3,
192						(PyrParseNode*)$4, (PyrParseNode*)$6);
193			}
194		| '(' binop2 ')' '(' ')' blocklist1
195			{
196				$$ = (intptr_t)newPyrCallNode((PyrSlotNode*)$2, NULL, NULL, (PyrParseNode*)$6);
197			}
198		| '(' binop2 ')' '(' arglist1 optkeyarglist ')' blocklist
199			{
200				$$ = (intptr_t)newPyrCallNode((PyrSlotNode*)$2, (PyrParseNode*)$5,
201						(PyrParseNode*)$6, (PyrParseNode*)$8);
202			}
203		| name '(' arglistv1 optkeyarglist ')'
204			{
205				PyrSlotNode *selectornode;
206				PyrSlot slot;
207				PyrParseNode* args;
208
209				if (isSuperObjNode((PyrParseNode*)$3)) {
210					SetRaw(&((PyrPushNameNode*)$3)->mSlot, s_this);
211					SetSymbol(&slot, s_superPerformList);
212				} else {
213					SetSymbol(&slot, s_performList);
214				}
215				selectornode = newPyrSlotNode(&slot);
216				args = linkAfterHead(
217					(PyrParseNode*)$3,
218					newPyrPushLitNode((PyrSlotNode*)$1, NULL));
219				$$ = (intptr_t)newPyrCallNode(selectornode, args, (PyrParseNode*)$4, 0);
220			}
221		| '(' binop2 ')' '(' arglistv1 optkeyarglist ')'
222			{
223				PyrSlotNode *selectornode;
224				PyrSlot slot;
225				PyrParseNode* args;
226
227				SetSymbol(&slot, s_performList);
228				selectornode = newPyrSlotNode(&slot);
229				args = linkAfterHead(
230					(PyrParseNode*)$5,
231					newPyrPushLitNode((PyrSlotNode*)$2, NULL));
232				$$ = (intptr_t)newPyrCallNode(selectornode, args, (PyrParseNode*)$6, 0);
233			}
234		| classname '[' arrayelems ']'
235			{ $$ = (intptr_t)newPyrDynListNode((PyrParseNode*)$1, (PyrParseNode*)$3); }
236		| classname blocklist1
237			{
238				PyrSlotNode *selectornode;
239				PyrSlot slot;
240				PyrParseNode* args;
241
242				SetSymbol(&slot, s_new);
243				selectornode = newPyrSlotNode(&slot);
244				args = (PyrParseNode*)newPyrPushNameNode((PyrSlotNode*)$1);
245				$$ = (intptr_t)newPyrCallNode(selectornode, args, 0, (PyrParseNode*)$2);
246			}
247		| classname '(' ')' blocklist
248			{
249				PyrSlotNode *selectornode;
250				PyrSlot slot;
251				PyrParseNode* args;
252
253				SetSymbol(&slot, s_new);
254				selectornode = newPyrSlotNode(&slot);
255				args = (PyrParseNode*)newPyrPushNameNode((PyrSlotNode*)$1);
256				$$ = (intptr_t)newPyrCallNode(selectornode, args, NULL, (PyrParseNode*)$4);
257			}
258		| classname '(' keyarglist1 optcomma ')' blocklist
259			{
260				PyrSlotNode *selectornode;
261				PyrSlot slot;
262				PyrParseNode* args;
263
264				SetSymbol(&slot, s_new);
265				selectornode = newPyrSlotNode(&slot);
266				args = (PyrParseNode*)newPyrPushNameNode((PyrSlotNode*)$1);
267				$$ = (intptr_t)newPyrCallNode(selectornode, args, (PyrParseNode*)$3, (PyrParseNode*)$6);
268			}
269		| classname '(' arglist1 optkeyarglist ')' blocklist
270			{
271				PyrSlotNode *selectornode;
272				PyrSlot slot;
273				PyrParseNode* args;
274
275				SetSymbol(&slot, s_new);
276				selectornode = newPyrSlotNode(&slot);
277				args = linkNextNode(
278					(PyrParseNode*)newPyrPushNameNode((PyrSlotNode*)$1),
279					(PyrParseNode*)$3);
280				$$ = (intptr_t)newPyrCallNode(selectornode, args, (PyrParseNode*)$4, (PyrParseNode*)$6);
281			}
282		| classname '(' arglistv1 optkeyarglist ')'
283			{
284				PyrSlotNode *selectornode, *selectornode2;
285				PyrSlot slot, slot2;
286				PyrParseNode* args;
287
288				if (isSuperObjNode((PyrParseNode*)$1)) {
289					SetRaw(&((PyrPushNameNode*)$1)->mSlot, s_this);
290					SetSymbol(&slot, s_superPerformList);
291				} else {
292					SetSymbol(&slot, s_performList);
293				}
294				SetSymbol(&slot2, s_new);
295				selectornode = newPyrSlotNode(&slot);
296				selectornode2 = newPyrSlotNode(&slot2);
297				args = linkNextNode(
298					(PyrParseNode*)newPyrPushNameNode((PyrSlotNode*)$1),
299					newPyrPushLitNode(selectornode2, NULL));
300				args = linkNextNode(args, (PyrParseNode*)$3);
301				$$ = (intptr_t)newPyrCallNode(selectornode, args, (PyrParseNode*)$5, 0);
302			}
303		| expr '.' '(' ')' blocklist
304			{
305				PyrSlotNode *selectornode;
306				PyrSlot slot;
307
308				SetSymbol(&slot, s_value);
309				selectornode = newPyrSlotNode(&slot);
310				$$ = (intptr_t)newPyrCallNode(selectornode, (PyrParseNode*)$1, NULL, (PyrParseNode*)$5);
311			}
312		| expr '.' '(' keyarglist1 optcomma ')' blocklist
313			{
314				PyrSlotNode *selectornode;
315				PyrSlot slot;
316
317				SetSymbol(&slot, s_value);
318				selectornode = newPyrSlotNode(&slot);
319				$$ = (intptr_t)newPyrCallNode(selectornode, (PyrParseNode*)$1, (PyrParseNode*)$4, (PyrParseNode*)$7);
320			}
321		| expr '.' name '(' keyarglist1 optcomma ')' blocklist
322			{
323				$$ = (intptr_t)newPyrCallNode((PyrSlotNode*)$3, (PyrParseNode*)$1,
324					(PyrParseNode*)$5, (PyrParseNode*)$8);
325			}
326		| expr '.' '(' arglist1 optkeyarglist ')' blocklist
327			{
328				PyrSlotNode *selectornode;
329				PyrSlot slot;
330				PyrParseNode* args;
331
332				SetSymbol(&slot, s_value);
333				selectornode = newPyrSlotNode(&slot);
334				args = linkNextNode(
335					(PyrParseNode*)$1,
336					(PyrParseNode*)$4);
337				$$ = (intptr_t)newPyrCallNode(selectornode, args, (PyrParseNode*)$5, (PyrParseNode*)$7);
338			}
339		| expr '.' '(' arglistv1 optkeyarglist ')'
340			{
341				PyrSlotNode *selectornode;
342				PyrSlot slot, slot2;
343				PyrParseNode* args;
344
345				if (isSuperObjNode((PyrParseNode*)$1)) {
346					SetRaw(&((PyrPushNameNode*)$1)->mSlot, s_this);
347					SetSymbol(&slot, s_superPerformList);
348				} else {
349					SetSymbol(&slot, s_performList);
350				}
351				SetSymbol(&slot2, s_value);
352				selectornode = newPyrSlotNode(&slot);
353				args = linkNextNode(
354					(PyrParseNode*)$1,
355					newPyrPushLitNode(newPyrSlotNode(&slot2), NULL));
356				args = linkNextNode(args, (PyrParseNode*)$4);
357				$$ = (intptr_t)newPyrCallNode(selectornode, args, (PyrParseNode*)$5, 0);
358			}
359		| expr '.' name '(' ')' blocklist
360			{
361				$$ = (intptr_t)newPyrCallNode((PyrSlotNode*)$3, (PyrParseNode*)$1, NULL, (PyrParseNode*)$6);
362			}
363		| expr '.' name '(' arglist1 optkeyarglist ')' blocklist
364			{
365				PyrParseNode* args;
366				args = linkNextNode((PyrParseNode*)$1, (PyrParseNode*)$5);
367				$$ = (intptr_t)newPyrCallNode((PyrSlotNode*)$3, args, (PyrParseNode*)$6, (PyrParseNode*)$8);
368			}
369		| expr '.' name '(' arglistv1 optkeyarglist ')'
370			{
371				PyrSlotNode *selectornode;
372				PyrSlot slot;
373				PyrParseNode* args;
374
375				if (isSuperObjNode((PyrParseNode*)$1)) {
376					SetRaw(&((PyrPushNameNode*)$1)->mSlot, s_this);
377					SetSymbol(&slot, s_superPerformList);
378				} else {
379					SetSymbol(&slot, s_performList);
380				}
381				selectornode = newPyrSlotNode(&slot);
382
383				args = linkNextNode((PyrParseNode*)$1, newPyrPushLitNode((PyrSlotNode*)$3, NULL));
384				args = linkNextNode(args, (PyrParseNode*)$5);
385				$$ = (intptr_t)newPyrCallNode(selectornode, args, (PyrParseNode*)$6, 0);
386			}
387		| expr '.' name blocklist
388			{
389				$$ = (intptr_t)newPyrCallNode((PyrSlotNode*)$3, (PyrParseNode*)$1, 0, (PyrParseNode*)$4);
390			}
391		;
392
393generator : '{' ':' exprseq { pushls(&generatorStack, $3); pushls(&generatorStack, 1); } ',' qual '}'
394			{
395				PyrSlot slot;
396				SetSymbol(&slot, getsym("r"));
397				PyrSlotNode* selectornode = newPyrSlotNode(&slot);
398
399				PyrParseNode *block = (PyrParseNode*)newPyrBlockNode(0, 0, (PyrParseNode*)$6, false);
400				PyrParseNode *blocklit = (PyrParseNode*)newPyrPushLitNode(NULL, block);
401				$$ = (intptr_t)newPyrCallNode(selectornode, (PyrParseNode*)blocklit, 0, 0);
402			}
403		| '{' ';' exprseq { pushls(&generatorStack, $3); pushls(&generatorStack, 2); } ',' qual '}'
404			{
405				$$ = $6;
406			}
407		;
408
409nextqual	:
410				{
411					// innermost part
412					int action = popls(&generatorStack);
413					PyrParseNode* expr = (PyrParseNode*)popls(&generatorStack);
414
415					switch (action)
416					{
417						case 1 :
418						{
419							PyrSlot slot;
420							SetSymbol(&slot, getsym("yield"));
421							PyrSlotNode* selectornode = newPyrSlotNode(&slot);
422
423							$$ = (intptr_t)newPyrCallNode(selectornode, expr, 0, 0);
424						} break;
425						case 2 :
426						{
427							$$ = (intptr_t)expr;
428						} break;
429					}
430				}
431			| ',' qual
432				{ $$ = $2; }
433			;
434
435qual	: name LEFTARROW exprseq nextqual
436			{
437				// later should check if exprseq is a series and optimize it to for loop
438				PyrParseNode *exprseq = (PyrParseNode*)$3;
439				if (exprseq->mClassno == pn_CallNode) {
440					PyrCallNode *callnode = (PyrCallNode*)exprseq;
441					if (slotRawSymbol(&callnode->mSelector->mSlot) == s_series)
442					{
443						SetSymbol(&callnode->mSelector->mSlot, getsym("forSeries"));
444
445						PyrVarDefNode* var = newPyrVarDefNode((PyrSlotNode*)$1, NULL, 0);
446						PyrArgListNode* args = newPyrArgListNode(var, NULL);
447						PyrParseNode *block = (PyrParseNode*)newPyrBlockNode(args, 0, (PyrParseNode*)$4, false);
448						PyrParseNode *blocklit = (PyrParseNode*)newPyrPushLitNode(NULL, block);
449
450						callnode->mArglist = linkNextNode(callnode->mArglist, blocklit);
451						$$ = (intptr_t)callnode;
452
453					} else goto notoptimized1;
454				} else {
455					notoptimized1:
456					PyrSlot slot;
457					SetSymbol(&slot, getsym("do"));
458					PyrSlotNode* selectornode = newPyrSlotNode(&slot);
459
460					PyrVarDefNode* var = newPyrVarDefNode((PyrSlotNode*)$1, NULL, 0);
461					PyrArgListNode* args = newPyrArgListNode(var, NULL);
462					PyrParseNode *block = (PyrParseNode*)newPyrBlockNode(args, 0, (PyrParseNode*)$4, false);
463					PyrParseNode *blocklit = (PyrParseNode*)newPyrPushLitNode(NULL, block);
464
465					PyrParseNode* args2 = linkNextNode(exprseq, blocklit);
466					$$ = (intptr_t)newPyrCallNode(selectornode, args2, 0, 0);
467				}
468			}
469		| name name LEFTARROW exprseq nextqual
470			{
471				// later should check if exprseq is a series and optimize it to for loop
472				PyrParseNode *exprseq = (PyrParseNode*)$4;
473				if (exprseq->mClassno == pn_CallNode) {
474					PyrCallNode *callnode = (PyrCallNode*)exprseq;
475					if (slotRawSymbol(&callnode->mSelector->mSlot) == s_series)
476					{
477						SetSymbol(&callnode->mSelector->mSlot, getsym("forSeries"));
478
479						PyrVarDefNode* var1 = newPyrVarDefNode((PyrSlotNode*)$1, NULL, 0);
480						PyrVarDefNode* var2 = newPyrVarDefNode((PyrSlotNode*)$2, NULL, 0);
481						PyrVarDefNode* vars = (PyrVarDefNode*)linkNextNode(var1, var2);
482						PyrArgListNode* args = newPyrArgListNode(vars, NULL);
483						PyrParseNode *block = (PyrParseNode*)newPyrBlockNode(args, 0, (PyrParseNode*)$5, false);
484						PyrParseNode *blocklit = (PyrParseNode*)newPyrPushLitNode(NULL, block);
485
486						callnode->mArglist = linkNextNode(callnode->mArglist, blocklit);
487						$$ = (intptr_t)callnode;
488
489					} else goto notoptimized2;
490				} else {
491					notoptimized2:
492					PyrSlot slot;
493					SetSymbol(&slot, getsym("do"));
494					PyrSlotNode* selectornode = newPyrSlotNode(&slot);
495
496					PyrVarDefNode* var1 = newPyrVarDefNode((PyrSlotNode*)$1, NULL, 0);
497					PyrVarDefNode* var2 = newPyrVarDefNode((PyrSlotNode*)$2, NULL, 0);
498					PyrVarDefNode* vars = (PyrVarDefNode*)linkNextNode(var1, var2);
499					PyrArgListNode* args = newPyrArgListNode(vars, NULL);
500					PyrParseNode *block = (PyrParseNode*)newPyrBlockNode(args, 0, (PyrParseNode*)$5, false);
501					PyrParseNode *blocklit = (PyrParseNode*)newPyrPushLitNode(NULL, block);
502
503					PyrParseNode* args2 = linkNextNode(exprseq, blocklit);
504					$$ = (intptr_t)newPyrCallNode(selectornode, args2, 0, 0);
505				}
506			}
507		| VAR name '=' exprseq nextqual
508			{
509				PyrSlot slot;
510				SetSymbol(&slot, s_value);
511				PyrSlotNode* selectornode = newPyrSlotNode(&slot);
512
513				PyrVarDefNode* var = newPyrVarDefNode((PyrSlotNode*)$2, NULL, 0);
514				PyrArgListNode* args = newPyrArgListNode(var, NULL);
515				PyrParseNode *block = (PyrParseNode*)newPyrBlockNode(args, 0, (PyrParseNode*)$5, false);
516				PyrParseNode *blocklit = (PyrParseNode*)newPyrPushLitNode(NULL, block);
517				PyrParseNode* args2 = (PyrParseNode*)linkNextNode(blocklit, (PyrParseNode*)$4);
518
519				$$ = (intptr_t)newPyrCallNode(selectornode, args2, 0, 0);
520			}
521		| exprseq nextqual
522			{
523				PyrSlot slot;
524				SetSymbol(&slot, getsym("if"));
525				PyrSlotNode* selectornode = newPyrSlotNode(&slot);
526				PyrParseNode *block = (PyrParseNode*)newPyrBlockNode(0, 0, (PyrParseNode*)$2, false);
527				PyrParseNode *blocklit = (PyrParseNode*)newPyrPushLitNode(NULL, block);
528				PyrParseNode* args2 = (PyrParseNode*)linkNextNode((PyrParseNode*)$1, blocklit);
529
530				$$ = (intptr_t)newPyrCallNode(selectornode, args2, 0, 0);
531			}
532		| ':' ':' exprseq nextqual
533			{
534				$$ = (intptr_t)newPyrDropNode((PyrParseNode*)$3, (PyrParseNode*)$4);
535			}
536		| ':' WHILE exprseq nextqual
537			{
538				PyrSlot slot;
539				SetSymbol(&slot, getsym("alwaysYield"));
540				PyrSlotNode* selectornode1 = newPyrSlotNode(&slot);
541
542				SetSymbol(&slot, getsym("if"));
543				PyrSlotNode* selectornode2 = newPyrSlotNode(&slot);
544
545				SetNil(&slot);
546				PyrParseNode *pushnil = (PyrParseNode*)newPyrPushLitNode(newPyrSlotNode(&slot), NULL);
547
548				PyrParseNode *yieldNil = (PyrParseNode*)newPyrCallNode(selectornode1, pushnil, 0, 0);
549
550				PyrParseNode *block1 = (PyrParseNode*)newPyrBlockNode(0, 0, yieldNil, false);
551				PyrParseNode *blocklit1 = (PyrParseNode*)newPyrPushLitNode(NULL, block1);
552				PyrParseNode *block2 = (PyrParseNode*)newPyrBlockNode(0, 0, (PyrParseNode*)$4, false);
553				PyrParseNode *blocklit2 = (PyrParseNode*)newPyrPushLitNode(NULL, block2);
554				PyrParseNode* args2 = (PyrParseNode*)linkNextNode((PyrParseNode*)$3, blocklit2);
555				PyrParseNode* args3 = (PyrParseNode*)linkNextNode(args2, blocklit1);
556
557				$$ = (intptr_t)newPyrCallNode(selectornode2, args3, 0, 0);
558			}
559		;
560
561expr1	: pushliteral
562		| blockliteral
563		| generator
564		| pushname
565		| curryarg
566		| msgsend
567		| '(' exprseq ')'
568			{
569				PyrParseNode* node = (PyrParseNode*)$2;
570				node->mParens = 1;
571				$$ = $2;
572			}
573		| '~' name
574			{
575				PyrParseNode* argnode;
576				PyrSlotNode* selectornode;
577				PyrSlot slot;
578				argnode = (PyrParseNode*)newPyrPushLitNode((PyrSlotNode*)$2, NULL);
579				SetSymbol(&slot, s_envirGet);
580				selectornode = newPyrSlotNode(&slot);
581				$$ = (intptr_t)newPyrCallNode(selectornode, argnode, 0, 0);
582			}
583		|  '[' arrayelems ']'
584			{ $$ = (intptr_t)newPyrDynListNode(0, (PyrParseNode*)$2); }
585		|	'(' valrange2 ')'
586			{ $$ = $2; }
587		|	'(' ':' valrange3 ')'
588			{ $$ = $3; }
589		|	'(' dictslotlist ')'
590			{ $$ = (intptr_t)newPyrDynDictNode((PyrParseNode*)$2); }
591		| pseudovar
592			{ $$ = (intptr_t)newPyrPushNameNode((PyrSlotNode*)$1); }
593		| expr1 '[' arglist1 ']'
594			{
595				PyrSlotNode *selectornode;
596				PyrSlot slot;
597				PyrParseNode* args;
598
599				SetSymbol(&slot, s_at);
600				selectornode = newPyrSlotNode(&slot);
601				args = linkNextNode(
602					(PyrParseNode*)$1,
603					(PyrParseNode*)$3);
604				$$ = (intptr_t)newPyrCallNode(selectornode, args, 0, 0);
605			}
606		| valrangex1
607		;
608
609valrangex1	: expr1 '[' arglist1 DOTDOT ']'
610			{
611				PyrSlotNode *selectornode;
612				PyrPushLitNode *nilnode1, *nilnode2;
613				PyrSlot selectorSlot, nilSlot;
614				PyrParseNode* args;
615
616				int arglen = nodeListLength((PyrParseNode*)$3);
617				if (arglen > 2) {
618					error("ArrayedCollection subrange has too many arguments.\n");
619					nodePostErrorLine((PyrParseNode*)$3);
620					compileErrors++;
621				}
622
623				SetNil(&nilSlot);
624				nilnode2 = newPyrPushLitNode(newPyrSlotNode(&nilSlot), NULL);
625
626				SetSymbol(&selectorSlot, s_copyseries);
627				selectornode = newPyrSlotNode(&selectorSlot);
628				args = linkNextNode((PyrParseNode*)$1, (PyrParseNode*)$3);
629				if (arglen < 2) {
630					nilnode1 = newPyrPushLitNode(newPyrSlotNode(&nilSlot), NULL);
631					args = linkNextNode(args, nilnode1);
632				}
633				args = linkNextNode(args, nilnode2);
634				$$ = (intptr_t)newPyrCallNode(selectornode, args, 0, 0);
635			}
636		| expr1 '[' DOTDOT exprseq ']'
637			{
638				PyrSlotNode *selectornode;
639				PyrPushLitNode *nilnode1, *nilnode2;
640				PyrSlot selectorSlot, nilSlot;
641				PyrParseNode* args;
642
643				SetNil(&nilSlot);
644				nilnode1 = newPyrPushLitNode(newPyrSlotNode(&nilSlot), NULL);
645				nilnode2 = newPyrPushLitNode(newPyrSlotNode(&nilSlot), NULL);
646
647				SetSymbol(&selectorSlot, s_copyseries);
648				selectornode = newPyrSlotNode(&selectorSlot);
649				args = linkNextNode((PyrParseNode*)$1, nilnode1);
650				args = linkNextNode(args, nilnode2);
651				args = linkNextNode(args, (PyrParseNode*)$4);
652				$$ = (intptr_t)newPyrCallNode(selectornode, args, 0, 0);
653			}
654		| expr1 '[' arglist1 DOTDOT exprseq ']'
655			{
656				PyrSlotNode *selectornode;
657				PyrPushLitNode *nilnode1;
658				PyrSlot selectorSlot, nilSlot;
659				PyrParseNode* args;
660
661				int arglen = nodeListLength((PyrParseNode*)$3);
662				if (arglen > 2) {
663					error("ArrayedCollection subrange has too many arguments.\n");
664					nodePostErrorLine((PyrParseNode*)$3);
665					compileErrors++;
666				}
667
668				SetSymbol(&selectorSlot, s_copyseries);
669				selectornode = newPyrSlotNode(&selectorSlot);
670				args = linkNextNode((PyrParseNode*)$1, (PyrParseNode*)$3);
671				if (arglen < 2) {
672					SetNil(&nilSlot);
673					nilnode1 = newPyrPushLitNode(newPyrSlotNode(&nilSlot), NULL);
674					args = linkNextNode(args, nilnode1);
675				}
676				args = linkNextNode(args, (PyrParseNode*)$5);
677				$$ = (intptr_t)newPyrCallNode(selectornode, args, 0, 0);
678			}
679		;
680
681valrangeassign : expr1 '[' arglist1 DOTDOT ']' '=' expr
682			{
683				PyrSlotNode *selectornode;
684				PyrPushLitNode *nilnode1, *nilnode2;
685				PyrSlot selectorSlot, nilSlot;
686				PyrParseNode* args;
687
688				int arglen = nodeListLength((PyrParseNode*)$3);
689				if (arglen > 2) {
690					error("ArrayedCollection subrange has too many arguments.\n");
691					nodePostErrorLine((PyrParseNode*)$3);
692					compileErrors++;
693				}
694
695				SetNil(&nilSlot);
696				nilnode2 = newPyrPushLitNode(newPyrSlotNode(&nilSlot), NULL);
697
698				SetSymbol(&selectorSlot, s_putseries);
699				selectornode = newPyrSlotNode(&selectorSlot);
700				args = linkNextNode((PyrParseNode*)$1, (PyrParseNode*)$3);
701				if (arglen < 2) {
702					nilnode1 = newPyrPushLitNode(newPyrSlotNode(&nilSlot), NULL);
703					args = linkNextNode(args, nilnode1);
704				}
705				args = linkNextNode(args, nilnode2);
706				args = linkNextNode(args, (PyrParseNode*)$7);
707				$$ = (intptr_t)newPyrCallNode(selectornode, args, 0, 0);
708			}
709		| expr1 '[' DOTDOT exprseq ']' '=' expr
710			{
711				PyrSlotNode *selectornode;
712				PyrPushLitNode *nilnode1, *nilnode2;
713				PyrSlot selectorSlot, nilSlot;
714				PyrParseNode* args;
715
716				SetNil(&nilSlot);
717				nilnode1 = newPyrPushLitNode(newPyrSlotNode(&nilSlot), NULL);
718				nilnode2 = newPyrPushLitNode(newPyrSlotNode(&nilSlot), NULL);
719
720				SetSymbol(&selectorSlot, s_putseries);
721				selectornode = newPyrSlotNode(&selectorSlot);
722				args = linkNextNode((PyrParseNode*)$1, nilnode1);
723				args = linkNextNode(args, nilnode2);
724				args = linkNextNode(args, (PyrParseNode*)$4);
725				args = linkNextNode(args, (PyrParseNode*)$7);
726				$$ = (intptr_t)newPyrCallNode(selectornode, args, 0, 0);
727			}
728		| expr1 '[' arglist1 DOTDOT exprseq ']' '=' expr
729			{
730				PyrSlotNode *selectornode;
731				PyrPushLitNode *nilnode1;
732				PyrSlot selectorSlot, nilSlot;
733				PyrParseNode* args;
734
735				int arglen = nodeListLength((PyrParseNode*)$3);
736				if (arglen > 2) {
737					error("ArrayedCollection subrange has too many arguments.\n");
738					nodePostErrorLine((PyrParseNode*)$3);
739					compileErrors++;
740				}
741
742				SetSymbol(&selectorSlot, s_putseries);
743				selectornode = newPyrSlotNode(&selectorSlot);
744				args = linkNextNode((PyrParseNode*)$1, (PyrParseNode*)$3);
745				if (arglen < 2) {
746					SetNil(&nilSlot);
747					nilnode1 = newPyrPushLitNode(newPyrSlotNode(&nilSlot), NULL);
748					args = linkNextNode(args, nilnode1);
749				}
750				args = linkNextNode(args, (PyrParseNode*)$5);
751				args = linkNextNode(args, (PyrParseNode*)$8);
752				$$ = (intptr_t)newPyrCallNode(selectornode, args, 0, 0);
753			}
754	;
755
756valrangexd	: expr '.' '[' arglist1 DOTDOT ']'
757			{
758				PyrSlotNode *selectornode;
759				PyrPushLitNode *nilnode1, *nilnode2;
760				PyrSlot selectorSlot, nilSlot;
761				PyrParseNode* args;
762
763				int arglen = nodeListLength((PyrParseNode*)$4);
764				if (arglen > 2) {
765					error("ArrayedCollection subrange has too many arguments.\n");
766					nodePostErrorLine((PyrParseNode*)$3);
767					compileErrors++;
768				}
769
770				SetNil(&nilSlot);
771				nilnode2 = newPyrPushLitNode(newPyrSlotNode(&nilSlot), NULL);
772
773				SetSymbol(&selectorSlot, s_copyseries);
774				selectornode = newPyrSlotNode(&selectorSlot);
775				args = linkNextNode((PyrParseNode*)$1, (PyrParseNode*)$4);
776				if (arglen < 2) {
777					nilnode1 = newPyrPushLitNode(newPyrSlotNode(&nilSlot), NULL);
778					args = linkNextNode(args, nilnode1);
779				}
780				args = linkNextNode(args, nilnode2);
781				$$ = (intptr_t)newPyrCallNode(selectornode, args, 0, 0);
782			}
783		| expr '.' '[' DOTDOT exprseq ']'
784			{
785				PyrSlotNode *selectornode;
786				PyrPushLitNode *nilnode1, *nilnode2;
787				PyrSlot selectorSlot, nilSlot;
788				PyrParseNode* args;
789
790				SetNil(&nilSlot);
791				nilnode1 = newPyrPushLitNode(newPyrSlotNode(&nilSlot), NULL);
792				nilnode2 = newPyrPushLitNode(newPyrSlotNode(&nilSlot), NULL);
793
794				SetSymbol(&selectorSlot, s_copyseries);
795				selectornode = newPyrSlotNode(&selectorSlot);
796				args = linkNextNode((PyrParseNode*)$1, nilnode1);
797				args = linkNextNode(args, nilnode2);
798				args = linkNextNode(args, (PyrParseNode*)$5);
799				$$ = (intptr_t)newPyrCallNode(selectornode, args, 0, 0);
800			}
801		| expr '.' '[' arglist1 DOTDOT exprseq ']'
802			{
803				PyrSlotNode *selectornode;
804				PyrPushLitNode *nilnode1;
805				PyrSlot selectorSlot, nilSlot;
806				PyrParseNode* args;
807
808				int arglen = nodeListLength((PyrParseNode*)$4);
809				if (arglen > 2) {
810					error("ArrayedCollection subrange has too many arguments.\n");
811					nodePostErrorLine((PyrParseNode*)$3);
812					compileErrors++;
813				}
814
815				SetSymbol(&selectorSlot, s_copyseries);
816				selectornode = newPyrSlotNode(&selectorSlot);
817				args = linkNextNode((PyrParseNode*)$1, (PyrParseNode*)$4);
818				if (arglen < 2) {
819					SetNil(&nilSlot);
820					nilnode1 = newPyrPushLitNode(newPyrSlotNode(&nilSlot), NULL);
821					args = linkNextNode(args, nilnode1);
822				}
823				args = linkNextNode(args, (PyrParseNode*)$6);
824				$$ = (intptr_t)newPyrCallNode(selectornode, args, 0, 0);
825			}
826		| expr '.' '[' arglist1 DOTDOT ']' '=' expr
827			{
828				PyrSlotNode *selectornode;
829				PyrPushLitNode *nilnode1, *nilnode2;
830				PyrSlot selectorSlot, nilSlot;
831				PyrParseNode* args;
832
833				int arglen = nodeListLength((PyrParseNode*)$4);
834				if (arglen > 2) {
835					error("ArrayedCollection subrange has too many arguments.\n");
836					nodePostErrorLine((PyrParseNode*)$3);
837					compileErrors++;
838				}
839
840				SetNil(&nilSlot);
841				nilnode2 = newPyrPushLitNode(newPyrSlotNode(&nilSlot), NULL);
842
843				SetSymbol(&selectorSlot, s_putseries);
844				selectornode = newPyrSlotNode(&selectorSlot);
845				args = linkNextNode((PyrParseNode*)$1, (PyrParseNode*)$4);
846				if (arglen < 2) {
847					nilnode1 = newPyrPushLitNode(newPyrSlotNode(&nilSlot), NULL);
848					args = linkNextNode(args, nilnode1);
849				}
850				args = linkNextNode(args, nilnode2);
851				args = linkNextNode(args, (PyrParseNode*)$8);
852				$$ = (intptr_t)newPyrCallNode(selectornode, args, 0, 0);
853			}
854		| expr '.' '[' DOTDOT exprseq ']' '=' expr
855			{
856				PyrSlotNode *selectornode;
857				PyrPushLitNode *nilnode1, *nilnode2;
858				PyrSlot selectorSlot, nilSlot;
859				PyrParseNode* args;
860
861				SetNil(&nilSlot);
862				nilnode1 = newPyrPushLitNode(newPyrSlotNode(&nilSlot), NULL);
863				nilnode2 = newPyrPushLitNode(newPyrSlotNode(&nilSlot), NULL);
864
865				SetSymbol(&selectorSlot, s_putseries);
866				selectornode = newPyrSlotNode(&selectorSlot);
867				args = linkNextNode((PyrParseNode*)$1, nilnode1);
868				args = linkNextNode(args, nilnode2);
869				args = linkNextNode(args, (PyrParseNode*)$5);
870				args = linkNextNode(args, (PyrParseNode*)$8);
871				$$ = (intptr_t)newPyrCallNode(selectornode, args, 0, 0);
872			}
873		| expr '.' '[' arglist1 DOTDOT exprseq ']' '=' expr
874			{
875				PyrSlotNode *selectornode;
876				PyrPushLitNode *nilnode1;
877				PyrSlot selectorSlot, nilSlot;
878				PyrParseNode* args;
879
880				int arglen = nodeListLength((PyrParseNode*)$4);
881				if (arglen > 2) {
882					error("ArrayedCollection subrange has too many arguments.\n");
883					nodePostErrorLine((PyrParseNode*)$3);
884					compileErrors++;
885				}
886
887				SetSymbol(&selectorSlot, s_putseries);
888				selectornode = newPyrSlotNode(&selectorSlot);
889				args = linkNextNode((PyrParseNode*)$1, (PyrParseNode*)$4);
890				if (arglen < 2) {
891					SetNil(&nilSlot);
892					nilnode1 = newPyrPushLitNode(newPyrSlotNode(&nilSlot), NULL);
893					args = linkNextNode(args, nilnode1);
894				}
895				args = linkNextNode(args, (PyrParseNode*)$6);
896				args = linkNextNode(args, (PyrParseNode*)$9);
897				$$ = (intptr_t)newPyrCallNode(selectornode, args, 0, 0);
898			}
899	;
900
901valrange2	: exprseq DOTDOT
902			{
903				// if this is not used in a 'do' or list comprehension, then should return an error.
904				PyrSlotNode *selectornode;
905				PyrPushLitNode *nilnode, *nilnode2;
906				PyrSlot selectorSlot, nilSlot;
907				PyrParseNode* args;
908
909				SetNil(&nilSlot);
910				nilnode = newPyrPushLitNode(newPyrSlotNode(&nilSlot), NULL);
911				nilnode2 = newPyrPushLitNode(newPyrSlotNode(&nilSlot), NULL);
912
913				SetSymbol(&selectorSlot, s_series);
914				selectornode = newPyrSlotNode(&selectorSlot);
915				args = linkNextNode((PyrParseNode*)$1, nilnode);
916				args = linkNextNode(args, nilnode2);
917				$$ = (intptr_t)newPyrCallNode(selectornode, args, 0, 0);
918			}
919
920		| DOTDOT exprseq
921			{
922				PyrSlotNode *selectornode;
923				PyrPushLitNode *nilnode, *zeronode;
924				PyrSlot selectorSlot, nilSlot, zeroSlot;
925				PyrParseNode* args;
926
927				SetInt(&zeroSlot, 0);
928				SetNil(&nilSlot);
929				nilnode = newPyrPushLitNode(newPyrSlotNode(&nilSlot), NULL);
930				zeronode = newPyrPushLitNode(newPyrSlotNode(&zeroSlot), NULL);
931
932				SetSymbol(&selectorSlot, s_series);
933				selectornode = newPyrSlotNode(&selectorSlot);
934				args = linkNextNode(zeronode, nilnode);
935				args = linkNextNode(args, (PyrParseNode*)$2);
936				$$ = (intptr_t)newPyrCallNode(selectornode, args, 0, 0);
937			}
938
939		| exprseq DOTDOT exprseq
940			{
941				PyrSlotNode *selectornode;
942				PyrPushLitNode *nilnode;
943				PyrSlot selectorSlot, nilSlot;
944				PyrParseNode* args;
945
946				SetNil(&nilSlot);
947				nilnode = newPyrPushLitNode(newPyrSlotNode(&nilSlot), NULL);
948
949				SetSymbol(&selectorSlot, s_series);
950				selectornode = newPyrSlotNode(&selectorSlot);
951				args = linkNextNode((PyrParseNode*)$1, nilnode);
952				args = linkNextNode(args, (PyrParseNode*)$3);
953				$$ = (intptr_t)newPyrCallNode(selectornode, args, 0, 0);
954			}
955
956		| exprseq ',' exprseq DOTDOT exprseq
957			{
958				PyrSlotNode *selectornode;
959				PyrSlot selectorSlot;
960				PyrParseNode* args;
961
962				SetSymbol(&selectorSlot, s_series);
963				selectornode = newPyrSlotNode(&selectorSlot);
964				args = linkNextNode(
965					(PyrParseNode*)$1,
966					(PyrParseNode*)$3);
967				args = linkNextNode(args, (PyrParseNode*)$5);
968				$$ = (intptr_t)newPyrCallNode(selectornode, args, 0, 0);
969			}
970		| exprseq ',' exprseq DOTDOT
971			{
972				// if this is not used in a 'do' or list comprehension, then should return an error.
973				PyrSlotNode *selectornode;
974				PyrSlot selectorSlot, nilSlot;
975				PyrParseNode* args;
976				PyrPushLitNode *nilnode;
977
978				SetNil(&nilSlot);
979				nilnode = newPyrPushLitNode(newPyrSlotNode(&nilSlot), NULL);
980
981				SetSymbol(&selectorSlot, s_series);
982				selectornode = newPyrSlotNode(&selectorSlot);
983				args = linkNextNode(
984					(PyrParseNode*)$1,
985					(PyrParseNode*)$3);
986				args = linkNextNode(args, nilnode);
987				$$ = (intptr_t)newPyrCallNode(selectornode, args, 0, 0);
988			}
989	;
990
991valrange3	: DOTDOT exprseq
992			{
993				PyrSlotNode *selectornode;
994				PyrPushLitNode *nilnode, *zeronode;
995				PyrSlot selectorSlot, nilSlot, zeroSlot;
996				PyrParseNode* args;
997
998				SetInt(&zeroSlot, 0);
999				SetNil(&nilSlot);
1000				nilnode = newPyrPushLitNode(newPyrSlotNode(&nilSlot), NULL);
1001				zeronode = newPyrPushLitNode(newPyrSlotNode(&zeroSlot), NULL);
1002
1003				SetSymbol(&selectorSlot, getsym("seriesIter"));
1004				selectornode = newPyrSlotNode(&selectorSlot);
1005				args = linkNextNode(zeronode, nilnode);
1006				args = linkNextNode(args, (PyrParseNode*)$2);
1007				$$ = (intptr_t)newPyrCallNode(selectornode, args, 0, 0);
1008			}
1009
1010		| exprseq DOTDOT
1011			{
1012				PyrSlotNode *selectornode;
1013				PyrPushLitNode *nilnode, *nilnode2;
1014				PyrSlot selectorSlot, nilSlot;
1015				PyrParseNode* args;
1016
1017				SetNil(&nilSlot);
1018				nilnode = newPyrPushLitNode(newPyrSlotNode(&nilSlot), NULL);
1019				nilnode2 = newPyrPushLitNode(newPyrSlotNode(&nilSlot), NULL);
1020
1021				SetSymbol(&selectorSlot, getsym("seriesIter"));
1022				selectornode = newPyrSlotNode(&selectorSlot);
1023				args = linkNextNode((PyrParseNode*)$1, nilnode);
1024				args = linkNextNode(args, nilnode2);
1025				$$ = (intptr_t)newPyrCallNode(selectornode, args, 0, 0);
1026			}
1027
1028		| exprseq DOTDOT exprseq
1029			{
1030				PyrSlotNode *selectornode;
1031				PyrPushLitNode *nilnode;
1032				PyrSlot selectorSlot, nilSlot;
1033				PyrParseNode* args;
1034
1035				SetNil(&nilSlot);
1036				nilnode = newPyrPushLitNode(newPyrSlotNode(&nilSlot), NULL);
1037
1038				SetSymbol(&selectorSlot, getsym("seriesIter"));
1039				selectornode = newPyrSlotNode(&selectorSlot);
1040				args = linkNextNode((PyrParseNode*)$1, nilnode);
1041				args = linkNextNode(args, (PyrParseNode*)$3);
1042				$$ = (intptr_t)newPyrCallNode(selectornode, args, 0, 0);
1043			}
1044
1045		| exprseq ',' exprseq DOTDOT
1046			{
1047				PyrSlotNode *selectornode;
1048				PyrPushLitNode *nilnode;
1049				PyrSlot selectorSlot, nilSlot;
1050				PyrParseNode* args;
1051
1052				SetNil(&nilSlot);
1053				nilnode = newPyrPushLitNode(newPyrSlotNode(&nilSlot), NULL);
1054
1055				SetSymbol(&selectorSlot, getsym("seriesIter"));
1056				selectornode = newPyrSlotNode(&selectorSlot);
1057				args = linkNextNode((PyrParseNode*)$1, (PyrParseNode*)$3);
1058				args = linkNextNode(args, nilnode);
1059				$$ = (intptr_t)newPyrCallNode(selectornode, args, 0, 0);
1060			}
1061		| exprseq ',' exprseq DOTDOT exprseq
1062			{
1063				PyrSlotNode *selectornode;
1064				PyrSlot selectorSlot;
1065				PyrParseNode* args;
1066
1067				SetSymbol(&selectorSlot, getsym("seriesIter"));
1068				selectornode = newPyrSlotNode(&selectorSlot);
1069				args = linkNextNode(
1070					(PyrParseNode*)$1,
1071					(PyrParseNode*)$3);
1072				args = linkNextNode(args, (PyrParseNode*)$5);
1073				$$ = (intptr_t)newPyrCallNode(selectornode, args, 0, 0);
1074			}
1075	;
1076
1077expr	: expr1
1078		| valrangexd
1079		| valrangeassign
1080		| classname { $$ = (intptr_t)newPyrPushNameNode((PyrSlotNode*)$1); }
1081		| expr '.' '[' arglist1 ']'
1082			{
1083				PyrSlotNode *selectornode;
1084				PyrSlot slot;
1085				PyrParseNode* args;
1086
1087				SetSymbol(&slot, s_at);
1088				selectornode = newPyrSlotNode(&slot);
1089				args = linkNextNode(
1090					(PyrParseNode*)$1,
1091					(PyrParseNode*)$4);
1092				$$ = (intptr_t)newPyrCallNode(selectornode, args, 0, 0);
1093			}
1094		| '`' expr
1095			{
1096				PyrParseNode *node, *args;
1097				PyrSlotNode *slotnode;
1098				PyrSlot slot;
1099
1100				SetSymbol(&slot, s_ref);
1101				slotnode = newPyrSlotNode(&slot);
1102				node = (PyrParseNode*)newPyrPushNameNode(slotnode);
1103				args = linkNextNode(node, (PyrParseNode*)$2);
1104				SetSymbol(&slot, s_new);
1105				slotnode = newPyrSlotNode(&slot);
1106				$$ = (intptr_t)newPyrCallNode(slotnode, args, 0, 0);
1107			}
1108		| expr binop2 adverb expr %prec BINOP
1109			{
1110				$$ = (intptr_t)newPyrBinopCallNode((PyrSlotNode*)$2,
1111						(PyrParseNode*)$1, (PyrParseNode*)$4, (PyrParseNode*)$3);
1112			}
1113		| name '=' expr
1114			{
1115				$$ = (intptr_t)newPyrAssignNode((PyrSlotNode*)$1, (PyrParseNode*)$3, 0);
1116			}
1117		| '~' name '=' expr
1118			{
1119				PyrParseNode *argnode, *args;
1120				PyrSlotNode* selectornode;
1121				PyrSlot slot;
1122				argnode = (PyrParseNode*)newPyrPushLitNode((PyrSlotNode*)$2, NULL);
1123				args = linkNextNode(argnode, (PyrParseNode*)$4);
1124				SetSymbol(&slot, s_envirPut);
1125				selectornode = newPyrSlotNode(&slot);
1126				$$ = (intptr_t)newPyrCallNode(selectornode, args, 0, 0);
1127			}
1128		| expr '.' name '=' expr
1129			{
1130				$$ = (intptr_t)newPyrSetterNode((PyrSlotNode*)$3,
1131						(PyrParseNode*)$1, (PyrParseNode*)$5);
1132			}
1133		| name '(' arglist1 optkeyarglist ')' '=' expr
1134			{
1135				if ($4 != 0) {
1136					error("Setter method called with keyword arguments.\n");
1137					nodePostErrorLine((PyrParseNode*)$4);
1138					compileErrors++;
1139				}
1140				$$ = (intptr_t)newPyrSetterNode((PyrSlotNode*)$1,
1141						(PyrParseNode*)$3, (PyrParseNode*)$7);
1142			}
1143		| '#' mavars '=' expr
1144			{
1145				$$ = (intptr_t)newPyrMultiAssignNode((PyrMultiAssignVarListNode*)$2,
1146					(PyrParseNode*)$4, 0);
1147			}
1148		| expr1 '[' arglist1 ']' '=' expr
1149			{
1150				PyrSlotNode *selectornode;
1151				PyrSlot slot;
1152				PyrParseNode* args;
1153
1154				SetSymbol(&slot, s_put);
1155				selectornode = newPyrSlotNode(&slot);
1156				args = linkNextNode(
1157					(PyrParseNode*)$1,
1158					(PyrParseNode*)$3);
1159				args = linkNextNode( args, (PyrParseNode*)$6);
1160				$$ = (intptr_t)newPyrCallNode(selectornode, args, 0, 0);
1161			}
1162		| expr '.' '[' arglist1 ']' '=' expr
1163			{
1164				PyrSlotNode *selectornode;
1165				PyrSlot slot;
1166				PyrParseNode* args;
1167
1168				SetSymbol(&slot, s_put);
1169				selectornode = newPyrSlotNode(&slot);
1170				args = linkNextNode(
1171					(PyrParseNode*)$1,
1172					(PyrParseNode*)$4);
1173				args = linkNextNode( args, (PyrParseNode*)$7);
1174				$$ = (intptr_t)newPyrCallNode(selectornode, args, 0, 0);
1175			}
1176		;
1177
1178adverb  : { $$ = 0; }
1179		| '.' name { $$ = (intptr_t)newPyrPushLitNode((PyrSlotNode*)$2, NULL); }
1180		| '.' integer { $$ = (intptr_t)newPyrPushLitNode((PyrSlotNode*)$2, NULL); }
1181		| '.' '(' exprseq ')' { $$ = $3; }
1182		;
1183
1184exprn	: expr
1185		| exprn ';' expr
1186			{
1187				$$ = (intptr_t)newPyrDropNode((PyrParseNode*)$1, (PyrParseNode*)$3);
1188			}
1189		;
1190
1191exprseq : exprn optsemi
1192		;
1193
1194arrayelems	: { $$ = 0; }
1195			| arrayelems1 optcomma
1196			  { $$ = $1; }
1197			;
1198
1199arrayelems1	: exprseq
1200			| exprseq ':' exprseq
1201				{ $$ = (intptr_t)linkNextNode((PyrParseNode*)$1, (PyrParseNode*)$3); }
1202			| keybinop exprseq
1203				{
1204					PyrParseNode* key = newPyrPushLitNode((PyrSlotNode*)$1, NULL);
1205					$$ = (intptr_t)linkNextNode(key, (PyrParseNode*)$2);
1206				}
1207			| arrayelems1 ',' exprseq
1208					{ $$ = (intptr_t)linkNextNode((PyrParseNode*)$1, (PyrParseNode*)$3); }
1209			| arrayelems1 ',' keybinop exprseq
1210				{
1211					PyrParseNode* elems;
1212					PyrParseNode* key = newPyrPushLitNode((PyrSlotNode*)$3, NULL);
1213					elems = (PyrParseNode*)linkNextNode(key, (PyrParseNode*)$4);
1214					$$ = (intptr_t)linkNextNode((PyrParseNode*)$1, elems);
1215				}
1216			| arrayelems1 ',' exprseq ':' exprseq
1217				{
1218					PyrParseNode* elems;
1219					elems = (PyrParseNode*)linkNextNode((PyrParseNode*)$3, (PyrParseNode*)$5);
1220					$$ = (intptr_t)linkNextNode((PyrParseNode*)$1, elems);
1221				}
1222			;
1223
1224arglist1	: exprseq
1225			| arglist1 ',' exprseq
1226					{ $$ = (intptr_t)linkNextNode((PyrParseNode*)$1, (PyrParseNode*)$3); }
1227			;
1228
1229arglistv1	: '*' exprseq
1230				{ $$ = $2; }
1231			| arglist1 ',' '*' exprseq
1232					{ $$ = (intptr_t)linkNextNode((PyrParseNode*)$1, (PyrParseNode*)$4); }
1233			;
1234
1235keyarglist1	: keyarg
1236			| keyarglist1 ',' keyarg
1237					{ $$ = (intptr_t)linkNextNode((PyrParseNode*)$1, (PyrParseNode*)$3); }
1238			;
1239
1240keyarg	: keybinop exprseq
1241				{ $$ = (intptr_t)newPyrPushKeyArgNode((PyrSlotNode*)$1, (PyrParseNode*)$2); }
1242		;
1243
1244optkeyarglist	: optcomma { $$ = 0; }
1245				| ',' keyarglist1 optcomma { $$ = $2; }
1246				;
1247
1248mavars	: mavarlist
1249			{ $$ = (intptr_t)newPyrMultiAssignVarListNode((PyrSlotNode*)$1, NULL); }
1250		| mavarlist ELLIPSIS name
1251			{ $$ = (intptr_t)newPyrMultiAssignVarListNode((PyrSlotNode*)$1, (PyrSlotNode*)$3); }
1252		;
1253
1254mavarlist	: name
1255			| mavarlist ',' name
1256					{ $$ = (intptr_t)linkNextNode((PyrParseNode*)$1, (PyrParseNode*)$3); }
1257			;
1258
1259slotliteral
1260		: integer	{ $$ = (intptr_t)newPyrLiteralNode((PyrSlotNode*)$1, NULL); }
1261		| floatp	{ $$ = (intptr_t)newPyrLiteralNode((PyrSlotNode*)$1, NULL); }
1262		| ascii		{ $$ = (intptr_t)newPyrLiteralNode((PyrSlotNode*)$1, NULL); }
1263		| string	{ $$ = (intptr_t)newPyrLiteralNode((PyrSlotNode*)$1, NULL); }
1264		| symbol	{ $$ = (intptr_t)newPyrLiteralNode((PyrSlotNode*)$1, NULL); }
1265		| trueobj	{ $$ = (intptr_t)newPyrLiteralNode((PyrSlotNode*)$1, NULL); }
1266		| falseobj	{ $$ = (intptr_t)newPyrLiteralNode((PyrSlotNode*)$1, NULL); }
1267		| nilobj	{ $$ = (intptr_t)newPyrLiteralNode((PyrSlotNode*)$1, NULL); }
1268		| listlit	{ $$ = (intptr_t)newPyrLiteralNode(NULL, (PyrParseNode*)$1); }
1269		;
1270
1271blockliteral : block	{ $$ = (intptr_t)newPyrPushLitNode(NULL, (PyrParseNode*)$1); }
1272			;
1273
1274pushname	: name		{ $$ = (intptr_t)newPyrPushNameNode((PyrSlotNode*)$1); }
1275			;
1276
1277pushliteral	: integer	{ $$ = (intptr_t)newPyrPushLitNode((PyrSlotNode*)$1, NULL); }
1278			| floatp	{ $$ = (intptr_t)newPyrPushLitNode((PyrSlotNode*)$1, NULL); }
1279			| ascii		{ $$ = (intptr_t)newPyrPushLitNode((PyrSlotNode*)$1, NULL); }
1280			| string	{ $$ = (intptr_t)newPyrPushLitNode((PyrSlotNode*)$1, NULL); }
1281			| symbol	{ $$ = (intptr_t)newPyrPushLitNode((PyrSlotNode*)$1, NULL); }
1282			| trueobj	{ $$ = (intptr_t)newPyrPushLitNode((PyrSlotNode*)$1, NULL); }
1283			| falseobj	{ $$ = (intptr_t)newPyrPushLitNode((PyrSlotNode*)$1, NULL); }
1284			| nilobj	{ $$ = (intptr_t)newPyrPushLitNode((PyrSlotNode*)$1, NULL); }
1285			| listlit	{ $$ = (intptr_t)newPyrPushLitNode(NULL, (PyrParseNode*)$1); }
1286			;
1287
1288listliteral	: integer	{ $$ = (intptr_t)newPyrLiteralNode((PyrSlotNode*)$1, NULL); }
1289			| floatp	{ $$ = (intptr_t)newPyrLiteralNode((PyrSlotNode*)$1, NULL); }
1290			| ascii		{ $$ = (intptr_t)newPyrLiteralNode((PyrSlotNode*)$1, NULL); }
1291			| string	{ $$ = (intptr_t)newPyrLiteralNode((PyrSlotNode*)$1, NULL); }
1292			| symbol	{ $$ = (intptr_t)newPyrLiteralNode((PyrSlotNode*)$1, NULL); }
1293			| name		{ $$ = (intptr_t)newPyrLiteralNode((PyrSlotNode*)$1, NULL); }
1294			| trueobj	{ $$ = (intptr_t)newPyrLiteralNode((PyrSlotNode*)$1, NULL); }
1295			| falseobj	{ $$ = (intptr_t)newPyrLiteralNode((PyrSlotNode*)$1, NULL); }
1296			| nilobj	{ $$ = (intptr_t)newPyrLiteralNode((PyrSlotNode*)$1, NULL); }
1297			| listlit2	{ $$ = (intptr_t)newPyrLiteralNode(NULL, (PyrParseNode*)$1); }
1298			| dictlit2  { $$ = (intptr_t)newPyrLiteralNode(NULL, (PyrParseNode*)$1); }
1299			;
1300
1301block	: '{' argdecls funcvardecls funcbody '}'
1302				{ $$ = (intptr_t)newPyrBlockNode((PyrArgListNode*)$2, (PyrVarListNode*)$3,
1303					(PyrParseNode*)$4, false); }
1304		| BEGINCLOSEDFUNC argdecls funcvardecls funcbody '}'
1305				{ $$ = (intptr_t)newPyrBlockNode((PyrArgListNode*)$2, (PyrVarListNode*)$3,
1306					(PyrParseNode*)$4, true); }
1307		;
1308
1309funcvardecls	: { $$ = 0; }
1310				| funcvardecls funcvardecl
1311					{ $$ = (intptr_t)linkNextNode((PyrParseNode*)$1, (PyrParseNode*)$2); }
1312				;
1313
1314funcvardecls1	: funcvardecl
1315				| funcvardecls1 funcvardecl
1316					{ $$ = (intptr_t)linkNextNode((PyrParseNode*)$1, (PyrParseNode*)$2); }
1317				;
1318
1319funcvardecl	: VAR vardeflist ';'
1320				{ $$ = (intptr_t)newPyrVarListNode((PyrVarDefNode*)$2, varLocal); }
1321			;
1322
1323argdecls	: { $$ = 0; }
1324			| ARG vardeflist ';'
1325				{
1326					$$ = (intptr_t)newPyrArgListNode((PyrVarDefNode*)$2, NULL);
1327				}
1328			| ARG vardeflist0 ELLIPSIS name ';'
1329				{
1330					$$ = (intptr_t)newPyrArgListNode((PyrVarDefNode*)$2, (PyrSlotNode*)$4);
1331				}
1332			| '|' slotdeflist '|'
1333				{
1334					$$ = (intptr_t)newPyrArgListNode((PyrVarDefNode*)$2, NULL);
1335				}
1336			| '|' slotdeflist0 ELLIPSIS name '|'
1337				{
1338					$$ = (intptr_t)newPyrArgListNode((PyrVarDefNode*)$2, (PyrSlotNode*)$4);
1339				}
1340			;
1341
1342constdeflist	: constdef
1343				| constdeflist optcomma constdef
1344					{ $$ = (intptr_t)linkNextNode((PyrParseNode*)$1, (PyrParseNode*)$3); }
1345				;
1346
1347constdef	: rspec name '=' slotliteral
1348				{ $$ = (intptr_t)newPyrVarDefNode((PyrSlotNode*)$2, (PyrParseNode*)$4, $1); }
1349			;
1350
1351slotdeflist0 	: { $$ = 0; }
1352				| slotdeflist
1353				;
1354
1355slotdeflist	: slotdef
1356			| slotdeflist optcomma slotdef
1357				{ $$ = (intptr_t)linkNextNode((PyrParseNode*)$1, (PyrParseNode*)$3); }
1358			;
1359
1360slotdef		: name
1361				{ $$ = (intptr_t)newPyrVarDefNode((PyrSlotNode*)$1, NULL, 0); }
1362			| name optequal slotliteral
1363				{ $$ = (intptr_t)newPyrVarDefNode((PyrSlotNode*)$1, (PyrParseNode*)$3, 0); }
1364			| name optequal '(' exprseq ')'
1365				{
1366					PyrParseNode* node = (PyrParseNode*)$4;
1367					node->mParens = 1;
1368					$$ = (intptr_t)newPyrVarDefNode((PyrSlotNode*)$1, node, 0);
1369				}
1370			;
1371
1372vardeflist0 	: { $$ = 0; }
1373				| vardeflist
1374				;
1375
1376vardeflist      : vardef
1377                        | vardeflist ',' vardef
1378                                { $$ = (intptr_t)linkNextNode((PyrParseNode*)$1, (PyrParseNode*)$3); }
1379                        ;
1380
1381vardef          : name
1382                                { $$ = (intptr_t)newPyrVarDefNode((PyrSlotNode*)$1, NULL, 0); }
1383                        | name '=' expr
1384                                { $$ = (intptr_t)newPyrVarDefNode((PyrSlotNode*)$1, (PyrParseNode*)$3, 0); }
1385                        | name '(' exprseq ')'
1386                                {
1387									PyrParseNode* node = (PyrParseNode*)$3;
1388									node->mParens = 1;
1389									$$ = (intptr_t)newPyrVarDefNode((PyrSlotNode*)$1, node, 0);
1390								}
1391                        ;
1392
1393dictslotdef	: exprseq ':' exprseq
1394				{ $$ = (intptr_t)linkNextNode((PyrParseNode*)$1, (PyrParseNode*)$3); }
1395			| keybinop exprseq
1396				{
1397					PyrParseNode* key = newPyrPushLitNode((PyrSlotNode*)$1, NULL);
1398					$$ = (intptr_t)linkNextNode(key, (PyrParseNode*)$2);
1399				}
1400			;
1401
1402dictslotlist1	: dictslotdef
1403				| dictslotlist1 ',' dictslotdef
1404					{ $$ = (intptr_t)linkNextNode((PyrParseNode*)$1, (PyrParseNode*)$3); }
1405				;
1406
1407dictslotlist	: { $$ = 0; }
1408				| dictslotlist1 optcomma
1409				;
1410
1411rwslotdeflist	: rwslotdef
1412				| rwslotdeflist ',' rwslotdef
1413					{ $$ = (intptr_t)linkNextNode((PyrParseNode*)$1, (PyrParseNode*)$3); }
1414				;
1415
1416rwslotdef		: rwspec name
1417					{ $$ = (intptr_t)newPyrVarDefNode((PyrSlotNode*)$2, NULL, $1); }
1418				| rwspec name '=' slotliteral
1419					{ $$ = (intptr_t)newPyrVarDefNode((PyrSlotNode*)$2, (PyrParseNode*)$4, $1); }
1420				;
1421
1422dictlit2	: '(' litdictslotlist ')'
1423				{ $$ = (intptr_t)newPyrLitDictNode((PyrParseNode*)$2); }
1424			;
1425
1426litdictslotdef	: listliteral ':' listliteral
1427				{ $$ = (intptr_t)linkNextNode((PyrParseNode*)$1, (PyrParseNode*)$3); }
1428			| keybinop listliteral
1429				{
1430					PyrParseNode* key = newPyrPushLitNode((PyrSlotNode*)$1, NULL);
1431					$$ = (intptr_t)linkNextNode(key, (PyrParseNode*)$2);
1432				}
1433			;
1434
1435litdictslotlist1	: litdictslotdef
1436				| litdictslotlist1 ',' litdictslotdef
1437					{ $$ = (intptr_t)linkNextNode((PyrParseNode*)$1, (PyrParseNode*)$3); }
1438				;
1439
1440litdictslotlist	: { $$ = 0; }
1441				| litdictslotlist1 optcomma
1442				;
1443
1444
1445
1446listlit	: '#' '[' literallistc ']'
1447				{ $$ = (intptr_t)newPyrLitListNode(0, (PyrParseNode*)$3); }
1448		| '#' classname  '[' literallistc ']'
1449				{ $$ = (intptr_t)newPyrLitListNode((PyrParseNode*)$2, (PyrParseNode*)$4); }
1450		;
1451
1452listlit2	: '[' literallistc ']'
1453				{ $$ = (intptr_t)newPyrLitListNode(0, (PyrParseNode*)$2); }
1454			| classname  '[' literallistc ']'
1455				{ $$ = (intptr_t)newPyrLitListNode((PyrParseNode*)$1, (PyrParseNode*)$3); }
1456			;
1457
1458literallistc	: { $$ = 0; }
1459				| literallist1 optcomma
1460				;
1461
1462literallist1	: listliteral
1463				| literallist1 ',' listliteral
1464					{ $$ = (intptr_t)linkNextNode((PyrParseNode*)$1, (PyrParseNode*)$3); }
1465				;
1466
1467rwspec	:  { $$ = rwPrivate; }
1468		| '<'
1469			{ $$ = rwReadOnly; }
1470		| READWRITEVAR
1471			{ $$ = rwReadWrite; }
1472		| '>'
1473			{ $$ = rwWriteOnly; }
1474		;
1475
1476rspec	:  { $$ = rwPrivate; }
1477		| '<'
1478			{ $$ = rwReadOnly; }
1479		;
1480
1481integer	: INTEGER { $$ = zzval; }
1482		| '-'INTEGER %prec UMINUS
1483			{
1484				PyrSlotNode *node;
1485				node = (PyrSlotNode*)zzval;
1486				SetRaw(&node->mSlot, -slotRawInt(&node->mSlot));
1487				$$ = zzval;
1488			}
1489	;
1490
1491floatr	: SC_FLOAT { $$ = zzval; }
1492		| '-' SC_FLOAT %prec UMINUS
1493			{
1494				PyrSlotNode *node;
1495				node = (PyrSlotNode*)zzval;
1496				SetRaw(&node->mSlot, -slotRawFloat(&node->mSlot));
1497				$$ = zzval;
1498			}
1499	;
1500
1501accidental : ACCIDENTAL { $$ = zzval; }
1502			| '-' ACCIDENTAL %prec UMINUS
1503				{
1504					PyrSlotNode *node;
1505					double intval, fracval;
1506					node = (PyrSlotNode*)zzval;
1507					intval = floor(slotRawFloat(&node->mSlot) + 0.5);
1508					fracval = slotRawFloat(&node->mSlot) - intval;
1509					SetRaw(&node->mSlot, -intval + fracval);
1510					$$ = zzval;
1511				}
1512
1513pie		: PIE { $$ = zzval; }
1514	;
1515
1516floatp	: floatr
1517		| accidental
1518		| floatr pie
1519			{
1520				PyrSlotNode *node;
1521				node = (PyrSlotNode*)$1;
1522				SetRaw(&node->mSlot, slotRawFloat(&node->mSlot) * pi);
1523			}
1524		| integer pie
1525			{
1526				PyrSlotNode *node;
1527				double ival;
1528				node = (PyrSlotNode*)$1;
1529				ival = slotRawInt(&node->mSlot);
1530				SetFloat(&node->mSlot, ival * pi);
1531			}
1532		| pie
1533			{
1534				PyrSlotNode *node;
1535				node = (PyrSlotNode*)zzval;
1536				SetFloat(&node->mSlot, pi);
1537				$$ = zzval;
1538			}
1539		| '-' pie
1540			{
1541				PyrSlotNode *node;
1542				node = (PyrSlotNode*)zzval;
1543				SetFloat(&node->mSlot, -pi);
1544				$$ = zzval;
1545			}
1546	;
1547
1548name		: NAME { $$ = zzval; }
1549			| WHILE { $$ = zzval; }
1550		;
1551
1552classname		: CLASSNAME { $$ = zzval; }
1553		;
1554
1555primname		: PRIMITIVENAME { $$ = zzval; }
1556		;
1557
1558trueobj		: TRUEOBJ { $$ = zzval; }
1559		;
1560
1561falseobj	: FALSEOBJ { $$ = zzval; }
1562		;
1563
1564nilobj		: NILOBJ { $$ = zzval; }
1565		;
1566
1567ascii		: ASCII { $$ = zzval; }
1568		;
1569
1570symbol		: SYMBOL { $$ = zzval; }
1571		;
1572
1573string		: STRING { $$ = zzval; }
1574		;
1575
1576pseudovar	: PSEUDOVAR { $$ = zzval; }
1577		;
1578
1579binop	: BINOP { $$ = zzval; }
1580		| READWRITEVAR { $$ = zzval; }
1581		| '<'  { $$ = zzval; }
1582		| '>'  { $$ = zzval; }
1583		| '-'  { $$ = zzval; }
1584		| '*'  { $$ = zzval; }
1585		| '+'  { $$ = zzval; }
1586		| '|'  { $$ = zzval; }
1587	;
1588
1589keybinop : KEYBINOP { $$ = zzval; }
1590		;
1591
1592binop2  : binop
1593		| keybinop
1594		;
1595
1596curryarg : CURRYARG { $$ = zzval; }
1597
1598