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 110 111 112 113 114 115 116 117 118 119 120
|
/*
* This file is part of tela the Tensor Language.
* Copyright (c) 1994-2001 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 const 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(0), prev(0), length(0) {}
};
class TNodePoolState {
private:
TNodeBlock* ptr;
int len;
//-- TNodePoolState(const TNodePoolState&); // FIXME: using default implementation - cls
TNodePoolState& operator=(const TNodePoolState&); // do not implement
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;}
};
struct TObjectListNode {
TObjectPtr op;
TObjectListNode *nextobj;
};
class TNodePool {
private:
TNodeBlock *first;
TNodeBlock *last;
int nblocks;
void AddDeletedObjectsInList(TNodeBlock*p, int start, int stop, TObjectListNode *&objlist);
TNodePool(const TNodePool&); // do not implement
TNodePool& operator=(const TNodePool&); // do not implement
public:
TNodePool() : first(new TNodeBlock), last(first), 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;
|