home *** CD-ROM | disk | FTP | other *** search
/ MacFormat 1995 January / macformat-020.iso / Shareware City / Developers / OutOfPhase1.01Source / OutOfPhase Folder / PcodeStack.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-10-01  |  10.6 KB  |  335 lines  |  [TEXT/KAHL]

  1. /* PcodeStack.c */
  2. /*****************************************************************************/
  3. /*                                                                           */
  4. /*    Out Of Phase:  Digital Music Synthesis on General Purpose Computers    */
  5. /*    Copyright (C) 1994  Thomas R. Lawrence                                 */
  6. /*                                                                           */
  7. /*    This program is free software; you can redistribute it and/or modify   */
  8. /*    it under the terms of the GNU General Public License as published by   */
  9. /*    the Free Software Foundation; either version 2 of the License, or      */
  10. /*    (at your option) any later version.                                    */
  11. /*                                                                           */
  12. /*    This program is distributed in the hope that it will be useful,        */
  13. /*    but WITHOUT ANY WARRANTY; without even the implied warranty of         */
  14. /*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          */
  15. /*    GNU General Public License for more details.                           */
  16. /*                                                                           */
  17. /*    You should have received a copy of the GNU General Public License      */
  18. /*    along with this program; if not, write to the Free Software            */
  19. /*    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.              */
  20. /*                                                                           */
  21. /*    Thomas R. Lawrence can be reached at tomlaw@world.std.com.             */
  22. /*                                                                           */
  23. /*****************************************************************************/
  24.  
  25. #include "MiscInfo.h"
  26. #include "Audit.h"
  27. #include "Debug.h"
  28. #include "Definitions.h"
  29.  
  30. #define SHOW_ME_STACKELEMENT  /* we need to be able to see contents of StackElement */
  31. #include "PcodeStack.h"
  32. #include "Memory.h"
  33.  
  34.  
  35. #define INITIALNUMSTACKCELLS (32)
  36. #define STACKEXTENDSIZE (16)
  37.  
  38.  
  39. /* this structure remembers the parameters until evaluation is called for */
  40. struct ParamStackRec
  41.     {
  42.         StackElement*            InitialStack;
  43.         long                            NumElements;
  44.         long                            InitialStackSize;
  45.     };
  46.  
  47.  
  48. /* create a list of parameters that will lead to a function call */
  49. ParamStackRec*        NewParamStack(void)
  50.     {
  51.         ParamStackRec*    Stack;
  52.  
  53.         Stack = (ParamStackRec*)AllocPtrCanFail(sizeof(ParamStackRec),
  54.             "ParamStackRec");
  55.         if (Stack == NIL)
  56.             {
  57.              FailurePoint1:
  58.                 return NIL;
  59.             }
  60.         Stack->InitialStack = (StackElement*)AllocPtrCanFail(
  61.             INITIALNUMSTACKCELLS * sizeof(StackElement),"StackElement");
  62.         if (Stack->InitialStack == NIL)
  63.             {
  64.              FailurePoint2:
  65.                 ReleasePtr((char*)Stack);
  66.                 goto FailurePoint1;
  67.             }
  68.         Stack->NumElements = 0;
  69.         Stack->InitialStackSize = INITIALNUMSTACKCELLS;
  70.         return Stack;
  71.     }
  72.  
  73.  
  74. void                            DisposeParamStack(ParamStackRec* Stack)
  75.     {
  76.         long                        Scan;
  77.  
  78.         CheckPtrExistence(Stack);
  79.         for (Scan = Stack->NumElements - 1; Scan >= 0; Scan -= 1)
  80.             {
  81.                 PRNGCHK(Stack->InitialStack,&(Stack->InitialStack[Scan]),
  82.                     sizeof(Stack->InitialStack[Scan]));
  83.                 if ((Stack->InitialStack[Scan].ElementType == esArray)
  84.                     && (Stack->InitialStack[Scan].Data.Array != NIL))
  85.                     {
  86.                         DisposeIfNotOnStack(Stack->InitialStack,Scan);
  87.                     }
  88.             }
  89.         ReleasePtr((char*)(Stack->InitialStack));
  90.         ReleasePtr((char*)Stack);
  91.     }
  92.  
  93.  
  94. void                            DisposeIfNotOnStack(StackElement* Stack, long StackPtr)
  95.     {
  96.         long                        Scan;
  97.  
  98.         PRNGCHK(Stack,&(Stack[StackPtr]),sizeof(Stack[StackPtr]));
  99.         ERROR(Stack[StackPtr].ElementType != esArray,PRERR(ForceAbort,
  100.             "DisposeIfNotOnStack:  top of stack isn't an array"));
  101.         ERROR(Stack[StackPtr].Data.Array == NIL,PRERR(ForceAbort,
  102.             "DisposeIfNotOnStack:  array is NIL"));
  103.         for (Scan = StackPtr - 1; Scan >= 0; Scan -= 1)
  104.             {
  105.                 PRNGCHK(Stack,&(Stack[Scan]),sizeof(Stack[Scan]));
  106.                 if ((Stack[Scan].ElementType == esArray)
  107.                     && (Stack[Scan].Data.Array == Stack[StackPtr].Data.Array))
  108.                     {
  109.                         /* if it's on the stack, then don't dispose of it */
  110.                         return;
  111.                     }
  112.             }
  113.         ReleasePtr((char*)Stack[StackPtr].Data.Array);
  114.     }
  115.  
  116.  
  117. void                            DisposeIfOnStackOnlyOnce(StackElement* Stack, long StackPtr, long Where)
  118.     {
  119.         long                        Scan;
  120.  
  121.         ERROR(Stack[Where].Data.Array == NIL,PRERR(ForceAbort,
  122.             "DisposeIfOnStackOnlyOnce:  array is NIL"));
  123.         ERROR(Stack[Where].ElementType != esArray,PRERR(ForceAbort,
  124.             "DisposeIfOnStackOnlyOnce:  top of stack isn't an array"));
  125.         for (Scan = StackPtr; Scan >= 0; Scan -= 1)
  126.             {
  127.                 PRNGCHK(Stack,&(Stack[Scan]),sizeof(Stack[Scan]));
  128.                 if ((Scan != Where)
  129.                     && (Stack[Scan].ElementType == esArray)
  130.                     && (Stack[Scan].Data.Array == Stack[Where].Data.Array))
  131.                     {
  132.                         /* if it's on the stack somewhere else, then don't dispose of it */
  133.                         return;
  134.                     }
  135.             }
  136.         ReleasePtr((char*)Stack[Where].Data.Array);
  137.     }
  138.  
  139.  
  140. /* this is a utility routine to update the address of an array when it has been */
  141. /* resized. */
  142. void                            UpdateStackArrayRefs(StackElement* Stack, long StackPtr,
  143.                                         void* OriginalArrayRef, void* NewArrayRef)
  144.     {
  145.         long                        Scan;
  146.  
  147.         for (Scan = StackPtr; Scan >= 0; Scan -= 1)
  148.             {
  149.                 PRNGCHK(Stack,&(Stack[Scan]),sizeof(Stack[Scan]));
  150.                 if ((Stack[Scan].ElementType == esArray)
  151.                     && (Stack[Scan].Data.Array == OriginalArrayRef))
  152.                     {
  153.                         /* update the reference */
  154.                         Stack[Scan].Data.Array = NewArrayRef;
  155.                     }
  156.             }
  157.     }
  158.  
  159.  
  160. MyBoolean                    AddIntegerToStack(ParamStackRec* Stack, long IntegerValue)
  161.     {
  162.         CheckPtrExistence(Stack);
  163.         if (Stack->NumElements == Stack->InitialStackSize)
  164.             {
  165.                 StackElement*        NewStack;
  166.  
  167.                 /* enlarge stack */
  168.                 NewStack = (StackElement*)ResizePtr((char*)(Stack->InitialStack),
  169.                     (Stack->InitialStackSize + STACKEXTENDSIZE) * sizeof(StackElement));
  170.                 if (NewStack == NIL)
  171.                     {
  172.                         return False;
  173.                     }
  174.                 Stack->InitialStack = NewStack;
  175.                 Stack->InitialStackSize += STACKEXTENDSIZE;
  176.             }
  177.         Stack->InitialStack[Stack->NumElements].Data.Integer = IntegerValue;
  178.         Stack->InitialStack[Stack->NumElements].ElementType = esScalar;
  179.         Stack->NumElements += 1;
  180.         return True;
  181.     }
  182.  
  183.  
  184. MyBoolean                    AddFloatToStack(ParamStackRec* Stack, float FloatValue)
  185.     {
  186.         CheckPtrExistence(Stack);
  187.         if (Stack->NumElements == Stack->InitialStackSize)
  188.             {
  189.                 StackElement*        NewStack;
  190.  
  191.                 /* enlarge stack */
  192.                 NewStack = (StackElement*)ResizePtr((char*)(Stack->InitialStack),
  193.                     (Stack->InitialStackSize + STACKEXTENDSIZE) * sizeof(StackElement));
  194.                 if (NewStack == NIL)
  195.                     {
  196.                         return False;
  197.                     }
  198.                 Stack->InitialStack = NewStack;
  199.                 Stack->InitialStackSize += STACKEXTENDSIZE;
  200.             }
  201.         Stack->InitialStack[Stack->NumElements].Data.Float = FloatValue;
  202.         Stack->InitialStack[Stack->NumElements].ElementType = esScalar;
  203.         Stack->NumElements += 1;
  204.         return True;
  205.     }
  206.  
  207.  
  208. MyBoolean                    AddDoubleToStack(ParamStackRec* Stack, double DoubleValue)
  209.     {
  210.         CheckPtrExistence(Stack);
  211.         if (Stack->NumElements == Stack->InitialStackSize)
  212.             {
  213.                 StackElement*        NewStack;
  214.  
  215.                 /* enlarge stack */
  216.                 NewStack = (StackElement*)ResizePtr((char*)(Stack->InitialStack),
  217.                     (Stack->InitialStackSize + STACKEXTENDSIZE) * sizeof(StackElement));
  218.                 if (NewStack == NIL)
  219.                     {
  220.                         return False;
  221.                     }
  222.                 Stack->InitialStack = NewStack;
  223.                 Stack->InitialStackSize += STACKEXTENDSIZE;
  224.             }
  225.         Stack->InitialStack[Stack->NumElements].Data.Double = DoubleValue;
  226.         Stack->InitialStack[Stack->NumElements].ElementType = esScalar;
  227.         Stack->NumElements += 1;
  228.         return True;
  229.     }
  230.  
  231.  
  232. /* the ACTUAL array is added, so you no longer own it after this! */
  233. MyBoolean                    AddArrayToStack(ParamStackRec* Stack, void* Array)
  234.     {
  235.         CheckPtrExistence(Stack);
  236.         if (Stack->NumElements == Stack->InitialStackSize)
  237.             {
  238.                 StackElement*        NewStack;
  239.  
  240.                 /* enlarge stack */
  241.                 NewStack = (StackElement*)ResizePtr((char*)(Stack->InitialStack),
  242.                     (Stack->InitialStackSize + STACKEXTENDSIZE) * sizeof(StackElement));
  243.                 if (NewStack == NIL)
  244.                     {
  245.                         return False;
  246.                     }
  247.                 Stack->InitialStack = NewStack;
  248.                 Stack->InitialStackSize += STACKEXTENDSIZE;
  249.             }
  250.         Stack->InitialStack[Stack->NumElements].Data.Array = Array;
  251.         Stack->InitialStack[Stack->NumElements].ElementType = esArray;
  252.         Stack->NumElements += 1;
  253.         return True;
  254.     }
  255.  
  256.  
  257. long                            GetStackInteger(ParamStackRec* Stack, long Index)
  258.     {
  259.         CheckPtrExistence(Stack);
  260.         ERROR((Index < 0) || (Index >= Stack->NumElements),PRERR(ForceAbort,
  261.             "GetStackInteger:  index out of range"));
  262.         ERROR(Stack->InitialStack[Index].ElementType != esScalar,PRERR(ForceAbort,
  263.             "GetStackInteger:  not a scalar value"));
  264.         return Stack->InitialStack[Index].Data.Integer;
  265.     }
  266.  
  267.  
  268. float                            GetStackFloat(ParamStackRec* Stack, long Index)
  269.     {
  270.         CheckPtrExistence(Stack);
  271.         ERROR((Index < 0) || (Index >= Stack->NumElements),PRERR(ForceAbort,
  272.             "GetStackFloat:  index out of range"));
  273.         ERROR(Stack->InitialStack[Index].ElementType != esScalar,PRERR(ForceAbort,
  274.             "GetStackFloat:  not a scalar value"));
  275.         return Stack->InitialStack[Index].Data.Float;
  276.     }
  277.  
  278.  
  279. double                        GetStackLongDouble(ParamStackRec* Stack, long Index)
  280.     {
  281.         CheckPtrExistence(Stack);
  282.         ERROR((Index < 0) || (Index >= Stack->NumElements),PRERR(ForceAbort,
  283.             "GetStackLongDouble:  index out of range"));
  284.         ERROR(Stack->InitialStack[Index].ElementType != esScalar,PRERR(ForceAbort,
  285.             "GetStackLongDouble:  not a scalar value"));
  286.         return Stack->InitialStack[Index].Data.Double;
  287.     }
  288.  
  289.  
  290. /* It returns the actual array, so you only get to use it on a loan basis */
  291. void*                            GetStackArray(ParamStackRec* Stack, long Index)
  292.     {
  293.         CheckPtrExistence(Stack);
  294.         ERROR((Index < 0) || (Index >= Stack->NumElements),PRERR(ForceAbort,
  295.             "GetStackArrayCopy:  index out of range"));
  296.         ERROR(Stack->InitialStack[Index].ElementType != esArray,PRERR(ForceAbort,
  297.             "GetStackArrayCopy:  not an array value"));
  298.         return Stack->InitialStack[Index].Data.Array;
  299.     }
  300.  
  301.  
  302. StackElement*            GetStackBase(ParamStackRec* Stack)
  303.     {
  304.         CheckPtrExistence(Stack);
  305.         return Stack->InitialStack;
  306.     }
  307.  
  308.  
  309. long                            GetStackInitialSize(ParamStackRec* Stack)
  310.     {
  311.         CheckPtrExistence(Stack);
  312.         return Stack->InitialStackSize;
  313.     }
  314.  
  315.  
  316. long                            GetStackNumElements(ParamStackRec* Stack)
  317.     {
  318.         CheckPtrExistence(Stack);
  319.         return Stack->NumElements;
  320.     }
  321.  
  322.  
  323. void                            SetStackInformation(ParamStackRec* Stack, long NewTotalSize,
  324.                                         long NewNumElements, StackElement* NewStackAddress)
  325.     {
  326.         CheckPtrExistence(Stack);
  327.         PRNGCHK(NewStackAddress,NewStackAddress,sizeof(StackElement) * NewTotalSize);
  328.         ERROR((NewNumElements < 0) || (NewNumElements > NewTotalSize),PRERR(ForceAbort,
  329.             "SetStackInformation:  parametric weirdness"));
  330.         ERROR(NewNumElements != Stack->NumElements,PRERR(ForceAbort,
  331.             "SetStackInformation:  initial stack pointer is different"));
  332.         Stack->InitialStack = NewStackAddress;
  333.         Stack->InitialStackSize = NewTotalSize;
  334.     }
  335.