1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
|
/*
* This file is part of tela the Tensor Language.
* Copyright (c) 1994-1996 Pekka Janhunen
*/
#ifdef __GNUC__
# pragma interface
#endif
#include <strstream.h>
#include <setjmp.h>
extern strstream err;
#define COMPTYPE Tint
#define DEFAULT_COMPVALUE 0
#define LINEARLIST TIntLL
# include "templ/tLL.H"
#undef LINEARLIST
#undef DEFAULT_COMPVALUE
#undef COMPTYPE
class TIntStack { // Program counter stack, common for all functions
private:
TIntLL LL; // Implemented as a linear list of integers
public:
TIntStack() : LL(0) {} // Initially, the stack is empty
void push(Tint i) {LL.append(i);}
Tint top() const {return LL[LL.length()-1];} // stack.top() gives ref to last int pushed
Tint top(int nth) const {return LL[LL.length()-nth];} // stack.top(n) gives the nth-last int pushed
Tint pop() {int L; LL=L=LL.length()-1; return LL[L];} // stack.pop() gives stack.top() and removes it
int length() const {return LL.length();} // stack.length() == number of items in the stack
Tint& operator[](int i) {return LL[LL.length()-1-i];} // stack[0] == &stack.top(), etc.
};
extern TIntStack thePCstack; // General program counter stack
/* TJumpBuffer could be a class, but some C++ compilers don't like
setjmp inside inline function, or refuse to inline the function
which is equally bad because then setjmp will record wrong context
- therefore we just use #define macros here */
struct TJumpBuffer {
jmp_buf jmp;
int PCstacklen;
};
// SetJmp(jmp) will return in its first argument the value returned by setjmp()
#define SetJmp(val,jumpbuffer)\
{(jumpbuffer).PCstacklen=thePCstack.length();\
(val)=setjmp((jumpbuffer).jmp);}
#define LongJmp(jumpbuffer,val)\
{\
while (thePCstack.length() > (jumpbuffer).PCstacklen) thePCstack.pop();\
longjmp((jumpbuffer).jmp,val);\
}
extern TJumpBuffer jmp1,jmp2;
extern void error();
|