aboutsummaryrefslogtreecommitdiff
path: root/sc4pd/headers/lang
diff options
context:
space:
mode:
Diffstat (limited to 'sc4pd/headers/lang')
-rw-r--r--sc4pd/headers/lang/AdvancingAllocPool.h82
-rw-r--r--sc4pd/headers/lang/AllocPools.h34
-rw-r--r--sc4pd/headers/lang/ByteCodeArray.h50
-rw-r--r--sc4pd/headers/lang/FIFOT.h75
-rw-r--r--sc4pd/headers/lang/GC.h263
-rw-r--r--sc4pd/headers/lang/HashTable.h274
-rw-r--r--sc4pd/headers/lang/InitAlloc.h32
-rw-r--r--sc4pd/headers/lang/MiscInlineMath.h54
-rw-r--r--sc4pd/headers/lang/OSCData.h1
-rw-r--r--sc4pd/headers/lang/Opcodes.h426
-rw-r--r--sc4pd/headers/lang/PowerOfTwoAllocPool.h154
-rw-r--r--sc4pd/headers/lang/PredefinedSymbols.h29
-rw-r--r--sc4pd/headers/lang/PriorityQueue.h90
-rw-r--r--sc4pd/headers/lang/PyrArchiverT.h619
-rw-r--r--sc4pd/headers/lang/PyrDeepCopier.h221
-rw-r--r--sc4pd/headers/lang/PyrDeepFreezer.h178
-rw-r--r--sc4pd/headers/lang/PyrErrors.h49
-rw-r--r--sc4pd/headers/lang/PyrFilePrim.h62
-rw-r--r--sc4pd/headers/lang/PyrFileUtils.h50
-rw-r--r--sc4pd/headers/lang/PyrInterpreter.h47
-rw-r--r--sc4pd/headers/lang/PyrKernel.h256
-rw-r--r--sc4pd/headers/lang/PyrKernelProto.h62
-rw-r--r--sc4pd/headers/lang/PyrLexer.h136
-rw-r--r--sc4pd/headers/lang/PyrListPrim.h34
-rw-r--r--sc4pd/headers/lang/PyrMathPrim.h51
-rw-r--r--sc4pd/headers/lang/PyrMessage.h55
-rw-r--r--sc4pd/headers/lang/PyrObject.h288
-rw-r--r--sc4pd/headers/lang/PyrObjectProto.h44
-rw-r--r--sc4pd/headers/lang/PyrParseNode.h456
-rw-r--r--sc4pd/headers/lang/PyrPrimitive.h42
-rw-r--r--sc4pd/headers/lang/PyrPrimitiveProto.h81
-rw-r--r--sc4pd/headers/lang/PyrSched.h58
-rw-r--r--sc4pd/headers/lang/PyrSignal.h417
-rw-r--r--sc4pd/headers/lang/PyrSignalPrim.h56
-rw-r--r--sc4pd/headers/lang/PyrSlot.h286
-rw-r--r--sc4pd/headers/lang/PyrSymbol.h59
-rw-r--r--sc4pd/headers/lang/PyrSymbolTable.h78
-rw-r--r--sc4pd/headers/lang/ReadWriteMacros.h336
-rw-r--r--sc4pd/headers/lang/SCBase.h68
-rw-r--r--sc4pd/headers/lang/SC_ComPort.h118
-rw-r--r--sc4pd/headers/lang/SC_LanguageClient.h164
-rw-r--r--sc4pd/headers/lang/SC_LibraryConfig.h108
-rw-r--r--sc4pd/headers/lang/SC_List.h229
-rw-r--r--sc4pd/headers/lang/SC_LogFile.h29
-rw-r--r--sc4pd/headers/lang/SC_Msg.h70
-rw-r--r--sc4pd/headers/lang/SC_SynthImpl.h42
-rw-r--r--sc4pd/headers/lang/SC_TerminalClient.h92
-rw-r--r--sc4pd/headers/lang/SC_UnorderedList.h60
-rw-r--r--sc4pd/headers/lang/SFHeaders.h140
-rw-r--r--sc4pd/headers/lang/Samp.h46
-rw-r--r--sc4pd/headers/lang/SimpleStack.h32
-rw-r--r--sc4pd/headers/lang/VMGlobals.h94
-rw-r--r--sc4pd/headers/lang/bullet.h7
-rw-r--r--sc4pd/headers/lang/libraryConfig.h31
-rw-r--r--sc4pd/headers/lang/readSamples.h1
55 files changed, 6916 insertions, 0 deletions
diff --git a/sc4pd/headers/lang/AdvancingAllocPool.h b/sc4pd/headers/lang/AdvancingAllocPool.h
new file mode 100644
index 0000000..b89d69b
--- /dev/null
+++ b/sc4pd/headers/lang/AdvancingAllocPool.h
@@ -0,0 +1,82 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+/*
+
+AdvancingAllocPool implements a simple advancing pointer allocation scheme.
+There is no Free(). All objects in the pool are freed at once with FreeAll().
+Thus it is very fast.
+
+*/
+
+#ifndef _AdvancingAllocPool_
+#define _AdvancingAllocPool_
+
+#include <stdexcept>
+#include <stdlib.h>
+
+class AllocPool;
+
+struct AdvancingAllocPoolChunk;
+
+typedef int int32;
+
+inline void FailNil(void *ptr) {
+ if (!ptr) throw std::runtime_error("alloc failed");
+}
+
+struct AdvancingAllocPoolChunkHdr {
+ AdvancingAllocPoolChunk *mNext;
+ size_t mSize;
+ int32 mPad1, mPad2;
+};
+
+struct AdvancingAllocPoolChunk {
+ AdvancingAllocPoolChunk *mNext;
+ size_t mSize;
+ int32 mPad1, mPad2;
+ char mSpace[16];
+};
+
+class AdvancingAllocPool
+{
+public:
+ AdvancingAllocPool();
+ ~AdvancingAllocPool() { FreeAll(); }
+
+ void Init(AllocPool *inAllocPool, size_t initSize, size_t growSize, size_t tooBigSize);
+
+ void *Alloc(size_t inBytes);
+ void FreeAll();
+
+ bool SanityCheck();
+
+private:
+ void AddChunk(size_t inSize);
+
+ AllocPool* mAllocPool;
+ size_t mInitSize;
+ size_t mGrowSize;
+ size_t mCurSize;
+ size_t mTooBig;
+ AdvancingAllocPoolChunk *mChunks;
+ AdvancingAllocPoolChunk *mFatties;
+};
+
+#endif
diff --git a/sc4pd/headers/lang/AllocPools.h b/sc4pd/headers/lang/AllocPools.h
new file mode 100644
index 0000000..111f7c3
--- /dev/null
+++ b/sc4pd/headers/lang/AllocPools.h
@@ -0,0 +1,34 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+/*
+
+Pools for memory allocation.
+
+*/
+
+
+#ifndef _AllocPools_
+#define _AllocPools_
+
+class AllocPool;
+extern AllocPool *pyr_pool_compile;
+extern AllocPool *pyr_pool_runtime;
+
+#endif
diff --git a/sc4pd/headers/lang/ByteCodeArray.h b/sc4pd/headers/lang/ByteCodeArray.h
new file mode 100644
index 0000000..5ec1520
--- /dev/null
+++ b/sc4pd/headers/lang/ByteCodeArray.h
@@ -0,0 +1,50 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+typedef unsigned char Byte;
+
+#define BYTE_CODE_CHUNK_SIZE 64
+
+typedef struct {
+ Byte *bytes;
+ Byte *ptr;
+ long size;
+} ByteCodeArray, *ByteCodes;
+
+extern ByteCodes gCompilingByteCodes;
+extern long totalByteCodes;
+
+void initByteCodes();
+void compileByte(long byte);
+void compileAndFreeByteCodes(ByteCodes byteCodes);
+void copyByteCodes(Byte *dest, ByteCodes byteCodes);
+ByteCodes getByteCodes();
+ByteCodes saveByteCodeArray();
+void restoreByteCodeArray(ByteCodes byteCodes);
+int byteCodeLength(ByteCodes byteCodes);
+void compileByteCodes(ByteCodes byteCodes);
+ByteCodes allocByteCodes();
+void reallocByteCodes(ByteCodes byteCodes);
+void freeByteCodes(ByteCodes byteCodes);
+int compileOpcode(long opcode, long operand1);
+void compileJump(long opcode, long jumplen);
+int compileNumber(unsigned long value);
+int compileNumber24(unsigned long value);
+
diff --git a/sc4pd/headers/lang/FIFOT.h b/sc4pd/headers/lang/FIFOT.h
new file mode 100644
index 0000000..52b6203
--- /dev/null
+++ b/sc4pd/headers/lang/FIFOT.h
@@ -0,0 +1,75 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+/*
+
+A Fifo for sending/receiving some type of object.
+
+*/
+
+#ifndef _FIFOT_
+#define _FIFOT_
+
+template <class T, int N> class FIFOT
+{
+public:
+ FIFOT()
+ : mMask(N-1), mReadHead(0), mWriteHead(0)
+ {
+ }
+ void MakeEmpty() { mReadHead = mWriteHead; }
+ bool IsEmpty() { return mReadHead == mWriteHead; }
+ int CanGet() {
+ int diff = mWriteHead - mReadHead;
+ return diff >= 0 ? diff : N - diff;
+ }
+ int CanPut() { return N-1-CanGet(); }
+
+ int NextPos(int inPos) { return (inPos + 1) & mMask; }
+
+ bool Put(const T& inItem)
+ {
+ long next = NextPos(mWriteHead);
+ if (next == mReadHead) return false; // fifo is full
+ mItems[next] = inItem;
+ mWriteHead = next;
+ return true;
+ }
+
+ bool Get(T& outItem) // get next and advance
+ {
+ if (IsEmpty()) return false;
+ long next = NextPos(mReadHead);
+ outItem = mItems[next];
+ mReadHead = next;
+ return true;
+ }
+ void DebugDump()
+ {
+ post("FIFO N %d mMask %d mReadHead %d mWriteHead%d\n",
+ N, mMask, mReadHead, mWriteHead);
+ }
+
+private:
+ long mMask;
+ volatile long mReadHead, mWriteHead;// mReclaimHead;
+ T mItems[N];
+};
+
+#endif \ No newline at end of file
diff --git a/sc4pd/headers/lang/GC.h b/sc4pd/headers/lang/GC.h
new file mode 100644
index 0000000..4dc162a
--- /dev/null
+++ b/sc4pd/headers/lang/GC.h
@@ -0,0 +1,263 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+/*
+
+The garbage collector for SuperCollider.
+Based on Wilson and Johnstone's real time collector and the Baker treadmill.
+
+*/
+
+#ifndef _GC_
+#define _GC_
+
+#include "PyrObject.h"
+#include "VMGlobals.h"
+#include "AdvancingAllocPool.h"
+
+void DumpSimpleBackTrace(VMGlobals *g);
+
+const int kMaxPoolSet = 7;
+const int kNumGCSizeClasses = 28;
+const int kFinalizerSet = kNumGCSizeClasses;
+const int kNumGCSets = kNumGCSizeClasses + 1;
+
+class GCSet
+{
+public:
+ GCSet() {}
+ void Init(int inSizeClass);
+
+ bool HasFree() { return mFree != &mBlack; }
+
+private:
+ friend class PyrGC;
+
+ void MoveWhiteToFree();
+
+ PyrObjectHdr mBlack;
+ PyrObjectHdr mWhite;
+ PyrObjectHdr* mFree;
+};
+
+struct SlotRef {
+ SlotRef(PyrObject* inObj, int32 inIndex) : obj(inObj), slotIndex(inIndex) {}
+
+ PyrObject *obj;
+ int32 slotIndex;
+};
+
+class PyrGC
+{
+public:
+ PyrGC(VMGlobals *g, AllocPool *inPool, PyrClass *mainProcessClass, long poolSize);
+
+ PyrObject* New(size_t inNumBytes, long inFlags, long inFormat, bool inCollect);
+
+ static PyrObject* NewPermanent(size_t inNumBytes,
+ long inFlags, long inFormat);
+
+ PyrObject* NewFinalizer(ObjFuncPtr finalizeFunc, PyrObject *inObject, bool inCollect);
+
+ int32 ProcessID() { return mProcessID; }
+
+#if 0
+// Codewarrior is not inlining these.. why?
+ bool IsBlack(PyrObjectHdr* inObj) { return inObj->gc_color == mBlackColor; }
+ bool IsWhite(PyrObjectHdr* inObj) { return inObj->gc_color == mWhiteColor; }
+ bool IsGrey(PyrObjectHdr* inObj) { return inObj->gc_color == mGreyColor; }
+ bool IsMarker(PyrObjectHdr* inObj) { return inObj->gc_color == obj_gcmarker; }
+#else
+
+#define IsBlack(inObj) ((inObj)->gc_color == mBlackColor)
+#define IsWhite(inObj) ((inObj)->gc_color == mWhiteColor)
+#define IsGrey(inObj) ((inObj)->gc_color == mGreyColor)
+#define IsFree(inObj) (!(IsMarker(inObj) || inObj->IsPermanent() || \
+ IsBlack(inObj) || IsWhite(inObj) || IsGrey(inObj)))
+#define IsMarker(inObj) ((inObj)->gc_color == obj_gcmarker)
+#endif
+
+ bool ObjIsBlack(PyrObjectHdr* inObj) { return IsBlack(inObj); }
+ bool ObjIsGrey(PyrObjectHdr* inObj) { return IsGrey(inObj); }
+ bool ObjIsFree(PyrObjectHdr* inObj) { return IsFree(inObj); }
+
+
+ // general purpose write barriers:
+ void GCWrite(PyrObjectHdr* inParent, PyrSlot* inSlot)
+ {
+ if (IsBlack(inParent) && IsObj(inSlot) && IsWhite(inSlot->uo)) {
+ ToGrey(inSlot->uo);
+ }
+ }
+ void GCWrite(PyrObjectHdr* inParent, PyrObjectHdr* inChild)
+ {
+ if (IsBlack(inParent) && IsWhite(inChild)) {
+ ToGrey(inChild);
+ }
+ }
+ // when you know the parent is black:
+ void GCWriteBlack(PyrSlot* inSlot)
+ {
+ if (IsObj(inSlot)) {
+ if (IsWhite(inSlot->uo)) {
+ ToGrey(inSlot->uo);
+ }
+ }
+ }
+ void GCWriteBlack(PyrObjectHdr* inChild)
+ {
+ if (IsWhite(inChild)) {
+ ToGrey(inChild);
+ }
+ }
+ // when you know the child is white
+ void GCWriteNew(PyrObjectHdr* inParent, PyrObjectHdr* inChild)
+ {
+ if (IsBlack(inParent)) {
+ ToGrey(inChild);
+ }
+ }
+
+// users should not call anything below.
+
+ void Collect();
+ void Collect(int32 inNumToScan);
+ void FullCollection();
+ void ScanFinalizers();
+ GCSet* GetGCSet(PyrObjectHdr* inObj);
+ void CompletePartialScan(PyrObject *obj);
+
+ void ToGrey(PyrObjectHdr* inObj);
+ void ToGrey2(PyrObjectHdr* inObj);
+ void ToBlack(PyrObjectHdr* inObj);
+ void ToWhite(PyrObjectHdr *obj);
+
+ int32 StackDepth() { return mVMGlobals->sp - mStack->slots + 1; }
+ PyrObject* Stack() { return mStack; }
+ void SetStack(PyrObject* inStack) { mStack = inStack; }
+
+ bool SanityCheck();
+ bool SanityCheck2();
+ bool LinkSanity();
+ bool ListSanity();
+ bool BlackToWhiteCheck(PyrObject *objA);
+ bool SanityMarkObj(PyrObject *objA, PyrObject *fromObj, int level);
+ bool SanityClearObj(PyrObject *objA, int level);
+ void DumpInfo();
+ void DumpEverything();
+
+ void BecomePermanent(PyrObject *inObject);
+ void BecomeImmutable(PyrObject *inObject);
+
+private:
+ void Free(PyrObject* inObj);
+ void ScanSlots(PyrSlot *inSlots, long inNumToScan);
+ void SweepBigObjects();
+ void DoPartialScan(int32 inObjSize);
+ bool ScanOneObj();
+ void Flip();
+ void ScanStack();
+ void DLRemove(PyrObjectHdr *obj);
+ void DLInsertAfter(PyrObjectHdr *after, PyrObjectHdr *obj);
+ void DLInsertBefore(PyrObjectHdr *before, PyrObjectHdr *obj);
+
+ void ClearMarks();
+ void Finalize(PyrObject *obj);
+
+ VMGlobals *mVMGlobals;
+ AllocPool *mPool;
+ AdvancingAllocPool mNewPool;
+ GCSet mSets[kNumGCSets];
+ PyrProcess *mProcess; // the root is the pyrprocess which contains this struct
+ PyrObject *mStack;
+ PyrObject *mPartialScanObj;
+ PyrObjectHdr mGrey;
+
+ GCSet *mPartialScanSet;
+ int32 mPartialScanSlot;
+ int32 mNumToScan;
+ int32 mNumGrey;
+ int32 mCurSet;
+
+ int32 mFlips, mCollects, mAllocTotal, mScans, mNumAllocs;
+
+ unsigned char mBlackColor, mGreyColor, mWhiteColor, mFreeColor;
+ int8 mProcessID;
+ bool mCanSweep;
+ bool mRunning;
+};
+
+inline void PyrGC::DLRemove(PyrObjectHdr *obj)
+{
+ obj->next->prev = obj->prev;
+ obj->prev->next = obj->next;
+}
+
+inline void PyrGC::DLInsertAfter(PyrObjectHdr *after, PyrObjectHdr *obj)
+{
+ obj->next = after->next;
+ obj->prev = after;
+ after->next->prev = obj;
+ after->next = obj;
+}
+
+inline void PyrGC::DLInsertBefore(PyrObjectHdr *before, PyrObjectHdr *obj)
+{
+ obj->prev = before->prev;
+ obj->next = before;
+ before->prev->next = obj;
+ before->prev = obj;
+}
+
+inline GCSet* PyrGC::GetGCSet(PyrObjectHdr* inObj)
+{
+ return mSets + (inObj->classptr == class_finalizer ? kFinalizerSet : inObj->obj_sizeclass);
+}
+
+inline void PyrGC::ToBlack(PyrObjectHdr *obj)
+{
+ if (IsGrey(obj)) {
+ mNumGrey--;
+ //post("ToBlack %d\n", mNumGrey);
+ }
+
+ DLRemove(obj);
+
+ GCSet *gcs = GetGCSet(obj);
+ DLInsertAfter(&gcs->mBlack, obj);
+
+ obj->gc_color = mBlackColor;
+}
+
+inline void PyrGC::ToWhite(PyrObjectHdr *obj)
+{
+ if (IsGrey(obj)) {
+ mNumGrey--;
+ //post("ToWhite %d\n", mNumGrey);
+ }
+
+ DLRemove(obj);
+
+ GCSet *gcs = GetGCSet(obj);
+ DLInsertAfter(&gcs->mWhite, obj);
+
+ obj->gc_color = mWhiteColor;
+}
+
+#endif
diff --git a/sc4pd/headers/lang/HashTable.h b/sc4pd/headers/lang/HashTable.h
new file mode 100644
index 0000000..835f593
--- /dev/null
+++ b/sc4pd/headers/lang/HashTable.h
@@ -0,0 +1,274 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#ifndef _HashTable_
+#define _HashTable_
+
+#include "SC_Types.h"
+#include "SC_BoundsMacros.h"
+#include "Hash.h"
+#include <stddef.h>
+
+template<class T, class Allocator, class KeyType>
+class HashTable
+{
+ Allocator *mPool;
+ int32 mNumItems, mMaxItems, mTableSize, mHashMask;
+ T** mItems;
+ bool mCanResize;
+
+public:
+
+ HashTable(Allocator *inPool, int32 inMaxItems, bool inCanResize = true)
+ : mPool(inPool)
+ {
+ mNumItems = 0;
+ mMaxItems = inMaxItems;
+ mTableSize = mMaxItems << 1;
+ mItems = AllocTable(mTableSize);
+ mHashMask = mTableSize - 1;
+ mCanResize = inCanResize;
+ }
+
+ ~HashTable() {
+ mPool->Free(mItems);
+ }
+
+ int32 TableSize() const { return mTableSize; }
+ int32 MaxItems() const { return mMaxItems; }
+ int32 NumItems() const { return mNumItems; }
+
+ T** AllocTable(int inTableSize)
+ {
+ size_t size = inTableSize * sizeof(T*);
+ T** items = static_cast<T**>(mPool->Alloc(size));
+ for (int i=0; i<inTableSize; ++i) {
+ items[i] = 0;
+ }
+ return items;
+ }
+
+ void Resize()
+ {
+ int32 newSize = sc_max(mTableSize << 1, 32);
+ T** oldItems = mItems;
+ mItems = AllocTable(newSize);
+ for (int i=0; i<mTableSize; ++i) {
+ T* item = oldItems[i];
+ if (item) Add(item);
+ }
+ mTableSize = newSize;
+ mMaxItems = mTableSize >> 1;
+ mHashMask = mTableSize - 1;
+ mPool->Free(oldItems);
+ //printf("mMaxItems %d mTableSize %d newSize %d\n", mMaxItems, mTableSize, newSize);
+ }
+
+ bool Add(T* inItem)
+ {
+ //printf("mNumItems %d\n", mNumItems);
+ //printf("mMaxItems %d\n", mMaxItems);
+ //printf("mCanResize %d\n", mCanResize);
+ if (mNumItems >= mMaxItems) {
+ if (!mCanResize) return false;
+ Resize();
+ }
+
+ //printf("GetHash(inItem) %d\n", GetHash(inItem));
+ //printf("GetKey(inItem) %s\n", GetKey(inItem));
+ int32 index = IndexFor(GetHash(inItem), GetKey(inItem));
+ //printf("index %d\n", index);
+
+ T *item = mItems[index];
+ if (item) return item == inItem;
+
+ mItems[index] = inItem;
+ mNumItems++;
+ return true;
+ }
+
+ bool Remove(T* inItem)
+ {
+ int32 index = IndexFor(GetHash(inItem), GetKey(inItem));
+ if (mItems[index] != inItem) return false;
+ mItems[index] = 0;
+
+ FixCollisionsFrom(index);
+ mNumItems--;
+ return true;
+ }
+
+ int32 IndexFor(int32 inHashID, KeyType inKey) const
+ {
+ int index = inHashID & mHashMask;
+ for(;;) {
+ T *item = mItems[index];
+ if (!item) return index;
+ if (GetHash(item) == inHashID
+ && strcmp(inKey, GetKey(item)) == 0) return index;
+ index = (index + 1) & mHashMask;
+ }
+ }
+
+ T* Get(KeyType inKey) const
+ {
+ return Get(Hash(inKey), inKey);
+ }
+
+ T* Get(int32 inHashID, KeyType inKey) const
+ {
+ int32 index = IndexFor(inHashID, inKey);
+ return mItems[index];
+ }
+
+ bool Includes(T* inItem) const
+ {
+ return Get(GetHash(inItem), GetKey(inItem)) == inItem;
+ }
+
+ T* AtIndex(int32 inIndex) const
+ {
+ return mItems[inIndex];
+ }
+
+private:
+ void FixCollisionsFrom(int32 inIndex)
+ {
+ int oldIndex = inIndex;
+ for (;;) {
+ oldIndex = (oldIndex + 1) & mHashMask;
+ T *oldItem = mItems[oldIndex];
+ if (!oldItem) break;
+ int newIndex = IndexFor(GetHash(oldItem), GetKey(oldItem));
+ if (oldIndex != newIndex) {
+ mItems[oldIndex] = mItems[newIndex];
+ mItems[newIndex] = oldItem;
+ }
+ }
+ }
+};
+
+template<class T, int kMaxItems, class KeyType>
+class StaticHashTable
+{
+ int32 mNumItems, mTableSize, mHashMask;
+ T* mItems[kMaxItems*2];
+
+public:
+
+ StaticHashTable()
+ {
+ mNumItems = 0;
+ mTableSize = kMaxItems << 1;
+ ClearTable();
+ mHashMask = mTableSize - 1;
+ }
+
+ ~StaticHashTable() {
+ }
+
+ int32 TableSize() const { return mTableSize; }
+ int32 MaxItems() const { return kMaxItems; }
+ int32 NumItems() const { return mNumItems; }
+
+ void ClearTable()
+ {
+ for (int i=0; i<mTableSize; ++i) {
+ mItems[i] = 0;
+ }
+ }
+
+ bool Add(T* inItem)
+ {
+ if (mNumItems >= kMaxItems) return false;
+
+ int32 index = IndexFor(GetHash(inItem), GetKey(inItem));
+
+ T *item = mItems[index];
+ if (item) return item == inItem;
+
+ mItems[index] = inItem;
+ mNumItems++;
+ return true;
+ }
+
+ bool Remove(T* inItem)
+ {
+ int32 index = IndexFor(GetHash(inItem), GetKey(inItem));
+ if (mItems[index] != inItem) return false;
+ mItems[index] = 0;
+
+ FixCollisionsFrom(index);
+ mNumItems--;
+ return true;
+ }
+
+ int32 IndexFor(int32 inHashID, KeyType inKey) const
+ {
+ int index = inHashID & mHashMask;
+ for(;;) {
+ T *item = mItems[index];
+ if (!item) return index;
+ if (GetHash(item) == inHashID
+ && strcmp(inKey, GetKey(item)) == 0) return index;
+ index = (index + 1) & mHashMask;
+ }
+ }
+
+ T* Get(KeyType inKey) const
+ {
+ return Get(Hash(inKey), inKey);
+ }
+
+ T* Get(int32 inHashID, KeyType inKey) const
+ {
+ int32 index = IndexFor(inHashID, inKey);
+ return mItems[index];
+ }
+
+ bool Includes(T* inItem) const
+ {
+ return Get(GetHash(inItem), GetKey(inItem)) == inItem;
+ }
+
+ T* AtIndex(int32 inIndex) const
+ {
+ return mItems[inIndex];
+ }
+
+private:
+ void FixCollisionsFrom(int32 inIndex)
+ {
+ int oldIndex = inIndex;
+ for (;;) {
+ oldIndex = (oldIndex + 1) & mHashMask;
+ T *oldItem = mItems[oldIndex];
+ if (!oldItem) break;
+ int newIndex = IndexFor(GetHash(oldItem), GetKey(oldItem));
+ if (oldIndex != newIndex) {
+ mItems[oldIndex] = mItems[newIndex];
+ mItems[newIndex] = oldItem;
+ }
+ }
+ }
+};
+
+
+#endif
diff --git a/sc4pd/headers/lang/InitAlloc.h b/sc4pd/headers/lang/InitAlloc.h
new file mode 100644
index 0000000..762b940
--- /dev/null
+++ b/sc4pd/headers/lang/InitAlloc.h
@@ -0,0 +1,32 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#ifndef _InitAlloc_
+#define _InitAlloc_
+
+#include "SCBase.h"
+#include "SC_AllocPool.h"
+#include <stdexcept>
+
+#define MEMFAIL(ptr) if (!(ptr)) { throw std::runtime_error("Out of memory!\n"); }
+#define MEMFAILED throw std::runtime_error("Out of memory!\n");
+
+#endif
+
diff --git a/sc4pd/headers/lang/MiscInlineMath.h b/sc4pd/headers/lang/MiscInlineMath.h
new file mode 100644
index 0000000..6dd33ab
--- /dev/null
+++ b/sc4pd/headers/lang/MiscInlineMath.h
@@ -0,0 +1,54 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#define NUMPRIMES 6542
+long nthPrime(int n);
+long findPrime(int n);
+long prevPrime(int n);
+long nextPrime(int n);
+
+
+inline double linlin(double x, double a, double b, double c, double d)
+{
+ if (x <= a) return c;
+ if (x >= b) return d;
+ return (x-a)/(b-a) * (d-c) + c;
+}
+
+inline double explin(double x, double a, double b, double c, double d)
+{
+ if (x <= a) return c;
+ if (x >= b) return d;
+ return (log(x/a)) / (log(b/a)) * (d-c) + c;
+}
+
+inline double expexp(double x, double a, double b, double c, double d)
+{
+ if (x <= a) return c;
+ if (x >= b) return d;
+ return pow(d/c, log(x/a)) / (log(b/a)) * c;
+}
+
+inline double linexp(double x, double a, double b, double c, double d)
+{
+ if (x <= a) return c;
+ if (x >= b) return d;
+ return pow(d/c, (x-a)/(b-a)) * c;
+}
diff --git a/sc4pd/headers/lang/OSCData.h b/sc4pd/headers/lang/OSCData.h
new file mode 100644
index 0000000..b2721b0
--- /dev/null
+++ b/sc4pd/headers/lang/OSCData.h
@@ -0,0 +1 @@
+/* SuperCollider real time audio synthesis system Copyright (c) 2002 James McCartney. All rights reserved. http://www.audiosynth.com This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _OSCData_ #define _OSCData_ #include "PyrObject.h" #include "FIFOT.h" #include <netinet/in.h> #endif \ No newline at end of file
diff --git a/sc4pd/headers/lang/Opcodes.h b/sc4pd/headers/lang/Opcodes.h
new file mode 100644
index 0000000..c5e1c7a
--- /dev/null
+++ b/sc4pd/headers/lang/Opcodes.h
@@ -0,0 +1,426 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#ifndef _OPCODES_H_
+#define _OPCODES_H_
+
+/* opcodes */
+enum {
+ opExtended, // 0
+ opPushInstVar,
+ opPushTempVar,
+ opPushTempZeroVar,
+ opPushLiteral,
+ opPushClassVar, // 5
+ opPushSpecialValue,
+ opStoreInstVar,
+ opStoreTempVar,
+ opStoreClassVar,
+ opSendMsg, // 10
+ opSendSuper,
+ opSendSpecialMsg,
+ opSendSpecialUnaryArithMsg,
+ opSendSpecialBinaryArithMsg,
+ opSpecialOpcode, // 15
+
+
+ opNumOpcodes
+};
+
+/* special opcodes */
+enum {
+ opcDrop, // 0
+ opcDup,
+ opcFunctionReturn,
+ opcReturn,
+ opcReturnSelf,
+ opcReturnTrue, // 5
+ opcReturnFalse,
+ opcReturnNil,
+ opcJumpIfFalse, // IF 3 args
+ opcJumpIfFalsePushNil, // IF 2 args
+ opcJumpIfFalsePushFalse, // AND: (10)
+ opcJumpIfTruePushTrue, // OR:
+ opcJumpFwd,
+ opcJumpBak,
+ opcSpecialBinaryOpWithAdverb,
+ opcSuperNew, // 15
+
+ opcNewList,
+
+ opcNumSpecialOpcodes
+/*
+ opcSlotAt,
+ opcByteAt, // 15
+ opcShortAt,
+ opcInt32At,
+ opcColorAt,
+ opcFloatAt,
+ opcDoubleAt
+*/
+};
+
+/* special unary math operators */
+enum {
+ opNeg,
+ opNot,
+ opIsNil,
+ opNotNil,
+ opBitNot,
+ opAbs,
+ opAsFloat,
+ opAsInt,
+ opCeil, //5
+ opFloor,
+ opFrac,
+ opSign,
+ opSquared,
+ opCubed, //10
+ opSqrt,
+ opExp,
+ opRecip,
+ opMIDICPS,
+ opCPSMIDI, //15
+
+ opMIDIRatio,
+ opRatioMIDI,
+ opDbAmp,
+ opAmpDb,
+ opOctCPS, //20
+ opCPSOct,
+ opLog,
+ opLog2,
+ opLog10,
+ opSin, //25
+ opCos,
+ opTan,
+ opArcSin,
+ opArcCos,
+ opArcTan,
+ opSinH,
+ opCosH, //30
+ opTanH,
+ opRand,
+ opRand2,
+ opLinRand,
+ opBiLinRand,
+
+// opExpRand,
+// opBiExpRand,
+ opSum3Rand,
+// opGammaRand,
+// opGaussRand,
+// opPoiRand,
+
+ opDistort,
+ opSoftClip,
+ opCoin,
+
+ opDigitValue,
+ opSilence,
+ opThru,
+ opRectWindow,
+ opHanWindow,
+ opWelchWindow,
+ opTriWindow,
+
+ opRamp,
+ opSCurve,
+
+ opNumUnarySelectors
+};
+
+#define IS_UNARY_BOOL_OP(op) ((op)>=opCoin && (op)<=opOdd)
+#define IS_BINARY_BOOL_OP(op) ((op)>=opEQ && (op)<=opGE)
+
+/* special binary math operators */
+enum {
+ opAdd,
+ opSub,
+ opMul,
+ opIDiv,
+ opFDiv,
+ opMod,
+ opEQ,
+ opNE,
+ opLT,
+ opGT,
+ opLE,
+ opGE,
+ //opIdentical,
+ //opNotIdentical,
+
+ opMin,
+ opMax,
+ opBitAnd,
+ opBitOr,
+ opBitXor,
+ opLCM,
+ opGCD,
+ opRound,
+ opRoundUp,
+ opTrunc,
+ opAtan2,
+ opHypot,
+ opHypotx,
+ opPow,
+ opShiftLeft,
+ opShiftRight,
+ opUnsignedShift,
+ opFill,
+ opRing1, // a * (b + 1) == a * b + a
+ opRing2, // a * b + a + b
+ opRing3, // a*a*b
+ opRing4, // a*a*b - a*b*b
+ opDifSqr, // a*a - b*b
+ opSumSqr, // a*a + b*b
+ opSqrSum, // (a + b)^2
+ opSqrDif, // (a - b)^2
+ opAbsDif, // |a - b|
+ opThresh,
+ opAMClip,
+ opScaleNeg,
+ opClip2,
+ opExcess,
+ opFold2,
+ opWrap2,
+ opFirstArg,
+ opRandRange,
+ opExpRandRange,
+
+ opNumBinarySelectors
+};
+
+/* other special math operators */
+enum {
+ /* 3 operands */
+ opDivz,
+ opClip,
+ opWrap,
+ opFold,
+ opRampMult,
+ opMix,
+ /* 4 operands */
+ opPoly3,
+ /* 5 operands */
+ opMapRange
+};
+
+enum {
+ opmNew, // 0
+ opmInit,
+ opmAt,
+ opmPut,
+ opmNext,
+ opmReset, // 5
+ opmValue,
+ opmCopyToEnd, // used by multi assign
+ opmAdd, // used by dynamic list
+ //opmIsNil,
+ //opmNotNil, // 10
+ opmSize,
+ opmClass,
+ opmIf,
+ opmWhile,
+ opmFor, // 15
+ opmAnd,
+ opmOr,
+ opmIdentical,
+ opmNotIdentical,
+ opmPrint, // 20
+ opmRemove,
+ opmIndexOf,
+ opmWrapAt,
+ opmClipAt,
+ opmFoldAt, // 25
+ opmWrapPut,
+ opmClipPut,
+ opmFoldPut,
+ opmDo,
+ opmCollect, // 30
+ opmSelect,
+ opmReject,
+ opmAny,
+ opmEvery,
+ opmFind,
+ opmChoose,
+ opmValueList,
+ opmAddFirst,
+ opmPrimitiveFailed,
+ opmSubclassResponsibility,
+ opmShouldNotImplement,
+ opmNotYetImplemented,
+ opmDoesNotUnderstand,
+
+ opmAtSign,
+ opmWrapAtSign,
+ opmClipAtSign,
+ opmFoldAtSign,
+
+ opmNewClear,
+ opmNewCopyArgs,
+ opmMultiNew,
+ opmMultiNewList,
+ opmAR,
+ opmKR,
+ opmIR,
+
+ opmCopy,
+ opmPerformList,
+ opmIsKindOf,
+ opmPostln,
+ opmAsString,
+
+ opmEnvirGet,
+ opmEnvirPut,
+
+ opmHalt,
+ opmForBy,
+ opmReverseDo,
+ opmLoop,
+
+ opmNonBooleanError,
+
+ opmPlusPlus,
+ opmLTLT,
+ opmQuestionMark,
+ opmDoubleQuestionMark,
+
+ opmYield,
+ opmName,
+ opmMulAdd,
+
+ opmNumSpecialSelectors
+};
+
+enum {
+ opsvSelf, // 0
+ opsvMinusOne,
+ opsvNegOne,
+ opsvZero,
+ opsvOne,
+ opsvTwo, // 5
+ opsvFHalf,
+ opsvFNegOne,
+ opsvFZero,
+ opsvFOne,
+ opsvFTwo, // 10
+ opsvPlusOne,
+ opsvTrue,
+ opsvFalse,
+ opsvNil,
+ opsvInf, // 15
+
+ opsvNumSpecialValues
+};
+
+enum {
+ opgProcess,
+ opgMethod,
+ opgFunctionDef,
+ opgFunction,
+ opgThread,
+ //opgSampleRate,
+ //opgAudioClock,
+ //opgLogicalClock,
+
+ opgNumPseudoVars
+};
+
+/* selector types */
+enum {
+ selNormal,
+ selSpecial,
+ selUnary,
+ selBinary,
+ selIf,
+ selWhile,
+ selAnd,
+ selOr,
+ selLoop,
+ selSuperNew,
+
+ selNumSelectorTypes
+};
+
+
+
+/*
+ special classes:
+ Object, List, Number, Int, Float, Signal, Complex, Point
+*/
+enum {
+ op_class_object,
+ op_class_symbol,
+ op_class_nil,
+ op_class_boolean,
+ op_class_true,
+ op_class_false,
+ op_class_magnitude,
+ op_class_char,
+ op_class_number,
+ op_class_complex,
+ op_class_simple_number,
+ op_class_int,
+ op_class_float,
+ op_class_method,
+ op_class_fundef,
+ op_class_stream,
+ op_class_func,
+ op_class_frame,
+ op_class_process,
+ op_class_main,
+ op_class_class,
+ op_class_string,
+ op_class_collection,
+ op_class_sequenceable_collection,
+ op_class_arrayed_collection,
+ op_class_array,
+ op_class_int8array,
+ op_class_int16array,
+ op_class_int32array,
+ op_class_floatarray,
+ op_class_signal,
+ op_class_doublearray,
+ op_class_symbolarray,
+ op_class_list,
+ op_class_linkedlist,
+ op_class_bag,
+ op_class_set,
+ op_class_identityset,
+ op_class_dictionary,
+ op_class_identitydictionary,
+ op_class_sortedlist,
+ op_class_synth,
+ op_class_ref,
+ op_class_environment,
+ op_class_wavetable,
+ op_class_env,
+
+ op_class_routine,
+ op_class_color,
+ op_class_rect,
+
+ op_NumSpecialClasses
+};
+
+
+
+#endif
diff --git a/sc4pd/headers/lang/PowerOfTwoAllocPool.h b/sc4pd/headers/lang/PowerOfTwoAllocPool.h
new file mode 100644
index 0000000..8dde18f
--- /dev/null
+++ b/sc4pd/headers/lang/PowerOfTwoAllocPool.h
@@ -0,0 +1,154 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+// Implements a power of two size class allocator.
+// There is no consolidation of free space. Once a chunk is allocated it
+// remains at that size from then on whether free or allocated.
+// It uses AdvancingAllocPool as its parent allocator.
+// It is very fast. This is used to allocate Unit output buffers.
+
+#ifndef _PowerOfTwoAllocPool_
+#define _PowerOfTwoAllocPool_
+
+#include <stdexcept>
+#include <stdlib.h>
+#include "clz.h"
+#include "AdvancingAllocPool.h"
+#include "SC_AllocPool.h"
+void post(const char *fmt, ...);
+void postbuf(const char *fmt, ...);
+
+template<class Hdr, class Obj, class Elem, int LargeObjSizeClass, int Align>
+class PowerOfTwoAllocPool
+{
+public:
+ PowerOfTwoAllocPool(::AllocPool *inPool,
+ size_t initSize = 64*1024,
+ size_t growSize = 64*1024
+ )
+ {
+ mLargeObjPool = inPool;
+ mNumLargeObjects = 0;
+ mNumAlloc = 0;
+ mNumFree = 0;
+ size_t tooBigSize = (sizeof(Hdr) + (sizeof(Elem) << (LargeObjSizeClass-1))) + 1;
+ mSmallObjPool.Init(inPool, initSize, growSize, tooBigSize);
+ Init();
+ assert(SanityCheck());
+ }
+ ~PowerOfTwoAllocPool()
+ {
+ assert(SanityCheck());
+ assert(mNumLargeObjects == 0); // you have to free the big ones yourself
+ mSmallObjPool.FreeAll();
+ }
+
+ Obj* Alloc(int32 inNumElems)
+ {
+ //mNumAlloc++;
+ assert(SanityCheck());
+ int sizeclass = LOG2CEIL(inNumElems);
+ if (sizeclass >= LargeObjSizeClass) {
+ mNumLargeObjects++;
+ size_t size = sizeof(Hdr) + (sizeof(Elem) * inNumElems);
+ return (Obj*)mLargeObjPool->Alloc(size);
+ }
+
+ // get from free list
+ Obj* obj = mFreeLists[sizeclass];
+ if (obj != NULL) {
+ // set free list to next element.
+ mFreeLists[sizeclass] = *(Obj**)obj;
+ } else {
+ // have to allocate it
+ size_t size = mSizes[sizeclass];
+ obj = (Obj*)mSmallObjPool.Alloc(size);
+ if (!obj) throw runtime_error("PowerOfTwoAllocPool out of memory");
+ }
+ //obj->mMagic = 'magk';
+ assert(SanityCheck());
+ return obj;
+ }
+ void Free(Obj* inObjPtr)
+ {
+ //mNumFree++;
+ assert(SanityCheck());
+ if (inObjPtr == 0) return; /* free(0) has no effect */
+ /*if (inObjPtr->mMagic != 'magk') {
+ postbuf("bad object\n");
+ throw runtime_error("bad object");
+ }*/
+ int sizeclass = inObjPtr->SizeClass();
+ if (sizeclass >= LargeObjSizeClass) {
+ mLargeObjPool->Free(inObjPtr);
+ mNumLargeObjects--;
+ } else {
+ Obj* nextfree = mFreeLists[sizeclass];
+ mFreeLists[sizeclass] = inObjPtr;
+ *(Obj**)inObjPtr = nextfree;
+ }
+ assert(SanityCheck());
+ }
+ void FreeAll()
+ {
+ assert(mNumLargeObjects == 0); // you have to free the big ones yourself
+ mSmallObjPool.FreeAll();
+ Init();
+ }
+
+ bool SanityCheck()
+ {
+ //postbuf("PowerOfTwoAllocPool::SanityCheck %d %d\n", mNumAlloc, mNumFree);
+ mLargeObjPool->DoCheckPool();
+ mSmallObjPool.SanityCheck();
+ for (int i=0; i<LargeObjSizeClass; ++i) {
+ Obj* obj = mFreeLists[i];
+ for (int j=0; obj; ++j) {
+ if (j>=1000) {
+ post("linked loop??\n");
+ throw runtime_error("linked loop??\n");
+ return false;
+ }
+ obj = *(Obj**)obj;
+ }
+ }
+ return true;
+ }
+private:
+ void Init()
+ {
+ for (int i=0; i<LargeObjSizeClass; ++i) {
+ mFreeLists[i] = NULL;
+ size_t size = sizeof(Hdr) + (sizeof(Elem) << i);
+ mSizes[i] = (size + (Align-1)) & ~(Align-1); // alignment
+ }
+ }
+
+ Obj* mFreeLists[LargeObjSizeClass];
+ size_t mSizes[LargeObjSizeClass];
+ AllocPool* mLargeObjPool;
+ AdvancingAllocPool mSmallObjPool;
+ int mNumLargeObjects;
+ int mNumAlloc, mNumFree;
+};
+
+
+#endif
+
diff --git a/sc4pd/headers/lang/PredefinedSymbols.h b/sc4pd/headers/lang/PredefinedSymbols.h
new file mode 100644
index 0000000..c6e09b9
--- /dev/null
+++ b/sc4pd/headers/lang/PredefinedSymbols.h
@@ -0,0 +1,29 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+
+extern PyrSymbol *s_func, *s_absfunc;
+extern PyrSymbol *s_docmdline;
+extern PyrSymbol *s_nocomprendo;
+extern PyrSymbol *s_curProcess, *s_curMethod, *s_curBlock, *s_curClosure, *s_curThread;
+extern PyrSymbol *s_startup;
+extern PyrSymbol *s_hardwaresetup, *s_shutdown;
+extern PyrSymbol *s_envirGet, *s_envirPut;
+
diff --git a/sc4pd/headers/lang/PriorityQueue.h b/sc4pd/headers/lang/PriorityQueue.h
new file mode 100644
index 0000000..0bd19f1
--- /dev/null
+++ b/sc4pd/headers/lang/PriorityQueue.h
@@ -0,0 +1,90 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#ifndef _PriorityQueue_
+#define _PriorityQueue_
+
+#include <limits>
+
+template <class Event, class TimeType, int N>
+class PriorityQueueT
+{
+public:
+ PriorityQueueT() {
+ Empty();
+ }
+
+ bool Add(Event& inEvent)
+ {
+ if (mSize >= N) return false;
+ long mom = mSize++;
+ long me = mom;
+ for (; mom>0;) { /* percolate up heap */
+ mom = mom - 1 >> 1;
+ if (inEvent.mTime < mEvents[mom].mTime) {
+ mEvents[me] = mEvents[mom];
+ me = mom;
+ } else break;
+ }
+ mEvents[me] = inEvent;
+ return true;
+ }
+ void Perform(TimeType inNow)
+ {
+ while (NextTime() <= inNow) {
+ Event event = Remove();
+ event.Perform();
+ }
+ }
+ TimeType NextTime() { return mEvents[0].mTime; }
+ bool Ready(TimeType inTime) { return NextTime() <= inTime; }
+ void Flush() { Perform(std::numeric_limits<TimeType>::max()); }
+ void Empty() { mSize = 0; SetEmptyTime(); }
+ void SetEmptyTime() { mEvents[0].mTime = std::numeric_limits<TimeType>::max(); }
+
+ Event Remove()
+ {
+ Event event = mEvents[0];
+ if (--mSize == 0) SetEmptyTime();
+ else {
+ Event temp = mEvents[mSize];
+ long mom = 0;
+ long me = 1;
+ for (;me < mSize;) { /* demote heap */
+ if (me+1 < mSize && mEvents[me].mTime > mEvents[me+1].mTime) {
+ me ++;
+ }
+ if (temp.mTime > mEvents[me].mTime) {
+ mEvents[mom] = mEvents[me];
+ mom = me;
+ me = (me << 1) + 1;
+ } else break;
+ }
+ mEvents[mom] = temp;
+ }
+ return event;
+ }
+
+private:
+ long mSize;
+ Event mEvents[N];
+};
+
+#endif \ No newline at end of file
diff --git a/sc4pd/headers/lang/PyrArchiverT.h b/sc4pd/headers/lang/PyrArchiverT.h
new file mode 100644
index 0000000..3beaa0c
--- /dev/null
+++ b/sc4pd/headers/lang/PyrArchiverT.h
@@ -0,0 +1,619 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+/*
+
+An object archiving system for SuperCollider.
+
+*/
+
+
+#ifndef _PyrArchiver_
+#define _PyrArchiver_
+
+#include "PyrObject.h"
+#include "SC_AllocPool.h"
+
+#include "PyrKernel.h"
+#include "PyrPrimitive.h"
+#include "VMGlobals.h"
+#include "GC.h"
+#include "ReadWriteMacros.h"
+
+const int32 kArchHdrSize = 12;
+const int32 kObjectArrayInitialCapacity = 32;
+
+template <class S>
+class PyrArchiver
+{
+public:
+ PyrArchiver(VMGlobals *inG, bool inSameAddressSpace = false)
+ : g(inG), mObjectArray(mInitialObjectArray), mNumObjects(0),
+ mObjectArrayCapacity( kObjectArrayInitialCapacity ),
+ mSameAddressSpace(inSameAddressSpace), mReadArchiveVersion(0)
+ {
+ }
+
+ ~PyrArchiver()
+ {
+ if (mObjectArray != mInitialObjectArray) {
+ g->allocPool->Free(mObjectArray);
+ }
+ }
+
+ void setStream(S s) { mStream.SetStream(s); }
+
+ int32 calcArchiveSize()
+ {
+ PyrSlot *slot;
+ int32 size = kArchHdrSize;
+ if (mNumObjects == 0) {
+ size += sizeOfElem(&mTopSlot) + 1;
+ } else {
+ // object table size
+ for (int i=0; i<mNumObjects; ++i) {
+ PyrObject* obj = mObjectArray[i];
+ size += obj->classptr->name.us->length + 1; // class name symbol
+ size += sizeof(int32); // size
+ if (obj->obj_format <= obj_slot) {
+ size += obj->size; // tags
+ slot = obj->slots;
+ for (int j=0; j<obj->size; ++j, ++slot) {
+ size += sizeOfElem(slot);
+ }
+ } else if (obj->obj_format == obj_symbol) {
+ PyrSymbol **symbol = ((PyrSymbolArray*)obj)->symbols;
+ for (int j=0; j<obj->size; ++j, ++symbol) {
+ size += (**symbol).length + 1;
+ }
+ } else {
+ size += obj->size * gFormatElemSize[obj->obj_format];
+ }
+ }
+ }
+ return size;
+ }
+
+ long prepareToWriteArchive(PyrSlot *objectSlot)
+ {
+ long err = errNone;
+
+ try {
+ mTopSlot.ucopy = objectSlot->ucopy;
+ if (IsObj(objectSlot)) constructObjectArray(objectSlot->uo);
+ } catch (std::exception &ex) {
+ error(ex.what());
+ err = errFailed;
+ }
+ return err;
+ }
+
+ long writeArchive()
+ {
+ long err = errNone;
+
+ try {
+ writeArchiveHeader();
+
+ if (mNumObjects == 0) {
+ writeSlot(&mTopSlot);
+ } else {
+ for (int i=0; i<mNumObjects; ++i) {
+ writeObjectHeader(mObjectArray[i]);
+ }
+ for (int i=0; i<mNumObjects; ++i) {
+ writeSlots(mObjectArray[i]);
+ }
+ }
+ } catch (std::exception &ex) {
+ error(ex.what());
+ err = errFailed;
+ }
+ return err;
+ }
+
+ long readArchive(PyrSlot *objectSlot)
+ {
+ //postfl("->readArchive\n");
+ long err = errNone;
+
+
+ SetNil(objectSlot);
+
+ try {
+ readArchiveHeader();
+ //postfl("readObjectHeaders %d\n", mNumObjects);
+ if (mNumObjects == 0) {
+ readSlot(objectSlot);
+ } else {
+ for (int i=0; i<mNumObjects; ++i) {
+ mObjectArray[i] = readObjectHeader();
+ }
+ //postfl("readSlots\n");
+ for (int i=0; i<mNumObjects; ++i) {
+ readSlots(mObjectArray[i]);
+ }
+ //postfl("done reading\n");
+ //postfl("SetObject\n");
+ SetObject(objectSlot, mObjectArray[0]);
+ }
+ } catch (std::exception &ex) {
+ error(ex.what());
+ err = errFailed;
+ } catch (...) {
+ err = errFailed;
+ }
+ //postfl("<-readArchive\n");
+ return err;
+ }
+
+private:
+
+ void writeArchiveHeader()
+ {
+ mStream.writeInt32_be('!SCa');
+ mStream.writeInt32_be(2); // file version
+ mStream.writeInt32_be(mNumObjects);
+ }
+
+ void readArchiveHeader()
+ {
+ int32 magicNumber = mStream.readInt32_be();
+ if (magicNumber != '!SCa') {
+ throw std::runtime_error("not an SC archive.\n");
+ }
+ mReadArchiveVersion = mStream.readInt32_be(); // file version
+ mNumObjects = mStream.readInt32_be();
+ //post("readArchiveHeader %d %d\n", mReadArchiveVersion, mNumObjects);
+
+ if (mNumObjects > kObjectArrayInitialCapacity) {
+ mObjectArray = (PyrObject**)g->allocPool->Alloc(mNumObjects * sizeof(PyrObject*));
+ mObjectArrayCapacity = mNumObjects;
+ }
+
+ }
+
+ void recurse(PyrObject *obj, int n)
+ {
+ PyrSlot *slot = obj->slots;
+ for (int i=0; i<n; ++i, ++slot) {
+ if (IsObj(slot)) constructObjectArray(slot->uo);
+ }
+ }
+
+ void growObjectArray()
+ {
+ int32 newObjectArrayCapacity = mObjectArrayCapacity << 1;
+
+ int32 newSize = newObjectArrayCapacity * sizeof(PyrObject*);
+ PyrObject** newArray = (PyrObject**)g->allocPool->Alloc(newSize);
+ memcpy(newArray, mObjectArray, mNumObjects * sizeof(PyrObject*));
+ if (mObjectArray != mInitialObjectArray) {
+ g->allocPool->Free(mObjectArray);
+ }
+ mObjectArrayCapacity = newObjectArrayCapacity;
+ mObjectArray = newArray;
+ }
+
+ void putObject(PyrObject *obj)
+ {
+ obj->SetMark();
+ obj->scratch1 = mNumObjects;
+
+ // expand array if needed
+ if (mNumObjects >= mObjectArrayCapacity) growObjectArray();
+
+ // add to array
+ mObjectArray[mNumObjects++] = obj;
+ }
+
+ void constructObjectArray(PyrObject *obj)
+ {
+ if (!obj->IsMarked()) {
+ if (isKindOf(obj, class_class)) {
+ } else if (isKindOf(obj, class_process)) {
+ } else if (isKindOf(obj, s_interpreter->u.classobj)) {
+ } else if (isKindOf(obj, class_method)) {
+ throw std::runtime_error("cannot archive Methods.\n");
+ } else if (isKindOf(obj, class_thread)) {
+ throw std::runtime_error("cannot archive Threads.\n");
+ } else if (isKindOf(obj, class_frame)) {
+ throw std::runtime_error("cannot archive Frames.\n");
+ } else if (isKindOf(obj, class_func)) {
+ if (NotNil(&((PyrClosure*)obj)->block.uoblk->context)) {
+ throw std::runtime_error("open Function can not be archived.\n");
+ }
+ putObject(obj);
+ recurse(obj, obj->size);
+ } else {
+ if (mSameAddressSpace && obj->IsPermanent()) {
+ // skip it
+ } else {
+ if (isKindOf(obj, class_rawarray)) {
+ putObject(obj);
+ } else if (isKindOf(obj, class_array)) {
+ putObject(obj);
+ recurse(obj, obj->size);
+
+ } else {
+ putObject(obj);
+ recurse(obj, obj->size);
+ }
+ }
+ }
+ }
+ }
+
+ int32 sizeOfElem(PyrSlot *slot)
+ {
+ //postfl("writeSlot %08X\n", slot->utag);
+ switch (slot->utag) {
+ case tagObj :
+ if (isKindOf(slot->uo, class_class)) {
+ return slot->uoc->name.us->length + 1;
+ } else if (isKindOf(slot->uo, class_process)) {
+ return 0;
+ } else if (isKindOf(slot->uo, s_interpreter->u.classobj)) {
+ return 0;
+ } else {
+ return sizeof(int32);
+ }
+ break;
+ case tagHFrame :
+ case tagSFrame :
+ return 0;
+ case tagInt :
+ return sizeof(int32);
+ case tagSym :
+ return slot->us->length + 1;
+ case tagChar :
+ return sizeof(int32);
+ case tagNil :
+ return 0;
+ case tagFalse :
+ return 0;
+ case tagTrue :
+ return 0;
+ case tagInf :
+ return 0;
+ case tagPtr :
+ throw std::runtime_error("cannot archive RawPointers.");
+ return 0;
+ default :
+ return sizeof(double);
+ }
+ }
+
+ PyrSymbol* readSymbolID()
+ {
+ char str[256];
+ mStream.readSymbol(str);
+ return getsym(str);
+ }
+
+
+ PyrObject* readObjectID()
+ {
+ int32 objID = mStream.readInt32_be();
+ //postfl("readObjectID %d\n", objID);
+ return mObjectArray[objID];
+ }
+
+ void writeObjectHeader(PyrObject *obj)
+ {
+ obj->ClearMark();
+
+ //postfl("writeObjectHeader %s\n", obj->classptr->name.us->name);
+ mStream.writeSymbol(obj->classptr->name.us->name);
+
+ mStream.writeInt32_be(obj->size);
+ }
+
+ PyrObject* readObjectHeader()
+ {
+ PyrSymbol* classname = readSymbolID();
+ //post("readObjectHeader %s\n", classname->name);
+ PyrObject *obj;
+ int32 size = mStream.readInt32_be();
+ if (classname->u.classobj->classFlags.ui & classHasIndexableInstances) {
+ obj = instantiateObject(g->gc, classname->u.classobj, size, false, false);
+ obj->size = size;
+ } else {
+ obj = instantiateObject(g->gc, classname->u.classobj, 0, false, false);
+ }
+ return obj;
+ }
+
+ void writeSlots(PyrObject *obj)
+ {
+ //postfl(" writeSlots %s\n", obj->classptr->name.us->name);
+ if (isKindOf(obj, class_rawarray)) {
+ writeRawArray(obj);
+ } else if (isKindOf(obj, class_func)) {
+ PyrClosure* closure = (PyrClosure*)obj;
+ writeSlot(&closure->block);
+ } else {
+ for (int i=0; i<obj->size; ++i) {
+ writeSlot(obj->slots + i);
+ }
+ }
+ }
+
+ void readSlots(PyrObject *obj)
+ {
+ //postfl("readSlots\n");
+ if (isKindOf(obj, class_rawarray)) {
+ readRawArray(obj);
+ } else if (isKindOf(obj, class_func)) {
+ PyrClosure* closure = (PyrClosure*)obj;
+ readSlot(&closure->block);
+ closure->context.ucopy = g->process->interpreter.uoi->context.ucopy;
+ } else {
+ for (int i=0; i<obj->size; ++i) {
+ readSlot(obj->slots + i);
+ }
+ }
+ }
+
+ void writeSlot(PyrSlot *slot)
+ {
+ PyrObject *obj;
+ //postfl(" writeSlot %08X\n", slot->utag);
+ switch (slot->utag) {
+ case tagObj :
+ obj = slot->uo;
+ if (isKindOf(obj, class_class)) {
+ mStream.writeInt8('C');
+ mStream.writeSymbol(slot->uoc->name.us->name);
+ } else if (isKindOf(obj, class_process)) {
+ mStream.writeInt8('P');
+ } else if (isKindOf(obj, s_interpreter->u.classobj)) {
+ mStream.writeInt8('R');
+ } else {
+ if (mSameAddressSpace && obj->IsPermanent()) {
+ mStream.writeInt8('z');
+ mStream.writeInt32_be((int32)obj);
+ } else {
+ mStream.writeInt8('o');
+ mStream.writeInt32_be(obj->scratch1);
+ }
+ }
+ break;
+ case tagHFrame :
+ case tagSFrame :
+ mStream.writeInt8('N');
+ break;
+ case tagInt :
+ mStream.writeInt8('i');
+ mStream.writeInt32_be(slot->ui);
+ break;
+ case tagSym :
+ mStream.writeInt8('s');
+ mStream.writeSymbol(slot->us->name);
+ break;
+ case tagChar :
+ mStream.writeInt8('c');
+ mStream.writeInt32_be(slot->ui);
+ break;
+ case tagNil :
+ mStream.writeInt8('N');
+ break;
+ case tagFalse :
+ mStream.writeInt8('F');
+ break;
+ case tagTrue :
+ mStream.writeInt8('T');
+ break;
+ case tagInf :
+ mStream.writeInt8('I');
+ break;
+ case tagPtr :
+ mStream.writeInt8('N');
+ break;
+ default :
+ mStream.writeInt8('f');
+ mStream.writeDouble_be(slot->uf);
+ break;
+ }
+ }
+
+ void readSlot(PyrSlot *slot)
+ {
+ char tag = mStream.readInt8();
+ switch (tag) {
+ case 'o' :
+ slot->utag = tagObj;
+ slot->uo = readObjectID();
+ break;
+ case 'z' :
+ slot->utag = tagObj;
+ slot->ui = mStream.readInt32_be();
+ break;
+ case 'C' :
+ slot->utag = tagObj;
+ slot->uo = (PyrObject*)readSymbolID()->u.classobj;
+ break;
+ case 'P' :
+ slot->utag = tagObj;
+ slot->uo = (PyrObject*)g->process;
+ break;
+ case 'R' :
+ slot->utag = tagObj;
+ slot->uo = g->process->interpreter.uo;
+ break;
+ case 'i' :
+ slot->utag = tagInt;
+ slot->ui = mStream.readInt32_be();
+ break;
+ case 's' :
+ slot->utag = tagSym;
+ slot->us = readSymbolID();
+ break;
+ case 'c' :
+ slot->utag = tagChar;
+ slot->ui = mStream.readInt32_be();
+ break;
+ case 'f' :
+ slot->uf = mStream.readDouble_be();
+ break;
+ case 'N' :
+ slot->utag = tagNil;
+ slot->ui = 0;
+ break;
+ case 'T' :
+ slot->utag = tagTrue;
+ slot->ui = 0;
+ break;
+ case 'F' :
+ slot->utag = tagFalse;
+ slot->ui = 0;
+ break;
+ case 'I' :
+ slot->utag = tagInf;
+ slot->ui = 0;
+ break;
+ default :
+ slot->utag = tagNil;
+ slot->ui = 0;
+ break;
+ }
+ }
+
+ void writeRawArray(PyrObject *obj)
+ {
+ int32 size = obj->size;
+ //postfl("writeRawArray %d\n", size);
+ switch (obj->obj_format) {
+ case obj_char :
+ case obj_int8 : {
+ char *data = (char*)obj->slots;
+ mStream.writeData(data, size);
+ } break;
+ case obj_int16 : {
+ int16 *data = (int16*)obj->slots;
+ for (int i=0; i<size; ++i) {
+ mStream.writeInt16_be(data[i]);
+ }
+ } break;
+ case obj_int32 :
+ case obj_float : {
+ int32 *data = (int32*)obj->slots;
+ for (int i=0; i<size; ++i) {
+ mStream.writeInt32_be(data[i]);
+ }
+ } break;
+ case obj_double : {
+ double *data = (double*)obj->slots;
+ for (int i=0; i<size; ++i) {
+ mStream.writeDouble_be(data[i]);
+ }
+ } break;
+ case obj_symbol : {
+ PyrSymbol **data = (PyrSymbol**)obj->slots;
+ for (int i=0; i<size; ++i) {
+ mStream.writeSymbol(data[i]->name);
+ }
+ } break;
+ }
+ }
+
+ void readRawArray(PyrObject *obj)
+ {
+ //postfl("readRawArray\n");
+ int32 size = obj->size;
+ switch (obj->obj_format) {
+ case obj_char :
+ case obj_int8 : {
+ int8 *data = (int8*)obj->slots;
+ for (int i=0; i<size; ++i) {
+ data[i] = mStream.readInt8();
+ }
+ } break;
+ case obj_int16 : {
+ int16 *data = (int16*)obj->slots;
+ for (int i=0; i<size; ++i) {
+ data[i] = mStream.readInt16_be();
+ }
+ } break;
+ case obj_int32 :
+ case obj_float : {
+ int32 *data = (int32*)obj->slots;
+ for (int i=0; i<size; ++i) {
+ data[i] = mStream.readInt32_be();
+ }
+ } break;
+ case obj_double : {
+ double *data = (double*)obj->slots;
+ for (int i=0; i<size; ++i) {
+ data[i] = mStream.readDouble_be();
+ }
+ } break;
+ case obj_symbol : {
+ PyrSymbol **data = (PyrSymbol**)obj->slots;
+ for (int i=0; i<size; ++i) {
+ data[i] = readSymbolID();
+ }
+ } break;
+ }
+
+ }
+
+ VMGlobals *g;
+
+ PyrObject **mObjectArray;
+ int32 mNumObjects;
+ int32 mObjectArrayCapacity;
+ PyrSlot mTopSlot;
+
+ bool mSameAddressSpace;
+ SC_IOStream<S> mStream;
+ int32 mReadArchiveVersion;
+
+ PyrObject *mInitialObjectArray[kObjectArrayInitialCapacity];
+};
+
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+/*
+
+An object archiving system for SuperCollider.
+
+*/
+
+
+
+#endif
+
diff --git a/sc4pd/headers/lang/PyrDeepCopier.h b/sc4pd/headers/lang/PyrDeepCopier.h
new file mode 100644
index 0000000..3b46280
--- /dev/null
+++ b/sc4pd/headers/lang/PyrDeepCopier.h
@@ -0,0 +1,221 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+/*
+
+An object archiving system for SuperCollider.
+
+*/
+
+
+#ifndef _PyrDeepCopier_
+#define _PyrDeepCopier_
+
+#include "PyrObject.h"
+#include "SC_AllocPool.h"
+
+#include "PyrKernel.h"
+#include "PyrPrimitive.h"
+#include "VMGlobals.h"
+#include "GC.h"
+#include "ReadWriteMacros.h"
+
+const int32 kDeepCopierObjectArrayInitialCapacity = 32;
+
+class PyrDeepCopier
+{
+public:
+ PyrDeepCopier(VMGlobals *inG)
+ : g(inG), objectArray(initialObjectArray), numObjects(0),
+ objectArrayCapacity( kDeepCopierObjectArrayInitialCapacity )
+ {
+ }
+
+ ~PyrDeepCopier()
+ {
+ if (objectArrayCapacity > kDeepCopierObjectArrayInitialCapacity) {
+ g->allocPool->Free(objectArray);
+ }
+ }
+
+ long doDeepCopy(PyrSlot *objectSlot)
+ {
+ long err = errNone;
+
+ try {
+ if (IsObj(objectSlot)) {
+ constructObjectArray(objectSlot->uo);
+ for (int i=0; i<numObjects; ++i) {
+ fixSlots(objectArray[i]);
+ }
+ fixObjSlot(objectSlot);
+ for (int i=0; i<numObjects; ++i) {
+ objectArray[i]->ClearMark();
+ }
+
+ }
+ } catch (std::exception &ex) {
+ error(ex.what());
+ err = errFailed;
+ }
+ return err;
+ }
+
+private:
+
+ void recurse(PyrObject *obj, int n)
+ {
+ //post("->recurse %s %08X\n", obj->classptr->name.us->name, obj);
+ PyrSlot *slot = obj->slots;
+ for (int i=0; i<n; ++i, ++slot) {
+ if (IsObj(slot)) constructObjectArray(slot->uo);
+ }
+ //post("<-recurse %s %08X\n", obj->classptr->name.us->name, obj);
+ }
+
+ void growObjectArray()
+ {
+ int32 newObjectArrayCapacity = objectArrayCapacity << 1;
+
+ int32 newSize = newObjectArrayCapacity * sizeof(PyrObject*);
+ PyrObject** newArray = (PyrObject**)g->allocPool->Alloc(newSize);
+ memcpy(newArray, objectArray, numObjects * sizeof(PyrObject*));
+ if (objectArrayCapacity > kDeepCopierObjectArrayInitialCapacity) {
+ g->allocPool->Free(objectArray);
+ }
+ objectArrayCapacity = newObjectArrayCapacity;
+ objectArray = newArray;
+ }
+
+ void putSelf(PyrObject *obj)
+ {
+ obj->SetMark();
+ obj->scratch1 = numObjects;
+
+ // expand array if needed
+ if (numObjects >= objectArrayCapacity) growObjectArray();
+
+ //post("putSelf %d %08X\n", numObjects, obj);
+ // add to array
+ objectArray[numObjects++] = obj;
+ }
+
+ void putCopy(PyrObject *obj)
+ {
+ obj->SetMark();
+ obj->scratch1 = numObjects;
+
+ // expand array if needed
+ if (numObjects+2 >= objectArrayCapacity) growObjectArray();
+
+ // add a shallow copy to object array
+ PyrObject *copy = copyObject(g->gc, obj, false);
+ copy->ClearMark();
+
+ //post("putCopy %d %08X\n", numObjects, copy);
+
+ // add to array
+ objectArray[numObjects++] = copy;
+ objectArray[numObjects++] = obj;
+ }
+
+ void constructObjectArray(PyrObject *obj)
+ {
+ //post("->constructObjectArray %s %08X\n", obj->classptr->name.us->name, obj);
+ if (!obj->IsMarked()) {
+ if (isKindOf(obj, class_class)) {
+ putSelf(obj);
+ } else if (isKindOf(obj, class_process)) {
+ putSelf(obj);
+ } else if (isKindOf(obj, s_interpreter->u.classobj)) {
+ putSelf(obj);
+ } else if (isKindOf(obj, class_rawarray)) {
+ putCopy(obj);
+ } else if (isKindOf(obj, class_array)) {
+ putCopy(obj);
+ recurse(obj, obj->size);
+ } else if (isKindOf(obj, class_func)) {
+ putSelf(obj);
+ } else if (isKindOf(obj, class_method)) {
+ putSelf(obj);
+ } else if (isKindOf(obj, class_thread)) {
+ putSelf(obj);
+ } else {
+ putCopy(obj);
+ recurse(obj, obj->size);
+ }
+ }
+ //post("<-constructObjectArray %s %08X\n", obj->classptr->name.us->name, obj);
+ }
+
+ void fixObjSlot(PyrSlot* slot)
+ {
+ //post("fixObjSlot %s %08X %d %08X\n", slot->uo->classptr->name.us->name, slot->uo, slot->uo->scratch1, objectArray[slot->uo->scratch1]);
+ slot->uo = objectArray[slot->uo->scratch1];
+ }
+
+ void fixSlots(PyrObject *obj)
+ {
+ //post("fixSlots %s %08X %d\n", obj->classptr->name.us->name, obj, obj->IsMarked());
+ if (!obj->IsMarked() && obj->obj_format <= obj_slot) { // it is a copy
+ PyrSlot *slot = obj->slots;
+ for (int i=0; i<obj->size; ++i, ++slot) {
+ if (IsObj(slot)) fixObjSlot(slot);
+ }
+ }
+ }
+
+ VMGlobals *g;
+
+ PyrObject **objectArray;
+ int32 numObjects;
+ int32 objectArrayCapacity;
+
+ PyrObject *initialObjectArray[kDeepCopierObjectArrayInitialCapacity];
+};
+
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+/*
+
+An object archiving system for SuperCollider.
+
+*/
+
+
+
+#endif
+
diff --git a/sc4pd/headers/lang/PyrDeepFreezer.h b/sc4pd/headers/lang/PyrDeepFreezer.h
new file mode 100644
index 0000000..28d9a12
--- /dev/null
+++ b/sc4pd/headers/lang/PyrDeepFreezer.h
@@ -0,0 +1,178 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+/*
+
+An object archiving system for SuperCollider.
+
+*/
+
+#ifndef _PyrDeepFreezer_
+#define _PyrDeepFreezer_
+
+#include "PyrObject.h"
+#include "SC_AllocPool.h"
+#include "PyrKernel.h"
+#include "PyrPrimitive.h"
+#include "VMGlobals.h"
+#include "GC.h"
+
+const int32 kDeepFreezerObjectArrayInitialCapacity = 32;
+
+class PyrDeepFreezer
+{
+public:
+ PyrDeepFreezer(VMGlobals *inG)
+ : g(inG), objectArray(initialObjectArray), numObjects(0),
+ objectArrayCapacity( kDeepCopierObjectArrayInitialCapacity )
+ {
+ }
+
+ ~PyrDeepFreezer()
+ {
+ if (objectArrayCapacity > kDeepCopierObjectArrayInitialCapacity) {
+ g->allocPool->Free(objectArray);
+ }
+ }
+
+ long doDeepFreeze(PyrSlot *objectSlot)
+ {
+ long err = errNone;
+
+ try {
+ if (IsObj(objectSlot)) {
+ constructObjectArray(objectSlot->uo);
+ for (int i=0; i<numObjects; ++i) {
+ g->gc->BecomePermanent( objectArray[i] );
+ }
+ }
+ } catch (std::exception &ex) {
+ error(ex.what());
+ err = errFailed;
+ }
+ return err;
+ }
+
+private:
+
+ void recurse(PyrObject *obj, int n)
+ {
+ PyrSlot *slot = obj->slots;
+ for (int i=0; i<n; ++i, ++slot) {
+ if (IsObj(slot)) constructObjectArray(slot->uo);
+ }
+ }
+
+ void growObjectArray()
+ {
+ int32 newObjectArrayCapacity = objectArrayCapacity << 1;
+
+ int32 newSize = newObjectArrayCapacity * sizeof(PyrObject*);
+ PyrObject** newArray = (PyrObject**)g->allocPool->Alloc(newSize);
+ memcpy(newArray, objectArray, numObjects * sizeof(PyrObject*));
+ if (objectArrayCapacity > kDeepCopierObjectArrayInitialCapacity) {
+ g->allocPool->Free(objectArray);
+ }
+ objectArrayCapacity = newObjectArrayCapacity;
+ objectArray = newArray;
+ }
+
+ void putObject(PyrObject *obj)
+ {
+ obj->SetMark();
+ obj->scratch1 = numObjects;
+
+ // expand array if needed
+ if (numObjects >= objectArrayCapacity) growObjectArray();
+
+ // add to array
+ objectArray[numObjects++] = obj;
+ }
+
+ void constructObjectArray(PyrObject *obj)
+ {
+ if (obj->IsPermanent()) return;
+
+ if (!obj->IsMarked()) {
+ if (isKindOf(obj, class_process)) {
+ throw std::runtime_error("cannot freeze Process.\n");
+ } else if (isKindOf(obj, s_interpreter->u.classobj)) {
+ throw std::runtime_error("cannot freeze Interpreter.\n");
+ } else if (isKindOf(obj, class_rawarray)) {
+ putObject(obj);
+ } else if (isKindOf(obj, class_array)) {
+ putObject(obj);
+ recurse(obj, obj->size);
+ } else if (isKindOf(obj, class_func)) {
+ if (NotNil(&((PyrClosure*)obj)->block.uoblk->context)) {
+ throw std::runtime_error("open Function can not be frozen.\n");
+ }
+ putObject(obj);
+ recurse(obj, obj->size);
+ } else if (isKindOf(obj, class_method)) {
+ throw std::runtime_error("cannot freeze Methods.\n");
+ } else if (isKindOf(obj, class_thread)) {
+ throw std::runtime_error("cannot freeze Threads.\n");
+ } else if (isKindOf(obj, class_frame)) {
+ throw std::runtime_error("cannot freeze Frames.\n");
+ } else {
+ putObject(obj);
+ recurse(obj, obj->size);
+ }
+ }
+ }
+
+ VMGlobals *g;
+
+ PyrObject **objectArray;
+ int32 numObjects;
+ int32 objectArrayCapacity;
+
+ PyrObject *initialObjectArray[kDeepCopierObjectArrayInitialCapacity];
+};
+
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+/*
+
+An object archiving system for SuperCollider.
+
+*/
+
+
+
+#endif
+
diff --git a/sc4pd/headers/lang/PyrErrors.h b/sc4pd/headers/lang/PyrErrors.h
new file mode 100644
index 0000000..b2be76e
--- /dev/null
+++ b/sc4pd/headers/lang/PyrErrors.h
@@ -0,0 +1,49 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+/*
+
+virtual machine error codes.
+
+*/
+
+#ifndef _SCErrors_
+#define _SCErrors_
+
+enum { // primitive errors
+ errReturn = -1, // not really an error.. primitive executed a non-local return
+ errNone,
+ errFailed = 5000,
+ errBadPrimitive,
+ errWrongType,
+ errIndexNotAnInteger,
+ errIndexOutOfRange,
+ errImmutableObject,
+ errNotAnIndexableObject,
+ errStackOverflow,
+ errOutOfMemory,
+ errCantCallOS,
+ errException,
+
+ errPropertyNotFound = 6000,
+
+ errLastError
+};
+
+#endif
diff --git a/sc4pd/headers/lang/PyrFilePrim.h b/sc4pd/headers/lang/PyrFilePrim.h
new file mode 100644
index 0000000..3574927
--- /dev/null
+++ b/sc4pd/headers/lang/PyrFilePrim.h
@@ -0,0 +1,62 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+#ifndef _PYRFILEPRIM_H_
+#define _PYRFILEPRIM_H_
+
+#include "PyrObject.h"
+
+struct PyrFile : public PyrObjectHdr
+{
+ PyrSlot fileptr;
+};
+
+void initFilePrimitives();
+
+long prFileDelete(VMGlobals *g, long numArgsPushed);
+long prFileOpen(VMGlobals *g, long numArgsPushed);
+long prFileClose(VMGlobals *g, long numArgsPushed);
+long prFileSeek(VMGlobals *g, long numArgsPushed);
+long prFilePos(VMGlobals *g, long numArgsPushed);
+long prFileLength(VMGlobals *g, long numArgsPushed);
+long prFileWrite(VMGlobals *g, long numArgsPushed);
+long prFileReadLine(VMGlobals *g, long numArgsPushed);
+
+long prFilePutRGB(VMGlobals *g, long numArgsPushed);
+long prFilePutInt32(VMGlobals *g, long numArgsPushed);
+long prFilePutInt16(VMGlobals *g, long numArgsPushed);
+long prFilePutInt8(VMGlobals *g, long numArgsPushed);
+long prFilePutChar(VMGlobals *g, long numArgsPushed);
+long prFilePutFloat(VMGlobals *g, long numArgsPushed);
+long prFilePutDouble(VMGlobals *g, long numArgsPushed);
+
+long prFileGetRGB(VMGlobals *g, long numArgsPushed);
+long prFileGetInt32(VMGlobals *g, long numArgsPushed);
+long prFileGetInt16(VMGlobals *g, long numArgsPushed);
+long prFileGetInt8(VMGlobals *g, long numArgsPushed);
+long prFileGetChar(VMGlobals *g, long numArgsPushed);
+long prFileGetFloat(VMGlobals *g, long numArgsPushed);
+long prFileGetDouble(VMGlobals *g, long numArgsPushed);
+
+long prFilePutString(VMGlobals *g, long numArgsPushed);
+long prFileRead(VMGlobals *g, long numArgsPushed);
+
+
+#endif
+
diff --git a/sc4pd/headers/lang/PyrFileUtils.h b/sc4pd/headers/lang/PyrFileUtils.h
new file mode 100644
index 0000000..1fd682b
--- /dev/null
+++ b/sc4pd/headers/lang/PyrFileUtils.h
@@ -0,0 +1,50 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+/*
+
+Some utils for file i/o.
+
+*/
+
+#ifndef _PYRFILEUTIL_H_
+#define _PYRFILEUTIL_H_
+
+int headerFormatFromSymbol(struct PyrSymbol *inSymbol);
+int sampleFormatFromSymbol(struct PyrSymbol *inSymbol, int inHeaderFormat);
+
+#ifdef __MAC__
+
+#include <Files.h>
+
+long setTypeCreator(unsigned char *filename, long type, long creator);
+bool filelen(FILE *file, size_t *length);
+
+int allocasync(int fildes, int count, IOParam *pb, IOCompletionUPP completionFunc);
+int createasync(unsigned char *path, int oflag, HParamBlockRec *hpb, IOCompletionUPP completionFunc);
+int openasync(unsigned char *path, int oflag, HParamBlockRec *hpb, IOCompletionUPP completionFunc);
+int closeasync(int fildes, HParamBlockRec *hpb, IOCompletionUPP completionFunc);
+int writeasync(int fildes, const char *buf, int count, IOParam *pb, IOCompletionUPP completionFunc);
+int readasync(int fildes, char *buf, int count, IOParam *pb, IOCompletionUPP completionFunc);
+int seekwriteasync(int fildes, const char *buf, int count, int pos, IOParam *pb, IOCompletionUPP completionFunc);
+int seekreadasync(int fildes, char *buf, int count, int pos, IOParam *pb, IOCompletionUPP completionFunc);
+
+
+#endif
+#endif
diff --git a/sc4pd/headers/lang/PyrInterpreter.h b/sc4pd/headers/lang/PyrInterpreter.h
new file mode 100644
index 0000000..a21126d
--- /dev/null
+++ b/sc4pd/headers/lang/PyrInterpreter.h
@@ -0,0 +1,47 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#ifndef _PYRINTERPRETER_H_
+#define _PYRINTERPRETER_H_
+
+#include "PyrSlot.h"
+#include "VMGlobals.h"
+
+extern bool gRunningInterpreterThread;
+
+extern int gNumClasses;
+
+bool initInterpreter(VMGlobals *g, PyrSymbol *selector, int numArgsPushed);
+bool initRuntime(VMGlobals *g, int poolSize, AllocPool *inPool, int processID);
+void Interpret(VMGlobals *g);
+void endInterpreter(VMGlobals *g);
+
+int doSpecialUnaryArithMsg(VMGlobals *g, int numArgsPushed);
+int prSpecialBinaryArithMsg(VMGlobals *g, int numArgsPushed);
+int doSpecialBinaryArithMsg(VMGlobals *g, int numArgsPushed, bool isPrimitive);
+void DumpBackTrace(VMGlobals *g);
+void DumpStack(VMGlobals *g, PyrSlot *sp);
+void DumpFrame(struct PyrFrame *frame);
+bool FrameSanity(PyrFrame *frame, char *tagstr);
+struct PyrProcess* newPyrProcess(VMGlobals *g, struct PyrClass *classobj);
+void startProcess(VMGlobals *g, PyrSymbol *selector);
+void runInterpreter(VMGlobals *g, PyrSymbol *selector, int numArgsPushed);
+
+#endif
diff --git a/sc4pd/headers/lang/PyrKernel.h b/sc4pd/headers/lang/PyrKernel.h
new file mode 100644
index 0000000..d5c6af7
--- /dev/null
+++ b/sc4pd/headers/lang/PyrKernel.h
@@ -0,0 +1,256 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+/*
+
+This file contains the definitions of the core objects that implement the class system.
+
+*/
+
+#ifndef _PYRKERNEL_H_
+#define _PYRKERNEL_H_
+
+#include "PyrObject.h"
+#include "VMGlobals.h"
+
+#define classClassNumInstVars 16
+
+enum { classIsIntrinsic = 1, classHasIndexableInstances = 2, classCompileUGen = 4 };
+
+struct PyrClass : public PyrObjectHdr
+{
+ PyrSlot name;
+ PyrSlot nextclass;
+ PyrSlot superclass;
+ PyrSlot subclasses;
+ PyrSlot methods;
+
+ PyrSlot instVarNames;
+ PyrSlot classVarNames;
+ PyrSlot iprototype; // instance prototype
+ PyrSlot cprototype; // class var prototype
+
+ PyrSlot instanceFormat;
+ PyrSlot instanceFlags;
+ PyrSlot classIndex;
+ PyrSlot classFlags;
+ PyrSlot maxSubclassIndex; // used by isKindOf
+ PyrSlot filenameSym;
+ PyrSlot charPos;
+};
+
+
+
+inline bool isKindOf(PyrObjectHdr *obj, struct PyrClass *testclass)
+{
+ int objClassIndex = obj->classptr->classIndex.ui;
+ return objClassIndex >= testclass->classIndex.ui && objClassIndex <= testclass->maxSubclassIndex.ui;
+}
+
+inline bool isKindOfSlot(PyrSlot *slot, struct PyrClass *testclass)
+{
+ return IsObj(slot) && isKindOf(slot->uo, testclass);
+}
+
+/*
+ operations on class:
+ numInstVars()
+ numClassVars()
+
+*/
+
+struct PyrFrame {
+ PyrSlot vars[1];
+ PyrSlot myself;
+ PyrSlot method;
+ PyrSlot caller;
+ PyrSlot context;
+ PyrSlot homeContext;
+ PyrSlot ip;
+};
+
+#define FRAMESIZE 6
+#define USESTACKFRAMES 1
+
+struct PyrProcess : public PyrObjectHdr
+{
+
+ PyrSlot classVars;
+ PyrSlot interpreter;
+ PyrSlot curThread, mainThread;
+ PyrSlot processID;
+ PyrSlot sysSchedulerQueue;
+};
+
+
+enum { tInit, tStart, tReady, tRunning, tSleeping, tBlocked, tYieldToChild, tYieldToParent, tDone };
+
+struct PyrThread : public PyrObjectHdr
+{
+
+ PyrSlot state, func, stack, stackSize, method, block, frame, ip, sp;
+ PyrSlot numpop, returnLevels, receiver, numArgsPushed;
+ PyrSlot parent, terminalValue;
+ PyrSlot primitiveError;
+ PyrSlot primitiveIndex;
+ PyrSlot randData;
+ PyrSlot beats, seconds, clock;
+ PyrSlot environment;
+ PyrSlot exceptionHandler;
+};
+
+#define EVALSTACKDEPTH 8192
+
+
+
+struct PyrMethodRaw {
+
+ unsigned short unused1;
+ unsigned short specialIndex;
+ unsigned short methType;
+ unsigned short frameSize;
+
+ unsigned char unused2;
+ unsigned char numargs;
+ unsigned char varargs;
+ unsigned char numvars;
+ unsigned char numtemps;
+ unsigned char needsHeapContext;
+ unsigned char popSize;
+ unsigned char posargs;
+
+};
+
+
+#define METHRAW(obj) ((PyrMethodRaw*)&(((PyrBlock*)obj)->rawData1))
+
+struct PyrBlock : public PyrObjectHdr
+{
+
+ PyrSlot rawData1;
+ PyrSlot rawData2;
+ PyrSlot code; // byte codes, nil if inlined
+ PyrSlot selectors; // method selectors, class names, closures table
+ PyrSlot constants; // floating point constants table (to alleviate the literal table problem)
+ PyrSlot prototypeFrame; // prototype of an activation frame
+ PyrSlot context; // ***defining block context
+ PyrSlot argNames; // ***arguments to block
+ PyrSlot varNames; // ***variables in block
+ PyrSlot sourceCode; // source code if it is a closed function.
+};
+
+struct PyrMethod : public PyrBlock
+{
+ PyrSlot ownerclass;
+ PyrSlot name;
+ PyrSlot primitiveName;
+ PyrSlot filenameSym;
+ PyrSlot charPos;
+ //PyrSlot byteMeter;
+ //PyrSlot callMeter;
+};
+
+enum {
+ methNormal = 0,
+ methReturnSelf,
+ methReturnLiteral,
+ methReturnArg,
+ methReturnInstVar,
+ methAssignInstVar,
+ methReturnClassVar,
+ methAssignClassVar,
+ methRedirect,
+ methForward,
+ methPrimitive,
+ methBlock
+};
+
+struct PyrClosure : public PyrObjectHdr
+{
+
+ PyrSlot block;
+ PyrSlot context;
+};
+
+struct PyrInterpreter : public PyrObjectHdr
+{
+
+ PyrSlot cmdLine, context;
+ PyrSlot a, b, c, d, e, f, g, h, i, j;
+ PyrSlot k, l, m, n, o, p, q, r, s, t;
+ PyrSlot u, v, w, x, y, z;
+ PyrSlot codeDump;
+};
+
+/* special values */
+enum {
+ svNil,
+ svFalse,
+ svTrue,
+ svNegOne,
+ svZero,
+ svOne,
+ svTwo,
+ svFHalf,
+ svFNegOne,
+ svFZero,
+ svFOne,
+ svFTwo,
+ svInf,
+
+ svNumSpecialValues
+};
+
+extern double gSpecialValues[svNumSpecialValues];
+
+extern PyrMethod *gNullMethod; // used to fill row table
+
+PyrObject* instantiateObject(class PyrGC *gc, PyrClass* classobj, int size,
+ bool fill, bool collect);
+
+PyrObject* newPyrObject(class PyrGC *gc, size_t inNumBytes, int inFlags, int inFormat, bool inCollect);
+PyrString* newPyrString(class PyrGC *gc, const char *s, int flags, bool collect);
+PyrString* newPyrStringN(class PyrGC *gc, int size, int flags, bool collect);
+PyrObject* newPyrArray(class PyrGC *gc, int size, int flags, bool collect);
+PyrSymbolArray* newPyrSymbolArray(class PyrGC *gc, int size, int flags, bool collect);
+PyrInt8Array* newPyrInt8Array(class PyrGC *gc, int size, int flags, bool collect);
+PyrInt32Array* newPyrInt32Array(class PyrGC *gc, int size, int flags, bool collect);
+PyrDoubleArray* newPyrDoubleArray(class PyrGC *gc, int size, int flags, bool collect);
+
+PyrObject* copyObject(class PyrGC *gc, PyrObject *inobj, bool collect);
+PyrObject* copyObjectRange(class PyrGC *gc, PyrObject *inobj, int start, int end, bool collect);
+
+inline void SetFrame(PyrSlot* slot, PyrFrame* frame)
+{
+ (slot)->ui = ((int)(frame));
+ (slot)->utag = tagSFrame - METHRAW((frame)->method.uoblk)->needsHeapContext;
+}
+
+inline void SetFrameOrNil(PyrSlot* slot, PyrFrame* frame)
+{
+ if (frame) {
+ (slot)->ui = ((int)(frame));
+ (slot)->utag = tagSFrame - METHRAW((frame)->method.uoblk)->needsHeapContext;
+ } else {
+ (slot)->utag = tagNil;
+ (slot)->ui = 0;
+ }
+}
+
+#endif
diff --git a/sc4pd/headers/lang/PyrKernelProto.h b/sc4pd/headers/lang/PyrKernelProto.h
new file mode 100644
index 0000000..f040507
--- /dev/null
+++ b/sc4pd/headers/lang/PyrKernelProto.h
@@ -0,0 +1,62 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+
+#ifndef _PYRKERNELPROTO_H_
+#define _PYRKERNELPROTO_H_
+
+PyrClass* newClassObj(PyrClass *classObjSuperClass,
+ PyrSymbol* className, PyrSymbol* superClassName,
+ int numInstVars, int numClassVars, int numInstMethods,
+ int instFormat, int instFlags);
+
+void reallocClassObj(PyrClass* classobj,
+ int numInstVars, int numClassVars, int numMethods,
+ int instFormat, int instFlags);
+
+int numInstVars(PyrClass* classobj);
+int numClassVars(PyrClass* classobj);
+int numSuperInstVars(PyrClass *superclassobj);
+bool classFindInstVar(PyrClass* classobj, PyrSymbol *name, int *index);
+bool classFindClassVar(PyrClass** classobj, PyrSymbol *name, int *index);
+
+void buildClassTree();
+void indexClassTree(PyrClass *classobj, int numSuperMethods);
+void postClassTree(PyrClass *classobj, int level);
+void setSelectorFlags();
+void buildBigMethodMatrix();
+void fillClassRow(PyrClass *classobj, struct PyrMethod** bigTable);
+
+bool funcFindArg(PyrBlock* func, PyrSymbol *name, int *index);
+bool funcFindVar(PyrBlock* func, PyrSymbol *name, int *index);
+void addMethod(PyrClass *classobj, PyrMethod *method);
+
+
+PyrMethod* classFindDirectMethod(PyrClass* classobj, PyrSymbol *name);
+
+PyrBlock* newPyrBlock(int flags);
+PyrMethod* newPyrMethod();
+PyrClass* makeIntrinsicClass(PyrSymbol *className, PyrSymbol *superClassName,
+ int numInstVars, int numClassVars);
+void addIntrinsicVar(PyrClass *classobj, char *varName, PyrSlot *slot);
+
+
+
+#endif \ No newline at end of file
diff --git a/sc4pd/headers/lang/PyrLexer.h b/sc4pd/headers/lang/PyrLexer.h
new file mode 100644
index 0000000..5166337
--- /dev/null
+++ b/sc4pd/headers/lang/PyrLexer.h
@@ -0,0 +1,136 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+
+#ifndef _PYRLEXER_H_
+#define _PYRLEXER_H_
+
+#include "PyrSymbol.h"
+
+extern int charno, lineno, linepos;
+extern int *linestarts;
+
+struct ClassExtFile {
+ struct ClassExtFile *next;
+ PyrSymbol *fileSym;
+};
+
+typedef struct classdep {
+ struct classdep *next;
+ struct classdep *superClassDep;
+ struct classdep *subclasses;
+ PyrSymbol *className;
+ PyrSymbol *superClassName;
+ PyrSymbol *fileSym;
+} ClassDependancy;
+
+extern PyrSymbol *gCompilingFileSym;
+
+ClassDependancy* newClassDependancy(PyrSymbol *className, PyrSymbol *superClassName,
+ PyrSymbol *fileSym);
+bool parseOneClass(PyrSymbol *fileSym);
+void initPassOne();
+void finiPassOne();
+bool passOne();
+void buildDepTree();
+void traverseFullDepTree();
+void traverseDepTree(ClassDependancy *classdep, int level);
+void traverseFullDepTree2();
+void traverseDepTree2(ClassDependancy *classdep, int level);
+void compileClassExtensions();
+void compileFileSym(PyrSymbol *fileSym);
+
+void runLibrary(PyrSymbol* selector);
+
+void interpretCmdLine(const char *textbuf, int textlen, char *methodname);
+
+
+int input();
+int input0();
+void unput(int c);
+void unput0(int c);
+
+void finiLexer() ;
+bool startLexer(char* filename) ;
+void startLexerCmdLine(char *textbuf, int textbuflen);
+int yylex() ;
+void yyerror(char *s) ;
+void fatal() ;
+bool isValidSourceFileName(char *filename);
+bool passOne_ProcessOneFile(char *filename, int level);
+
+extern void asRelativePath(char *inPath,char *outPath);
+
+void initLexer();
+void init_SuperCollider();
+
+int processbinop(char *token);
+int processident(char *token);
+int processfloat(char *token, int sawpi);
+int processint(char *token);
+int processchar(int c);
+int processintradix(char *s);
+int processfloatradix(char *s);
+int processhex(char *s);
+int processsymbol(char *token);
+int processstring(char *token);
+int processkeywordbinop(char *token);
+
+void postErrorLine(int linenum, int start, int charpos);
+bool scanForClosingBracket();
+void parseClasses();
+
+extern int parseFailed;
+extern bool compilingCmdLine;
+extern bool compilingCmdLineErrorWindow;
+extern bool compiledOK;
+
+#define MAXYYLEN 8192
+
+extern int gNumCompiledFiles;
+extern int gClassCompileOrderNum;
+extern ClassDependancy **gClassCompileOrder;
+extern char curfilename[PATH_MAX];
+
+extern int runcount;
+
+extern char *binopchars;
+extern char yytext[MAXYYLEN];
+extern char linebuf[256];
+extern char curfilename[PATH_MAX];
+
+extern int yylen;
+extern int lexCmdLine;
+extern bool compilingCmdLine;
+extern bool compilingCmdLineErrorWindow;
+extern long zzval;
+
+extern int lineno, charno, linepos;
+extern int *linestarts;
+extern int maxlinestarts;
+
+extern char *text;
+extern int textlen;
+extern int textpos;
+extern int parseFailed;
+extern bool compiledOK;
+extern int radixcharpos, decptpos;
+
+#endif
diff --git a/sc4pd/headers/lang/PyrListPrim.h b/sc4pd/headers/lang/PyrListPrim.h
new file mode 100644
index 0000000..43288a7
--- /dev/null
+++ b/sc4pd/headers/lang/PyrListPrim.h
@@ -0,0 +1,34 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+
+#ifndef _PYRARRAYPRIM_H_
+#define _PYRARRAYPRIM_H_
+
+void initArrayPrimitives();
+
+int prArrayMultiChanExpand(VMGlobals *g, int numArgsPushed);
+
+int arrayAtIdentityHash(PyrObject *array, PyrSlot *key);
+int arrayAtIdentityHashInPairs(PyrObject *array, PyrSlot *key);
+int arrayAtIdentityHashInPairsWithHash(PyrObject *array, PyrSlot *key, int hash);
+
+
+#endif \ No newline at end of file
diff --git a/sc4pd/headers/lang/PyrMathPrim.h b/sc4pd/headers/lang/PyrMathPrim.h
new file mode 100644
index 0000000..f4e2dd1
--- /dev/null
+++ b/sc4pd/headers/lang/PyrMathPrim.h
@@ -0,0 +1,51 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#ifndef _PYRMATHPRIM_H_
+#define _PYRMATHPRIM_H_
+
+void initMathPrimitives();
+
+int prAddNum(VMGlobals *g, int numArgsPushed);
+int prSubNum(VMGlobals *g, int numArgsPushed);
+int prMulNum(VMGlobals *g, int numArgsPushed);
+
+int prAddInt(VMGlobals *g, int numArgsPushed);
+int prSubInt(VMGlobals *g, int numArgsPushed);
+int prMulInt(VMGlobals *g, int numArgsPushed);
+
+int prAddFloat(VMGlobals *g, int numArgsPushed);
+int prSubFloat(VMGlobals *g, int numArgsPushed);
+int prMulFloat(VMGlobals *g, int numArgsPushed);
+
+int mathClip(VMGlobals *g, int numArgsPushed);
+int mathWrap(VMGlobals *g, int numArgsPushed);
+int mathFold(VMGlobals *g, int numArgsPushed);
+int mathClipInt(VMGlobals *g, int numArgsPushed);
+int mathWrapInt(VMGlobals *g, int numArgsPushed);
+int mathFoldInt(VMGlobals *g, int numArgsPushed);
+int mathClipFloat(VMGlobals *g, int numArgsPushed);
+int mathWrapFloat(VMGlobals *g, int numArgsPushed);
+int mathFoldFloat(VMGlobals *g, int numArgsPushed);
+int mathClipSignal(VMGlobals *g, int numArgsPushed);
+int mathWrapSignal(VMGlobals *g, int numArgsPushed);
+int mathFoldSignal(VMGlobals *g, int numArgsPushed);
+
+#endif
diff --git a/sc4pd/headers/lang/PyrMessage.h b/sc4pd/headers/lang/PyrMessage.h
new file mode 100644
index 0000000..436128a
--- /dev/null
+++ b/sc4pd/headers/lang/PyrMessage.h
@@ -0,0 +1,55 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+
+#ifndef _PYRMESSAGE_H_
+#define _PYRMESSAGE_H_
+
+#include "PyrKernel.h"
+
+#define MAXKEYSLOTS 128
+extern PyrSlot keywordstack[MAXKEYSLOTS];
+extern bool gKeywordError;
+extern PyrMethod **gRowTable;
+
+void initUniqueMethods();
+
+void sendMessageWithKeys(VMGlobals *g, PyrSymbol *selector,
+ long numArgsPushed, long numKeyArgsPushed);
+void sendMessage(VMGlobals *g, PyrSymbol *selector, long numArgsPushed);
+void sendSuperMessageWithKeys(VMGlobals *g, PyrSymbol *selector,
+ long numArgsPushed, long numKeyArgsPushed);
+void sendSuperMessage(VMGlobals *g, PyrSymbol *selector, long numArgsPushed);
+void doesNotUnderstandWithKeys(VMGlobals *g, PyrSymbol *selector,
+ long numArgsPushed, long numKeyArgsPushed);
+void doesNotUnderstand(VMGlobals *g, PyrSymbol *selector,
+ long numArgsPushed);
+void returnFromBlock(VMGlobals *g);
+void returnFromMethod(VMGlobals *g);
+void executeMethod(VMGlobals *g, PyrMethod *meth, long numArgsPushed);
+void executeMethodWithKeys(VMGlobals *g, PyrMethod *meth, long allArgsPushed,
+ long numKeyArgsPushed);
+void keywordFixStack(VMGlobals *g, PyrMethod *meth, PyrMethodRaw *methraw, long allArgsPushed,
+ long numKeyArgsPushed);
+
+#endif
+
+
+
diff --git a/sc4pd/headers/lang/PyrObject.h b/sc4pd/headers/lang/PyrObject.h
new file mode 100644
index 0000000..05abf21
--- /dev/null
+++ b/sc4pd/headers/lang/PyrObject.h
@@ -0,0 +1,288 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+/*
+
+PyrObject represents the structure of all SC Objects.
+
+*/
+
+#ifndef _PYROBJECT_H_
+#define _PYROBJECT_H_
+
+#include "PyrSlot.h"
+
+/* special gc colors */
+enum {
+ obj_permanent = 1, // sent to gc->New as a flag
+ obj_gcmarker = 2 // gc treadmill marker
+};
+
+/* obj flag fields */
+enum {
+ obj_immutable = 16,
+ obj_marked = 128
+};
+
+/* format types : */
+enum {
+ obj_notindexed,
+ obj_slot,
+ obj_double,
+ obj_float,
+ obj_int32,
+ obj_int16,
+ obj_int8,
+ obj_char,
+ obj_symbol,
+
+ NUMOBJFORMATS
+};
+
+
+/*
+ PyrObjectHdr : object header fields
+ prev, next : pointers in the GC treadmill
+ classptr : pointer to the object's class
+ size : number of slots or indexable elements.
+
+ obj_format : what kind of data this object holds
+ obj_sizeclass : power of two size class of the object
+ obj_flags :
+ immutable : set if object may not be updated.
+ finalize : set if object requires finalization.
+ marked : used by garbage collector debug sanity check. may be used by primitives but must be cleared before exiting primitive.
+ gc_color : GC color : black, grey, white, free, permanent
+ scratch1 : undefined value. may be used within primitives as a temporary scratch value.
+*/
+
+struct PyrObjectHdr {
+ struct PyrObjectHdr *prev, *next;
+ struct PyrClass *classptr;
+ int size;
+
+ unsigned char obj_format;
+ unsigned char obj_sizeclass;
+ unsigned char obj_flags;
+ unsigned char gc_color;
+
+ int scratch1;
+
+ int SizeClass() { return obj_sizeclass; }
+
+ void SetMark() { obj_flags |= obj_marked; }
+ void ClearMark() { obj_flags &= ~obj_marked; }
+ bool IsMarked() { return obj_flags & obj_marked; }
+ bool IsPermanent() { return gc_color == obj_permanent; }
+};
+
+struct PyrObject : public PyrObjectHdr {
+ PyrSlot slots[1];
+};
+
+struct PyrList : public PyrObjectHdr
+{
+ PyrSlot array;
+};
+
+struct PyrDoubleArray : public PyrObjectHdr
+{
+ double d[1];
+};
+
+struct PyrFloatArray : public PyrObjectHdr
+{
+ float f[1];
+};
+
+struct PyrInt32Array : public PyrObjectHdr
+{
+ uint32 i[1];
+};
+
+struct PyrInt16Array : public PyrObjectHdr
+{
+ uint16 i[1];
+};
+
+struct PyrInt8Array : public PyrObjectHdr
+{
+ uint8 b[1];
+};
+
+struct PyrRGBArray : public PyrObjectHdr
+{
+ RGBColor8 r[1];
+};
+
+struct PyrString : public PyrObjectHdr
+{
+ char s[1];
+};
+
+struct PyrSymbolArray : public PyrObjectHdr
+{
+ PyrSymbol* symbols[1];
+};
+
+extern struct PyrClass *class_object;
+extern struct PyrClass *class_array;
+extern struct PyrClass *class_list, *class_method, *class_fundef, *class_frame, *class_class;
+extern struct PyrClass *class_symbol, *class_nil;
+extern struct PyrClass *class_boolean, *class_true, *class_false;
+extern struct PyrClass *class_int, *class_char, *class_float, *class_complex;
+extern struct PyrClass *class_rawptr;
+extern struct PyrClass *class_string;
+extern struct PyrClass *class_magnitude, *class_number, *class_collection;
+extern struct PyrClass *class_sequenceable_collection;
+extern struct PyrClass *class_arrayed_collection;
+extern struct PyrClass *class_simple_number;
+extern struct PyrClass *class_signal;
+extern struct PyrClass *class_wavetable;
+extern struct PyrClass *class_rawarray;
+extern struct PyrClass *class_int8array;
+extern struct PyrClass *class_int16array;
+extern struct PyrClass *class_int32array;
+extern struct PyrClass *class_symbolarray;
+extern struct PyrClass *class_floatarray;
+extern struct PyrClass *class_doublearray;
+extern struct PyrClass *class_func, *class_absfunc;
+extern struct PyrClass *class_stream;
+extern struct PyrClass *class_process;
+extern struct PyrClass *class_thread;
+extern struct PyrClass *class_routine;
+extern struct PyrClass *class_inf;
+extern struct PyrClass *class_finalizer;
+
+extern PyrSymbol *s_none;
+extern PyrSymbol *s_object;
+extern PyrSymbol *s_bag;
+extern PyrSymbol *s_set;
+extern PyrSymbol *s_identityset;
+extern PyrSymbol *s_dictionary;
+extern PyrSymbol *s_identitydictionary;
+extern PyrSymbol *s_linkedlist;
+extern PyrSymbol *s_sortedlist;
+extern PyrSymbol *s_array;
+extern PyrSymbol *s_list, *s_method, *s_fundef, *s_frame, *s_class;
+extern PyrSymbol *s_symbol, *s_nil, *s_inf;
+extern PyrSymbol *s_boolean, *s_true, *s_false;
+extern PyrSymbol *s_int, *s_char, *s_color, *s_float, *s_complex;
+extern PyrSymbol *s_rawptr, *s_objptr;
+extern PyrSymbol *s_string;
+extern PyrSymbol *s_magnitude, *s_number, *s_collection;
+extern PyrSymbol *s_ordered_collection;
+extern PyrSymbol *s_sequenceable_collection;
+extern PyrSymbol *s_arrayed_collection;
+extern PyrSymbol *s_simple_number;
+extern PyrSymbol *s_signal;
+extern PyrSymbol *s_wavetable;
+extern PyrSymbol *s_int8array;
+extern PyrSymbol *s_int16array;
+extern PyrSymbol *s_int32array;
+extern PyrSymbol *s_symbolarray;
+extern PyrSymbol *s_floatarray;
+extern PyrSymbol *s_doublearray;
+extern PyrSymbol *s_point;
+extern PyrSymbol *s_rect;
+extern PyrSymbol *s_stream;
+extern PyrSymbol *s_process;
+extern PyrSymbol *s_main;
+extern PyrSymbol *s_thread;
+extern PyrSymbol *s_routine;
+extern PyrSymbol *s_linear, *s_exponential, *s_gate;
+extern PyrSymbol *s_env;
+
+extern PyrSymbol *s_audio, *s_control, *s_scalar;
+extern PyrSymbol *s_run;
+extern PyrSymbol *s_next;
+extern PyrSymbol *s_at;
+extern PyrSymbol *s_put;
+extern PyrSymbol *s_series, *s_copyseries, *s_putseries;
+extern PyrSymbol *s_value;
+extern PyrSymbol *s_performList;
+extern PyrSymbol *s_superPerformList;
+extern PyrSymbol *s_ugen, *s_outputproxy;
+extern PyrSymbol *s_new, *s_ref;
+extern PyrSymbol *s_synth, *s_spawn, *s_environment, *s_event;
+extern PyrSymbol *s_interpreter;
+extern PyrSymbol *s_finalizer;
+extern PyrSymbol *s_awake;
+extern PyrSymbol *s_appclock;
+extern PyrSymbol *s_systemclock;
+
+
+extern int gFormatElemSize[NUMOBJFORMATS];
+extern int gFormatElemCapc[NUMOBJFORMATS];
+extern int gFormatElemTag[NUMOBJFORMATS];
+
+void dumpObject(PyrObject *obj);
+void dumpObjectSlot(PyrSlot *slot);
+
+bool respondsTo(PyrSlot *slot, PyrSymbol *selector);
+bool isSubclassOf(struct PyrClass *classobj, struct PyrClass *testclass);
+
+const int kFloatTagIndex = 12;
+extern struct PyrClass* gTagClassTable[16];
+
+inline struct PyrClass* classOfSlot(PyrSlot *slot)
+{
+ PyrClass *classobj;
+ int tag;
+ if (IsFloat(slot)) classobj = gTagClassTable[kFloatTagIndex];
+ else if ((tag = slot->utag & 0xF) == 1) classobj = slot->uo->classptr;
+ else classobj = gTagClassTable[tag];
+
+ return classobj;
+}
+
+typedef int (*ObjFuncPtr)(struct VMGlobals*, struct PyrObject*);
+
+void stringFromPyrString(PyrString *obj, char *str, int maxlength);
+void pstringFromPyrString(PyrString *obj, unsigned char *str, int maxlength);
+
+int instVarOffset(char *classname, char *instvarname);
+int classVarOffset(char *classname, char *classvarname, PyrClass** classobj);
+
+void fillSlots(PyrSlot* slot, int size, PyrSlot* fillslot);
+void nilSlots(PyrSlot* slot, int size);
+void zeroSlots(PyrSlot* slot, int size);
+
+int calcHash(PyrSlot *a);
+int getIndexedFloat(struct PyrObject *obj, int index, float *value);
+int getIndexedDouble(struct PyrObject *obj, int index, double *value);
+void getIndexedSlot(struct PyrObject *obj, PyrSlot *a, int index);
+int putIndexedSlot(struct VMGlobals *g, struct PyrObject *obj, PyrSlot *c, int index);
+int putIndexedFloat(PyrObject *obj, double val, int index);
+
+inline int ARRAYMAXINDEXSIZE(PyrObjectHdr* obj)
+{
+ return (1L << obj->obj_sizeclass);
+}
+
+inline int MAXINDEXSIZE(PyrObjectHdr* obj)
+{
+ return ((1L << obj->obj_sizeclass) * gFormatElemCapc[ obj->obj_format ]);
+}
+
+void InstallFinalizer(VMGlobals* g, PyrObject *inObj, int slotIndex, ObjFuncPtr inFunc);
+
+/////
+
+#endif
diff --git a/sc4pd/headers/lang/PyrObjectProto.h b/sc4pd/headers/lang/PyrObjectProto.h
new file mode 100644
index 0000000..b66ecc2
--- /dev/null
+++ b/sc4pd/headers/lang/PyrObjectProto.h
@@ -0,0 +1,44 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#ifndef _PYROBJPROTO_H_
+#define _PYROBJPROTO_H_
+
+#include "PyrObject.h"
+
+void initSymbols();
+void initClasses();
+void buildClassTree();
+
+void freePyrSlot(PyrSlot *slot);
+void freePyrObject(PyrObject* obj);
+
+bool objAddIndexedSlot(PyrObject *obj, PyrSlot *slot);
+bool objAddIndexedSymbol(PyrSymbolArray *obj, PyrSymbol *symbol);
+bool objAddIndexedObject(PyrObject *obj, PyrObject *obj2);
+
+void CallStackSanity(struct VMGlobals *g, char* tagstr);
+bool FrameSanity(struct PyrFrame *frame, char* tagstr);
+
+void dumpBadObject(PyrObject *obj);
+void initRawRegistry();
+
+#endif
+
diff --git a/sc4pd/headers/lang/PyrParseNode.h b/sc4pd/headers/lang/PyrParseNode.h
new file mode 100644
index 0000000..cd6688c
--- /dev/null
+++ b/sc4pd/headers/lang/PyrParseNode.h
@@ -0,0 +1,456 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#ifndef _PYRPARSENODE_H_
+#define _PYRPARSENODE_H_
+
+#include "PyrSlot.h"
+#include "PyrKernel.h"
+#include "ByteCodeArray.h"
+#include "Opcodes.h"
+#include "AdvancingAllocPool.h"
+
+extern AdvancingAllocPool gParseNodePool;
+
+#define ALLOCNODE(type) (type*)gParseNodePool.Alloc(sizeof(type))
+//#define FREENODE(node) if (node) (*parseNodeClasses[(node)->classno]->deleteFunc)(node);
+#define DUMPNODE(node, level) if (node) (*parseNodeClasses[(node)->classno]->dumpFunc)((node),(level));
+#define COMPILENODE(node, result) (*parseNodeClasses[(node)->classno]->compileFunc)((node),(result));
+
+typedef void (*PyrCompileNodeFunc)(void*, void*);
+typedef void (*PyrDumpNodeFunc)(void*,int);
+
+typedef struct pyrparsenodeclass {
+ int type;
+ PyrCompileNodeFunc compileFunc;
+ PyrDumpNodeFunc dumpFunc;
+} PyrParseNodeClass;
+
+
+struct PyrParseNode {
+ struct PyrParseNode *next;
+ struct PyrParseNode *tail;
+ short lineno;
+ unsigned char charno, classno;
+};
+
+
+struct PyrSlotNode : public PyrParseNode {
+ PyrSlot slot;
+};
+
+extern PyrParseNodeClass *pyrSlotNodeClass;
+
+struct PyrPushNameNode : public PyrParseNode {
+ PyrSlot varName;
+} ;
+
+extern PyrParseNodeClass *pyrPushNameNodeClass;
+
+struct PyrClassExtNode : public PyrParseNode {
+ struct PyrSlotNode* className;
+ struct PyrMethodNode *methods;
+} ;
+
+extern PyrParseNodeClass *pyrClassExtNodeClass;
+
+struct PyrClassNode : public PyrParseNode {
+ struct PyrSlotNode* className;
+ struct PyrSlotNode* superClassName;
+ struct PyrSlotNode* indexType;
+ struct PyrVarListNode *varlists;
+ struct PyrMethodNode *methods;
+ int varTally[3];
+ int numsuperinstvars;
+} ;
+
+extern PyrParseNodeClass *pyrClassNodeClass;
+
+struct PyrMethodNode : public PyrParseNode {
+ struct PyrSlotNode* methodName;
+ struct PyrSlotNode* primitiveName;
+ struct PyrArgListNode *arglist;
+ struct PyrVarListNode *varlist;
+ struct PyrParseNode *body;
+ int isClassMethod; // is class method?
+ bool extension;
+} ;
+
+extern PyrParseNodeClass *pyrMethodNodeClass;
+
+struct PyrVarListNode : public PyrParseNode {
+ struct PyrVarDefNode *varDefs;
+ int flags;
+} ;
+
+extern PyrParseNodeClass *pyrVarListNodeClass;
+
+struct PyrVarDefNode : public PyrParseNode {
+ struct PyrSlotNode* varName;
+ struct PyrLiteralNode* defVal;
+ int flags;
+} ;
+
+extern PyrParseNodeClass *pyrVarDefNodeClass;
+
+struct PyrCallNode : public PyrParseNode {
+ struct PyrSlotNode* selector;
+ struct PyrParseNode *arglist;
+ struct PyrParseNode *keyarglist;
+} ;
+
+extern PyrParseNodeClass *pyrCallNodeClass;
+
+struct PyrBinopCallNode : public PyrParseNode {
+ struct PyrSlotNode* selector;
+ struct PyrParseNode *arg1;
+ struct PyrParseNode *arg2;
+ struct PyrParseNode *arg3;
+} ;
+
+extern PyrParseNodeClass *pyrBinopCallNodeClass;
+
+struct PyrDropNode : public PyrParseNode {
+ struct PyrParseNode *expr1;
+ struct PyrParseNode *expr2;
+} ;
+
+extern PyrParseNodeClass *pyrDropNodeClass;
+
+struct PyrPushLitNode : public PyrParseNode {
+ PyrSlot literalSlot;
+} ;
+
+extern PyrParseNodeClass *pyrPushLitNodeClass;
+
+struct PyrPushKeyArgNode : public PyrParseNode {
+ struct PyrSlotNode* selector;
+ struct PyrParseNode *expr;
+} ;
+
+extern PyrParseNodeClass *pyrPushKeyArgNodeClass;
+
+struct PyrLiteralNode : public PyrParseNode {
+ PyrSlot literalSlot;
+} ;
+
+extern PyrParseNodeClass *pyrLiteralNodeClass;
+
+
+struct PyrReturnNode : public PyrParseNode {
+ struct PyrParseNode *expr; // if null, return self
+} ;
+
+extern PyrParseNodeClass *pyrReturnNodeClass;
+
+struct PyrBlockReturnNode : public PyrParseNode {
+ struct PyrParseNode *expr; // if null, return self
+} ;
+
+extern PyrParseNodeClass *pyrBlockReturnNodeClass;
+
+
+struct PyrAssignNode : public PyrParseNode {
+ struct PyrSlotNode* varName;
+ struct PyrParseNode *expr;
+ bool drop; // allow drop
+} ;
+
+extern PyrParseNodeClass *pyrAssignNodeClass;
+
+struct PyrSetterNode : public PyrParseNode {
+ struct PyrSlotNode* selector;
+ struct PyrParseNode *expr1;
+ struct PyrParseNode *expr2;
+ int flags; // is a var def ?
+} ;
+
+extern PyrParseNodeClass *pyrSetterNodeClass;
+
+struct PyrMultiAssignNode : public PyrParseNode {
+ struct PyrMultiAssignVarListNode *varList;
+ struct PyrParseNode *expr;
+ bool drop; // allow drop
+} ;
+
+extern PyrParseNodeClass *pyrMultiAssignNodeClass;
+
+struct PyrMultiAssignVarListNode : public PyrParseNode {
+ struct PyrSlotNode *varNames;
+ struct PyrSlotNode *rest;
+} ;
+
+extern PyrParseNodeClass *pyrMultiAssignVarListNodeClass;
+
+struct PyrBlockNode : public PyrParseNode {
+ struct PyrArgListNode *arglist;
+ struct PyrVarListNode *varlist;
+ struct PyrParseNode *body;
+ bool isTopLevel;
+ int beginCharNo;
+} ;
+
+
+extern PyrParseNodeClass *pyrBlockNodeClass;
+
+struct PyrArgListNode : public PyrParseNode {
+ struct PyrVarDefNode *varDefs;
+ struct PyrSlotNode *rest;
+} ;
+
+extern PyrParseNodeClass *pyrArgListNodeClass;
+
+struct PyrDynListNode : public PyrParseNode {
+ struct PyrParseNode *classname;
+ struct PyrParseNode *elems;
+} ;
+
+extern PyrParseNodeClass *pyrDynListNodeClass;
+
+struct PyrDynDictNode : public PyrParseNode {
+ struct PyrParseNode *elems;
+} ;
+
+extern PyrParseNodeClass *pyrDynDictNodeClass;
+
+struct PyrLitListNode : public PyrParseNode {
+ struct PyrParseNode *classname;
+ struct PyrParseNode *elems;
+} ;
+
+extern PyrParseNodeClass *pyrLitListNodeClass;
+
+extern PyrParseNode* gRootParseNode;
+extern int gParserResult;
+
+enum { rwPrivate=0, rwReadOnly=1, rwWriteOnly=2, rwReadWrite=3 };
+
+enum { varInst, varClass, varTemp, varPseudo };
+
+enum {
+ /* structural units */
+ pn_ClassNode,
+ pn_ClassExtNode,
+ pn_MethodNode,
+ pn_BlockNode,
+ pn_SlotNode,
+
+ /* variable declarations */
+ pn_VarListNode,
+ pn_VarDefNode,
+ pn_DynDictNode,
+ pn_DynListNode,
+ pn_LitListNode,
+
+ pn_StaticVarListNode,
+ pn_InstVarListNode,
+ pn_PoolVarListNode,
+ pn_ArgListNode,
+ pn_SlotDefNode,
+
+ /* selectors */
+ pn_LiteralNode,
+
+ /* code */
+ pn_PushLitNode,
+ pn_PushNameNode,
+ pn_PushKeyArgNode,
+ pn_CallNode,
+ pn_BinopCallNode,
+ pn_DropNode,
+ pn_AssignNode,
+ pn_MultiAssignNode,
+ pn_MultiAssignVarListNode,
+ pn_SetterNode,
+
+ pn_ReturnNode,
+ pn_BlockReturnNode,
+
+ pn_NumTypes
+};
+
+extern char *parseNodeFormat[pn_NumTypes];
+extern PyrParseNodeClass* parseNodeClasses[pn_NumTypes];
+
+
+void initParseNodes();
+
+PyrParseNodeClass* newParseNodeClass(int type, PyrCompileNodeFunc compileFunc,
+ PyrDumpNodeFunc dumpFunc);
+
+PyrSlotNode* newPyrSlotNode(PyrSlot *slot);
+PyrClassNode* newPyrClassNode(PyrSlotNode* className, PyrSlotNode* superClassName,
+ PyrVarListNode* varlists, PyrMethodNode* methods, PyrSlotNode* indexType);
+PyrClassExtNode* newPyrClassExtNode(PyrSlotNode* className, PyrMethodNode* methods);
+PyrMethodNode* newPyrMethodNode(PyrSlotNode* methodName, PyrSlotNode* primitiveName,
+ PyrArgListNode* arglist, PyrVarListNode *varlist, PyrParseNode* body, int isClassMethod);
+PyrArgListNode* newPyrArgListNode(PyrVarDefNode* varDefs, PyrSlotNode* rest);
+PyrVarListNode* newPyrVarListNode(PyrVarDefNode* vardefs, int flags);
+PyrVarDefNode* newPyrVarDefNode(PyrSlotNode* varName, PyrLiteralNode* defVal, int flags);
+PyrCallNode* newPyrCallNode(PyrSlotNode* selector, PyrParseNode* arglist,
+ PyrParseNode* keyarglist, PyrParseNode* blocklist);
+PyrBinopCallNode* newPyrBinopCallNode(PyrSlotNode* selector,
+ PyrParseNode* arg1, PyrParseNode* arg2, PyrParseNode* arg3);
+PyrDropNode* newPyrDropNode(PyrParseNode* expr1, PyrParseNode* expr2);
+PyrPushKeyArgNode* newPyrPushKeyArgNode(PyrSlotNode* selector, PyrParseNode* expr);
+PyrPushLitNode* newPyrPushLitNode(PyrSlotNode* literalSlot, PyrParseNode* literalObj);
+PyrLiteralNode* newPyrLiteralNode(PyrSlotNode* literalSlot, PyrParseNode* literalObj);
+PyrReturnNode* newPyrReturnNode(PyrParseNode* expr);
+PyrBlockReturnNode* newPyrBlockReturnNode();
+PyrAssignNode* newPyrAssignNode(PyrSlotNode* varName, PyrParseNode* expr, int flags);
+PyrSetterNode* newPyrSetterNode(PyrSlotNode* varName,
+ PyrParseNode* expr1, PyrParseNode* expr2);
+PyrMultiAssignNode* newPyrMultiAssignNode(PyrMultiAssignVarListNode* varList,
+ PyrParseNode* expr, int flags);
+PyrPushNameNode* newPyrPushNameNode(PyrSlotNode *slotNode);
+PyrDynDictNode* newPyrDynDictNode(PyrParseNode *elems);
+PyrDynListNode* newPyrDynListNode(PyrParseNode *classname, PyrParseNode *elems);
+PyrLitListNode* newPyrLitListNode(PyrParseNode *classname, PyrParseNode *elems);
+PyrMultiAssignVarListNode* newPyrMultiAssignVarListNode(PyrSlotNode* varNames,
+ PyrSlotNode* rest);
+PyrBlockNode* newPyrBlockNode(PyrArgListNode *arglist, PyrVarListNode *varlist, PyrParseNode *body, bool isTopLevel);
+
+void compilePyrSlotNode(PyrSlotNode* node, void *result);
+void compilePyrClassNode(PyrClassNode* node, void *result);
+void compilePyrClassExtNode(PyrClassExtNode* node, void *result);
+void compilePyrMethodNode(PyrMethodNode* node, void *result);
+void compilePyrArgListNode(PyrArgListNode* node, void *result);
+void compilePyrVarListNode(PyrVarListNode* node, void *result);
+void compilePyrVarDefNode(PyrVarDefNode* node, void *result);
+void compilePyrCallNode(PyrCallNode* node, void *result);
+void compilePyrBinopCallNode(PyrBinopCallNode* node, void *result);
+void compilePyrPushLitNode(PyrPushLitNode* node, void *result);
+void compilePyrLiteralNode(PyrLiteralNode* node, void *result);
+void compilePyrReturnNode(PyrReturnNode* node, void *result);
+void compilePyrBlockReturnNode(PyrBlockReturnNode* node, void *result);
+void compilePyrAssignNode(PyrAssignNode* node, void *result);
+void compilePyrSetterNode(PyrSetterNode* node, void* result);
+void compilePyrMultiAssignNode(PyrMultiAssignNode* node, void *result);
+void compilePyrMultiAssignVarListNode(PyrMultiAssignVarListNode* node, void *result);
+void compilePyrDynDictNode(PyrDynDictNode* node, void *result);
+void compilePyrDynListNode(PyrDynListNode* node, void *result);
+void compilePyrLitListNode(PyrLitListNode* node, void *result);
+void compilePyrBlockNode(PyrBlockNode* node, void *result);
+void compilePyrPushNameNode(PyrPushNameNode* node, void *result);
+void compilePyrDropNode(PyrDropNode* node, void *result);
+void compilePyrPushKeyArgNode(PyrPushKeyArgNode* node, void *result);
+
+void dumpPyrSlotNode(PyrSlotNode* node, int level);
+void dumpPyrClassNode(PyrClassNode* node, int level);
+void dumpPyrClassExtNode(PyrClassExtNode* node, int level);
+void dumpPyrMethodNode(PyrMethodNode* node, int level);
+void dumpPyrArgListNode(PyrArgListNode* node, int level);
+void dumpPyrVarListNode(PyrVarListNode* node, int level);
+void dumpPyrVarDefNode(PyrVarDefNode* node, int level);
+void dumpPyrCallNode(PyrCallNode* node, int level);
+void dumpPyrBinopCallNode(PyrBinopCallNode* node, int level);
+void dumpPyrPushLitNode(PyrPushLitNode* node, int level);
+void dumpPyrLiteralNode(PyrLiteralNode* node, int level);
+void dumpPyrReturnNode(PyrReturnNode* node, int level);
+void dumpPyrBlockReturnNode(PyrBlockReturnNode* node, int level);
+void dumpPyrAssignNode(PyrAssignNode* node, int level);
+void dumpPyrSetterNode(PyrSetterNode* node, int level);
+void dumpPyrMultiAssignNode(PyrMultiAssignNode* node, int level);
+void dumpPyrMultiAssignVarListNode(PyrMultiAssignVarListNode* node, int level);
+void dumpPyrDynDictNode(PyrDynDictNode* node, int level);
+void dumpPyrDynListNode(PyrDynListNode* node, int level);
+void dumpPyrLitListNode(PyrLitListNode* node, int level);
+void dumpPyrBlockNode(PyrBlockNode* node, int level);
+void dumpPyrPushNameNode(PyrPushNameNode* node, int level);
+void dumpPyrPushKeyArgNode(PyrPushKeyArgNode* node, int level);
+void dumpPyrDropNode(PyrDropNode* node, int level);
+
+PyrClass* getNodeSuperclass(PyrClassNode *node);
+void countNodeMethods(PyrClassNode* node, int *numClassMethods, int *numInstMethods);
+void compileExtNodeMethods(PyrClassExtNode* node);
+void countVarDefs(PyrClassNode* node);
+bool compareVarDefs(PyrClassNode* node, PyrClass* classobj);
+void recompileSubclasses(PyrClass* classobj);
+void compileNodeMethods(PyrClassNode* node);
+void fillClassPrototypes(PyrClassNode *node, PyrClass *classobj, PyrClass *superclassobj);
+
+int nodeListLength(PyrParseNode *node);
+bool isSuperObjNode(PyrParseNode *node);
+bool isThisObjNode(PyrParseNode *node);
+int conjureSelectorIndex(PyrParseNode *node, PyrBlock* func,
+ bool isSuper, PyrSymbol *selector, int *selType);
+int conjureLiteralSlotIndex(PyrParseNode *node, PyrBlock* func, PyrSlot *slot);
+bool findVarName(PyrBlock* func, PyrClass **classobj, PyrSymbol *name,
+ int *varType, int *level, int *index, PyrBlock** tempfunc);
+void countClassVarDefs(PyrClassNode* node, int *numClassMethods, int *numInstMethods);
+void compileNodeList(PyrParseNode *node);
+void dumpNodeList(PyrParseNode *node);
+int compareCallArgs(PyrMethodNode* node, PyrCallNode *cnode, int *varIndex);
+
+bool findSpecialClassName(PyrSymbol *className, int *index);
+int getIndexType(PyrClassNode *classnode);
+
+void compileIfMsg(PyrCallNode* node);
+void compileWhileMsg(PyrCallNode* node);
+void compileLoopMsg(PyrCallNode* node);
+void compileAndMsg(PyrParseNode* arg1, PyrParseNode* arg2);
+void compileOrMsg(PyrParseNode* arg1, PyrParseNode* arg2);
+
+void compilePushInt(int value);
+void compileAssignVar(PyrParseNode *node, PyrSymbol* varName, bool drop);
+void compilePushVar(PyrParseNode *node, PyrSymbol *varName);
+bool isAnInlineableBlock(PyrParseNode *node);
+bool isWhileTrue(PyrParseNode *node);
+void installByteCodes(PyrBlock *block);
+
+ByteCodes compileSubExpression(PyrPushLitNode* litnode);
+ByteCodes compileSubExpressionWithGoto(PyrPushLitNode* litnode, int branchLen);
+//ByteCodes compileDefaultValue(int litIndex, int realExprLen);
+
+void initParser();
+void finiParser();
+void initParserPool();
+void freeParserPool();
+
+void initSpecialSelectors();
+void initSpecialClasses();
+
+void nodePostErrorLine(PyrParseNode* node);
+
+PyrParseNode* linkNextNode(PyrParseNode* a, PyrParseNode* b);
+PyrParseNode* linkAfterHead(PyrParseNode* a, PyrParseNode* b);
+
+extern int compileErrors;
+
+extern long zzval;
+extern PyrSymbol *ps_newlist;
+extern PyrSymbol *gSpecialUnarySelectors[opNumUnarySelectors];
+extern PyrSymbol *gSpecialBinarySelectors[opNumBinarySelectors];
+extern PyrSymbol *gSpecialSelectors[opmNumSpecialSelectors];
+extern PyrSymbol* gSpecialClasses[op_NumSpecialClasses];
+
+extern PyrClass *gCurrentClass;
+extern PyrClass *gCurrentMetaClass;
+extern PyrClass *gCompilingClass;
+extern PyrMethod *gCompilingMethod;
+extern PyrBlock *gCompilingBlock;
+
+/*
+ compiling
+ "inlining" of special arithmetic opcodes.
+ inlining of IF, WHILE, AND, OR
+*/
+
+#endif
diff --git a/sc4pd/headers/lang/PyrPrimitive.h b/sc4pd/headers/lang/PyrPrimitive.h
new file mode 100644
index 0000000..4afe653
--- /dev/null
+++ b/sc4pd/headers/lang/PyrPrimitive.h
@@ -0,0 +1,42 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+/*
+
+Functions for defining language primitives.
+
+*/
+
+#ifndef _PYRPRIMITIVE_H_
+#define _PYRPRIMITIVE_H_
+
+#include "PyrSlot.h"
+
+typedef int (*PrimitiveHandler)(struct VMGlobals *g, int numArgsPushed);
+typedef int (*PrimitiveWithKeysHandler)(struct VMGlobals *g, int numArgsPushed, int numKeyArgsPushed);
+
+int nextPrimitiveIndex();
+int definePrimitive(int base, int index, char *name, PrimitiveHandler handler, int numArgs, int varArgs);
+int definePrimitiveWithKeys(int base, int index, char *name,
+ PrimitiveHandler handler, PrimitiveWithKeysHandler keyhandler,
+ int numArgs, int varArgs);
+int getPrimitiveNumArgs(int index);
+PyrSymbol* getPrimitiveName(int index);
+
+#endif
diff --git a/sc4pd/headers/lang/PyrPrimitiveProto.h b/sc4pd/headers/lang/PyrPrimitiveProto.h
new file mode 100644
index 0000000..43464a4
--- /dev/null
+++ b/sc4pd/headers/lang/PyrPrimitiveProto.h
@@ -0,0 +1,81 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#ifndef _PYRPRIMITIVEPROTO_H_
+#define _PYRPRIMITIVEPROTO_H_
+
+#include "PyrPrimitive.h"
+
+int basicNew(VMGlobals *g, int numArgsPushed);
+int basicNewClear(VMGlobals *g, int numArgsPushed);
+int basicSwap(VMGlobals *g, int numArgsPushed);
+int instVarAt(VMGlobals *g, int numArgsPushed);
+int instVarPut(VMGlobals *g, int numArgsPushed);
+int instVarSize(VMGlobals *g, int numArgsPushed);
+int objectHash(VMGlobals *g, int numArgsPushed);
+int objectClass(VMGlobals *g, int numArgsPushed);
+int blockValue(VMGlobals *g, int numArgsPushed);
+int blockValueWithKeys(VMGlobals *g, int allArgsPushed, int numKeyArgsPushed);
+int blockValueArray(VMGlobals *g, int numArgsPushed);
+int blockSpawn(VMGlobals *g, int numArgsPushed);
+
+int objectIsKindOf(VMGlobals *g, int numArgsPushed);
+int objectIsMemberOf(VMGlobals *g, int numArgsPushed);
+int objectDump(VMGlobals *g, int numArgsPushed);
+int haltInterpreter(VMGlobals *g, int numArgsPushed);
+int objectIdentical(VMGlobals *g, int numArgsPushed);
+int objectNotIdentical(VMGlobals *g, int numArgsPushed);
+int objectPerform(VMGlobals *g, int numArgsPushed);
+int objectPerformList(VMGlobals *g, int numArgsPushed);
+int objectPerformSelList(VMGlobals *g, int numArgsPushed);
+int undefinedPrimitive(VMGlobals *g, int numArgsPushed);
+
+int prObjectString(VMGlobals *g, int numArgsPushed);
+int prClassString(VMGlobals *g, int numArgsPushed);
+int prSymbolString(VMGlobals *g, int numArgsPushed);
+int prSymbolClass(VMGlobals *g, int numArgsPushed);
+int prPostString(VMGlobals *g, int numArgsPushed);
+int prPostLine(VMGlobals *g, int numArgsPushed);
+int prFlushPostBuf(VMGlobals *g, int numArgsPushed);
+
+int prPrimitiveError(VMGlobals *g, int numArgsPushed);
+int prPrimitiveErrorString(VMGlobals *g, int numArgsPushed);
+int prDumpStack(VMGlobals *g, int numArgsPushed);
+int prDebugger(VMGlobals *g, int numArgsPushed);
+int prPrimName(VMGlobals *g, int numArgsPushed);
+int prObjectShallowCopy(VMGlobals *g, int numArgsPushed);
+int prObjectCopyRange(VMGlobals *g, int numArgsPushed);
+int prObjectPointsTo(VMGlobals *g, int numArgsPushed);
+int prObjectRespondsTo(VMGlobals *g, int numArgsPushed);
+
+int prCompileString(VMGlobals *g, int numArgsPushed);
+int prDumpBackTrace(VMGlobals *g, int numArgsPushed);
+int prDumpByteCodes(VMGlobals *g, int numArgsPushed);
+int prAllClasses(VMGlobals *g, int numArgsPushed);
+int prPostClassTree(VMGlobals *g, int numArgsPushed);
+
+void initPrimitiveTable();
+void growPrimitiveTable(int newsize);
+
+void initPrimitives();
+void doPrimitive(VMGlobals* g, struct PyrMethod* meth, int numArgsPushed);
+void doPrimitiveWithKeys(VMGlobals* g, struct PyrMethod* meth, int allArgsPushed, int numKeysPushed);
+
+#endif
diff --git a/sc4pd/headers/lang/PyrSched.h b/sc4pd/headers/lang/PyrSched.h
new file mode 100644
index 0000000..5102582
--- /dev/null
+++ b/sc4pd/headers/lang/PyrSched.h
@@ -0,0 +1,58 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#ifndef _PYRSCHED_H_
+#define _PYRSCHED_H_
+
+#include "VMGlobals.h"
+#include <pthread.h>
+
+extern pthread_mutex_t gLangMutex;
+
+void schedInit();
+void schedCleanup();
+
+void schedRun();
+void schedStop();
+void schedClear();
+
+double elapsedTime();
+int64 OSCTime();
+
+int64 ElapsedTimeToOSC(double elapsed);
+double OSCToElapsedTime(int64 oscTime);
+
+void syncOSCOffsetWithTimeOfDay();
+void doubleToTimespec(double secs, struct timespec *spec);
+
+
+bool addheap(VMGlobals *g, PyrObject *heap, double schedtime, PyrSlot *task);
+bool lookheap(PyrObject *heap, double *schedtime, PyrSlot *task) ;
+bool getheap(PyrObject *heap, double *schedtime, PyrSlot *task) ;
+void offsetheap(VMGlobals *g, PyrObject *heap, double offset) ;
+void dumpheap(PyrObject *heap);
+
+const double kSecondsToOSC = 4294967296.; // pow(2,32)/1
+const double kMicrosToOSC = 4294.967296; // pow(2,32)/1e6
+const double kNanosToOSC = 4.294967296; // pow(2,32)/1e9
+const double kOSCtoSecs = 2.328306436538696e-10; // 1/pow(2,32)
+const double kOSCtoNanos = 0.2328306436538696; // 1e9/pow(2,32)
+
+#endif \ No newline at end of file
diff --git a/sc4pd/headers/lang/PyrSignal.h b/sc4pd/headers/lang/PyrSignal.h
new file mode 100644
index 0000000..ee57b38
--- /dev/null
+++ b/sc4pd/headers/lang/PyrSignal.h
@@ -0,0 +1,417 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+
+#pragma once on
+
+#include "PyrObject.h"
+#include "GC.h"
+
+#define UNROLL 1
+
+enum {
+ kSignalRate = 0, // index of rate slot
+ kSignalNextNode
+};
+
+#define FSINESIZE 8192.
+#define SINESIZE 8192
+#define SINEMASK 8191
+#define VERY_BIG_FLOAT (1.e10)
+extern float *sineCycle;
+extern float *invSineCycle;
+extern float *pmSineCycle;
+extern double phaseToSineIndex;
+extern double sineIndexToPhase;
+
+//#define FRACTABLESIZE 4096
+//#define FRACMASK 0x3FFC
+//extern float *gFracTable;
+
+
+PyrObject* newPyrSignal(VMGlobals *g, long size);
+
+#if 0
+#define UNROLL8_CODE(size,var,stmt) \
+ endptr = var + size; \
+ switch (size & 7) { \
+ while (var < endptr) { \
+ stmt; \
+ case 7 : stmt; \
+ case 6 : stmt; \
+ case 5 : stmt; \
+ case 4 : stmt; \
+ case 3 : stmt; \
+ case 2 : stmt; \
+ case 1 : stmt; \
+ case 0 : ; \
+ } \
+ }
+#else
+#define UNROLL8_CODE(size,var,stmt) \
+ { int tempi, tempend; \
+ tempend = size>>3; \
+ for (tempi=0; tempi<tempend; ++tempi) { \
+ stmt;stmt;stmt;stmt; \
+ stmt;stmt;stmt;stmt; \
+ } \
+ tempend = size&7; \
+ for (tempi=0; tempi<tempend; ++tempi) { \
+ stmt; \
+ } \
+ }
+#endif
+
+#if 0
+#define UNROLL4_CODE(size,var,stmt) \
+ endptr = var + size; \
+ switch (size & 3) { \
+ while (var < endptr) { \
+ stmt; \
+ case 3 : stmt; \
+ case 2 : stmt; \
+ case 1 : stmt; \
+ case 0 : ; \
+ } \
+ }
+#else
+#define UNROLL4_CODE(size,var,stmt) \
+ { int tempi, tempend; \
+ tempend = size>>2; \
+ for (tempi=0; tempi<tempend; ++tempi) { \
+ stmt;stmt;stmt;stmt; \
+ } \
+ tempend = size&3; \
+ for (tempi=0; tempi<tempend; ++tempi) { \
+ stmt; \
+ } \
+ }
+#endif
+
+#if 0
+#define FILTER_LOOP(size,var,stmt,stmt2) \
+ endptr = var + size; \
+ switch (size & 3) { \
+ case 0 : while (var < endptr) { \
+ stmt; \
+ case 3 : stmt; \
+ case 2 : stmt; \
+ case 1 : stmt; \
+ stmt2; \
+ } \
+ }
+#else
+#define FILTER_LOOP(size,var,stmt,stmt2) \
+ { int tempi, tempend; \
+ tempend = size>>2; \
+ for (tempi=0; tempi<tempend; ++tempi) { \
+ stmt;stmt;stmt;stmt; \
+ stmt2; \
+ } \
+ tempend = size&3; \
+ for (tempi=0; tempi<tempend; ++tempi) { \
+ stmt; \
+ } \
+ }
+#endif
+
+#define UNROLL1_CODE(size,var,stmt) \
+ { int tempi, tempend; \
+ tempend = size; \
+ for (tempi=0; tempi<tempend; ++tempi) { \
+ stmt; \
+ } \
+ }
+
+
+#if UNROLL == 8
+#define UNROLL_CODE UNROLL8_CODE
+#elif UNROLL == 4
+#define UNROLL_CODE UNROLL4_CODE
+#else
+#define UNROLL_CODE UNROLL1_CODE
+#endif
+
+#if 0
+
+#define BINOP_LOOP1(OP)
+#define BINOP_LOOP2(STMT1, STMT2, STMT3)
+
+#else
+
+#define BINOP_LOOP1(OP) \
+ float *a, *b, *c, *endptr; \
+ PyrObject *outc; \
+ long size; \
+ a = (float*)(ina->slots) - 1; \
+ b = (float*)(inb->slots) - 1; \
+ size = sc_min(ina->size, inb->size); \
+ outc = newPyrSignal(g, size); \
+ c = (float*)(outc->slots) - 1; \
+ endptr = c + size; \
+ switch (size & 3) { \
+ while (c < endptr) { \
+ *++c = *++a OP *++b; \
+ case 3 : *++c = *++a OP *++b; \
+ case 2 : *++c = *++a OP *++b; \
+ case 1 : *++c = *++a OP *++b; \
+ case 0 : ; \
+ } \
+ } \
+ return outc; \
+
+
+#define BINOP_LOOP2(STMT1) \
+ float *a, *b, *c, *endptr; \
+ PyrObject *outc; \
+ long size; \
+ a = (float*)(ina->slots) - 1; \
+ b = (float*)(inb->slots) - 1; \
+ size = sc_min(ina->size, inb->size); \
+ outc = newPyrSignal(g, size); \
+ c = (float*)(outc->slots) - 1; \
+ endptr = c + size; \
+ switch (size & 3) { \
+ while (c < endptr) { \
+ STMT1; \
+ case 3 :STMT1; \
+ case 2 :STMT1; \
+ case 1 :STMT1; \
+ case 0 : ; \
+ } \
+ } \
+ return outc; \
+
+#endif
+
+/*
+ compound formulas :
+ amclip out = B<=0 ? 0 : A*B; // two quadrant amplitude modulation
+ ring1 out = A*(B+1) = A*B + A; // amplitude modulation of a by b.
+ ring2 out = A*B + A + B; // ring modulation plus both original signals
+ ring3 out = A*A*B; // ring modulation variant
+ ring4 out = A*A*B - A*B*B; // ring modulation variant
+ difsqr out = A*A - B*B; // difference of squares
+ sumsqr out = A*A + B*B; // sum of squares
+ sqrdif out = (A - B)^2 // square of the difference = a^2 + b^2 - 2ab
+ sqrsum out = (A + B)^2 // square of the sum = a^2 + b^2 + 2ab
+*/
+
+void signal_init_globs();
+PyrObject* signal_fill(PyrObject *outSignal, float inValue);
+PyrObject* signal_scale(PyrObject *outSignal, float inValue);
+PyrObject* signal_offset(PyrObject *outSignal, float inValue);
+PyrObject* signal_scale_offset(PyrObject *outSignal, float mul, float add);
+PyrObject* signal_mix(PyrObject* ina, PyrObject* inb, float start, float end, float slopeFactor);
+PyrObject* signal_add_xx(VMGlobals *g, PyrObject* ina, PyrObject* inb);
+PyrObject* signal_sub_xx(VMGlobals *g, PyrObject* ina, PyrObject* inb);
+PyrObject* signal_mul_xx(VMGlobals *g, PyrObject* ina, PyrObject* inb);
+PyrObject* signal_mul_ds_xx(VMGlobals *g, PyrObject* ina, PyrObject* inb);
+PyrObject* signal_add_ds_xx(VMGlobals *g, PyrObject* ina, PyrObject* inb);
+PyrObject* signal_sub_ds_xx(VMGlobals *g, PyrObject* ina, PyrObject* inb);
+PyrObject* signal_ring1_xx(VMGlobals *g, PyrObject* ina, PyrObject* inb);
+PyrObject* signal_ring2_xx(VMGlobals *g, PyrObject* ina, PyrObject* inb);
+PyrObject* signal_ring3_xx(VMGlobals *g, PyrObject* ina, PyrObject* inb);
+PyrObject* signal_ring4_xx(VMGlobals *g, PyrObject* ina, PyrObject* inb);
+PyrObject* signal_thresh_xx(VMGlobals *g, PyrObject* ina, PyrObject* inb);
+PyrObject* signal_amclip_xx(VMGlobals *g, PyrObject* ina, PyrObject* inb);
+PyrObject* signal_div_xx(VMGlobals *g, PyrObject* ina, PyrObject* inb);
+PyrObject* signal_difsqr_xx(VMGlobals *g, PyrObject* ina, PyrObject* inb);
+PyrObject* signal_sumsqr_xx(VMGlobals *g, PyrObject* ina, PyrObject* inb);
+PyrObject* signal_sqrsum_xx(VMGlobals *g, PyrObject* ina, PyrObject* inb);
+PyrObject* signal_sqrdif_xx(VMGlobals *g, PyrObject* ina, PyrObject* inb);
+PyrObject* signal_add_xf(VMGlobals *g, PyrObject* ina, float inb);
+PyrObject* signal_sub_xf(VMGlobals *g, PyrObject* ina, float inb);
+PyrObject* signal_mul_xf(VMGlobals *g, PyrObject* ina, float inb);
+PyrObject* signal_ring1_xf(VMGlobals *g, PyrObject* ina, float inb);
+PyrObject* signal_ring2_xf(VMGlobals *g, PyrObject* ina, float inb);
+PyrObject* signal_ring3_xf(VMGlobals *g, PyrObject* ina, float inb);
+PyrObject* signal_ring4_xf(VMGlobals *g, PyrObject* ina, float inb);
+PyrObject* signal_thresh_xf(VMGlobals *g, PyrObject* ina, float inb);
+PyrObject* signal_amclip_xf(VMGlobals *g, PyrObject* ina, float inb);
+PyrObject* signal_div_xf(VMGlobals *g, PyrObject* ina, float inb);
+PyrObject* signal_difsqr_xf(VMGlobals *g, PyrObject* ina, float inb);
+PyrObject* signal_sumsqr_xf(VMGlobals *g, PyrObject* ina, float inb);
+PyrObject* signal_sqrsum_xf(VMGlobals *g, PyrObject* ina, float inb);
+PyrObject* signal_sqrdif_xf(VMGlobals *g, PyrObject* ina, float inb);
+PyrObject* signal_ring1_fx(VMGlobals *g, float ina, PyrObject* inb);
+PyrObject* signal_ring2_fx(VMGlobals *g, float ina, PyrObject* inb);
+PyrObject* signal_ring3_fx(VMGlobals *g, float ina, PyrObject* inb);
+PyrObject* signal_ring4_fx(VMGlobals *g, float ina, PyrObject* inb);
+PyrObject* signal_thresh_fx(VMGlobals *g, float ina, PyrObject* inb);
+PyrObject* signal_amclip_fx(VMGlobals *g, float ina, PyrObject* inb);
+PyrObject* signal_sub_fx(VMGlobals *g, float ina, PyrObject* inb);
+PyrObject* signal_div_fx(VMGlobals *g, float ina, PyrObject* inb);
+PyrObject* signal_difsqr_fx(VMGlobals *g, float ina, PyrObject* inb);
+PyrObject* signal_sumsqr_fx(VMGlobals *g, float ina, PyrObject* inb);
+PyrObject* signal_sqrsum_fx(VMGlobals *g, float ina, PyrObject* inb);
+PyrObject* signal_sqrdif_fx(VMGlobals *g, float ina, PyrObject* inb);
+PyrObject* signal_min_xx(VMGlobals *g, PyrObject* ina, PyrObject* inb);
+PyrObject* signal_max_xx(VMGlobals *g, PyrObject* ina, PyrObject* inb);
+PyrObject* signal_min_xf(VMGlobals *g, PyrObject* ina, float inb);
+PyrObject* signal_max_xf(VMGlobals *g, PyrObject* ina, float inb);
+PyrObject* signal_invert(VMGlobals *g, PyrObject *inPyrSignal);
+PyrObject* signal_recip(VMGlobals *g, PyrObject *inPyrSignal);
+PyrObject* signal_squared(VMGlobals *g, PyrObject *inPyrSignal);
+PyrObject* signal_cubed(VMGlobals *g, PyrObject *inPyrSignal);
+PyrObject* signal_abs(VMGlobals *g, PyrObject *inPyrSignal);
+PyrObject* signal_sign(VMGlobals *g, PyrObject *inPyrSignal);
+PyrObject* signal_negative(VMGlobals *g, PyrObject *inPyrSignal);
+PyrObject* signal_positive(VMGlobals *g, PyrObject *inPyrSignal);
+PyrObject* signal_strictly_positive(VMGlobals *g, PyrObject *inPyrSignal);
+PyrObject* signal_nyqring(VMGlobals *g, PyrObject *inPyrSignal);
+PyrObject* signal_clip_f(VMGlobals *g, PyrObject *inPyrSignal, float lo, float hi);
+PyrObject* signal_clip_f_ds(PyrObject *inPyrSignal, float lo, float hi);
+PyrObject* signal_clip_x(VMGlobals *g, PyrObject *ina, PyrObject *inb, PyrObject *inc);
+PyrObject* signal_wrap_f(VMGlobals *g, PyrObject *inPyrSignal, float lo, float hi);
+PyrObject* signal_wrap_x(VMGlobals *g, PyrObject *ina, PyrObject *inb, PyrObject *inc);
+PyrObject* signal_fold_f(VMGlobals *g, PyrObject *inPyrSignal, float lo, float hi);
+PyrObject* signal_fold_x(VMGlobals *g, PyrObject *ina, PyrObject *inb, PyrObject *inc);
+PyrObject* signal_log(VMGlobals *g, PyrObject *inPyrSignal);
+PyrObject* signal_log2(VMGlobals *g, PyrObject *inPyrSignal);
+PyrObject* signal_log10(VMGlobals *g, PyrObject *inPyrSignal);
+PyrObject* signal_sin(VMGlobals *g, PyrObject *inPyrSignal);
+PyrObject* signal_cos(VMGlobals *g, PyrObject *inPyrSignal);
+PyrObject* signal_tan(VMGlobals *g, PyrObject *inPyrSignal);
+PyrObject* signal_sinh(VMGlobals *g, PyrObject *inPyrSignal);
+PyrObject* signal_cosh(VMGlobals *g, PyrObject *inPyrSignal);
+PyrObject* signal_tanh(VMGlobals *g, PyrObject *inPyrSignal);
+PyrObject* signal_asin(VMGlobals *g, PyrObject *inPyrSignal);
+PyrObject* signal_acos(VMGlobals *g, PyrObject *inPyrSignal);
+PyrObject* signal_atan(VMGlobals *g, PyrObject *inPyrSignal);
+PyrObject* signal_exp(VMGlobals *g, PyrObject *inPyrSignal);
+PyrObject* signal_sqrt(VMGlobals *g, PyrObject *inPyrSignal);
+PyrObject* signal_distort(VMGlobals *g, PyrObject *inPyrSignal);
+PyrObject* signal_distortneg(VMGlobals *g, PyrObject *inPyrSignal);
+PyrObject* signal_softclip(VMGlobals *g, PyrObject *inPyrSignal);
+PyrObject* signal_softclipneg(VMGlobals *g, PyrObject *inPyrSignal);
+PyrObject* signal_fsin(VMGlobals *g, PyrObject *inPyrSignal);
+PyrObject* signal_poly3(VMGlobals *g, PyrObject *inPyrSignal, float a, float b, float c);
+PyrObject* signal_poly3r(VMGlobals *g, PyrObject *inPyrSignal,
+ float a1, float a2, float b1, float b2, float c1, float c2, float slopeFactor);
+PyrObject* signal_integrate(VMGlobals *g, PyrObject *inPyrSignal, float *ioSum);
+PyrObject* signal_leakdc(VMGlobals *g, PyrObject *inPyrSignal, float *ioDC, float leakFactor);
+PyrObject* signal_ampflw1(VMGlobals *g, PyrObject *inPyrSignal, float *ioAmp, float leak1);
+PyrObject* signal_ampflw2(VMGlobals *g, PyrObject *inPyrSignal, float *ioAmp, float leak1);
+PyrObject* signal_differentiate(VMGlobals *g, PyrObject *inPyrSignal, float *ioPrev);
+PyrObject* signal_rotate(VMGlobals *g, PyrObject* ina, int rot);
+PyrObject* signal_reverse_ds(PyrObject* ina);
+PyrObject* signal_cat(VMGlobals *g, PyrObject* ina, PyrObject* inb);
+PyrObject* signal_insert(VMGlobals *g, PyrObject* ina, PyrObject* inb, long index);
+PyrObject* signal_overdub(VMGlobals *g, PyrObject* ina, PyrObject* inb, long index);
+PyrObject* signal_overwrite(VMGlobals *g, PyrObject* ina, PyrObject* inb, long index);
+PyrObject* signal_cat3(VMGlobals *g, PyrObject* ina, PyrObject* inb, PyrObject* inc);
+PyrObject* signal_linen(VMGlobals *g, PyrObject* ina, long atk, long dcy, float amp);
+PyrObject* signal_linen2(VMGlobals *g, PyrObject* ina, long atk, long dcy, float amp, float midamp);
+PyrObject* signal_writesplice(VMGlobals *g, PyrObject* outc, PyrObject* ina, PyrObject* inb,
+ long indexc, long indexa, long indexb, long fadelen, float midamp);
+PyrObject* signal_splice(VMGlobals *g, PyrObject* ina, PyrObject* inb,
+ long indexa, long indexb, long fadelen, float midamp);
+
+PyrObject* signal_invert_ds(PyrObject *inPyrSignal);
+PyrObject* signal_recip_ds(PyrObject *inPyrSignal);
+PyrObject* signal_squared_ds(PyrObject *inPyrSignal);
+PyrObject* signal_cubed_ds(PyrObject *inPyrSignal);
+PyrObject* signal_abs_ds(PyrObject *inPyrSignal);
+PyrObject* signal_sign_ds(PyrObject *inPyrSignal);
+PyrObject* signal_negative_ds(PyrObject *inPyrSignal);
+PyrObject* signal_positive_ds(PyrObject *inPyrSignal);
+PyrObject* signal_strictly_positive_ds(PyrObject *inPyrSignal);
+PyrObject* signal_nyqring_ds(PyrObject *inPyrSignal);
+
+PyrObject* signal_clipneg_ds(PyrObject *inPyrSignal);
+PyrObject* signal_distort_ds(PyrObject *inPyrSignal);
+PyrObject* signal_distortneg_ds(PyrObject *inPyrSignal);
+PyrObject* signal_softclip_ds(PyrObject *inPyrSignal);
+PyrObject* signal_softclipneg_ds(PyrObject *inPyrSignal);
+PyrObject* signal_fsin_ds(PyrObject *inPyrSignal);
+
+PyrObject* signal_log_ds(PyrObject *inPyrSignal);
+PyrObject* signal_log2_ds(PyrObject *inPyrSignal);
+PyrObject* signal_log10_ds(PyrObject *inPyrSignal);
+PyrObject* signal_sin_ds(PyrObject *inPyrSignal);
+PyrObject* signal_cos_ds(PyrObject *inPyrSignal);
+PyrObject* signal_tan_ds(PyrObject *inPyrSignal);
+PyrObject* signal_sinh_ds(PyrObject *inPyrSignal);
+PyrObject* signal_cosh_ds(PyrObject *inPyrSignal);
+PyrObject* signal_tanh_ds(PyrObject *inPyrSignal);
+PyrObject* signal_asin_ds(PyrObject *inPyrSignal);
+PyrObject* signal_acos_ds(PyrObject *inPyrSignal);
+PyrObject* signal_atan_ds(PyrObject *inPyrSignal);
+PyrObject* signal_exp_ds(PyrObject *inPyrSignal);
+PyrObject* signal_sqrt_ds(PyrObject *inPyrSignal);
+
+float signal_findpeak(PyrObject *inPyrSignal);
+PyrObject* signal_normalize(PyrObject *inPyrSignal);
+PyrObject* signal_normalize_transfer_fn(PyrObject *inPyrSignal);
+float signal_integral(PyrObject *inPyrSignal);
+PyrObject* signal_combself(VMGlobals *g, PyrObject* ina, long rot);
+PyrObject* signal_bilinen(VMGlobals *g, PyrObject* ina, long atk, long dcy, float amp, float midamp);
+PyrObject* signal_lace2(VMGlobals *g, PyrObject* ina, PyrObject* inb);
+void signal_unlace2(VMGlobals *g, PyrObject* ina, PyrObject** outb, PyrObject** outc);
+void signal_convolve(VMGlobals *g, PyrObject* ina, PyrObject* ir, PyrObject* previn, long *ppos);
+PyrObject* signal_thumbnail(VMGlobals *g, PyrObject* ina, long startpos, long length, int binsize);
+
+PyrObject* signal_scaleneg_xx(VMGlobals *g, PyrObject* ina, PyrObject* inb);
+PyrObject* signal_scaleneg_xf(VMGlobals *g, PyrObject* ina, float inb);
+PyrObject* signal_scaleneg_fx(VMGlobals *g, float ina, PyrObject* inb);
+
+PyrObject* signal_clip2_xx(VMGlobals *g, PyrObject* ina, PyrObject* inb);
+PyrObject* signal_clip2_xf(VMGlobals *g, PyrObject* ina, float inb);
+PyrObject* signal_clip2_fx(VMGlobals *g, float ina, PyrObject* inb);
+
+PyrObject* signal_fold2_xx(VMGlobals *g, PyrObject* ina, PyrObject* inb);
+PyrObject* signal_fold2_xf(VMGlobals *g, PyrObject* ina, float inb);
+PyrObject* signal_fold2_fx(VMGlobals *g, float ina, PyrObject* inb);
+
+PyrObject* signal_wrap2_xx(VMGlobals *g, PyrObject* ina, PyrObject* inb);
+PyrObject* signal_wrap2_xf(VMGlobals *g, PyrObject* ina, float inb);
+PyrObject* signal_wrap2_fx(VMGlobals *g, float ina, PyrObject* inb);
+
+PyrObject* signal_excess_xx(VMGlobals *g, PyrObject* ina, PyrObject* inb);
+PyrObject* signal_excess_xf(VMGlobals *g, PyrObject* ina, float inb);
+PyrObject* signal_excess_fx(VMGlobals *g, float ina, PyrObject* inb);
+
+PyrObject* signal_absdif_fx(VMGlobals *g, float ina, PyrObject* inb);
+PyrObject* signal_absdif_xf(VMGlobals *g, PyrObject* ina, float inb);
+PyrObject* signal_absdif_xx(VMGlobals *g, PyrObject* ina, PyrObject* inb);
+
+bool signal_equal_xf(VMGlobals *g, PyrObject* ina, float inb);
+bool signal_equal_xx(VMGlobals *g, PyrObject* ina, PyrObject* inb);
+
+void signal_get_bounds(PyrObject* ina, float *ominval, float *omaxval);
+
+void signal_smooth_ds(PyrObject* inPyrSignal);
+void signal_hanning_ds(PyrObject* inPyrSignal);
+void signal_welch_ds(PyrObject* inPyrSignal);
+void signal_parzen_ds(PyrObject* inPyrSignal);
+
+PyrObject* signal_normalize_range(PyrObject* ina, long start, long end);
+PyrObject* signal_zero_range(PyrObject* ina, long start, long end);
+PyrObject* signal_invert_range(PyrObject* ina, long start, long end);
+PyrObject* signal_reverse_range(PyrObject* ina, long start, long end);
+PyrObject* signal_fade_in(PyrObject* ina, long start, long end);
+PyrObject* signal_fade_out(PyrObject* ina, long start, long end);
+PyrObject* signal_abs_range(PyrObject* ina, long start, long end);
+PyrObject* signal_squared_range(PyrObject* ina, long start, long end);
+PyrObject* signal_cubed_range(PyrObject* ina, long start, long end);
+PyrObject* signal_distort_range(PyrObject* ina, long start, long end);
+
+PyrObject* signal_fade_range(PyrObject* ina, long start, long end, float lvl0, float lvl1);
diff --git a/sc4pd/headers/lang/PyrSignalPrim.h b/sc4pd/headers/lang/PyrSignalPrim.h
new file mode 100644
index 0000000..bea68ca
--- /dev/null
+++ b/sc4pd/headers/lang/PyrSignalPrim.h
@@ -0,0 +1,56 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+
+#ifndef _PYRSIGNALPRIM_H_
+#define _PYRSIGNALPRIM_H_
+
+extern PyrSymbol *s_wavetable;
+extern struct PyrClass *class_wavetable;
+
+void initSignalPrimitives();
+
+int prSignalCat(VMGlobals *g, int numArgsPushed);
+int prSignalFill(VMGlobals *g, int numArgsPushed);
+int prSignalRamp(VMGlobals *g, int numArgsPushed);
+int prSignalScale(VMGlobals *g, int numArgsPushed);
+int prSignalOffset(VMGlobals *g, int numArgsPushed);
+int prSignalString(VMGlobals *g, int numArgsPushed);
+
+int prSignalPeak(VMGlobals *g, int numArgsPushed);
+int prSignalNormalize(VMGlobals *g, int numArgsPushed);
+int prSignalNormalizeTransferFn(VMGlobals *g, int numArgsPushed);
+int prSignalIntegral(VMGlobals *g, int numArgsPushed);
+
+int prSignalOverDub(VMGlobals *g, int numArgsPushed);
+int prSignalOverWrite(VMGlobals *g, int numArgsPushed);
+int prSignalFade(VMGlobals *g, int numArgsPushed);
+int prSignalAddHarmonic(VMGlobals *g, int numArgsPushed);
+int prSignalAsWavetable(VMGlobals *g, int numArgsPushed);
+int prWavetableAsSignal(VMGlobals *g, int numArgsPushed);
+
+int prSignalInvert(VMGlobals *g, int numArgsPushed);
+int prSignalReverse(VMGlobals *g, int numArgsPushed);
+int prSignalRotate(VMGlobals *g, int numArgsPushed);
+
+void signalAsWavetable(float *signal, float *wavetable, int size);
+void wavetableAsSignal(float *wavetable, float *signal, int size);
+
+#endif
diff --git a/sc4pd/headers/lang/PyrSlot.h b/sc4pd/headers/lang/PyrSlot.h
new file mode 100644
index 0000000..78bcd12
--- /dev/null
+++ b/sc4pd/headers/lang/PyrSlot.h
@@ -0,0 +1,286 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+/*
+
+PyrSlot is a value holder for SC variables.
+A PyrSlot is an 8-byte value which is either a double precision float or a
+32-bit tag plus a 32-bit value.
+
+*/
+
+#ifndef _PYRSLOT_H_
+#define _PYRSLOT_H_
+
+#include "SC_Endian.h"
+#include "PyrSymbol.h"
+
+/*
+ Pyrite slots are the size of an 8 byte double. If the upper bits
+ indicate that the double is a 'Not-A-Number' then the upper 32
+ bits are used as a tag to indicate one of a number of other types
+ whose data is in the lower 32 bits.
+*/
+
+/* some DSPs like the TIC32 do not support 8 byte doubles */
+/* on such CPUs, set DOUBLESLOTS to zero */
+
+#define DOUBLESLOTS 1
+
+/* use the high order bits of an IEEE double NaN as a tag */
+enum {
+ tagObj = 0x7FF90001,
+ tagHFrame = 0x7FF90002,
+ tagSFrame = 0x7FF90003,
+ tagInt = 0x7FF90004,
+ tagSym = 0x7FF90005,
+ tagChar = 0x7FF90006,
+ tagNil = 0x7FF90007, // nil, false, and true are indicated by the tag alone.
+ tagFalse = 0x7FF90008, // the lower 32 bits are zero.
+ tagTrue = 0x7FF90009,
+ tagInf = 0x7FF9000A,
+ tagPtr = 0x7FF9000B,
+ /* anything else is a double */
+ tagUnused = 0x7FF9000E
+
+
+#if !DOUBLESLOTS
+ ,tagFloat = 0x7FF9000F /* used only to initialized 4 byte float tags, never compared with */
+#endif
+};
+
+struct RGBColor8 {
+ unsigned char c[4];
+};
+
+typedef union pyrslot {
+ double f;
+ struct {
+#if BYTE_ORDER == BIG_ENDIAN
+ int tag;
+#endif // BIG_ENDIAN
+ union {
+ int c; /* char */
+ int i;
+ float f;
+ void *ptr;
+ struct RGBColor8 r;
+ struct PyrObject *o;
+ PyrSymbol *s;
+ struct PyrMethod *om;
+ struct PyrBlock *oblk;
+ struct PyrClass *oc;
+ struct PyrFrame *of;
+ struct PyrList *ol;
+ struct PyrString *os;
+ struct PyrInt8Array *ob;
+ struct PyrDoubleArray *od;
+ struct PyrSymbolArray *osym;
+ struct PyrParseNode *opn;
+ struct PyrProcess *op;
+ struct PyrThread *ot;
+ struct PyrInterpreter *oi;
+ struct PyrPlug *plug;
+ } u;
+#if BYTE_ORDER == LITTLE_ENDIAN
+ // need to swap on intel <sk>
+ int tag;
+#endif // LITTLE_ENDIAN
+ } s;
+} PyrSlot;
+
+/*
+ these are some defines to make accessing the structure less verbose.
+ obviously it polutes the namespace of identifiers beginning with 'u'.
+*/
+#define utag s.tag
+//int
+#define ui s.u.i
+//PyrObject
+#define uo s.u.o
+//PyrSymbol
+#define us s.u.s
+//RGBColor8
+#define ur s.u.r
+#define uc s.u.c
+#define uoc s.u.oc
+#define uof s.u.of
+#define uol s.u.ol
+#define uod s.u.od
+#define uob s.u.ob
+#define uop s.u.op
+#define uoi s.u.oi
+#define uod s.u.od
+//string
+#define uos s.u.os
+#define uot s.u.ot
+//method
+#define uom s.u.om
+//symbol array
+#define uosym s.u.osym
+#define uoblk s.u.oblk
+#define uopn s.u.opn
+#define uptr s.u.ptr
+#define uplug s.u.plug
+
+#if DOUBLESLOTS
+#define uf f
+#else
+#define uf s.u.f
+#endif
+
+#define ucopy f
+
+/*
+ Note that on the PowerPC, the fastest way to copy a slot is to
+ copy the double field, not the struct.
+*/
+
+/* some macros for setting values of slots */
+inline void SetInt(PyrSlot* slot, int val) { (slot)->utag = tagInt; (slot)->ui = (val); }
+inline void SetObject(PyrSlot* slot, void* val) { (slot)->utag = tagObj; (slot)->uo = (PyrObject*)(val); }
+inline void SetSymbol(PyrSlot* slot, PyrSymbol *val) { (slot)->utag = tagSym; (slot)->us = (val); }
+inline void SetChar(PyrSlot* slot, char val) { (slot)->utag = tagChar; (slot)->uc = (val); }
+inline void SetPtr(PyrSlot* slot, void* val) { (slot)->utag = tagPtr; (slot)->uptr = (void*)(val); }
+inline void SetObjectOrNil(PyrSlot* slot, PyrObject* val)
+{
+ if (val) {
+ (slot)->utag = tagObj;
+ (slot)->uo = (val);
+ } else {
+ (slot)->utag = tagNil;
+ (slot)->ui = 0;
+ }
+}
+
+inline void SetTrue(PyrSlot* slot) { (slot)->utag = tagTrue; (slot)->ui = 0; }
+inline void SetFalse(PyrSlot* slot) { (slot)->utag = tagFalse; (slot)->ui = 0; }
+inline void SetBool(PyrSlot* slot, bool test) { (slot)->utag = ((test) ? tagTrue : tagFalse); (slot)->ui = 0; }
+inline void SetNil(PyrSlot* slot) { (slot)->utag = tagNil; (slot)->ui = 0; }
+inline void SetInf(PyrSlot* slot) { (slot)->utag = tagInf; (slot)->ui = 0; }
+
+#if DOUBLESLOTS
+inline void SetFloat(PyrSlot* slot, double val) { (slot)->uf = (val); }
+#else
+inline void SetFloat(PyrSlot* slot, double val) { (slot)->utag = s_float; (slot)->uf = (val); }
+#endif
+
+inline bool IsObj(PyrSlot* slot) { return ((slot)->utag == tagObj); }
+inline bool NotObj(PyrSlot* slot) { return ((slot)->utag != tagObj); }
+
+inline bool IsNil(PyrSlot* slot) { return ((slot)->utag == tagNil); }
+inline bool NotNil(PyrSlot* slot) { return ((slot)->utag != tagNil); }
+
+inline bool IsFalse(PyrSlot* slot) { return ((slot)->utag == tagFalse); }
+inline bool IsTrue(PyrSlot* slot) { return ((slot)->utag == tagTrue); }
+
+inline bool SlotEq(PyrSlot* a, PyrSlot* b) { return ((a)->ui == (b)->ui && (a)->utag == (b)->utag); }
+
+inline bool IsSym(PyrSlot* slot) { return ((slot)->utag == tagSym); }
+inline bool NotSym(PyrSlot* slot) { return ((slot)->utag != tagSym); }
+
+inline bool IsInt(PyrSlot* slot) { return ((slot)->utag == tagInt); }
+inline bool NotInt(PyrSlot* slot) { return ((slot)->utag != tagInt); }
+
+inline bool IsFloatTag(int tag) { return ((tag & 0xFFFFFFF0) != 0x7FF90000); }
+inline bool IsFloat(PyrSlot* slot) { return (((slot)->utag & 0xFFFFFFF0) != 0x7FF90000); }
+inline bool NotFloat(PyrSlot* slot) { return (((slot)->utag & 0xFFFFFFF0) == 0x7FF90000); }
+
+inline bool IsInf(PyrSlot* slot) { return ((slot)->utag == tagInf); }
+inline bool IsPtr(PyrSlot* slot) { return ((slot)->utag == tagPtr); }
+
+inline bool IsFrame(PyrSlot* slot) { return ((slot)->utag == tagHFrame || (slot)->utag == tagSFrame); }
+
+
+void dumpPyrSlot(PyrSlot* slot);
+void slotString(PyrSlot *slot, char *str);
+void slotOneWord(PyrSlot *slot, char *str);
+bool postString(PyrSlot *slot, char *str);
+char *slotSymString(PyrSlot* slot);
+int asCompileString(PyrSlot *slot, char *str);
+
+int slotIntVal(PyrSlot* slot, int *value);
+int slotFloatVal(PyrSlot* slot, float *value);
+int slotDoubleVal(PyrSlot *slot, double *value);
+int slotStrVal(PyrSlot *slot, char *str, int maxlen);
+int slotPStrVal(PyrSlot *slot, unsigned char *str);
+int slotSymbolVal(PyrSlot *slot, PyrSymbol **symbol);
+
+extern PyrSlot o_nil, o_true, o_false, o_inf;
+extern PyrSlot o_pi, o_twopi;
+extern PyrSlot o_fhalf, o_fnegone, o_fzero, o_fone, o_ftwo;
+extern PyrSlot o_negtwo, o_negone, o_zero, o_one, o_two;
+extern PyrSlot o_emptyarray, o_onenilarray, o_argnamethis;
+
+extern PyrSymbol *s_object; // "Object"
+extern PyrSymbol *s_this; // "this"
+extern PyrSymbol *s_super; // "super"
+
+inline int slotFloatVal(PyrSlot *slot, float *value)
+{
+ if (IsFloat(slot)) {
+ *value = slot->uf;
+ return errNone;
+ } else if (IsInt(slot)) {
+ *value = slot->ui;
+ return errNone;
+ }
+ return errWrongType;
+}
+
+inline int slotIntVal(PyrSlot *slot, int *value)
+{
+ if (IsInt(slot)) {
+ *value = slot->ui;
+ return errNone;
+ } else if (IsFloat(slot)) {
+ *value = (int)slot->uf;
+ return errNone;
+ }
+ return errWrongType;
+}
+
+inline int slotDoubleVal(PyrSlot *slot, double *value)
+{
+ if (IsFloat(slot)) {
+ *value = slot->uf;
+ return errNone;
+ } else if (IsInt(slot)) {
+ *value = slot->ui;
+ return errNone;
+ }
+ return errWrongType;
+}
+
+inline int slotSymbolVal(PyrSlot *slot, PyrSymbol **symbol)
+{
+ if (!IsSym(slot)) return errWrongType;
+ *symbol = slot->us;
+ return errNone;
+}
+
+inline void slotCopy(PyrSlot *dst, PyrSlot *src, int num)
+{
+ double *dstp = (double*)dst - 1;
+ double *srcp = (double*)src - 1;
+ for (int i=0;i<num;++i) { *++dstp = *++srcp; }
+}
+
+
+#endif
diff --git a/sc4pd/headers/lang/PyrSymbol.h b/sc4pd/headers/lang/PyrSymbol.h
new file mode 100644
index 0000000..621f7c2
--- /dev/null
+++ b/sc4pd/headers/lang/PyrSymbol.h
@@ -0,0 +1,59 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+/*
+
+A PyrSymbol is a unique string that resides in a global hash table.
+
+*/
+
+#ifndef _PYRSYMBOL_H_
+#define _PYRSYMBOL_H_
+
+#include "SCBase.h"
+
+struct PyrSymbol {
+ char *name;
+ long hash;
+ short specialIndex;
+ uint8 flags;
+ uint8 length;
+ union {
+ long index; // index in row table or primitive table
+ struct PyrClass *classobj; // pointer to class with this name.
+ } u;
+ struct classdep *classdep;
+};
+
+enum {
+ sym_Selector = 1,
+ sym_Class = 2,
+ sym_Compiled = 4,
+ sym_Called = 8,
+ sym_Primitive = 16,
+ sym_Setter = 32,
+ sym_MetaClass = 64,
+ sym_Filename = 128
+};
+
+PyrSymbol* getsym(const char *name);
+PyrSymbol* getmetasym(const char *name);
+PyrSymbol* findsym(const char *name);
+
+#endif \ No newline at end of file
diff --git a/sc4pd/headers/lang/PyrSymbolTable.h b/sc4pd/headers/lang/PyrSymbolTable.h
new file mode 100644
index 0000000..7cc03cb
--- /dev/null
+++ b/sc4pd/headers/lang/PyrSymbolTable.h
@@ -0,0 +1,78 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#ifndef _SymbolTable_
+#define _SymbolTable_
+
+#include "PyrSymbol.h"
+#include "AdvancingAllocPool.h"
+
+#define STRINGCHUNK 32000
+#define SYMBOLCHUNK 32000
+
+class SymbolSpace
+{
+public:
+ SymbolSpace(AllocPool *inPool);
+ PyrSymbol* NewSymbol(const char *inName, int inHash, int inLength);
+
+private:
+ AllocPool *mPool;
+ AdvancingAllocPool mStringPool;
+ AdvancingAllocPool mSymbolPool;
+};
+
+class SymbolTable
+{
+public:
+
+ SymbolTable(AllocPool *inPool, int inSize);
+
+ void CopyFrom(SymbolTable& inTable);
+
+ int NumItems() { return mNumItems; }
+ int TableSize() { return mMaxItems; }
+ PyrSymbol* Get(int inIndex) { return mTable[inIndex]; }
+
+ void CheckSymbols();
+
+private:
+ friend PyrSymbol* getsym(const char *name);
+ friend PyrSymbol* findsym(const char *name);
+
+ PyrSymbol* Find(const char *inName);
+ PyrSymbol* Make(const char *inName);
+ PyrSymbol* MakeNew(const char *inName, int inHash, int inLength);
+
+ int StrHash(const char *inName, int *outLength);
+ void AllocTable();
+ void Grow();
+ PyrSymbol* Find(const char *inName, int inHash);
+ void Add(PyrSymbol* inSymbol);
+ void Rehash(PyrSymbol** inTable, int inSize);
+ void MakeEmpty();
+
+ AllocPool *mPool;
+ SymbolSpace mSpace;
+ PyrSymbol **mTable;
+ int mNumItems, mMaxItems, mMask;
+};
+
+#endif
diff --git a/sc4pd/headers/lang/ReadWriteMacros.h b/sc4pd/headers/lang/ReadWriteMacros.h
new file mode 100644
index 0000000..2117fb6
--- /dev/null
+++ b/sc4pd/headers/lang/ReadWriteMacros.h
@@ -0,0 +1,336 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+
+#ifndef _ReadWriteMacros_
+#define _ReadWriteMacros_
+
+#include "SC_Types.h"
+#include "SC_Endian.h"
+#include <stdio.h>
+#include <string.h>
+
+template <class T>
+class SC_IOStream
+{
+protected:
+ T s;
+public:
+ SC_IOStream() : s(0) {}
+ SC_IOStream(T inStream) : s(inStream) {}
+
+ void SetStream(T inStream) { s = inStream; }
+ T GetStream() { return s; }
+
+ // core routines
+ void readData(char *data, int size);
+ uint8 readUInt8();
+
+ void writeData(char *data, int size);
+ void writeUInt8(uint8 inInt);
+
+ // built using core routines
+ void writeInt8(int8 inInt)
+ {
+ writeUInt8((uint8)inInt);
+ }
+
+ void writeInt16_be(int16 inInt)
+ {
+ writeUInt8((uint8)(inInt >> 8));
+ writeUInt8(inInt);
+ }
+
+ void writeInt16_le(int16 inInt)
+ {
+ writeUInt8((uint8)inInt);
+ writeUInt8((uint8)(inInt >> 8));
+ }
+
+ void writeInt32_be(int32 inInt)
+ {
+ writeUInt8((uint8)(inInt >> 24));
+ writeUInt8((uint8)(inInt >> 16));
+ writeUInt8((uint8)(inInt >> 8));
+ writeUInt8((uint8)inInt);
+ }
+
+ void writeInt32_le(int32 inInt)
+ {
+ writeUInt8((uint8)inInt);
+ writeUInt8((uint8)(inInt >> 8));
+ writeUInt8((uint8)(inInt >> 16));
+ writeUInt8((uint8)(inInt >> 24));
+ }
+
+#if BYTE_ORDER == BIG_ENDIAN
+ void writeFloat_be(float inFloat)
+#else
+ void writeFloat_le(float inFloat)
+#endif
+ {
+ union {
+ float f;
+ uint8 c[4];
+ } u;
+ u.f = inFloat;
+ writeUInt8(u.c[0]);
+ writeUInt8(u.c[1]);
+ writeUInt8(u.c[2]);
+ writeUInt8(u.c[3]);
+ }
+
+#if BYTE_ORDER == BIG_ENDIAN
+ void writeFloat_le(float inFloat)
+#else
+ void writeFloat_be(float inFloat)
+#endif
+ {
+ union {
+ float f;
+ uint8 c[4];
+ } u;
+ u.f = inFloat;
+ writeUInt8(u.c[3]);
+ writeUInt8(u.c[2]);
+ writeUInt8(u.c[1]);
+ writeUInt8(u.c[0]);
+ }
+
+
+#if BYTE_ORDER == BIG_ENDIAN
+ void writeDouble_be(double inDouble)
+#else
+ void writeDouble_le(double inDouble)
+#endif
+ {
+ union {
+ double f;
+ uint8 c[8];
+ } u;
+ u.f = inDouble;
+ writeUInt8(u.c[0]);
+ writeUInt8(u.c[1]);
+ writeUInt8(u.c[2]);
+ writeUInt8(u.c[3]);
+ writeUInt8(u.c[4]);
+ writeUInt8(u.c[5]);
+ writeUInt8(u.c[6]);
+ writeUInt8(u.c[7]);
+ }
+
+#if BYTE_ORDER == BIG_ENDIAN
+ void writeDouble_le(double inDouble)
+#else
+ void writeDouble_be(double inDouble)
+#endif
+ {
+ union {
+ double f;
+ uint8 c[8];
+ } u;
+ u.f = inDouble;
+ writeUInt8(u.c[7]);
+ writeUInt8(u.c[6]);
+ writeUInt8(u.c[5]);
+ writeUInt8(u.c[4]);
+ writeUInt8(u.c[3]);
+ writeUInt8(u.c[2]);
+ writeUInt8(u.c[1]);
+ writeUInt8(u.c[0]);
+ }
+
+
+ int8 readInt8()
+ {
+ return (int8)readUInt8();
+ }
+
+ int16 readInt16_be()
+ {
+ uint8 a = readUInt8();
+ uint8 b = readUInt8();
+ return (int16)((a << 8) | b);
+ }
+
+ int16 readInt16_le()
+ {
+ uint8 a = readUInt8();
+ uint8 b = readUInt8();
+ return (int16)((b << 8) | a);
+ }
+
+ int32 readInt32_be()
+ {
+ uint8 a = readUInt8();
+ uint8 b = readUInt8();
+ uint8 c = readUInt8();
+ uint8 d = readUInt8();
+ return (int32)((a << 24) | (b << 16) | (c << 8) | d);
+ }
+
+ int32 readInt32_le()
+ {
+ uint8 a = readUInt8();
+ uint8 b = readUInt8();
+ uint8 c = readUInt8();
+ uint8 d = readUInt8();
+ return (int32)((d << 24) | (c << 16) | (b << 8) | a);
+ }
+
+#if BYTE_ORDER == BIG_ENDIAN
+ float readFloat_be()
+#else
+ float readFloat_le()
+#endif
+ {
+ union {
+ float f;
+ uint8 c[4];
+ } u;
+ u.c[0] = readUInt8();
+ u.c[1] = readUInt8();
+ u.c[2] = readUInt8();
+ u.c[3] = readUInt8();
+ return u.f;
+ }
+
+#if BYTE_ORDER == BIG_ENDIAN
+ float readFloat_le()
+#else
+ float readFloat_be()
+#endif
+ {
+ union {
+ float f;
+ uint8 c[4];
+ } u;
+ u.c[3] = readUInt8();
+ u.c[2] = readUInt8();
+ u.c[1] = readUInt8();
+ u.c[0] = readUInt8();
+ return u.f;
+ }
+
+
+#if BYTE_ORDER == BIG_ENDIAN
+ double readDouble_be()
+#else
+ double readDouble_le()
+#endif
+ {
+ union {
+ double f;
+ uint8 c[8];
+ } u;
+ u.c[0] = readUInt8();
+ u.c[1] = readUInt8();
+ u.c[2] = readUInt8();
+ u.c[3] = readUInt8();
+ u.c[4] = readUInt8();
+ u.c[5] = readUInt8();
+ u.c[6] = readUInt8();
+ u.c[7] = readUInt8();
+ return u.f;
+ }
+
+#if BYTE_ORDER == BIG_ENDIAN
+ double readDouble_le()
+#else
+ double readDouble_be()
+#endif
+ {
+ union {
+ double f;
+ uint8 c[8];
+ } u;
+ u.c[7] = readUInt8();
+ u.c[6] = readUInt8();
+ u.c[5] = readUInt8();
+ u.c[4] = readUInt8();
+ u.c[3] = readUInt8();
+ u.c[2] = readUInt8();
+ u.c[1] = readUInt8();
+ u.c[0] = readUInt8();
+ return u.f;
+ }
+
+ void readSymbol(char *outString)
+ {
+ int length = readUInt8();
+ readData(outString, length);
+ outString[length] = 0;
+ }
+
+ void writeSymbol(char *inString)
+ {
+ int32 length = strlen(inString);
+ writeUInt8((uint8)length);
+ writeData(inString, length);
+ }
+};
+
+
+// core routines
+inline void SC_IOStream<FILE*>::readData(char *data, int size)
+{
+ fread(data, 1, size, s);
+}
+
+inline uint8 SC_IOStream<FILE*>::readUInt8()
+{
+ return (uint8)fgetc(s);
+}
+
+inline void SC_IOStream<FILE*>::writeData(char *data, int size)
+{
+ fwrite(data, 1, size, s);
+}
+
+inline void SC_IOStream<FILE*>::writeUInt8(uint8 inInt)
+{
+ fputc(inInt, s);
+}
+
+// core routines
+inline void SC_IOStream<char*>::readData(char *data, int size)
+{
+ memcpy(data, s, size);
+ s += size;
+}
+inline uint8 SC_IOStream<char*>::readUInt8()
+{
+ return (uint8)*s++;
+}
+
+inline void SC_IOStream<char*>::writeData(char *data, int size)
+{
+ memcpy(s, data, size);
+ s += size;
+}
+
+inline void SC_IOStream<char*>::writeUInt8(uint8 inInt)
+{
+ *s++ = (inInt & 255);
+}
+
+
+#endif
+
diff --git a/sc4pd/headers/lang/SCBase.h b/sc4pd/headers/lang/SCBase.h
new file mode 100644
index 0000000..10fe0ed
--- /dev/null
+++ b/sc4pd/headers/lang/SCBase.h
@@ -0,0 +1,68 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+/*
+
+Contains the most common definitions.
+
+*/
+
+#ifndef _SCBASE_
+#define _SCBASE_
+
+#include <limits.h>
+#include <stdio.h>
+
+#include "SC_BoundsMacros.h"
+#include "SC_Types.h"
+#include "PyrErrors.h"
+#include "AllocPools.h"
+
+void postfl(const char *fmt, ...);
+void post(const char *fmt, ...);
+void error(const char *fmt, ...);
+void postText(const char *text, long length);
+void postChar(char c);
+void flushPostBuf();
+void setPostFile(FILE *file); // If file is not NULL, causes all posted text to also be written to the file.
+
+void debugf(char *fmt, ...);
+void pprintf(unsigned char *str, char *fmt, ...);
+
+#pragma export on
+
+extern "C" {
+void schedInit();
+void init_OSC(int port);
+bool pyr_init_mem_pools(int runtime_space, int runtime_grow);
+
+void schedRun();
+void schedStop();
+bool compileLibrary();
+void runLibrary(struct PyrSymbol* selector);
+struct VMGlobals* scGlobals();
+void runInterpreter(struct VMGlobals *g, struct PyrSymbol *selector, int numArgsPushed);
+
+struct PyrSymbol* getsym(const char *inName);
+struct PyrSymbol* findsym(const char *name);
+}
+
+#pragma export off
+
+#endif
diff --git a/sc4pd/headers/lang/SC_ComPort.h b/sc4pd/headers/lang/SC_ComPort.h
new file mode 100644
index 0000000..bdbeabc
--- /dev/null
+++ b/sc4pd/headers/lang/SC_ComPort.h
@@ -0,0 +1,118 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#ifndef _SC_ComPort_
+#define _SC_ComPort_
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include "SC_Msg.h"
+#include "SC_Sem.h"
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+class SC_CmdPort
+{
+protected:
+ pthread_t mThread;
+
+ void Start();
+ virtual ReplyFunc GetReplyFunc()=0;
+public:
+ SC_CmdPort();
+
+ virtual void* Run()=0;
+};
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+class SC_ComPort : public SC_CmdPort
+{
+protected:
+ int mPortNum;
+ int mSocket;
+ struct sockaddr_in mBindSockAddr;
+
+public:
+ SC_ComPort(int inPortNum);
+ virtual ~SC_ComPort();
+
+ int Socket() { return mSocket; }
+
+ int PortNum() const { return mPortNum; }
+};
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+class SC_UdpInPort : public SC_ComPort
+{
+protected:
+ struct sockaddr_in mReplySockAddr;
+ virtual ReplyFunc GetReplyFunc();
+
+public:
+ SC_UdpInPort(int inPortNum);
+ ~SC_UdpInPort();
+
+ int PortNum() const { return mPortNum; }
+
+ void* Run();
+};
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+class SC_TcpInPort : public SC_ComPort
+{
+ SC_Semaphore mConnectionAvailable;
+ int mBacklog;
+
+protected:
+ virtual ReplyFunc GetReplyFunc();
+
+public:
+ SC_TcpInPort(int inPortNum, int inMaxConnections, int inBacklog);
+
+ virtual void* Run();
+
+ void ConnectionTerminated();
+};
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+class SC_TcpConnectionPort : public SC_ComPort
+{
+ SC_TcpInPort *mParent;
+
+protected:
+ virtual ReplyFunc GetReplyFunc();
+
+public:
+ SC_TcpConnectionPort(SC_TcpInPort *inParent, int inSocket);
+ virtual ~SC_TcpConnectionPort();
+
+ virtual void* Run();
+};
+
+const int kTextBufSize = 8192;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+#endif
+
diff --git a/sc4pd/headers/lang/SC_LanguageClient.h b/sc4pd/headers/lang/SC_LanguageClient.h
new file mode 100644
index 0000000..b7a499c
--- /dev/null
+++ b/sc4pd/headers/lang/SC_LanguageClient.h
@@ -0,0 +1,164 @@
+// emacs: -*- c++ -*-
+// file: SC_LanguageClient.h
+// copyright: 2003 stefan kersten <steve@k-hornz.de>
+// cvs: $Id: SC_LanguageClient.h,v 1.1.1.1 2004-07-14 16:21:17 timblech Exp $
+
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA
+
+#ifndef SC_LANGUAGECLIENT_H_INCLUDED
+#define SC_LANGUAGECLIENT_H_INCLUDED
+
+#include "SC_StringBuffer.h"
+#include <pthread.h>
+#include <stdarg.h>
+#include <stdio.h>
+
+// =====================================================================
+// SC_LanguageClient - abstract sclang client.
+// =====================================================================
+
+struct PyrSymbol;
+struct VMGlobals;
+
+extern long compiledOK;
+extern pthread_mutex_t gLangMutex;
+extern VMGlobals* gMainVMGlobals;
+
+class SC_LanguageClient
+{
+public:
+ struct Options
+ {
+ Options()
+ : mMemSpace(2*1024*1024),
+ mMemGrow(256*1024),
+ mPort(57120),
+ mRuntimeDir(0)
+ { }
+
+ int mMemSpace; // memory space in bytes
+ int mMemGrow; // memory growth in bytes
+ int mPort; // network port number
+ char* mRuntimeDir; // runtime directory
+ };
+
+public:
+ // create singleton instance
+ SC_LanguageClient(const char* name);
+ virtual ~SC_LanguageClient();
+
+ // return the singleton instance
+ static SC_LanguageClient* instance() { return gInstance; }
+
+ // initialize language runtime
+ void initRuntime(const Options& opt=Options());
+
+ // return application name
+ const char* getName() const { return mName; }
+
+ // library startup/shutdown
+ bool readLibraryConfig(const char* filePath, const char* fileName=0);
+ bool readDefaultLibraryConfig();
+ bool isLibraryCompiled() { return compiledOK; }
+ void compileLibrary();
+ void shutdownLibrary();
+ void recompileLibrary();
+
+ // interpreter access
+ void lock() { pthread_mutex_lock(&gLangMutex); }
+ bool trylock() { return pthread_mutex_trylock(&gLangMutex) == 0; }
+ void unlock() { pthread_mutex_unlock(&gLangMutex); }
+
+ VMGlobals* getVMGlobals() { return gMainVMGlobals; }
+
+ void setCmdLine(const char* buf, size_t size);
+ void setCmdLine(const char* str);
+ void setCmdLine(const SC_StringBuffer& strBuf);
+ void setCmdLinef(const char* fmt, ...);
+ void runLibrary(PyrSymbol* pyrSymbol);
+ void runLibrary(const char* methodName);
+ void interpretCmdLine() { runLibrary(s_interpretCmdLine); }
+ void interpretPrintCmdLine() { runLibrary(s_interpretPrintCmdLine); }
+ void executeFile(const char* fileName);
+ void runMain() { runLibrary(s_run); }
+ void stopMain() { runLibrary(s_stop); }
+
+ // post file access
+ FILE* getPostFile() { return mPostFile; }
+ void setPostFile(FILE* file) { mPostFile = file; }
+
+ // post buffer output (subclass responsibility)
+ // these routines should be thread-save.
+ virtual void post(const char *fmt, va_list ap, bool error) = 0;
+ virtual void post(char c) = 0;
+ virtual void post(const char* str, size_t len) = 0;
+ virtual void flush() = 0;
+
+ // common symbols
+ // only valid after the library has been compiled.
+ static PyrSymbol* s_interpretCmdLine;
+ static PyrSymbol* s_interpretPrintCmdLine;
+ static PyrSymbol* s_run;
+ static PyrSymbol* s_stop;
+
+ // command line argument handling utilities
+ static void snprintMemArg(char* dst, size_t size, int arg);
+ static bool parseMemArg(const char* arg, int* res);
+ static bool parsePortArg(const char* arg, int* res);
+
+protected:
+ // AppClock driver
+ // to be called from client mainloop.
+ void tick();
+
+ // language notifications, subclasses can override
+
+ // called after language runtime has been initialized
+ virtual void onInitRuntime();
+ // called after the library has been compiled
+ virtual void onLibraryStartup();
+ // called before the library is shut down
+ virtual void onLibraryShutdown();
+ // called after the interpreter has been started
+ virtual void onInterpStartup();
+
+private:
+ friend void closeAllGUIScreens();
+ friend void initGUIPrimitives();
+ friend void initGUI();
+
+private:
+ char* mName;
+ FILE* mPostFile;
+ SC_StringBuffer mScratch;
+ bool mRunning;
+ static SC_LanguageClient* gInstance;
+};
+
+// =====================================================================
+// library functions
+// =====================================================================
+
+extern void setPostFile(FILE* file);
+extern "C" int vpost(const char *fmt, va_list vargs);
+extern void post(const char *fmt, ...);
+extern void postfl(const char *fmt, ...);
+extern void postText(const char *text, long length);
+extern void postChar(char c);
+extern void error(const char *fmt, ...);
+extern void flushPostBuf();
+
+#endif // SC_LANGUAGECLIENT_H_INCLUDED
diff --git a/sc4pd/headers/lang/SC_LibraryConfig.h b/sc4pd/headers/lang/SC_LibraryConfig.h
new file mode 100644
index 0000000..5f7df3b
--- /dev/null
+++ b/sc4pd/headers/lang/SC_LibraryConfig.h
@@ -0,0 +1,108 @@
+// emacs: -*- c++ -*-
+// file: SC_LibraryConfig.h
+// cvs: $Id: SC_LibraryConfig.h,v 1.1.1.1 2004-07-14 16:21:24 timblech Exp $
+
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA
+
+#ifndef SC_LIBRARYCONFIG_H_INCLUDED
+#define SC_LIBRARYCONFIG_H_INCLUDED
+
+#include <stdarg.h>
+#include <stdio.h>
+
+// =====================================================================
+// SC_LibraryConfigFile
+// simple library configuration file parser
+// =====================================================================
+
+class SC_LibraryConfig;
+
+class SC_LibraryConfigFile
+{
+public:
+ typedef void (*ErrorFunc)(const char* fmt, ...);
+
+public:
+ SC_LibraryConfigFile(ErrorFunc errorFunc=0);
+
+ bool open(const char* filePath);
+ bool read(const char* fileName, SC_LibraryConfig* libConf);
+ void close();
+
+protected:
+ enum State
+ {
+ kBegin,
+ kAction,
+ kPath,
+ kEscape,
+ kEnvVar,
+ kEnvVarName,
+ kEnd
+ };
+
+ enum
+ {
+ kMaxIncludeDepth = 10
+ };
+
+ bool read(int depth, const char* fileName, SC_LibraryConfig* libConf);
+ bool parseLine(int depth, const char* fileName, int lineNumber, const char* line, SC_LibraryConfig* libConf);
+ static void defaultErrorFunc(const char* fmt, ...);
+
+private:
+ ErrorFunc mErrorFunc;
+ FILE* mFile;
+};
+
+// =====================================================================
+// SC_LibraryConfig
+// library configuration management
+// Copyright 2003 Maurizio Umberto Puxeddu
+// =====================================================================
+
+class SC_LibraryConfig
+{
+public:
+ SC_LibraryConfig(void);
+ virtual ~SC_LibraryConfig();
+
+ char **includedDirectories(void);
+ char **excludedDirectories(void);
+
+ void postExcludedDirectories(void);
+ bool forEachIncludedDirectory(bool (*func)(char *, int));
+
+ bool pathIsExcluded(const char *path);
+
+ void addIncludedDirectory(char *name);
+ void addExcludedDirectory(char *name);
+
+ // convenience functions to access the global library config
+ static bool readLibraryConfig(SC_LibraryConfigFile& file, const char* fileName);
+ static void freeLibraryConfig();
+
+private:
+ int m_nIncludedDirectories;
+ char **m_includedDirectories;
+ int m_nExcludedDirectories;
+ char **m_excludedDirectories;
+};
+
+extern SC_LibraryConfig* gLibraryConfig;
+extern char *unixStandardizePath(const char *path, char *newpath);
+
+#endif // SC_LIBRARYCONFIG_H_INCLUDED
diff --git a/sc4pd/headers/lang/SC_List.h b/sc4pd/headers/lang/SC_List.h
new file mode 100644
index 0000000..1713521
--- /dev/null
+++ b/sc4pd/headers/lang/SC_List.h
@@ -0,0 +1,229 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+/*
+
+A doubly linked list template.
+
+*/
+
+#ifndef _SC_List_
+#define _SC_List_
+
+#include <stdexcept>
+#ifndef NDEBUG
+# define NDEBUG
+#endif
+#include <assert.h>
+
+
+// A Link can be a node in a list or a list itself.
+
+template <class T>
+class Link
+{
+public:
+ Link() : mNext(this), mPrev(this) {}
+
+ T* Prev() { return static_cast<T*>(mPrev); }
+ T* Next() { return static_cast<T*>(mNext); }
+
+ void RemoveLeaveDangling()
+ {
+ mPrev->mNext = mNext;
+ mNext->mPrev = mPrev;
+ }
+
+ void Remove()
+ {
+ RemoveLeaveDangling();
+ mNext = mPrev = this;
+ }
+
+ void InsertAfter(T *inLink)
+ {
+ mPrev = inLink;
+ mNext = inLink->mNext;
+ mNext->mPrev = this;
+ mPrev->mNext = this;
+ }
+
+ void InsertBefore(T *inLink)
+ {
+ mNext = inLink;
+ mPrev = inLink->mPrev;
+ mNext->mPrev = this;
+ mPrev->mNext = this;
+ }
+
+ T* Head() { return static_cast<T*>(mNext); }
+ T* Tail() { return static_cast<T*>(mPrev); }
+
+ T* PopHead();
+ T* PopTail();
+ void PushHead(T* inBuf);
+ void PushTail(T* inBuf);
+
+ bool ContainsBuf(T* inBuf);
+ bool IsEmpty() { return mNext == this; }
+ void BeEmpty() { mNext = mPrev = this; }
+
+ void Cat(T* inLink);
+
+ bool SanityCheck();
+ void DebugDump();
+
+//private:
+// Codewarrior refuses to inline Next() in some places..
+ Link<T> *mNext, *mPrev;
+};
+
+template <class T, class Alloc>
+void MakeListEmpty(Link<T> *inLink, Alloc* inAlloc)
+{
+ Link<T>* link = inLink->mNext;
+ while (link != inLink) {
+ Link<T>* nextlink = link->mNext;
+ // SC uses placement new extensively, so here we do a 'placement delete'.
+ // Using DestructSelf allows me to have either virtual
+ // or non virtual destructors in subclasses at the discretion of the subclass.
+ ((T*)(link))->DestructSelf();
+ inAlloc->Free(static_cast<T*>(link));
+ link = nextlink;
+ }
+ inLink->mNext = inLink->mPrev = inLink;
+}
+
+template <class T>
+void Link<T>::PushHead(T* inLink)
+{
+ assert(SanityCheck());
+
+ Link<T>* link = static_cast<Link<T>*>(inLink);
+ link->InsertAfter(static_cast<T*>(this));
+
+ assert(SanityCheck());
+}
+
+template <class T>
+T* Link<T>::PopHead()
+{
+ assert(SanityCheck());
+ if (IsEmpty()) return 0;
+
+ Link<T>* link = mNext;
+
+ link->Remove();
+
+ assert(SanityCheck());
+ return static_cast<T*>(link);
+}
+
+template <class T>
+void Link<T>::PushTail(T* inLink)
+{
+ assert(SanityCheck());
+
+ Link<T>* link = static_cast<Link<T>*>(inLink);
+ link->InsertBefore(static_cast<T*>(this));
+
+ assert(SanityCheck());
+}
+
+template <class T>
+T* Link<T>::PopTail()
+{
+ assert(SanityCheck());
+ if (IsEmpty()) return 0;
+
+ Link<T>* link = mPrev;
+ link->Remove();
+
+ assert(SanityCheck());
+ return static_cast<T*>(link);
+}
+
+template <class T>
+void Link<T>::Cat(T* inLink)
+{
+ assert(SanityCheck());
+
+ Link<T>* link = static_cast<Link<T>*>(inLink);
+
+ if (link->IsEmpty()) return;
+ if (IsEmpty()) {
+ mNext = link->mNext;
+ mPrev = link->mPrev;
+ link->mNext->mPrev = this;
+ link->mPrev->mNext = this;
+ } else {
+ link->mNext->mPrev = mPrev;
+ link->mPrev->mNext = this;
+ mPrev->mNext = link->mNext;
+ mPrev = link->mPrev;
+ }
+ link->mPrev = link;
+ link->mNext = link;
+
+ assert(SanityCheck());
+}
+
+template <class T>
+bool Link<T>::ContainsBuf(T* inLink)
+{
+ Link<T>* link = static_cast<Link<T>*>(inLink);
+ Link<T>* curLink = mNext;
+ while (curLink != this) {
+ if (curLink == link) return true;
+ curLink = curLink->mNext;
+ }
+ return false;
+}
+
+template <class T>
+void Link<T>::DebugDump()
+{
+ Link<T>* link = mNext;
+ while (link != this) {
+ //post("Link-> %08X next %08X prev %08X\n",
+ // link, link->mNext, link->mPrev);
+ link = link->mNext;
+ }
+}
+
+template <class T>
+bool Link<T>::SanityCheck()
+{
+ Link<T>* link = mNext;
+ while (link != this) {
+ if (link->mPrev->mNext != link) {
+ throw std::runtime_error("Link: bad link <-,->");
+ }
+ if (link->mNext->mPrev != link) {
+ throw std::runtime_error("Link: bad link ->,<-");
+ }
+ link = link->mNext;
+ }
+ return true;
+}
+
+
+
+#endif
diff --git a/sc4pd/headers/lang/SC_LogFile.h b/sc4pd/headers/lang/SC_LogFile.h
new file mode 100644
index 0000000..d94c4e2
--- /dev/null
+++ b/sc4pd/headers/lang/SC_LogFile.h
@@ -0,0 +1,29 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+
+#ifndef _SC_LogFile_
+#define _SC_LogFile_
+
+#include <stdio.h>
+
+extern FILE *gLogFile;
+
+#endif
diff --git a/sc4pd/headers/lang/SC_Msg.h b/sc4pd/headers/lang/SC_Msg.h
new file mode 100644
index 0000000..b187f09
--- /dev/null
+++ b/sc4pd/headers/lang/SC_Msg.h
@@ -0,0 +1,70 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+
+#ifndef _SC_Msg_
+#define _SC_Msg_
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <netinet/in.h>
+#include "sc_msg_iter.h"
+
+class SC_Msg;
+
+enum { // Handler IDs
+ kUnknownAction = 0,
+ kRealTimeAction = 1,
+ kNonRealTimeAction = 2,
+ kEitherTimeAction = 3
+};
+
+typedef void (*ReplyFunc)(struct ReplyAddress *inReplyAddr, char* inBuf, int inSize);
+
+struct ReplyAddress
+{
+ struct sockaddr_in mSockAddr;
+ int mSockAddrLen;
+ int mSocket;
+ ReplyFunc mReplyFunc;
+};
+
+inline void SendReply(ReplyAddress *inReplyAddr, char* inBuf, int inSize)
+{
+ (inReplyAddr->mReplyFunc)(inReplyAddr, inBuf, inSize);
+}
+
+void DumpReplyAddress(ReplyAddress *inReplyAddress);
+int32 Hash(ReplyAddress *inReplyAddress);
+
+struct OSC_Packet
+{
+ char *mData;
+ int32 mSize;
+ bool mIsBundle;
+
+ ReplyAddress mReplyAddr;
+};
+
+void FreeOSCPacket(OSC_Packet *inPacket);
+
+#endif
+
+
diff --git a/sc4pd/headers/lang/SC_SynthImpl.h b/sc4pd/headers/lang/SC_SynthImpl.h
new file mode 100644
index 0000000..88411b3
--- /dev/null
+++ b/sc4pd/headers/lang/SC_SynthImpl.h
@@ -0,0 +1,42 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+
+#ifndef _SC_SynthImpl_
+#define _SC_SynthImpl_
+
+#include "SC_Synth.h"
+#include "SC_SynthDef.h"
+#include "HashTable.h"
+#include "SC_AllocPool.h"
+#include "SC_UnorderedList.h"
+
+extern SynthInterfaceTable gSynthInterfaceTable;
+void InitSynthInterfaceTable();
+
+typedef void (*SetupInterfaceFunc)(SynthInterfaceTable*);
+
+const int kMaxSynths = 1024;
+extern StaticHashTable<Synth, kMaxSynths, const char*> gSynthTable;
+extern AllocPool *gSynthAllocPool;
+
+extern float32 gSine[8193];
+
+#endif \ No newline at end of file
diff --git a/sc4pd/headers/lang/SC_TerminalClient.h b/sc4pd/headers/lang/SC_TerminalClient.h
new file mode 100644
index 0000000..b0375d0
--- /dev/null
+++ b/sc4pd/headers/lang/SC_TerminalClient.h
@@ -0,0 +1,92 @@
+// emacs: -*- c++ -*-
+// file: SC_TerminalClient.h
+// copyright: 2003 stefan kersten <steve@k-hornz.de>
+// cvs: $Id: SC_TerminalClient.h,v 1.1.1.1 2004-07-14 16:21:27 timblech Exp $
+
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA
+
+#ifndef SC_TERMINALCLIENT_H_INCLUDED
+#define SC_TERMINALCLIENT_H_INCLUDED
+
+#include "SC_LanguageClient.h"
+#include "SC_StringBuffer.h"
+
+// =====================================================================
+// SC_TerminalClient - command line sclang client.
+// =====================================================================
+
+class SC_TerminalClient : public SC_LanguageClient
+{
+public:
+ enum
+ {
+ kInterpretCmdLine = 0x1b,
+ kInterpretPrintCmdLine = 0x0c
+ };
+
+ struct Options : public SC_LanguageClient::Options
+ {
+ Options()
+ : mLibraryConfigFile(0),
+ mDaemon(false),
+ mCallRun(false),
+ mCallStop(false),
+ mArgc(0), mArgv(0)
+ { }
+
+ char* mLibraryConfigFile;
+ bool mDaemon;
+ bool mCallRun;
+ bool mCallStop;
+ int mArgc;
+ char** mArgv;
+ };
+
+ SC_TerminalClient(const char* name);
+
+ const Options& options() const { return mOptions; }
+ bool shouldBeRunning() const { return mShouldBeRunning; }
+
+ int run(int argc, char** argv);
+ void quit(int code);
+
+ virtual void post(const char *fmt, va_list ap, bool error);
+ virtual void post(char c);
+ virtual void post(const char* str, size_t len);
+ virtual void flush();
+
+protected:
+ bool parseOptions(int& argc, char**& argv, Options& opt);
+ void printUsage();
+
+ // fd is assumed to be non-blocking
+ bool readCmdLine(int fd, SC_StringBuffer& cmdLine);
+ void interpretCmdLine(PyrSymbol* method, SC_StringBuffer& cmdLine);
+
+ // subclasses should override
+ virtual void commandLoop();
+ virtual void daemonLoop();
+
+ static int prExit(struct VMGlobals* g, int);
+ virtual void onLibraryStartup();
+
+private:
+ bool mShouldBeRunning;
+ int mReturnCode;
+ Options mOptions;
+};
+
+#endif // SC_TERMINALCLIENT_H_INCLUDED
diff --git a/sc4pd/headers/lang/SC_UnorderedList.h b/sc4pd/headers/lang/SC_UnorderedList.h
new file mode 100644
index 0000000..37ce8d9
--- /dev/null
+++ b/sc4pd/headers/lang/SC_UnorderedList.h
@@ -0,0 +1,60 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+
+#ifndef _SC_UnorderedList_
+#define _SC_UnorderedList_
+
+template <class T, int kMaxItems>
+class SC_UnorderedList
+{
+ T* mList[kMaxItems];
+ unsigned int mSize;
+public:
+ SC_UnorderedList() : mSize(0) {}
+
+ unsigned int Size() const { return mSize; }
+ Synth* GetAt(unsigned int inIndex)
+ {
+ if (inIndex >= mSize) return 0;
+ return mList[inIndex];
+ }
+
+ void Add(T *inItem)
+ {
+ if (mSize < kMaxItems) {
+ mList[mSize] = inItem;
+ SetListIndex(inItem, mSize++);
+ }
+ }
+
+ void Remove(T *inItem)
+ {
+ --mSize;
+ unsigned int index = GetListIndex(inItem);
+ if (index < mSize) {
+ mList[index] = mList[mSize];
+ SetListIndex(mList[index], index);
+ }
+ }
+};
+
+#endif
+
diff --git a/sc4pd/headers/lang/SFHeaders.h b/sc4pd/headers/lang/SFHeaders.h
new file mode 100644
index 0000000..143652d
--- /dev/null
+++ b/sc4pd/headers/lang/SFHeaders.h
@@ -0,0 +1,140 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+
+#ifndef _SFHeaders_
+#define _SFHeaders_
+
+#include "SCBase.h"
+#include "ReadWriteMacros.h"
+
+enum {
+ unsupported_sound_file = -1,
+ AIFF_sound_file,
+ AIFC_sound_file,
+ RIFF_sound_file,
+ NeXT_sound_file,
+ IRCAM_sound_file,
+ SD2_sound_file,
+ raw_sound_file
+};
+
+enum {
+ snd_unsupported = -1,
+ snd_no_snd,
+ snd_16_linear,
+ snd_8_mulaw,
+ snd_8_linear,
+ snd_32_float,
+ snd_32_linear,
+ snd_8_alaw,
+ snd_8_unsigned,
+ snd_24_linear,
+ snd_64_double,
+ snd_16_linear_little_endian,
+ snd_32_linear_little_endian,
+ snd_32_float_little_endian,
+ snd_64_double_little_endian,
+ snd_16_unsigned,
+ snd_16_unsigned_little_endian,
+ snd_24_linear_little_endian,
+ snd_32_vax_float,
+ snd_12_linear,
+ snd_12_linear_little_endian,
+ snd_12_unsigned,
+ snd_12_unsigned_little_endian
+};
+
+
+class SFHeaderInfo
+{
+public:
+ SFHeaderInfo();
+
+ bool WriteHeader(FILE *inFile);
+
+ void SetPath(char *inPath);
+ double SampleRate() { return mSampleRate; }
+ void SetSampleRate(double inSampleRate) { mSampleRate = inSampleRate; }
+ void SetFormat(int inHeaderFormat, int inSampleFormat, int inCreator);
+
+ double Freq() { return mFreq; }
+
+ uint8 LoNote() { return mLoNote; }
+ uint8 HiNote() { return mHiNote; }
+ uint8 LoVeloc() { return mLoVeloc; }
+ uint8 HiVeloc() { return mHiVeloc; }
+
+ uint8 NumChannels() { return mNumChannels; }
+ int32 NumFramesInFile() { return mNumFramesInFile; }
+
+ int makeSoundFileHeader(SC_IOStream<char*>& rw);
+
+ int32 headerFileType();
+ int headerSize();
+ int sampleFormatSize();
+ void newSoundFilePath();
+
+ bool ReadSoundFileHeader(FILE *fp);
+
+ int32 CalcFrameSize();
+ bool SetTypeCreator();
+
+ char mPath[256];
+ double mSampleRate;
+ double mFreq;
+ int32 mNumFramesInFile;
+ int32 mDataOffset;
+ int32 mCreator;
+ void *mExtraStuff;
+ int16 mGain;
+ int8 mHeaderFormat;
+ int8 mSampleFormat;
+ uint8 mNumChannels;
+ uint8 mLoNote, mHiNote, mLoVeloc, mHiVeloc;
+
+private:
+
+
+ int make_AIFF_header(SC_IOStream<char*>& rw);
+ int make_AIFC_header(SC_IOStream<char*>& rw);
+ int make_RIFF_header(SC_IOStream<char*>& rw);
+ int make_Next_header(SC_IOStream<char*>& rw);
+ int make_IRCAM_header(SC_IOStream<char*>& rw);
+
+ int sampleFormat_AIFF();
+ int sampleFormat_AIFC();
+ int sampleFormat_RIFF();
+ int sampleFormat_Next();
+ int sampleFormat_Next_inv(int inFormat);
+ void writeCompressionFormat_AIFC(SC_IOStream<char*>& rw);
+
+ bool read_AIFF_Header(SC_IOStream<FILE*>& rw);
+ bool read_RIFF_Header(SC_IOStream<FILE*>& rw);
+ bool read_Next_Header(SC_IOStream<FILE*>& rw);
+};
+
+
+extern char gDefaultSoundFolder[256];
+extern char gDefaultSoundFilePath[256];
+
+int sampleFormatSize(int inSampleFormat);
+
+#endif
diff --git a/sc4pd/headers/lang/Samp.h b/sc4pd/headers/lang/Samp.h
new file mode 100644
index 0000000..7593ba8
--- /dev/null
+++ b/sc4pd/headers/lang/Samp.h
@@ -0,0 +1,46 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+/*
+
+Samp is a typedef for the output sample type.
+Should be defined to be either float or double.
+
+*/
+
+#ifndef _Samp_
+#define _Samp_
+
+#include "SC_Types.h"
+
+const long kSineSize = 8192;
+const long kSineMask = kSineSize - 1;
+const double kSinePhaseScale = kSineSize / (2.0 * 3.1415926535897932384626433832795);
+
+extern float32 gSine[kSineSize+1];
+extern float32 gPMSine[kSineSize+1];
+extern float32 gInvSine[kSineSize+1];
+extern float32 gSineWavetable[2*kSineSize];
+
+void SignalAsWavetable(float32* signal, float32* wavetable, long inSize);
+void WavetableAsSignal(float32* wavetable, float32* signal, long inSize);
+
+#endif
+
diff --git a/sc4pd/headers/lang/SimpleStack.h b/sc4pd/headers/lang/SimpleStack.h
new file mode 100644
index 0000000..3313785
--- /dev/null
+++ b/sc4pd/headers/lang/SimpleStack.h
@@ -0,0 +1,32 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+
+typedef struct {
+ long *stak;
+ short num, maxsize;
+} LongStack;
+
+void initLongStack(LongStack *self) ;
+void freeLongStack(LongStack *self);
+void growLongStack(LongStack *self);
+void pushls(LongStack *self, long value);
+long popls(LongStack *self);
+int emptyls(LongStack *self);
diff --git a/sc4pd/headers/lang/VMGlobals.h b/sc4pd/headers/lang/VMGlobals.h
new file mode 100644
index 0000000..9b5f2e1
--- /dev/null
+++ b/sc4pd/headers/lang/VMGlobals.h
@@ -0,0 +1,94 @@
+/*
+ SuperCollider real time audio synthesis system
+ Copyright (c) 2002 James McCartney. All rights reserved.
+ http://www.audiosynth.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+/*
+
+Each virtual machine has a copy of VMGlobals, which contains the state of the virtual machine.
+
+*/
+
+#ifndef _VMGLOBALS_H_
+#define _VMGLOBALS_H_
+
+#include "PyrSlot.h"
+#include "SC_AllocPool.h"
+#include "SC_RGen.h"
+
+const int kNumProcesses = 1;
+const int kMainProcessID = 0;
+
+typedef void (*FifoMsgFunc)(struct VMGlobals*, struct FifoMsg*);
+
+struct FifoMsg {
+ FifoMsg() : func(0), dataPtr(0) { dataWord[0] = dataWord[1] = 0; }
+ void Perform(struct VMGlobals* g);
+ void Free(struct VMGlobals* g);
+
+ FifoMsgFunc func;
+ void* dataPtr;
+ long dataWord[2];
+};
+
+struct VMGlobals {
+ VMGlobals();
+
+ // global context
+ class AllocPool *allocPool;
+ struct PyrProcess *process;
+ class SymbolTable *symbolTable;
+ class PyrGC *gc; // garbage collector for this process
+ PyrSlot *classvars;
+ bool canCallOS;
+
+ // thread context
+ struct PyrThread *thread;
+ struct PyrMethod *method;
+ struct PyrBlock *block;
+ struct PyrFrame *frame;
+ struct PyrMethod *primitiveMethod;
+ unsigned char *ip; // current instruction pointer
+ PyrSlot *sp; // current stack ptr
+ PyrSlot *args;
+ PyrSlot receiver; // the receiver
+ PyrSlot result;
+ int numpop; // number of args to pop for primitive
+ long returnLevels;
+ long processID;
+ long primitiveIndex;
+ RGen *rgen;
+
+ // scratch context
+ long execMethod;
+} ;
+
+inline void FifoMsg::Perform(struct VMGlobals* g)
+ {
+ (func)(g, this);
+ }
+
+inline void FifoMsg::Free(struct VMGlobals* g)
+ {
+ g->allocPool->Free(dataPtr);
+ }
+
+extern VMGlobals gVMGlobals[kNumProcesses];
+extern VMGlobals *gMainVMGlobals;
+extern VMGlobals *gCompilingVMGlobals;
+#endif
+
diff --git a/sc4pd/headers/lang/bullet.h b/sc4pd/headers/lang/bullet.h
new file mode 100644
index 0000000..463b062
--- /dev/null
+++ b/sc4pd/headers/lang/bullet.h
@@ -0,0 +1,7 @@
+
+// this should be an outstanding character
+// it is used in printing errors
+
+#define BULLET "¥"
+#define BULLET_CHAR '¥'
+
diff --git a/sc4pd/headers/lang/libraryConfig.h b/sc4pd/headers/lang/libraryConfig.h
new file mode 100644
index 0000000..b1f3844
--- /dev/null
+++ b/sc4pd/headers/lang/libraryConfig.h
@@ -0,0 +1,31 @@
+// Copyright 2003 Maurizio Umberto Puxeddu
+
+#ifndef _Supercollider_libraryConfig_h_
+#define _Supercollider_libraryConfig_h_
+
+class LibraryConfig {
+ public:
+ LibraryConfig(void);
+ virtual ~LibraryConfig();
+
+ char **includedDirectories(void);
+ char **excludedDirectories(void);
+
+ void postExcludedDirectories(void);
+ bool forEachIncludedDirectory(bool (*func)(char *, int));
+
+ bool pathIsExcluded(const char *path);
+
+ void addIncludedDirectory(char *name);
+ void addExcludedDirectory(char *name);
+
+ private:
+ int m_nIncludedDirectories;
+ char **m_includedDirectories;
+ int m_nExcludedDirectories;
+ char **m_excludedDirectories;
+};
+
+extern char *unixStandardizePath(const char *path, char *newpath);
+
+#endif // _Supercollider_libraryConfig_h_
diff --git a/sc4pd/headers/lang/readSamples.h b/sc4pd/headers/lang/readSamples.h
new file mode 100644
index 0000000..835f975
--- /dev/null
+++ b/sc4pd/headers/lang/readSamples.h
@@ -0,0 +1 @@
+/* SuperCollider real time audio synthesis system Copyright (c) 2002 James McCartney. All rights reserved. http://www.audiosynth.com This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _readSamples_ #define _readSamples_ long readSamplesInterleaved(FILE* fp, float *out, long numSamplesToRead, long format); void convertSamplesIn(float **out, char *in, long numFramesToRead, long numChannels, long sampOffset, long format); float convertSamplesOut(float **in, char *buffer, int numFramesToWrite, int numChannels, long sampOffset, int format); void convertSamplesInInterleaved(float *out, char *buffer, long numSamplesToRead, long sampOffset, long format); float convertSamplesOutInterleaved(float *in, char *buffer, long numSampsToWrite, int format); #endif \ No newline at end of file