#pragma once
#include "daScript/simulate/simulate.h"
#include "daScript/misc/string_writer.h"
#include "daScript/misc/vectypes.h"
#include "daScript/misc/arraytype.h"
#include "daScript/misc/rangetype.h"
#include "daScript/simulate/data_walker.h"
#include "daScript/simulate/debug_info.h"
#include "daScript/ast/compilation_errors.h"
#include "daScript/ast/ast_typedecl.h"
#include "daScript/simulate/aot_library.h"
namespace das
{
class Function;
typedef smart_ptr FunctionPtr;
struct Variable;
typedef smart_ptr VariablePtr;
class Program;
typedef smart_ptr ProgramPtr;
struct FunctionAnnotation;
typedef smart_ptr FunctionAnnotationPtr;
struct Expression;
typedef smart_ptr ExpressionPtr;
struct PassMacro;
typedef smart_ptr PassMacroPtr;
struct VariantMacro;
typedef smart_ptr VariantMacroPtr;
struct ReaderMacro;
typedef smart_ptr ReaderMacroPtr;
struct CallMacro;
typedef smart_ptr CallMacroPtr;
struct AnnotationArgumentList;
// [annotation (value,value,...,value)]
// or [annotation (key=value,key,value,...,key=value)]
struct AnnotationArgument {
Type type; // only tInt, tFloat, tBool, and tString are allowed
string name;
string sValue;
union {
bool bValue;
int iValue;
float fValue;
AnnotationArgumentList * aList; // only used during parsing
};
AnnotationArgument () : type(Type::tVoid), iValue(0) {}
//explicit copy is required to avoid copying union as float and cause FPE
AnnotationArgument (const AnnotationArgument&a)
: type(a.type), name(a.name), sValue(a.sValue), iValue(a.iValue) {}
AnnotationArgument ( const string & n, const string & s )
: type(Type::tString), name(n), sValue(s), iValue(0) {}
AnnotationArgument ( const string & n, bool b )
: type(Type::tBool), name(n), bValue(b) {}
AnnotationArgument ( const string & n, int i )
: type(Type::tInt), name(n), iValue(i) {}
AnnotationArgument ( const string & n, float f )
: type(Type::tFloat), name(n), fValue(f) {}
AnnotationArgument ( const string & n, AnnotationArgumentList * al )
: type(Type::none), name(n), aList(al) {}
};
typedef vector AnnotationArguments;
struct AnnotationArgumentList : AnnotationArguments {
const AnnotationArgument * find ( const string & name, Type type ) const;
bool getBoolOption(const string & name, bool def = false) const;
int32_t getIntOption(const string & name, int32_t def = false) const;
};
struct Annotation : BasicAnnotation {
Annotation ( const string & n, const string & cpn = "" ) : BasicAnnotation(n,cpn) {}
virtual ~Annotation() {}
virtual void seal( Module * m ) { module = m; }
virtual bool rtti_isHandledTypeAnnotation() const { return false; }
virtual bool rtti_isStructureAnnotation() const { return false; }
virtual bool rtti_isStructureTypeAnnotation() const { return false; }
virtual bool rtti_isFunctionAnnotation() const { return false; }
virtual bool rtti_isBasicStructureAnnotation() const { return false; }
string describe() const { return name; }
string getMangledName() const;
Module * module = nullptr;
};
struct AnnotationDeclaration : ptr_ref_count {
AnnotationPtr annotation;
AnnotationArgumentList arguments;
string getMangledName() const;
};
typedef smart_ptr AnnotationDeclarationPtr;
typedef vector AnnotationList;
class Enumeration : public ptr_ref_count {
public:
struct EnumEntry {
string name;
LineInfo at;
ExpressionPtr value;
};
public:
Enumeration() = default;
Enumeration( const string & na ) : name(na) {}
bool add ( const string & f, const LineInfo & at );
bool add ( const string & f, const ExpressionPtr & expr, const LineInfo & at );
bool addI ( const string & f, int64_t value, const LineInfo & at );
string describe() const { return name; }
string getMangledName() const;
int64_t find ( const string & na, int64_t def ) const;
string find ( int64_t va, const string & def ) const;
pair find ( const string & f ) const;
TypeDeclPtr makeBaseType() const;
Type getEnumType() const;
TypeDeclPtr makeEnumType() const;
public:
string name;
string cppName;
LineInfo at;
vector list;
Module * module = nullptr;
bool external = false;
Type baseType = Type::tInt;
};
class Structure : public ptr_ref_count {
public:
struct FieldDeclaration {
string name;
TypeDeclPtr type;
ExpressionPtr init;
AnnotationArgumentList annotation;
LineInfo at;
int offset = 0;
union {
struct {
bool moveSemantics : 1;
bool parentType : 1;
bool capturedConstant : 1;
bool generated : 1;
bool capturedRef : 1;
bool doNotDelete : 1;
};
uint32_t flags = 0;
};
FieldDeclaration() = default;
FieldDeclaration(const string & n, const TypeDeclPtr & t, const ExpressionPtr & i,
const AnnotationArgumentList & alist, bool ms, const LineInfo & a )
: name(n), type(t), init(i), annotation(alist), at(a) {
moveSemantics = ms;
}
};
public:
Structure() {}
Structure ( const string & n ) : name(n) {}
StructurePtr clone() const;
bool isCompatibleCast ( const Structure & castS ) const;
const FieldDeclaration * findField ( const string & name ) const;
const Structure * findFieldParent ( const string & name ) const;
int getSizeOf() const;
int getAlignOf() const;
bool canCopy() const;
bool canClone() const;
bool canMove() const;
bool canAot() const;
bool canAot( das_set & recAot ) const;
bool isNoHeapType() const;
bool isPod() const;
bool isRawPod() const;
bool isLocal( das_set & dep ) const;
bool isTemp( das_set & dep ) const;
bool isShareable ( das_set & dep ) const;
bool hasClasses( das_set & dep ) const;
string describe() const { return name; }
string getMangledName() const;
bool hasAnyInitializers() const;
public:
string name;
vector fields;
das_hash_map filedLookup;
LineInfo at;
Module * module = nullptr;
Structure * parent = nullptr;
AnnotationList annotations;
union {
struct {
bool isClass : 1;
bool genCtor : 1;
bool cppLayout : 1;
bool cppLayoutNotPod : 1;
bool generated : 1;
bool persistent : 1;
bool isLambda : 1;
};
uint32_t flags = 0;
};
};
struct Variable : ptr_ref_count {
VariablePtr clone() const;
string getMangledName() const;
bool isAccessUnused() const;
string name;
TypeDeclPtr type;
ExpressionPtr init;
ExpressionPtr source; // if its interator variable, this is where the source is
LineInfo at;
int index = -1;
uint32_t stackTop = 0;
Module * module = nullptr;
das_set useFunctions;
das_set useGlobalVariables;
uint32_t initStackSize = 0;
union {
struct {
bool init_via_move : 1;
bool init_via_clone : 1;
bool used : 1;
bool aliasCMRES : 1;
bool marked_used : 1;
bool global_shared : 1;
bool do_not_delete : 1;
bool generated : 1;
bool capture_as_ref : 1;
bool can_shadow : 1; // can shadow block or function arguments, as block argument
};
uint32_t flags = 0;
};
union {
struct {
bool access_extern : 1;
bool access_get : 1;
bool access_ref : 1;
bool access_init : 1;
bool access_pass : 1;
};
uint32_t access_flags = 0;
};
AnnotationArgumentList annotation;
};
struct VarLessPred {
__forceinline bool operator () ( const VariablePtr & a, const VariablePtr & b ) const {
if ( a==b) {
return false;
} else if ( a->name != b->name ) {
return a->name < b->name;
} else if ( a->at != b->at ) {
return a->at < b->at;
} else {
return false;
}
}
};
typedef das_safe_set safe_var_set;
struct ExprBlock;
struct ExprCallFunc;
struct FunctionAnnotation : Annotation {
FunctionAnnotation ( const string & n ) : Annotation(n) {}
virtual bool rtti_isFunctionAnnotation() const override { return true; }
virtual bool apply ( const FunctionPtr & func, ModuleGroup & libGroup,
const AnnotationArgumentList & args, string & err ) = 0;
virtual bool finalize ( const FunctionPtr & func, ModuleGroup & libGroup,
const AnnotationArgumentList & args,
const AnnotationArgumentList & progArgs, string & err ) = 0;
virtual bool apply ( ExprBlock * block, ModuleGroup & libGroup,
const AnnotationArgumentList & args, string & err ) = 0;
virtual bool finalize ( ExprBlock * block, ModuleGroup & libGroup,
const AnnotationArgumentList & args,
const AnnotationArgumentList & progArgs, string & err ) = 0;
virtual bool simulate ( Context *, SimFunction * ) { return true; }
virtual bool verifyCall ( ExprCallFunc * /*call*/, const AnnotationArgumentList & /*args*/, string & /*err*/ ) { return true; }
virtual ExpressionPtr transformCall ( ExprCallFunc * /*call*/, string & /*err*/ ) { return nullptr; }
virtual string aotName ( ExprCallFunc * call );
virtual void aotPrefix ( TextWriter &, ExprCallFunc * ) { }
virtual bool isGeneric() const { return false; }
};
struct TransformFunctionAnnotation : FunctionAnnotation {
TransformFunctionAnnotation ( const string & n ) : FunctionAnnotation(n) {}
virtual ExpressionPtr transformCall ( ExprCallFunc * /*call*/, string & /*err*/ ) override = 0;
virtual bool apply ( const FunctionPtr &, ModuleGroup &, const AnnotationArgumentList &, string & ) override {
return false;
}
virtual bool finalize ( const FunctionPtr &, ModuleGroup &, const AnnotationArgumentList &, const AnnotationArgumentList &, string & ) override {
return false;
}
virtual bool apply ( ExprBlock *, ModuleGroup &, const AnnotationArgumentList &, string & ) override {
return false;
}
virtual bool finalize ( ExprBlock *, ModuleGroup &, const AnnotationArgumentList &, const AnnotationArgumentList &, string & ) override {
return false;
}
};
struct TypeAnnotation : Annotation {
TypeAnnotation ( const string & n, const string & cpn = "" ) : Annotation(n,cpn) {}
virtual TypeAnnotationPtr clone ( const TypeAnnotationPtr & p = nullptr ) const {
DAS_ASSERTF(p, "can only clone real type %s", name.c_str());
p->name = name;
p->cppName = cppName;
return p;
}
virtual bool canAot(das_set &) const { return true; }
virtual bool canMove() const { return false; }
virtual bool canCopy() const { return false; }
virtual bool canClone() const { return false; }
virtual bool isPod() const { return false; }
virtual bool isRawPod() const { return false; }
virtual bool isRefType() const { return false; }
virtual bool isLocal() const { return false; }
virtual bool canNew() const { return false; }
virtual bool canDelete() const { return false; }
virtual bool needDelete() const { return canDelete(); }
virtual bool canDeletePtr() const { return false; }
virtual bool isIndexable ( const TypeDeclPtr & ) const { return false; }
virtual bool isIterable ( ) const { return false; }
virtual bool isShareable ( ) const { return true; }
virtual bool isSmart() const { return false; }
virtual bool canSubstitute ( TypeAnnotation * /* passType */ ) const { return false; }
virtual string getSmartAnnotationCloneFunction () const { return ""; }
virtual size_t getSizeOf() const { return sizeof(void *); }
virtual size_t getAlignOf() const { return 1; }
virtual TypeDeclPtr makeFieldType ( const string & ) const { return nullptr; }
virtual TypeDeclPtr makeSafeFieldType ( const string & ) const { return nullptr; }
virtual TypeDeclPtr makeIndexType ( const ExpressionPtr & /*src*/, const ExpressionPtr & /*idx*/ ) const { return nullptr; }
virtual TypeDeclPtr makeIteratorType ( const ExpressionPtr & /*src*/ ) const { return nullptr; }
// aot
virtual void aotPreVisitGetField ( TextWriter &, const string & ) { }
virtual void aotPreVisitGetFieldPtr ( TextWriter &, const string & ) { }
virtual void aotVisitGetField ( TextWriter & ss, const string & fieldName ) { ss