diff options
Diffstat (limited to 'sc4pd/headers/lang')
55 files changed, 6777 insertions, 0 deletions
diff --git a/sc4pd/headers/lang/AdvancingAllocPool.h b/sc4pd/headers/lang/AdvancingAllocPool.h new file mode 100755 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 100755 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 100755 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 100755 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 100755 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 100755 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 100755 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 100755 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 100755 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 100755 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 100755 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 100755 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 100755 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 100755 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 100755 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 100755 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 100755 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 100755 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 100755 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 100755 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 100755 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 100755 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 100755 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 100755 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 100755 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 100755 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 100755 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 100755 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 100755 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 100755 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 100755 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 100755 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 100755 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 100755 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 100755 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 100755 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 100755 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 100755 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 100755 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 100755 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 100755 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 100755 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 100755 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 100755 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 100755 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 100755 index 0000000..0504b27 --- /dev/null +++ b/sc4pd/headers/lang/SFHeaders.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 _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
\ No newline at end of file diff --git a/sc4pd/headers/lang/Samp.h b/sc4pd/headers/lang/Samp.h new file mode 100755 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 100755 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 100755 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 100755 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 100755 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 |