class library: SynthDef - lazy implementation of removeUGen
[supercollider.git] / include / lang / PyrParseNode.h
blobca03c991ad39c1a662c38ba1e5c7fa47611be159
1 /*
2 SuperCollider real time audio synthesis system
3 Copyright (c) 2002 James McCartney. All rights reserved.
4 http://www.audiosynth.com
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.
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.
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
21 #ifndef _PYRPARSENODE_H_
22 #define _PYRPARSENODE_H_
24 #include "PyrSlot.h"
25 #include "PyrKernel.h"
26 #include "ByteCodeArray.h"
27 #include "Opcodes.h"
28 #include "AdvancingAllocPool.h"
31 enum { rwPrivate=0, rwReadOnly=1, rwWriteOnly=2, rwReadWrite=3 };
33 enum { varInst, varClass, varTemp, varConst, varPseudo, varLocal };
35 enum {
36 /* structural units */
37 pn_ClassNode,
38 pn_ClassExtNode,
39 pn_MethodNode,
40 pn_BlockNode,
41 pn_SlotNode,
43 /* variable declarations */
44 pn_VarListNode,
45 pn_VarDefNode,
46 pn_DynDictNode,
47 pn_DynListNode,
48 pn_LitListNode,
49 pn_LitDictNode,
51 pn_StaticVarListNode,
52 pn_InstVarListNode,
53 pn_PoolVarListNode,
54 pn_ArgListNode,
55 pn_SlotDefNode,
57 /* selectors */
58 pn_LiteralNode,
60 /* code */
61 pn_PushLitNode,
62 pn_PushNameNode,
63 pn_PushKeyArgNode,
64 pn_CallNode,
65 pn_BinopCallNode,
66 pn_DropNode,
67 pn_AssignNode,
68 pn_MultiAssignNode,
69 pn_MultiAssignVarListNode,
70 pn_SetterNode,
71 pn_CurryArgNode,
73 pn_ReturnNode,
74 pn_BlockReturnNode,
76 pn_NumTypes
79 extern AdvancingAllocPool gParseNodePool;
81 #define ALLOCNODE(type) (new (gParseNodePool.Alloc(sizeof(type))) type())
82 #define ALLOCSLOTNODE(type, classno) (new (gParseNodePool.Alloc(sizeof(type))) type(classno))
83 #define COMPILENODE(node, result, onTailBranch) (compileNode((node), (result), (onTailBranch)))
84 #define DUMPNODE(node, level) do { if (node) (node)->dump(level); } while (false);
86 struct PyrParseNode {
87 PyrParseNode(int classno);
88 virtual ~PyrParseNode() {}
89 virtual void compile(PyrSlot *result) = 0;
90 virtual void dump(int level) = 0;
92 struct PyrParseNode *mNext;
93 struct PyrParseNode *mTail;
94 int mLineno;
95 int mCharno;
96 unsigned char mClassno;
97 unsigned char mParens;
100 struct PyrSlotNode : public PyrParseNode {
101 PyrSlotNode() : PyrParseNode(pn_SlotNode) {}
102 PyrSlotNode(int classno) : PyrParseNode(classno) {}
103 virtual ~PyrSlotNode() {}
105 virtual void compile(PyrSlot *result);
106 virtual void compileLiteral(PyrSlot *result);
107 virtual void compilePushLit(PyrSlot *result);
108 virtual void dump(int level);
109 virtual void dumpLiteral(int level);
110 virtual void dumpPushLit(int level);
112 PyrSlot mSlot;
115 typedef PyrSlotNode PyrLiteralNode;
116 typedef PyrSlotNode PyrPushLitNode;
117 typedef PyrSlotNode PyrPushNameNode;
119 struct PyrCurryArgNode : public PyrParseNode {
120 PyrCurryArgNode() : PyrParseNode(pn_CurryArgNode), mArgNum(-1) {}
121 virtual ~PyrCurryArgNode() {}
122 virtual void compile(PyrSlot *result);
123 virtual void dump(int level);
125 int mArgNum;
130 struct PyrClassExtNode : public PyrParseNode {
131 PyrClassExtNode() : PyrParseNode(pn_ClassExtNode) {}
132 virtual ~PyrClassExtNode() {}
133 virtual void compile(PyrSlot *result);
134 virtual void dump(int level);
136 struct PyrSlotNode* mClassName;
137 struct PyrMethodNode *mMethods;
140 struct PyrClassNode : public PyrParseNode {
141 PyrClassNode() : PyrParseNode(pn_ClassNode) {}
142 virtual ~PyrClassNode() {}
143 virtual void compile(PyrSlot *result);
144 virtual void dump(int level);
146 struct PyrSlotNode* mClassName;
147 struct PyrSlotNode* mSuperClassName;
148 struct PyrSlotNode* mIndexType;
149 struct PyrVarListNode *mVarlists;
150 struct PyrMethodNode *mMethods;
151 int mVarTally[4];
152 int mNumSuperInstVars;
155 struct PyrMethodNode : public PyrParseNode {
156 PyrMethodNode() : PyrParseNode(pn_MethodNode) {}
157 virtual ~PyrMethodNode() {}
158 virtual void compile(PyrSlot *result);
159 virtual void dump(int level);
161 struct PyrSlotNode* mMethodName;
162 struct PyrSlotNode* mPrimitiveName;
163 struct PyrArgListNode *mArglist;
164 struct PyrVarListNode *mVarlist;
165 struct PyrParseNode *mBody;
166 int mIsClassMethod; // is class method?
167 bool mExtension;
170 struct PyrVarListNode : public PyrParseNode {
171 PyrVarListNode() : PyrParseNode(pn_VarListNode) {}
172 virtual ~PyrVarListNode() {}
173 virtual void compile(PyrSlot *result);
174 virtual void dump(int level);
176 struct PyrVarDefNode *mVarDefs;
177 int mFlags;
180 struct PyrVarDefNode : public PyrParseNode {
181 PyrVarDefNode() : PyrParseNode(pn_VarDefNode) {}
182 virtual ~PyrVarDefNode() {}
183 virtual void compile(PyrSlot *result);
184 virtual void compileArg(PyrSlot *result);
185 virtual void dump(int level);
186 bool hasExpr(PyrSlot *result);
188 struct PyrSlotNode* mVarName;
189 PyrParseNode* mDefVal;
190 int mFlags;
191 bool mDrop;
194 struct PyrCallNodeBase : public PyrParseNode {
195 PyrCallNodeBase(int classno) : PyrParseNode(classno) {}
196 virtual ~PyrCallNodeBase() {}
198 virtual void compile(PyrSlot *result);
199 virtual void compilePartialApplication(int numCurryArgs, PyrSlot *result);
200 virtual void compileCall(PyrSlot *result)=0;
202 virtual int isPartialApplication()=0;
205 struct PyrCallNodeBase2 : public PyrCallNodeBase {
206 PyrCallNodeBase2(int classno) : PyrCallNodeBase(classno) {}
207 virtual ~PyrCallNodeBase2() {}
209 struct PyrSlotNode* mSelector;
210 struct PyrParseNode *mArglist;
211 struct PyrParseNode *mKeyarglist;
212 bool mTailCall;
215 struct PyrCallNode : public PyrCallNodeBase2 {
216 PyrCallNode() : PyrCallNodeBase2(pn_CallNode) {}
217 virtual ~PyrCallNode() {}
219 virtual void compileCall(PyrSlot *result);
220 virtual void dump(int level);
222 virtual int isPartialApplication();
225 struct PyrBinopCallNode : public PyrCallNodeBase2 {
226 PyrBinopCallNode() : PyrCallNodeBase2(pn_BinopCallNode) {}
227 virtual ~PyrBinopCallNode() {}
229 virtual void compileCall(PyrSlot *result);
230 virtual void dump(int level);
232 virtual int isPartialApplication();
235 struct PyrSetterNode : public PyrCallNodeBase {
236 PyrSetterNode() : PyrCallNodeBase(pn_SetterNode) {}
237 virtual ~PyrSetterNode() {}
238 virtual void compileCall(PyrSlot *result);
239 virtual void dump(int level);
241 virtual int isPartialApplication();
243 struct PyrSlotNode* mSelector;
244 struct PyrParseNode *mExpr1;
245 struct PyrParseNode *mExpr2;
246 int mFlags; // is a var def ?
249 struct PyrDynListNode : public PyrCallNodeBase {
250 PyrDynListNode() : PyrCallNodeBase(pn_DynListNode) {}
251 virtual ~PyrDynListNode() {}
252 virtual void compileCall(PyrSlot *result);
253 virtual void dump(int level);
255 virtual int isPartialApplication();
257 struct PyrParseNode *mClassname;
258 struct PyrParseNode *mElems;
261 struct PyrDynDictNode : public PyrCallNodeBase {
262 PyrDynDictNode() : PyrCallNodeBase(pn_DynDictNode) {}
263 virtual ~PyrDynDictNode() {}
264 virtual void compileCall(PyrSlot *result);
265 virtual void dump(int level);
267 virtual int isPartialApplication();
269 struct PyrParseNode *mElems;
273 struct PyrDropNode : public PyrParseNode {
274 PyrDropNode() : PyrParseNode(pn_DropNode) {}
275 virtual ~PyrDropNode() {}
276 virtual void compile(PyrSlot *result);
277 virtual void dump(int level);
279 struct PyrParseNode *mExpr1;
280 struct PyrParseNode *mExpr2;
283 struct PyrPushKeyArgNode : public PyrParseNode {
284 PyrPushKeyArgNode() : PyrParseNode(pn_PushKeyArgNode) {}
285 virtual ~PyrPushKeyArgNode() {}
286 virtual void compile(PyrSlot *result);
287 virtual void dump(int level);
289 struct PyrSlotNode* mSelector;
290 struct PyrParseNode *mExpr;
293 struct PyrReturnNode : public PyrParseNode {
294 PyrReturnNode() : PyrParseNode(pn_ReturnNode) {}
295 virtual ~PyrReturnNode() {}
296 virtual void compile(PyrSlot *result);
297 virtual void dump(int level);
299 struct PyrParseNode *mExpr; // if null, return self
302 struct PyrBlockReturnNode : public PyrParseNode {
303 PyrBlockReturnNode() : PyrParseNode(pn_BlockReturnNode) {}
304 virtual ~PyrBlockReturnNode() {}
305 virtual void compile(PyrSlot *result);
306 virtual void dump(int level);
308 struct PyrParseNode *mExpr; // if null, return self
311 struct PyrAssignNode : public PyrParseNode {
312 PyrAssignNode() : PyrParseNode(pn_AssignNode) {}
313 virtual ~PyrAssignNode() {}
314 virtual void compile(PyrSlot *result);
315 virtual void dump(int level);
317 struct PyrSlotNode* mVarName;
318 struct PyrParseNode *mExpr;
319 bool mDrop; // allow drop
322 struct PyrMultiAssignNode : public PyrParseNode {
323 PyrMultiAssignNode() : PyrParseNode(pn_MultiAssignNode) {}
324 virtual ~PyrMultiAssignNode() {}
325 virtual void compile(PyrSlot *result);
326 virtual void dump(int level);
328 struct PyrMultiAssignVarListNode *mVarList;
329 struct PyrParseNode *mExpr;
330 bool mDrop; // allow drop
333 struct PyrMultiAssignVarListNode : public PyrParseNode {
334 PyrMultiAssignVarListNode() : PyrParseNode(pn_MultiAssignVarListNode) {}
335 virtual ~PyrMultiAssignVarListNode() {}
336 virtual void compile(PyrSlot *result);
337 virtual void dump(int level);
339 struct PyrSlotNode *mVarNames;
340 struct PyrSlotNode *mRest;
343 struct PyrBlockNode : public PyrParseNode {
344 PyrBlockNode() : PyrParseNode(pn_BlockNode) {}
345 virtual ~PyrBlockNode() {}
346 virtual void compile(PyrSlot *result);
347 virtual void dump(int level);
349 struct PyrArgListNode *mArglist;
350 struct PyrVarListNode *mVarlist;
351 struct PyrParseNode *mBody;
352 bool mIsTopLevel;
353 int mBeginCharNo;
356 struct PyrArgListNode : public PyrParseNode {
357 PyrArgListNode() : PyrParseNode(pn_ArgListNode) {}
358 virtual ~PyrArgListNode() {}
359 virtual void compile(PyrSlot *result);
360 virtual void dump(int level);
362 struct PyrVarDefNode *mVarDefs;
363 struct PyrSlotNode *mRest;
366 struct PyrLitListNode : public PyrParseNode {
367 PyrLitListNode() : PyrParseNode(pn_LitListNode) {}
368 virtual ~PyrLitListNode() {}
369 virtual void compile(PyrSlot *result);
370 virtual void dump(int level);
372 struct PyrParseNode *mClassname;
373 struct PyrParseNode *mElems;
376 struct PyrLitDictNode : public PyrParseNode {
377 PyrLitDictNode() : PyrParseNode(pn_LitDictNode) {}
378 virtual ~PyrLitDictNode() {}
379 virtual void compile(PyrSlot *result);
380 virtual void dump(int level);
382 struct PyrParseNode *mElems;
385 extern PyrParseNode* gRootParseNode;
386 extern int gParserResult;
387 extern bool gIsTailCodeBranch;
388 extern bool gTailIsMethodReturn;
390 extern bool compilingCmdLine;
392 extern const char* nodename[];
394 void compileNode(PyrParseNode* node, PyrSlot *result, bool onTailBranch);
396 class SetTailBranch
398 bool mSave;
399 public:
400 SetTailBranch(bool inValue) {
401 mSave = gIsTailCodeBranch;
402 gIsTailCodeBranch = inValue;
404 ~SetTailBranch() {
405 gIsTailCodeBranch = mSave;
409 class SetTailIsMethodReturn
411 bool mSave;
412 public:
413 SetTailIsMethodReturn(bool inValue) {
414 mSave = gTailIsMethodReturn;
415 gTailIsMethodReturn = inValue;
417 ~SetTailIsMethodReturn() {
418 gTailIsMethodReturn = mSave;
422 inline void compileNode(PyrParseNode* node, PyrSlot *result, bool onTailBranch)
424 SetTailBranch branch(gIsTailCodeBranch && onTailBranch);
425 /*if (compilingCmdLine) {
426 printf("stb %14s %d %d\n", nodename[node->mClassno], onTailBranch, gIsTailCodeBranch);
428 node->compile(result);
431 void initParseNodes();
433 PyrSlotNode* newPyrSlotNode(PyrSlot *slot);
434 PyrCurryArgNode* newPyrCurryArgNode();
435 PyrClassNode* newPyrClassNode(PyrSlotNode* className, PyrSlotNode* superClassName,
436 PyrVarListNode* varlists, PyrMethodNode* methods, PyrSlotNode* indexType);
437 PyrClassExtNode* newPyrClassExtNode(PyrSlotNode* className, PyrMethodNode* methods);
438 PyrMethodNode* newPyrMethodNode(PyrSlotNode* methodName, PyrSlotNode* primitiveName,
439 PyrArgListNode* arglist, PyrVarListNode *varlist, PyrParseNode* body, int isClassMethod);
440 PyrArgListNode* newPyrArgListNode(PyrVarDefNode* varDefs, PyrSlotNode* rest);
441 PyrVarListNode* newPyrVarListNode(PyrVarDefNode* vardefs, int flags);
442 PyrVarDefNode* newPyrVarDefNode(PyrSlotNode* varName, PyrParseNode* defVal, int flags);
443 PyrCallNode* newPyrCallNode(PyrSlotNode* selector, PyrParseNode* arglist,
444 PyrParseNode* keyarglist, PyrParseNode* blocklist);
445 PyrBinopCallNode* newPyrBinopCallNode(PyrSlotNode* selector,
446 PyrParseNode* arg1, PyrParseNode* arg2, PyrParseNode* arg3);
447 PyrDropNode* newPyrDropNode(PyrParseNode* expr1, PyrParseNode* expr2);
448 PyrPushKeyArgNode* newPyrPushKeyArgNode(PyrSlotNode* selector, PyrParseNode* expr);
449 PyrPushLitNode* newPyrPushLitNode(PyrSlotNode* literalSlot, PyrParseNode* literalObj);
450 PyrLiteralNode* newPyrLiteralNode(PyrSlotNode* literalSlot, PyrParseNode* literalObj);
451 PyrReturnNode* newPyrReturnNode(PyrParseNode* expr);
452 PyrBlockReturnNode* newPyrBlockReturnNode();
453 PyrAssignNode* newPyrAssignNode(PyrSlotNode* varName, PyrParseNode* expr, int flags);
454 PyrSetterNode* newPyrSetterNode(PyrSlotNode* varName,
455 PyrParseNode* expr1, PyrParseNode* expr2);
456 PyrMultiAssignNode* newPyrMultiAssignNode(PyrMultiAssignVarListNode* varList,
457 PyrParseNode* expr, int flags);
458 PyrPushNameNode* newPyrPushNameNode(PyrSlotNode *slotNode);
459 PyrDynDictNode* newPyrDynDictNode(PyrParseNode *elems);
460 PyrDynListNode* newPyrDynListNode(PyrParseNode *classname, PyrParseNode *elems);
461 PyrLitListNode* newPyrLitListNode(PyrParseNode *classname, PyrParseNode *elems);
462 PyrLitDictNode* newPyrLitDictNode(PyrParseNode *elems);
463 PyrMultiAssignVarListNode* newPyrMultiAssignVarListNode(PyrSlotNode* varNames,
464 PyrSlotNode* rest);
465 PyrBlockNode* newPyrBlockNode(PyrArgListNode *arglist, PyrVarListNode *varlist, PyrParseNode *body, bool isTopLevel);
467 void compilePyrMethodNode(PyrMethodNode* node, PyrSlot *result);
468 void compilePyrLiteralNode(PyrLiteralNode* node, PyrSlot *result);
470 PyrClass* getNodeSuperclass(PyrClassNode *node);
471 void countNodeMethods(PyrClassNode* node, int *numClassMethods, int *numInstMethods);
472 void compileExtNodeMethods(PyrClassExtNode* node);
473 void countVarDefs(PyrClassNode* node);
474 bool compareVarDefs(PyrClassNode* node, PyrClass* classobj);
475 void recompileSubclasses(PyrClass* classobj);
476 void compileNodeMethods(PyrClassNode* node);
477 void fillClassPrototypes(PyrClassNode *node, PyrClass *classobj, PyrClass *superclassobj);
479 int nodeListLength(PyrParseNode *node);
480 bool isSuperObjNode(PyrParseNode *node);
481 bool isThisObjNode(PyrParseNode *node);
482 int conjureSelectorIndex(PyrParseNode *node, PyrBlock* func,
483 bool isSuper, PyrSymbol *selector, int *selType);
484 int conjureLiteralSlotIndex(PyrParseNode *node, PyrBlock* func, PyrSlot *slot);
485 bool findVarName(PyrBlock* func, PyrClass **classobj, PyrSymbol *name,
486 int *varType, int *level, int *index, PyrBlock** tempfunc);
487 void countClassVarDefs(PyrClassNode* node, int *numClassMethods, int *numInstMethods);
488 void compileNodeList(PyrParseNode *node, bool onTailBranch);
489 void dumpNodeList(PyrParseNode *node);
490 int compareCallArgs(PyrMethodNode* node, PyrCallNode *cnode, int *varIndex, PyrClass *specialClass);
492 bool findSpecialClassName(PyrSymbol *className, int *index);
493 int getIndexType(PyrClassNode *classnode);
495 void compileAnyIfMsg(PyrCallNodeBase2* node);
496 void compileIfMsg(PyrCallNodeBase2* node);
497 void compileIfNilMsg(PyrCallNodeBase2* node, bool flag);
498 void compileCaseMsg(PyrCallNodeBase2* node);
499 void compileWhileMsg(PyrCallNodeBase2* node);
500 void compileLoopMsg(PyrCallNodeBase2* node);
501 void compileAndMsg(PyrParseNode* arg1, PyrParseNode* arg2);
502 void compileOrMsg(PyrParseNode* arg1, PyrParseNode* arg2);
503 void compileQMsg(PyrParseNode* arg1, PyrParseNode* arg2);
504 void compileQQMsg(PyrParseNode* arg1, PyrParseNode* arg2);
505 void compileXQMsg(PyrParseNode* arg1, PyrParseNode* arg2);
506 void compileSwitchMsg(PyrCallNode* node);
508 void compilePushInt(int value);
509 void compileAssignVar(PyrParseNode *node, PyrSymbol* varName, bool drop);
510 void compilePushVar(PyrParseNode *node, PyrSymbol *varName);
511 bool isAnInlineableBlock(PyrParseNode *node);
512 bool isAnInlineableAtomicLiteralBlock(PyrParseNode *node);
513 bool isAtomicLiteral(PyrParseNode *node);
514 bool isWhileTrue(PyrParseNode *node);
515 void installByteCodes(PyrBlock *block);
517 ByteCodes compileSubExpression(PyrPushLitNode* litnode, bool onTailBranch);
518 ByteCodes compileSubExpressionWithGoto(PyrPushLitNode* litnode, int branchLen, bool onTailBranch);
519 ByteCodes compileBodyWithGoto(PyrParseNode* body, int branchLen, bool onTailBranch);
520 //ByteCodes compileDefaultValue(int litIndex, int realExprLen);
522 void initParser();
523 void finiParser();
524 void initParserPool();
525 void freeParserPool();
527 void initSpecialSelectors();
528 void initSpecialClasses();
530 void nodePostErrorLine(PyrParseNode* node);
532 PyrParseNode* linkNextNode(PyrParseNode* a, PyrParseNode* b);
533 PyrParseNode* linkAfterHead(PyrParseNode* a, PyrParseNode* b);
535 extern int compileErrors;
536 extern int numOverwrites;
537 extern std::string overwriteMsg;
539 extern long zzval;
540 extern PyrSymbol *ps_newlist;
541 extern PyrSymbol *gSpecialUnarySelectors[opNumUnarySelectors];
542 extern PyrSymbol *gSpecialBinarySelectors[opNumBinarySelectors];
543 extern PyrSymbol *gSpecialSelectors[opmNumSpecialSelectors];
544 extern PyrSymbol* gSpecialClasses[op_NumSpecialClasses];
546 extern PyrClass *gCurrentClass;
547 extern PyrClass *gCurrentMetaClass;
548 extern PyrClass *gCompilingClass;
549 extern PyrMethod *gCompilingMethod;
550 extern PyrBlock *gCompilingBlock;
553 compiling
554 "inlining" of special arithmetic opcodes.
555 inlining of IF, WHILE, AND, OR
558 #define YYSTYPE long
560 #endif