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 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109
|
/*
* This file is part of tela the Tensor Language.
* Copyright (c) 1994-1996 Pekka Janhunen
*/
#ifdef __GNUC__
# pragma interface
#endif
#include "symbol.H"
#include "common.H"
enum TNodeKind {Kconstant,Kvariable,Kbuiltin,Kslot,Kcolon};
enum Tfunc {
FPLUS,FDIFFERENCE,FMINUS,
FTIMES,FQUOTIENT,FPOWER,FMOD,
FEQ,FNE,FGT,FLT,FGE,FLE,
FAND,F_OR,FNOT,
FRANGE,
FREF,FMREF,FCALL,FLIST,
FSET,FBLOCK,FDEFUN,FPACKAGE,FLOCAL,FGLOBAL,FFORMAL,FFORMAL_ELLIPSIS,FGOTO,FLABEL,
FDISP,
FIF,FWHILE,FREPEAT,FFOR,FCONTINUE,FBREAK,FRETURN,
FARRAY,FEMPTY_ARRAY,FAPP,
FHARDNOP,FNOP
};
extern Tchar *FuncData[];
class Tnode {
public:
Tnode *next; // pointer to next node, or 0
Tnode *list; // pointer to sublist node, or 0
TNodeKind kind; // node kind
private:
union {void *ptr; Tfunc func; TPtrInt s;}; // ptr is Tobject* if k==Kconstant, and Tsymbol* if k==Kvariable
int lineno; // source code line number when this node was generated by the parser
public:
Tnode() {next=0; list=0; kind=Kbuiltin; func=FLIST; lineno=global::lineno;}
Tnode(Tnode*down, Tobject* objptr, Tnode*right) {next=right; list=down; kind=Kconstant; ptr=objptr; lineno=global::lineno;}
Tnode(Tnode*down, Tsymbol* symptr, Tnode*right) {next=right; list=down; kind=Kvariable; ptr=symptr; lineno=global::lineno;}
Tnode(Tnode*down, Tfunc f, Tnode*right) {next=right; list=down; kind=Kbuiltin; func=f; lineno=global::lineno;}
Tnode(Tnode*down, Tslot s1, Tnode*right) {next=right; list=down; kind=Kslot; s=s1; lineno=global::lineno;}
Tnode(Tnode*down, Tallrange a, Tnode*right) {next=right; list=down; kind=Kcolon; lineno=global::lineno;}
Tnode(const Tnode& node) {next=node.next; list=node.list; kind=node.kind; ptr=node.ptr; lineno=node.lineno;}
// --- assignments
Tnode& operator=(const Tnode& node)
{next=node.next; list=node.list; kind=node.kind; ptr=node.ptr; lineno=node.lineno; return *this;}
Tnode& operator=(Tobject& obj) {kind=Kconstant; ptr=&obj; lineno=global::lineno; return *this;}
Tnode& operator=(Tsymbol& sym) {kind=Kvariable; ptr=&sym; lineno=global::lineno; return *this;}
Tnode& operator=(Tfunc f) {kind=Kbuiltin; func=f; lineno=global::lineno; return *this;}
Tnode& operator=(Tslot s1) {kind=Kslot; s=s1; lineno=global::lineno; return *this;}
// --- inquiry functions
Tobject& ObjectValue() const {return *(Tobject*)ptr;}
Tsymbol& SymbolValue() const {return *(Tsymbol*)ptr;}
Tfunc FunctionValue() const {return func;}
Tslot SlotValue() const {return s;}
TPtrInt GeneralValue() const {return s;}
int LineNumber() const {return lineno;}
// --- dynamic allocation
void* operator new(size_t sz);
void operator delete(void*) {} // delete does nothing since mark/release approach is used
~Tnode() {kind=Kbuiltin;}
};
ostream& operator<<(ostream& o, const Tnode& node);
//Tnode* readtree(istream& i);
//inline istream& operator>>(istream& i, Tnode& node) {Tnode*ptr=readtree(i); node=*ptr; return i;}
struct TNodeBlock {
enum {SIZE=203/*1024*/};
TNodeBlock *next;
TNodeBlock *prev;
int length;
Tnode pool[SIZE];
TNodeBlock() {next=prev=0; length=0;}
};
class TNodePoolState {
private:
TNodeBlock* ptr;
int len;
public:
TNodePoolState(TNodeBlock* blockptr) {ptr=blockptr; len=blockptr->length;}
TNodePoolState(TNodeBlock* blockptr, int length) {ptr=blockptr; len=length;}
TNodeBlock* Ptr() {return ptr;}
int Len() const {return len;}
};
class TNodePool {
private:
TNodeBlock *first;
TNodeBlock *last;
int nblocks;
void DeleteObjects(TNodeBlock*p, int start, int stop);
public:
TNodePool() {first=last=new TNodeBlock; nblocks=1;}
TNodeBlock& First() const {return *first;}
TNodeBlock& Last() const {return *last;}
void SetLast(TNodeBlock*p) {last=p;}
TNodePoolState mark() {return TNodePoolState(last);}
void release(TNodePoolState& s);
int NodesInUse();
friend class Tnode;
~TNodePool() {TNodePoolState s(first,0); release(s);}
};
extern TNodePool theNodePool;
|