1 /*
2     SuperCollider real time audio synthesis system
3     Copyright (c) 2002 James McCartney. All rights reserved.
4     http://www.audiosynth.com
5 
6     This program is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version.
10 
11     This program is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.
15 
16     You should have received a copy of the GNU General Public License
17     along with this program; if not, write to the Free Software
18     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA
19 */
20 
21 #pragma once
22 
23 #include "PyrSlot.h"
24 #include "PyrKernel.h"
25 #include "ByteCodeArray.h"
26 #include "Opcodes.h"
27 #include "AdvancingAllocPool.h"
28 
29 
30 enum { rwPrivate = 0, rwReadOnly = 1, rwWriteOnly = 2, rwReadWrite = 3 };
31 
32 enum { varInst, varClass, varTemp, varConst, varPseudo, varLocal };
33 
34 enum {
35     /* structural units */
36     pn_ClassNode,
37     pn_ClassExtNode,
38     pn_MethodNode,
39     pn_BlockNode,
40     pn_SlotNode,
41 
42     /* variable declarations */
43     pn_VarListNode,
44     pn_VarDefNode,
45     pn_DynDictNode,
46     pn_DynListNode,
47     pn_LitListNode,
48     pn_LitDictNode,
49 
50     pn_StaticVarListNode,
51     pn_InstVarListNode,
52     pn_PoolVarListNode,
53     pn_ArgListNode,
54     pn_SlotDefNode,
55 
56     /* selectors */
57     pn_LiteralNode,
58 
59     /* code */
60     pn_PushLitNode,
61     pn_PushNameNode,
62     pn_PushKeyArgNode,
63     pn_CallNode,
64     pn_BinopCallNode,
65     pn_DropNode,
66     pn_AssignNode,
67     pn_MultiAssignNode,
68     pn_MultiAssignVarListNode,
69     pn_SetterNode,
70     pn_CurryArgNode,
71 
72     pn_ReturnNode,
73     pn_BlockReturnNode,
74 
75     pn_NumTypes
76 };
77 
78 extern AdvancingAllocPool gParseNodePool;
79 
80 #define ALLOCNODE(type) (new (gParseNodePool.Alloc(sizeof(type))) type())
81 #define ALLOCSLOTNODE(type, classno) (new (gParseNodePool.Alloc(sizeof(type))) type(classno))
82 #define COMPILENODE(node, result, onTailBranch) (compileNode((node), (result), (onTailBranch)))
83 #define DUMPNODE(node, level)                                                                                          \
84     do {                                                                                                               \
85         if (node)                                                                                                      \
86             (node)->dump(level);                                                                                       \
87     } while (false);
88 
89 struct PyrParseNode {
90     PyrParseNode(int classno);
~PyrParseNodePyrParseNode91     virtual ~PyrParseNode() {}
92     virtual void compile(PyrSlot* result) = 0;
93     virtual void dump(int level) = 0;
94 
95     struct PyrParseNode* mNext;
96     struct PyrParseNode* mTail;
97     int mLineno;
98     int mCharno;
99     unsigned char mClassno;
100     unsigned char mParens;
101 };
102 
103 struct PyrSlotNode : public PyrParseNode {
PyrSlotNodePyrSlotNode104     PyrSlotNode(): PyrParseNode(pn_SlotNode) {}
PyrSlotNodePyrSlotNode105     PyrSlotNode(int classno): PyrParseNode(classno) {}
~PyrSlotNodePyrSlotNode106     virtual ~PyrSlotNode() {}
107 
108     virtual void compile(PyrSlot* result);
109     virtual void compileLiteral(PyrSlot* result);
110     virtual void compilePushLit(PyrSlot* result);
111     virtual void dump(int level);
112     virtual void dumpLiteral(int level);
113     virtual void dumpPushLit(int level);
114 
115     PyrSlot mSlot;
116 };
117 
118 typedef PyrSlotNode PyrLiteralNode;
119 typedef PyrSlotNode PyrPushLitNode;
120 typedef PyrSlotNode PyrPushNameNode;
121 
122 struct PyrCurryArgNode : public PyrParseNode {
PyrCurryArgNodePyrCurryArgNode123     PyrCurryArgNode(): PyrParseNode(pn_CurryArgNode), mArgNum(-1) {}
~PyrCurryArgNodePyrCurryArgNode124     virtual ~PyrCurryArgNode() {}
125     virtual void compile(PyrSlot* result);
126     virtual void dump(int level);
127 
128     int mArgNum;
129 };
130 
131 
132 struct PyrClassExtNode : public PyrParseNode {
PyrClassExtNodePyrClassExtNode133     PyrClassExtNode(): PyrParseNode(pn_ClassExtNode) {}
~PyrClassExtNodePyrClassExtNode134     virtual ~PyrClassExtNode() {}
135     virtual void compile(PyrSlot* result);
136     virtual void dump(int level);
137 
138     struct PyrSlotNode* mClassName;
139     struct PyrMethodNode* mMethods;
140 };
141 
142 struct PyrClassNode : public PyrParseNode {
PyrClassNodePyrClassNode143     PyrClassNode(): PyrParseNode(pn_ClassNode) {}
~PyrClassNodePyrClassNode144     virtual ~PyrClassNode() {}
145     virtual void compile(PyrSlot* result);
146     virtual void dump(int level);
147 
148     struct PyrSlotNode* mClassName;
149     struct PyrSlotNode* mSuperClassName;
150     struct PyrSlotNode* mIndexType;
151     struct PyrVarListNode* mVarlists;
152     struct PyrMethodNode* mMethods;
153     int mVarTally[4];
154     int mNumSuperInstVars;
155 };
156 
157 struct PyrMethodNode : public PyrParseNode {
PyrMethodNodePyrMethodNode158     PyrMethodNode(): PyrParseNode(pn_MethodNode) {}
~PyrMethodNodePyrMethodNode159     virtual ~PyrMethodNode() {}
160     virtual void compile(PyrSlot* result);
161     virtual void dump(int level);
162 
163     struct PyrSlotNode* mMethodName;
164     struct PyrSlotNode* mPrimitiveName;
165     struct PyrArgListNode* mArglist;
166     struct PyrVarListNode* mVarlist;
167     struct PyrParseNode* mBody;
168     int mIsClassMethod; // is class method?
169     bool mExtension;
170 };
171 
172 struct PyrVarListNode : public PyrParseNode {
PyrVarListNodePyrVarListNode173     PyrVarListNode(): PyrParseNode(pn_VarListNode) {}
~PyrVarListNodePyrVarListNode174     virtual ~PyrVarListNode() {}
175     virtual void compile(PyrSlot* result);
176     virtual void dump(int level);
177 
178     struct PyrVarDefNode* mVarDefs;
179     int mFlags;
180 };
181 
182 struct PyrVarDefNode : public PyrParseNode {
PyrVarDefNodePyrVarDefNode183     PyrVarDefNode(): PyrParseNode(pn_VarDefNode) {}
~PyrVarDefNodePyrVarDefNode184     virtual ~PyrVarDefNode() {}
185     virtual void compile(PyrSlot* result);
186     virtual void compileArg(PyrSlot* result);
187     virtual void dump(int level);
188     bool hasExpr(PyrSlot* result);
189 
190     struct PyrSlotNode* mVarName;
191     PyrParseNode* mDefVal;
192     int mFlags;
193     bool mDrop;
194 };
195 
196 struct PyrCallNodeBase : public PyrParseNode {
PyrCallNodeBasePyrCallNodeBase197     PyrCallNodeBase(int classno): PyrParseNode(classno) {}
~PyrCallNodeBasePyrCallNodeBase198     virtual ~PyrCallNodeBase() {}
199 
200     virtual void compile(PyrSlot* result);
201     virtual void compilePartialApplication(int numCurryArgs, PyrSlot* result);
202     virtual void compileCall(PyrSlot* result) = 0;
203 
204     virtual int isPartialApplication() = 0;
205 };
206 
207 struct PyrCallNodeBase2 : public PyrCallNodeBase {
PyrCallNodeBase2PyrCallNodeBase2208     PyrCallNodeBase2(int classno): PyrCallNodeBase(classno) {}
~PyrCallNodeBase2PyrCallNodeBase2209     virtual ~PyrCallNodeBase2() {}
210 
211     struct PyrSlotNode* mSelector;
212     struct PyrParseNode* mArglist;
213     struct PyrParseNode* mKeyarglist;
214     bool mTailCall;
215 };
216 
217 struct PyrCallNode : public PyrCallNodeBase2 {
PyrCallNodePyrCallNode218     PyrCallNode(): PyrCallNodeBase2(pn_CallNode) {}
~PyrCallNodePyrCallNode219     virtual ~PyrCallNode() {}
220 
221     virtual void compileCall(PyrSlot* result);
222     virtual void dump(int level);
223 
224     virtual int isPartialApplication();
225 };
226 
227 struct PyrBinopCallNode : public PyrCallNodeBase2 {
PyrBinopCallNodePyrBinopCallNode228     PyrBinopCallNode(): PyrCallNodeBase2(pn_BinopCallNode) {}
~PyrBinopCallNodePyrBinopCallNode229     virtual ~PyrBinopCallNode() {}
230 
231     virtual void compileCall(PyrSlot* result);
232     virtual void dump(int level);
233 
234     virtual int isPartialApplication();
235 };
236 
237 struct PyrSetterNode : public PyrCallNodeBase {
PyrSetterNodePyrSetterNode238     PyrSetterNode(): PyrCallNodeBase(pn_SetterNode) {}
~PyrSetterNodePyrSetterNode239     virtual ~PyrSetterNode() {}
240     virtual void compileCall(PyrSlot* result);
241     virtual void dump(int level);
242 
243     virtual int isPartialApplication();
244 
245     struct PyrSlotNode* mSelector;
246     struct PyrParseNode* mExpr1;
247     struct PyrParseNode* mExpr2;
248     int mFlags; // is a var def ?
249 };
250 
251 struct PyrDynListNode : public PyrCallNodeBase {
PyrDynListNodePyrDynListNode252     PyrDynListNode(): PyrCallNodeBase(pn_DynListNode) {}
~PyrDynListNodePyrDynListNode253     virtual ~PyrDynListNode() {}
254     virtual void compileCall(PyrSlot* result);
255     virtual void dump(int level);
256 
257     virtual int isPartialApplication();
258 
259     struct PyrParseNode* mClassname;
260     struct PyrParseNode* mElems;
261 };
262 
263 struct PyrDynDictNode : public PyrCallNodeBase {
PyrDynDictNodePyrDynDictNode264     PyrDynDictNode(): PyrCallNodeBase(pn_DynDictNode) {}
~PyrDynDictNodePyrDynDictNode265     virtual ~PyrDynDictNode() {}
266     virtual void compileCall(PyrSlot* result);
267     virtual void dump(int level);
268 
269     virtual int isPartialApplication();
270 
271     struct PyrParseNode* mElems;
272 };
273 
274 
275 struct PyrDropNode : public PyrParseNode {
PyrDropNodePyrDropNode276     PyrDropNode(): PyrParseNode(pn_DropNode) {}
~PyrDropNodePyrDropNode277     virtual ~PyrDropNode() {}
278     virtual void compile(PyrSlot* result);
279     virtual void dump(int level);
280 
281     struct PyrParseNode* mExpr1;
282     struct PyrParseNode* mExpr2;
283 };
284 
285 struct PyrPushKeyArgNode : public PyrParseNode {
PyrPushKeyArgNodePyrPushKeyArgNode286     PyrPushKeyArgNode(): PyrParseNode(pn_PushKeyArgNode) {}
~PyrPushKeyArgNodePyrPushKeyArgNode287     virtual ~PyrPushKeyArgNode() {}
288     virtual void compile(PyrSlot* result);
289     virtual void dump(int level);
290 
291     struct PyrSlotNode* mSelector;
292     struct PyrParseNode* mExpr;
293 };
294 
295 struct PyrReturnNode : public PyrParseNode {
PyrReturnNodePyrReturnNode296     PyrReturnNode(): PyrParseNode(pn_ReturnNode) {}
~PyrReturnNodePyrReturnNode297     virtual ~PyrReturnNode() {}
298     virtual void compile(PyrSlot* result);
299     virtual void dump(int level);
300 
301     struct PyrParseNode* mExpr; // if null, return self
302 };
303 
304 struct PyrBlockReturnNode : public PyrParseNode {
PyrBlockReturnNodePyrBlockReturnNode305     PyrBlockReturnNode(): PyrParseNode(pn_BlockReturnNode) {}
~PyrBlockReturnNodePyrBlockReturnNode306     virtual ~PyrBlockReturnNode() {}
307     virtual void compile(PyrSlot* result);
308     virtual void dump(int level);
309 
310     struct PyrParseNode* mExpr; // if null, return self
311 };
312 
313 struct PyrAssignNode : public PyrParseNode {
PyrAssignNodePyrAssignNode314     PyrAssignNode(): PyrParseNode(pn_AssignNode) {}
~PyrAssignNodePyrAssignNode315     virtual ~PyrAssignNode() {}
316     virtual void compile(PyrSlot* result);
317     virtual void dump(int level);
318 
319     struct PyrSlotNode* mVarName;
320     struct PyrParseNode* mExpr;
321     bool mDrop; // allow drop
322 };
323 
324 struct PyrMultiAssignNode : public PyrParseNode {
PyrMultiAssignNodePyrMultiAssignNode325     PyrMultiAssignNode(): PyrParseNode(pn_MultiAssignNode) {}
~PyrMultiAssignNodePyrMultiAssignNode326     virtual ~PyrMultiAssignNode() {}
327     virtual void compile(PyrSlot* result);
328     virtual void dump(int level);
329 
330     struct PyrMultiAssignVarListNode* mVarList;
331     struct PyrParseNode* mExpr;
332     bool mDrop; // allow drop
333 };
334 
335 struct PyrMultiAssignVarListNode : public PyrParseNode {
PyrMultiAssignVarListNodePyrMultiAssignVarListNode336     PyrMultiAssignVarListNode(): PyrParseNode(pn_MultiAssignVarListNode) {}
~PyrMultiAssignVarListNodePyrMultiAssignVarListNode337     virtual ~PyrMultiAssignVarListNode() {}
338     virtual void compile(PyrSlot* result);
339     virtual void dump(int level);
340 
341     struct PyrSlotNode* mVarNames;
342     struct PyrSlotNode* mRest;
343 };
344 
345 struct PyrBlockNode : public PyrParseNode {
PyrBlockNodePyrBlockNode346     PyrBlockNode(): PyrParseNode(pn_BlockNode) {}
~PyrBlockNodePyrBlockNode347     virtual ~PyrBlockNode() {}
348     virtual void compile(PyrSlot* result);
349     virtual void dump(int level);
350 
351     struct PyrArgListNode* mArglist;
352     struct PyrVarListNode* mVarlist;
353     struct PyrParseNode* mBody;
354     bool mIsTopLevel;
355     int mBeginCharNo;
356 };
357 
358 struct PyrArgListNode : public PyrParseNode {
PyrArgListNodePyrArgListNode359     PyrArgListNode(): PyrParseNode(pn_ArgListNode) {}
~PyrArgListNodePyrArgListNode360     virtual ~PyrArgListNode() {}
361     virtual void compile(PyrSlot* result);
362     virtual void dump(int level);
363 
364     struct PyrVarDefNode* mVarDefs;
365     struct PyrSlotNode* mRest;
366 };
367 
368 struct PyrLitListNode : public PyrParseNode {
PyrLitListNodePyrLitListNode369     PyrLitListNode(): PyrParseNode(pn_LitListNode) {}
~PyrLitListNodePyrLitListNode370     virtual ~PyrLitListNode() {}
371     virtual void compile(PyrSlot* result);
372     virtual void dump(int level);
373 
374     struct PyrParseNode* mClassname;
375     struct PyrParseNode* mElems;
376 };
377 
378 struct PyrLitDictNode : public PyrParseNode {
PyrLitDictNodePyrLitDictNode379     PyrLitDictNode(): PyrParseNode(pn_LitDictNode) {}
~PyrLitDictNodePyrLitDictNode380     virtual ~PyrLitDictNode() {}
381     virtual void compile(PyrSlot* result);
382     virtual void dump(int level);
383 
384     struct PyrParseNode* mElems;
385 };
386 
387 extern PyrParseNode* gRootParseNode;
388 extern intptr_t gParserResult;
389 extern bool gIsTailCodeBranch;
390 extern bool gTailIsMethodReturn;
391 
392 extern bool compilingCmdLine;
393 
394 extern const char* nodename[];
395 
396 void compileNode(PyrParseNode* node, PyrSlot* result, bool onTailBranch);
397 
398 class SetTailBranch {
399     bool mSave;
400 
401 public:
SetTailBranch(bool inValue)402     SetTailBranch(bool inValue) {
403         mSave = gIsTailCodeBranch;
404         gIsTailCodeBranch = inValue;
405     }
~SetTailBranch()406     ~SetTailBranch() { gIsTailCodeBranch = mSave; }
407 };
408 
409 class SetTailIsMethodReturn {
410     bool mSave;
411 
412 public:
SetTailIsMethodReturn(bool inValue)413     SetTailIsMethodReturn(bool inValue) {
414         mSave = gTailIsMethodReturn;
415         gTailIsMethodReturn = inValue;
416     }
~SetTailIsMethodReturn()417     ~SetTailIsMethodReturn() { gTailIsMethodReturn = mSave; }
418 };
419 
compileNode(PyrParseNode * node,PyrSlot * result,bool onTailBranch)420 inline void compileNode(PyrParseNode* node, PyrSlot* result, bool onTailBranch) {
421     SetTailBranch branch(gIsTailCodeBranch && onTailBranch);
422     /*if (compilingCmdLine) {
423         printf("stb  %14s %d %d\n", nodename[node->mClassno], onTailBranch, gIsTailCodeBranch);
424     }*/
425     node->compile(result);
426 }
427 
428 void initParseNodes();
429 
430 PyrSlotNode* newPyrSlotNode(PyrSlot* slot);
431 PyrCurryArgNode* newPyrCurryArgNode();
432 PyrClassNode* newPyrClassNode(PyrSlotNode* className, PyrSlotNode* superClassName, PyrVarListNode* varlists,
433                               PyrMethodNode* methods, PyrSlotNode* indexType);
434 PyrClassExtNode* newPyrClassExtNode(PyrSlotNode* className, PyrMethodNode* methods);
435 PyrMethodNode* newPyrMethodNode(PyrSlotNode* methodName, PyrSlotNode* primitiveName, PyrArgListNode* arglist,
436                                 PyrVarListNode* varlist, PyrParseNode* body, int isClassMethod);
437 PyrArgListNode* newPyrArgListNode(PyrVarDefNode* varDefs, PyrSlotNode* rest);
438 PyrVarListNode* newPyrVarListNode(PyrVarDefNode* vardefs, int flags);
439 PyrVarDefNode* newPyrVarDefNode(PyrSlotNode* varName, PyrParseNode* defVal, int flags);
440 PyrCallNode* newPyrCallNode(PyrSlotNode* selector, PyrParseNode* arglist, PyrParseNode* keyarglist,
441                             PyrParseNode* blocklist);
442 PyrBinopCallNode* newPyrBinopCallNode(PyrSlotNode* selector, PyrParseNode* arg1, PyrParseNode* arg2,
443                                       PyrParseNode* arg3);
444 PyrDropNode* newPyrDropNode(PyrParseNode* expr1, PyrParseNode* expr2);
445 PyrPushKeyArgNode* newPyrPushKeyArgNode(PyrSlotNode* selector, PyrParseNode* expr);
446 PyrPushLitNode* newPyrPushLitNode(PyrSlotNode* literalSlot, PyrParseNode* literalObj);
447 PyrLiteralNode* newPyrLiteralNode(PyrSlotNode* literalSlot, PyrParseNode* literalObj);
448 PyrReturnNode* newPyrReturnNode(PyrParseNode* expr);
449 PyrBlockReturnNode* newPyrBlockReturnNode();
450 PyrAssignNode* newPyrAssignNode(PyrSlotNode* varName, PyrParseNode* expr, int flags);
451 PyrSetterNode* newPyrSetterNode(PyrSlotNode* varName, PyrParseNode* expr1, PyrParseNode* expr2);
452 PyrMultiAssignNode* newPyrMultiAssignNode(PyrMultiAssignVarListNode* varList, PyrParseNode* expr, int flags);
453 PyrPushNameNode* newPyrPushNameNode(PyrSlotNode* slotNode);
454 PyrDynDictNode* newPyrDynDictNode(PyrParseNode* elems);
455 PyrDynListNode* newPyrDynListNode(PyrParseNode* classname, PyrParseNode* elems);
456 PyrLitListNode* newPyrLitListNode(PyrParseNode* classname, PyrParseNode* elems);
457 PyrLitDictNode* newPyrLitDictNode(PyrParseNode* elems);
458 PyrMultiAssignVarListNode* newPyrMultiAssignVarListNode(PyrSlotNode* varNames, PyrSlotNode* rest);
459 PyrBlockNode* newPyrBlockNode(PyrArgListNode* arglist, PyrVarListNode* varlist, PyrParseNode* body, bool isTopLevel);
460 
461 void compilePyrMethodNode(PyrMethodNode* node, PyrSlot* result);
462 void compilePyrLiteralNode(PyrLiteralNode* node, PyrSlot* result);
463 
464 PyrClass* getNodeSuperclass(PyrClassNode* node);
465 void countNodeMethods(PyrClassNode* node, int* numClassMethods, int* numInstMethods);
466 void compileExtNodeMethods(PyrClassExtNode* node);
467 void countVarDefs(PyrClassNode* node);
468 bool compareVarDefs(PyrClassNode* node, PyrClass* classobj);
469 void recompileSubclasses(PyrClass* classobj);
470 void compileNodeMethods(PyrClassNode* node);
471 void fillClassPrototypes(PyrClassNode* node, PyrClass* classobj, PyrClass* superclassobj);
472 
473 int nodeListLength(PyrParseNode* node);
474 bool isSuperObjNode(PyrParseNode* node);
475 bool isThisObjNode(PyrParseNode* node);
476 int conjureSelectorIndex(PyrParseNode* node, PyrBlock* func, bool isSuper, PyrSymbol* selector, int* selType);
477 int conjureLiteralSlotIndex(PyrParseNode* node, PyrBlock* func, PyrSlot* slot);
478 bool findVarName(PyrBlock* func, PyrClass** classobj, PyrSymbol* name, int* varType, int* level, int* index,
479                  PyrBlock** tempfunc);
480 void countClassVarDefs(PyrClassNode* node, int* numClassMethods, int* numInstMethods);
481 void compileNodeList(PyrParseNode* node, bool onTailBranch);
482 void dumpNodeList(PyrParseNode* node);
483 int compareCallArgs(PyrMethodNode* node, PyrCallNode* cnode, int* varIndex, PyrClass* specialClass);
484 
485 bool findSpecialClassName(PyrSymbol* className, int* index);
486 int getIndexType(PyrClassNode* classnode);
487 
488 void compileAnyIfMsg(PyrCallNodeBase2* node);
489 void compileIfMsg(PyrCallNodeBase2* node);
490 void compileIfNilMsg(PyrCallNodeBase2* node, bool flag);
491 void compileCaseMsg(PyrCallNodeBase2* node);
492 void compileWhileMsg(PyrCallNodeBase2* node);
493 void compileLoopMsg(PyrCallNodeBase2* node);
494 void compileAndMsg(PyrParseNode* arg1, PyrParseNode* arg2);
495 void compileOrMsg(PyrParseNode* arg1, PyrParseNode* arg2);
496 void compileQMsg(PyrParseNode* arg1, PyrParseNode* arg2);
497 void compileQQMsg(PyrParseNode* arg1, PyrParseNode* arg2);
498 void compileXQMsg(PyrParseNode* arg1, PyrParseNode* arg2);
499 void compileSwitchMsg(PyrCallNode* node);
500 
501 void compilePushInt(int value);
502 void compileAssignVar(PyrParseNode* node, PyrSymbol* varName, bool drop);
503 void compilePushVar(PyrParseNode* node, PyrSymbol* varName);
504 bool isAnInlineableBlock(PyrParseNode* node);
505 bool isAnInlineableAtomicLiteralBlock(PyrParseNode* node);
506 bool isAtomicLiteral(PyrParseNode* node);
507 bool isWhileTrue(PyrParseNode* node);
508 void installByteCodes(PyrBlock* block);
509 
510 ByteCodes compileSubExpression(PyrPushLitNode* litnode, bool onTailBranch);
511 ByteCodes compileSubExpressionWithGoto(PyrPushLitNode* litnode, int branchLen, bool onTailBranch);
512 ByteCodes compileBodyWithGoto(PyrParseNode* body, int branchLen, bool onTailBranch);
513 // ByteCodes compileDefaultValue(int litIndex, int realExprLen);
514 
515 void initParser();
516 void finiParser();
517 void initParserPool();
518 void freeParserPool();
519 
520 void initSpecialSelectors();
521 void initSpecialClasses();
522 
523 void nodePostErrorLine(PyrParseNode* node);
524 
525 PyrParseNode* linkNextNode(PyrParseNode* a, PyrParseNode* b);
526 PyrParseNode* linkAfterHead(PyrParseNode* a, PyrParseNode* b);
527 
528 extern int compileErrors;
529 extern int numOverwrites;
530 extern std::string overwriteMsg;
531 
532 extern intptr_t zzval;
533 extern PyrSymbol* ps_newlist;
534 extern PyrSymbol* gSpecialUnarySelectors[opNumUnarySelectors];
535 extern PyrSymbol* gSpecialBinarySelectors[opNumBinarySelectors];
536 extern PyrSymbol* gSpecialSelectors[opmNumSpecialSelectors];
537 extern PyrSymbol* gSpecialClasses[op_NumSpecialClasses];
538 
539 extern PyrClass* gCurrentClass;
540 extern PyrClass* gCurrentMetaClass;
541 extern PyrClass* gCompilingClass;
542 extern PyrMethod* gCompilingMethod;
543 extern PyrBlock* gCompilingBlock;
544 
545 /*
546     compiling
547     "inlining" of special arithmetic opcodes.
548     inlining of IF, WHILE, AND, OR
549 */
550 
551 #define YYSTYPE intptr_t
552