Logo Search packages:      
Sourcecode: tela version File versions

prg.H

/*
 * 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);

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

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);

Generated by  Doxygen 1.6.0   Back to index