📄 afunction.hpp
字号:
// -*- Mode : c++ -*-//// SUMMARY : // USAGE : // ORG : // AUTHOR : Frederic Hecht// E-MAIL : hecht@ann.jussieu.fr///* This file is part of Freefem++ Freefem++ is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. Freefem++ is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with Freefem++; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA *///file afonction.h#ifndef __AFONCTION__#define __AFONCTION__#include "showverb.hpp" #include <typeinfo>#include <cstddef>#include <iostream>#include <fstream>#include <cstring>#include "error.hpp"#include <map>#include <deque>#include <list>#include <vector>#include <queue>#include <complex>#include <string>#include <cstdlib>#include <algorithm>extern bool showCPU;#include <time.h> #include "CodeAlloc.hpp"inline double CPUtime(){#ifdef SYSTIMES struct tms buf; if (times(&buf)!=-1) return ((double)buf.tms_utime+(double)buf.tms_stime)/(long) sysconf(_SC_CLK_TCK); else#endif return ((double) clock())/CLOCKS_PER_SEC;}extern long verbosity; // level off printingextern bool withrgraphique;using namespace std;#include "ffstack.hpp"#include "AnyType.hpp"#include "String.hpp"class basicForEachType;class E_F1_funcT_Type;class E_F0; // une instruction exec time class C_F0; // une instruction complie timeclass ListOfInst;class Polymorphic;class OneOperator;typedef E_F0 * Expression; // class AC_F0;class basicAC_F0;typedef complex<double> Complex;typedef pair<aType, E_F0 *> Type_Expr ;// to store the type and the expression 29042005 FH int FindType(const char * name) ; void lgerror (const char* s) ; void CompileError(string msg="",aType r=0); void ExecError(string msg=""); struct UnId { const char * id; aType r; Expression e; deque<UnId> * array; // to store a array aType re; bool ref; // a ref or non UnId() :id(0),r(0),e(0),array(0),re(0),ref(false) {} UnId(const char * idd) :id(idd),r(0),e(0),array(0),re(0),ref(false) {} UnId(const char * idd,const C_F0 & ee,aType rr,bool reff) ; UnId(deque<UnId> * d) : id(0),r(0),e(0),array(d?new deque<UnId>(*d):0),re(0),ref(false) {} UnId(const UnId & u) : id(u.id),r(u.r),e(u.e), array(u.array?new deque<UnId>(*u.array):0), re(u.re),ref(u.ref) {} // Modif 24032005 void operator= (const UnId & u) { id=u.id; r=u.r; e=u.e; re=u.re; ref=u.ref; if(array) delete array; array=0; if(u.array) array= new deque<UnId>(*u.array); } ~UnId(){ if( array) delete array;} // Modif 24032005 };typedef deque<UnId> ListOfId;// xxx is a type so xxx can't be a parameter #define ATYPE(xxx) map_type[typeid(xxx).name()]/* #define NEW_TYPE(type) map_type[typeid(type).name()] = new ForEachType<type >(0,0)//#define NEW_TYPE(type) map_type[typeid(type).name()] = new ForEachType<type >()#define NEW_TYPE_I(type,i,d) map_type[typeid(type).name()] = new ForEachType<type>(i,d) #define NEW_TYPE_Ptr(type) map_type[typeid(type*).name()] = new ForEachTypePtr<type >()#define NEW_TYPE_PtrND(type) map_type[typeid(type*).name()] = new ForEachTypePtr<type >(0)#define NEW_TYPE_PtrNIND(type) map_type[typeid(type*).name()] = new ForEachTypePtr<type >(0,0)//#define NEW_TYPE_PtrI(type) map_type[typeid(type*).name()] = new ForEachTypePtr<type*>(Initialize<type>)*/extern Polymorphic * TheOperators, * TheRightOperators;// -------------extern C_F0 *pOne,*pZero,*pminusOne;typedef AnyType (* Function1)(Stack, const AnyType &);typedef AnyType (* Function2)(Stack, const AnyType &,const AnyType &);typedef AnyType (* CFunction2)(Stack, E_F0 *, E_F0 *);typedef AnyType (* CFunction4)(Stack, E_F0 *, E_F0 *, E_F0 *, E_F0 *);Expression NewExpression(Function1,Expression);Expression NewExpression(Function2,Expression,Expression);inline Type_Expr make_Type_Expr(aType t, E_F0 * e) {return make_pair(t,e);}inline Type_Expr make_Type_Expr( E_F0 * e,aType t) {return make_pair(t,e);}struct Keyless : binary_function<const char *,const char *, bool> { typedef const char * Key; bool operator()(const Key& x, const Key& y) const { return strcmp(x,y)<0;} }; // un table Iden class TableOfIdentifier: public CodeAlloc { public: struct Value; typedef const char * Key; typedef map<Key,Value,Keyless> maptype; typedef pair<const Key,Value> pKV; typedef maptype::iterator iterator; typedef maptype::const_iterator const_iterator; struct Value :public Type_Expr { pKV * next; // link all the variable in reverse order to call delete on each variable bool del; Value(const Type_Expr & vv,pKV * n,bool dd=true) : Type_Expr(vv),next(n),del(dd) {} Value(aType t,E_F0 *f,pKV *n,bool dd=true): Type_Expr(t,f),next(n),del(dd) {} };// to store the type and the expression pKV * listofvar; // struct Keyless : binary_function<Key,Key, bool>// { bool operator()(const Key& x, const Key& y) const{ return strcmp(x,y)<0;} }; maptype m; C_F0 Find(Key) const ; C_F0 Find(Key,const basicAC_F0 &) const ; const Type_Expr & New(Key k,const Type_Expr & v,bool del=true); void Add(Key k,Key op,OneOperator *p0,OneOperator *p1=0, OneOperator *p2=0,OneOperator *p3=0,OneOperator *p4=0, OneOperator *p5=0,OneOperator *p6=0) ; void clear(); template<class T> C_F0 NewVar(Key k,aType t,size_t & top,const C_F0 &i) ;template<class T> C_F0 NewVar(Key k,aType t,size_t & top,const basicAC_F0 &args) ;template<class T,class U> C_F0 NewVar(Key k,aType t,size_t & top,const basicAC_F0 &args,const U & data) ;// C_F0 NewVar(Key k,aType t,size_t & top,const basicAC_F0 &args,const C_F0& f) ;template<class T> C_F0 NewVar(Key k,aType t,size_t & top) ; C_F0 NewID(aType t,Key k, C_F0 & c,size_t & top,bool del=true); C_F0 NewID(aType t,Key k, C_F0 & c,const ListOfId & l,size_t & top,bool del=true); template<class T> C_F0 NewFESpace(Key k,aType t,size_t & top,const basicAC_F0 &args); friend ostream & operator<<(ostream & f,const TableOfIdentifier & ); C_F0 destroy(); TableOfIdentifier() ; //: listofvar(0) {}; ~TableOfIdentifier(); //};// for all the type of the language class basicForEachType : public CodeAlloc { const type_info * ktype; // the real type_info // const type_info *ktypefunc;// the type of code public: const size_t size; typedef OneOperator * CastFunc; typedef map<aType,CastFunc>::const_iterator const_cast_iterator; typedef const char * Key; // virtual void print(ostream &f,const void *p) const =0; friend ostream & operator<<(ostream & f,const basicForEachType & e) { f << '<' << e.name() << '>' ;return f;} void Show(ostream & f) const ; const char * name() const { return this ? ktype->name() :"NULL" ;} virtual bool CastingFrom(const basicForEachType * t) const ; // modif FH ----- A TESTER // virtual bool SametypeRight(const basicForEachType * t) const {return this == t || t == un_ptr_type;}// virtual Type_Expr init(const Type_Expr & te) const { return Type_Expr(0,0);} virtual int TYPEOFID() const {return 0;}// bool SametypeLeft(const basicForEachType * t) const {return t == this;} // bool To(const basicForEachType * t) const { throwassert(t && this);return un_ptr_type == this ? t->un_ptr_type == this : t == this;} virtual C_F0 CastTo(const C_F0 & e) const ; virtual void SetArgs(const ListOfId *lid) const ;// { cout << "SetArgs::\n " ;throwassert(lid==0 || lid->size()==0);} aType right() const {return un_ptr_type;}; Expression RightValueExpr(Expression f) const; // Type_Expr NewVar(Key k,aType t,size_t & top,const C_F0 &i); virtual C_F0 Initialization(const Type_Expr & e) const ; virtual Expression Destroy(const C_F0 &) const ; virtual bool ExistDestroy() const {return destroy;} virtual Type_Expr SetParam(const C_F0 & c,const ListOfId * l,size_t & top) const; // { return make_pair<aType,const E_F0 *>(this,c.left());} protected: basicForEachType(const type_info & k ,const size_t , const E_F1_funcT_Type * p=0,basicForEachType *rr=0, Function1 iv=0,Function1 id=0) ;/* inline basicForEachType(const type_info & k ,const type_info & kf ,const size_t , const E_F1_funcT_Type * p=0,basicForEachType *rr=0, Function1 iv=0,Function1 id=0) ;*/public: const basicForEachType * un_ptr_type; // type of right exp private: // map<aType,CastFunc> mapofcast; OneOperator * casting; // list of operator for casting to this type const E_F1_funcT_Type * un_ptr; // is ptr -> get value function Function1 InitExp; // to init the ptr value Function1 destroy;// the destroy function TableOfIdentifier ti; // all polymorphisme of the Identifier public: // basicForEachType * FunctionType() const;// { return funct_type ? funct_type : (funct_type= new FuncForEachType(this));} C_F0 Find(const char * k) const; // {return ti->Find(k);} C_F0 Find(const char * k,const basicAC_F0 & args) const; // {return ti->Find(k);} void New(Key k,Type_Expr v,bool del=true){ti.New(k,v,del);} void Add(Key k,Key op,OneOperator *p0,OneOperator *p1=0, OneOperator *p2=0,OneOperator *p3=0,OneOperator *p4=0, OneOperator *p5=0,OneOperator *p6=0) {ti.Add(k,op,p0,p1,p2,p3,p4,p5,p6);} void AddCast(CastFunc f1,CastFunc f2=0,CastFunc f3=0,CastFunc f4=0, CastFunc f5=0,CastFunc f6=0,CastFunc f7=0,CastFunc f8=0); ostream & ShowTable(ostream & f) const { f << ti; return f;} // basicForEachType * funct_type; virtual ~basicForEachType(); };template<typename T> inline basicForEachType * atype() { map<const string,basicForEachType *>::iterator ir=map_type.find(typeid(T).name()); // basicForEachType * r=map_type[]; if (ir == map_type.end()) { cerr << "Error: aType '" << typeid(T).name() << "', doesn't exist\n"; ShowType(cerr); throw(ErrorExec("exit",1));} return ir->second;}// --------//typedef basicForEachType TheType;// const basicForEachType * ktype; // compilation time // class for all exp // a left exp is a pointer expression // -------// -- exec times le code is just E_F0*(fonction without args)class C_LF2;class C_LF1;// 3 types of function/expression 0,1,2 args class E_F0 :public CodeAlloc { public: struct kless : binary_function<Expression,Expression, bool> { bool operator()(const Expression& x, const Expression& y) const{ //cout << x << " " << y << x->compare(y) << " ::: "; int r1 = x->compare(y);// , r2 = y->compare(x); //assert(r1+r2==0); return r1<0;} }; typedef map< E_F0 *,int,kless> MapOfE_F0; virtual AnyType operator()(Stack) const =0; virtual bool Empty() const {return !this; } // virtual E_F0 * destroy(Stack ) const {return 0;} // virtual const E_F0 * Parameter(Stack ) const {return this;} virtual size_t nbitem() const {return 1;} virtual bool EvaluableWithOutStack() const {return false;} // virtual bool MeshIndependent() const {return true;} // virtual E_F0 * right_E_F0() const { return 0;} virtual bool ReadOnly() const { return true;} // the expression do not change the memory virtual ~E_F0() {} virtual int compare (const E_F0 *t) const { int r= (t==this) ? 0 : ( ( this<t) ?-1 : 1); //cout << "cmp " << typeid(*this).name() << r << endl; return r;} // to give a order in instuction virtual int Optimize(deque<pair<Expression,int> > &l,MapOfE_F0 & m, size_t & n) ; // build optimisation virtual AnyType operator()(Stack stack,AnyType *) const { return operator()(stack);} // call optim code virtual operator aType () const { assert(0);return 0;} // the type of the expression virtual ostream & dump(ostream &f) const { f << ' ' << typeid(*this).name() << ' ' << this << ' ' ;return f; } // for OPTIMIZATION int find(const MapOfE_F0 & m) ; int insert(Expression opt,deque<pair<Expression,int> > &l,MapOfE_F0 & m, size_t & n) ; // ajoute for optimisation to say if a expression in meshindep a exec time // to solve 0*x // question // juin 2007 FH virtual AnyType eval(Stack stack, bool & meshindep ) const { meshindep=MeshIndependent();return operator()(stack);} }; inline ostream & operator<<(ostream & f,const E_F0 &e) { if(&e) e.dump(f); else f << " --0-- " ;return f;}// a class E_F0mps : public E_F0 { public: virtual bool MeshIndependent() const {return false;} // };class E_F0info : public E_F0 { public: // not a real expression just to pass information virtual bool EvaluableWithOutStack() const {return true;} // virtual bool MeshIndependent() const {return true;} // virtual AnyType operator()(Stack ) const { return SetAny<const E_F0 *>(this);} operator aType () const { return atype<Expression>();} };class E_F1 : public CodeAlloc{ public: virtual AnyType operator()(Stack,AnyType &) const =0;}; class E_F2 : public CodeAlloc{ public: virtual AnyType operator()(Stack,AnyType &,AnyType &) const =0;};class E_FN : public CodeAlloc{ public: virtual AnyType operator()(Stack,size_t N,...) const =0;};// class to play with polymorphisme // ---------------------------------class basicAC_F0;class ArrayOfaType : public CodeAlloc{ // class for the type of parameter aType tt[11]; protected: int n; aType * t; // array of type bool ellipse; void operator=(const ArrayOfaType &); // no set operator public: // ArrayOfaType() :n(0),t(0),ellipse(false) {} explicit ArrayOfaType(bool ell=false) :n(0),t(0),ellipse(ell) {} explicit ArrayOfaType(const aType & a,bool ell=false) :n(1),t(tt),ellipse(ell) {t[0]=a;} explicit ArrayOfaType(const aType & a,const aType & b,bool ell=false) :n(2),t(tt),ellipse(ell) {t[0]=a,t[1]=b;} explicit ArrayOfaType(const aType & a,const aType & b,const aType & c,bool ell=false) :n(3),t(tt),ellipse(ell) {t[0]=a,t[1]=b;t[2]=c;} explicit ArrayOfaType(const aType & a,const aType & b,const aType & c,const aType & d,bool ell=false) :n(4),t(tt),ellipse(ell) {t[0]=a,t[1]=b;t[2]=c;t[3]=d; /* cout << * a << *b << * c << * d << " ---------" << endl; */} explicit ArrayOfaType(const aType & a,const aType & b,const aType & c,const aType & d,const aType & e,bool ell=false) :n(5),t(tt),ellipse(ell) {t[0]=a,t[1]=b;t[2]=c;t[3]=d; t[4]=e; } explicit ArrayOfaType(const aType & a,const aType & b,const aType & c,const aType & d,const aType & e,const aType & f,bool ell=false) :n(6),t(tt),ellipse(ell) {t[0]=a,t[1]=b;t[2]=c;t[3]=d; t[4]=e; t[5]=f; } explicit ArrayOfaType(const aType & a,const aType & b,const aType & c,const aType & d,const aType & e, const aType & f,const aType & g,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -