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_
25 #include "PyrKernel.h"
26 #include "ByteCodeArray.h"
28 #include "AdvancingAllocPool.h"
31 enum { rwPrivate
=0, rwReadOnly
=1, rwWriteOnly
=2, rwReadWrite
=3 };
33 enum { varInst
, varClass
, varTemp
, varConst
, varPseudo
, varLocal
};
36 /* structural units */
43 /* variable declarations */
69 pn_MultiAssignVarListNode
,
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);
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
;
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
);
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
);
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
;
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?
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
;
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
;
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
;
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
;
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
);
400 SetTailBranch(bool inValue
) {
401 mSave
= gIsTailCodeBranch
;
402 gIsTailCodeBranch
= inValue
;
405 gIsTailCodeBranch
= mSave
;
409 class SetTailIsMethodReturn
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
,
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);
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
;
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
;
554 "inlining" of special arithmetic opcodes.
555 inlining of IF, WHILE, AND, OR