File: prg.H

package info (click to toggle)
tela 2.0-10
  • links: PTS
  • area: main
  • in suites: sarge
  • size: 7,040 kB
  • ctags: 4,547
  • sloc: cpp: 21,090; ansic: 6,993; lex: 1,056; fortran: 1,010; sh: 761; lisp: 554; makefile: 464; yacc: 361
file content (171 lines) | stat: -rw-r--r-- 8,320 bytes parent folder | download
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
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
/*
 * This file is part of tela the Tensor Language.
 * Copyright (c) 1994-2001 Pekka Janhunen
 */

#ifdef __GNUC__
#  pragma interface
#endif
#include "machine.H"
#include "common.H"

#define COMPTYPE Toperand
#define DEFAULT_COMPVALUE Toperand()
#define LINEARLIST TInstructionList1

#include "templ/tLL.H"

#undef LINEARLIST
#undef DEFAULT_COMPVALUE
#undef COMPTYPE

class TInstructionList : public TInstructionList1 {
 private:
	int maxNops;			// Maximum number of operands in any instruction
 public:
	TInstructionList() : TInstructionList1(0), maxNops(0) {}
	void add(Tcode code) {append(Toperand(code));}
	void add(Tcode code, const Toperand& op1);
	void add(Tcode code, const Toperand& op1, const Toperand& op2);
	void add(Tcode code, const Toperand& op1, const Toperand& op2, const Toperand& op3);
	void add(Tcode code, const Toperand& op1, const Toperand& op2, const Toperand& op3, const Toperand& op4);
	void add(Tcode code, int Noperands);
	int MaxNops() const {return maxNops;}
	void set_maxNops(int i) {maxNops = i;}
	void clear() {TInstructionList1::operator=(0);}
	friend ostream& operator<<(ostream& o, const TInstructionList& il);
};

#define MAX_NOPERANDS 200

class TObjectStack {	// Runtime stack, common for all functions
 private:
	TObjectLL LL;		// Implemented as a linear list of TObjectPtrs
 public:
	TObjectStack() : LL(0) {}							// Initially, the stack is empty
	void push(TObjectPtr ptr) {LL.append(ptr);}			// stack.push(&obj) works
	void push(Tobject& obj) {LL.append(&obj);}			// stack.push(obj) also works
	void push(int N) {int L=LL.length(); LL=L+N;}		// push N null pointers
	Tobject& top() const {return *LL[LL.length()-1];}	// stack.top() gives ref to last object pushed
	void pop(int N);									// shorten the stack by N objects
	int length() const {return LL.length();}			// stack.length() == number of objects in the stack
	TObjectPtr& operator[](int i) {return LL[LL.length()-1-i];}	// stack[0] == &stack.top(), etc.
	friend inline ostream& operator<<(ostream& o, const TObjectStack& stack);
	~TObjectStack();
};

inline ostream& operator<<(ostream& o, const TObjectStack& stack) {return o << stack.LL;}

extern TObjectStack theStack;		// General runtime stack

extern void optimize(TInstructionList& il, TIntLL& linenums, const Tsymbol *symptr);

//extern void Call(const Tobject& fn,
//		 const TConstObjectPtr inputs[], const int Ninputs,
//		 const TObjectPtr outputs[], const int Noutputs,
//		 const Tsymbol* symptr=0, bool check_that_first_output_not_obligatory=false);

class Tprg {	// flatcode sequence with static objects
 private:
	TInstructionList il;	// the sequence of flatcode words
	TObjectLL ol;			// list of static objects
	TObjectLL* old_olptr;	// ptr to previous list of static objects
	TIntLL linenums;		// source line number information
	int nargin;				// (Maximum) number of input objects
	int nargout;			// (Maximum) number of output objects
	int nargin_min;			// Minimum number of input objects
	int nargout_min;		// Minimum number of output objects
	int nlocal;				// Number of local non-temporary objects
	int ntemp;				// Number of local temporary objects (introduced by codegen)
	int nstack;				// Stack frame size
	int inputellipsis;		// Nonzero if input arglist ends with ellipsis (...)
	int outputellipsis;		// Nonzero if output arglist ends with ellipsis
	Tchar *filename;		// source file name from this Tprg was compiled
	const Tsymbol* symptr;	// pointer to symbol whose value this Tprg is
	void CalcStack();
	void executeInstructionSequence();
	void MakeCurrent()
		{old_olptr=Toperand::objLLptr; Toperand::objLLptr = &ol;}	// Activate this Tprg to receive static objects into its ol
	void checkreadonlyoperand(const Toperand&, int) const;
	Tprg(const Tprg&);            // do not implement
	Tprg& operator=(const Tprg&); // do not implement
	friend void Call(const Tobject& fn,
					 const TConstObjectPtr inputs[], const int Ninputs,
					 const TObjectPtr outputs[], const int Noutputs,
					 const Tsymbol* symptr=0, bool check_that_first_output_not_obligatory=false);
 public:
	Tprg(const Tchar *fn);
	Tprg(const Tchar *fn, int in, int out);
	Tprg(const Tchar *fn, int in, int out, int loc);
	Tprg(const Tchar *fn, int in, int out, int minin, int minout, int loc, const Tsymbol* sympointer=0);
	void SetInputEllipsisFlag() {inputellipsis=1; CalcStack();}
	void SetOutputEllipsisFlag() {outputellipsis=1; CalcStack();}
	int HasInputEllipsis() const {return inputellipsis;}
	int HasOutputEllipsis() const {return outputellipsis;}
	void JustMakeCurrent()
	    {Toperand::objLLptr = &ol;}	// Same as MakeCurrent but do not modify old_oldptr
	int FindLineNumber(int startPC=0) const;		// find line number after error
	// --- add functions, add new instructions to program
	void add(Tcode code) {il.add(code); linenums.append(global::lineno);}
	void add(Tcode code, const Toperand& op1) {il.add(code,op1); linenums.append(global::lineno);}
	void add(Tcode code, const Toperand& op1, const Toperand& op2) {il.add(code,op1,op2); linenums.append(global::lineno);}
	void add(Tcode code, const Toperand& op1, const Toperand& op2, const Toperand& op3)
		{il.add(code,op1,op2,op3); linenums.append(global::lineno);}
	void add(Tcode code, const Toperand& op1, const Toperand& op2, const Toperand& op3, const Toperand& op4)
		{il.add(code,op1,op2,op3,op4); linenums.append(global::lineno);}
	// --- another form of add function: first use add(code,N), then call append() exactly N times
	// --- this can be used to form instructions with arbitrary number of operands
	void add(Tcode code, int Noperands) {il.add(code,Noperands); linenums.append(global::lineno);}
	void append(const Toperand& op) {il.append(op);}
	// --- execution functions
	void execute(const TConstObjectPtr[],int, const TObjectPtr[],int, const Tsymbol*fnsymptr=0);
	// --- function to add (possibly) more temporaries
	void AllocTemporaries(int N) {if (N>ntemp) {ntemp=N; CalcStack();}}
	// --- inquiry functions
	int length() const {return il.length();}			// prg.length() returns number of flatcode words in prg
	Toperand& operator[](int i) const {return il[i];}	// prg[i] returns the ith flatcode word in prg
	int Nstatic() const {return ol.length();}			// prg.Nstatic() is the number of static objects
	TObjectPtr nthobject(int n) {return ol[n];}			// prg.nthobject(n) returns the nth static object in prg
	int Nargin() const {return nargin;}					// prg.Nargin() returns the maximum number of input objects for prg
	int Nargout() const {return nargout;}				// prg.Nargout() returns the maximum number of output objects for prg
	int NMinArgin() const {return nargin_min;}			// prg.NMinArgin() returns the minimum number of input objects for prg
	int NMinArgout() const {return nargout_min;}		// prg.NMinArgout() returns the minimum number of output objects for prg
	int Nlocal() const {return nlocal;}					// prg.Nlocal() returns the number of local objects in prg
	int Ntemp() const {return ntemp;}					// prg.Ntemp() returns the number of temporary local objects
	int StackFrameSize() const {return nstack;}			// prg.StackFrameSize() returns the number of objects in stack frame
	int PermanentFrameSize() const {return 1+nargin+nargout+nlocal+(inputellipsis!=0)+(outputellipsis!=0);}	// same as StackFrameSize but without temporaries
	const Tchar *FileName() const {return filename;}
	const Tsymbol& Symbol() const {return *symptr;}
	int MaxNops() const {return il.MaxNops();}
	Tcode LastOpcode() const;							// prg.LastOpcode() is the last opcode appended, or Klit if none is found
	// --- function to check that input args are not modified
	void checkreadonlyvars() const;
	// --- function to optimize flatcode
	void optimize() {::optimize(il,linenums,symptr);}
	// --- outputting
	friend ostream& operator<<(ostream& o, Tprg& prg);
	// --- destructor
	~Tprg();
};

class TCodeStack {
 private:
	struct TCodeStackNode {
		Tprg *prgptr;
		TCodeStackNode *next;
	};
	TCodeStackNode *p;

        TCodeStack(const TCodeStack&);            // do not implement
        TCodeStack& operator=(const TCodeStack&); // do not implement
 public:
	TCodeStack() : p(0) {}
	int isempty() const {return p==0;}
	void push(Tprg* ptr);
	Tprg* top() const;
	Tprg* pop();
};

extern TCodeStack theCodeStack;		// General stack of pointer to Tprgs

extern void PerformanceReport(int longflag=0);