ast.h
No OneTemporary

File Metadata

Created
Wed, Jul 8, 8:21 AM
#ifndef AST_H
#define AST_H
#include "attachments.h"
#include <vector>
#include <stdlib.h>
#include <string>
#include <list>
#include <unordered_map>
#include <unordered_set>
#include <climits>
#include "utils.h"
#include <algorithm>
namespace llvm {
class Value;
}
namespace xreate {
struct String_t {
};
struct Identifier_t {
};
struct Number_t {
};
struct Type_t {
};
template<typename A>
class Atom {
};
//DEBT hold for all atoms/identifiers Parser::Token data, like line:col position
template<> class Atom<Identifier_t> {
public:
Atom(const std::wstring& value) {
char buffer[32];
wcstombs(buffer, value.c_str(), 32);
__value = buffer;
}
Atom(std::string && name) : __value(name) {
}
const std::string& get() const {
return __value;
}
private:
std::string __value;
};
template<> class Atom<Number_t> {
public:
Atom(wchar_t* value) {
__value = wcstol(value, 0, 10);
}
Atom(int value)
: __value(value) {
}
double get()const {
return __value;
}
private:
double __value;
};
template<> class Atom<String_t> {
public:
Atom(const std::wstring& value) {
assert(value.size());
__value = std::string(++value.begin(), --value.end());
}
const std::string& get() const {
return __value;
}
private:
std::string __value;
};
enum class TypePrimitive {
Bool, Num, Int, I32, I8, Float, String,
};
template<> class Atom<Type_t> {
public:
Atom(wchar_t* value) {
char buffer_[32];
wcstombs(buffer_, value, 32);
std::string buffer(buffer_);
if (buffer == "bool") {
__value = TypePrimitive::Bool;
} else if (buffer == "num") {
__value = TypePrimitive::Num;
} else if (buffer == "int") {
__value = TypePrimitive::Int;
} else if (buffer == "i8") {
__value = TypePrimitive::I8;
} else if (buffer == "i32") {
__value = TypePrimitive::I32;
} else if (buffer == "float") {
__value = TypePrimitive::Float;
} else if (buffer == "string") {
__value = TypePrimitive::String;
}
}
Atom() {
}
TypePrimitive get() const {
return __value;
}
private:
TypePrimitive __value;
};
typedef Atom<Type_t> TypeAtom;
enum class TypeOperator {
NONE, CALL, CUSTOM, VARIANT, ARRAY, TUPLE, STRUCT, ACCESS, LINK
};
struct llvm_array_tag {
};
struct struct_tag {
};
const llvm_array_tag tag_array = llvm_array_tag();
const struct_tag tag_struct = struct_tag();
class TypeAnnotation {
public:
TypeAnnotation();
TypeAnnotation(const Atom<Type_t>& typ);
TypeAnnotation(TypePrimitive typ);
TypeAnnotation(llvm_array_tag, TypeAnnotation typ, int size);
TypeAnnotation(TypeOperator op, std::initializer_list<TypeAnnotation> operands);
TypeAnnotation(TypeOperator op, std::vector<TypeAnnotation>&& operands);
void addBindings(std::vector<Atom<Identifier_t>>&& params);
void addFields(std::vector<Atom<Identifier_t>>&& listFields);
bool operator<(const TypeAnnotation& t) const;
// TypeAnnotation (struct_tag, std::initializer_list<TypePrimitive>);
TypeOperator __operator = TypeOperator::NONE;
std::vector<TypeAnnotation> __operands;
TypePrimitive __value;
std::string __valueCustom;
int conjuctionId = -1; //conjunction point id (relevant for recursive types)
uint64_t __size = 0;
std::vector<std::string> fields;
std::vector<std::string> bindings;
private:
};
enum class Operator {
ADD, SUB, MUL, DIV, EQU, NE, NEG, LSS, LSE, GTR, GTE, LIST, LIST_RANGE, LIST_NAMED, CALL, NONE, IMPL/* implication */, MAP, FOLD, FOLD_INF, LOOP_CONTEXT, INDEX, IF, SWITCH, SWITCH_ADHOC, CASE, CASE_DEFAULT, LOGIC_AND, ADHOC, CONTEXT_RULE, SEQUENCE
};
class Function;
class AST;
class CodeScope;
class MetaRuleAbstract;
template<class Target>
struct ManagedPtr {
static ManagedPtr<Target> Invalid() {
return ManagedPtr<Target>();
}
ManagedPtr() : __storage(0) {
}
ManagedPtr(unsigned int id, const std::vector<Target*>* storage)
: __id(id), __storage(storage) {
}
Target&
operator*() const {
assert(isValid() && "Invalid Ptr");
return *__storage->at(__id);
}
void operator=(const ManagedPtr<Target>& other) {
__id = other.__id;
__storage = other.__storage;
}
bool
operator==(const ManagedPtr<Target>& other) {
return isValid() && (__id == other.__id);
}
Target*
operator->() const noexcept {
assert(isValid() && "Invalid Ptr");
return __storage->at(__id);
}
inline bool isValid() const {
return (__storage) && (0 <= __id) && (__id < __storage->size());
}
inline operator bool() const {
return isValid();
}
ManagedPtr<Target>& operator++() {
++__id;
return *this;
}
inline unsigned int id() const {
return __id;
}
private:
unsigned int __id = 0;
const std::vector<Target*> * __storage = 0;
};
typedef ManagedPtr<Function> ManagedFnPtr;
typedef ManagedPtr<CodeScope> ManagedScpPtr;
typedef ManagedPtr<MetaRuleAbstract> ManagedRulePtr;
const ManagedScpPtr NO_SCOPE = ManagedScpPtr(UINT_MAX, 0);
//To update ExpressionHints in case of any changes
struct Expression {
friend class CodeScope;
friend class ClaspLayer;
friend class CFAPass;
friend class ExpressionHints;
Expression(const Operator &oprt, std::initializer_list<Expression> params);
Expression(const Atom<Identifier_t>& ident);
Expression(const Atom<Number_t>& number);
Expression(const Atom<String_t>& a);
Expression();
void setOp(Operator oprt);
void addArg(Expression&& arg);
void addBindings(std::initializer_list<Atom<Identifier_t>> params);
void bindType(TypeAnnotation t);
template<class InputIt>
void addBindings(InputIt paramsBegin, InputIt paramsEnd);
void addBlock(ManagedScpPtr scope);
const std::vector<Expression>& getOperands() const;
double getValueDouble() const;
void setValueDouble(double value);
const std::string& getValueString() const;
void setValue(const Atom<Identifier_t>&& v);
bool isValid() const;
bool isDefined() const;
bool operator==(const Expression& other) const;
enum {
INVALID, COMPOUND, IDENT, NUMBER, STRING, VARIANT, BINDING
} __state = INVALID;
Operator op;
std::vector<std::string> bindings;
std::map<std::string, size_t> __indexBindings;
std::vector<Expression> operands;
TypeAnnotation type;
mutable std::map<std::string, Expression> tags;
mutable Attachments tagsInternal;
std::list<CodeScope*> blocks;
private:
std::string __valueS;
double __valueD;
};
template<class InputIt>
void Expression::addBindings(InputIt paramsBegin, InputIt paramsEnd) {
size_t index = bindings.size();
std::transform(paramsBegin, paramsEnd, std::inserter(bindings, bindings.end()),
[&index, this] (const Atom<Identifier_t> atom) {
std::string key = atom.get();
this->__indexBindings[key] = index++;
return key;
});
}
typedef std::list<Expression> ExpressionList;
enum class TagModifier {
NONE, ASSERT, REQUIRE
};
enum class DomainAnnotation {
FUNCTION, VARIABLE
};
class RuleArguments : public std::vector<std::pair<std::string, DomainAnnotation>>
{
public:
void add(const Atom<Identifier_t>& name, DomainAnnotation typ);
};
class RuleGuards : public std::vector<Expression> {
public:
void add(Expression&& e);
};
class ClaspLayer;
class LLVMLayer;
class MetaRuleAbstract {
public:
MetaRuleAbstract(RuleArguments&& args, RuleGuards&& guards);
virtual ~MetaRuleAbstract();
virtual void compile(ClaspLayer& layer) = 0;
protected:
RuleArguments __args;
RuleGuards __guards;
};
class RuleWarning : public MetaRuleAbstract {
friend class ClaspLayer;
public:
RuleWarning(RuleArguments&& args, RuleGuards&& guards, Expression&& condition, Atom<String_t>&& message);
virtual void compile(ClaspLayer& layer);
~RuleWarning();
private:
std::string __message;
Expression __condition;
};
typedef unsigned int VID;
/*
class Expression: ExpressionAbstract
{
friend class CFGPass;
public:
llvm::Value* compile(LLVMLayer& l, Function* f, std::string* hintRetVar=0) const;
};
*/
typedef std::pair<Expression, TagModifier> Tag;
struct Symbol {
VID identifier;
CodeScope * scope;
};
bool operator<(const Symbol& s1, const Symbol& s2);
bool operator==(const Symbol& s1, const Symbol& s2);
class CodeScope {
friend class Function;
friend class PassManager;
public:
CodeScope(CodeScope* parent = 0);
void setBody(const Expression& body);
void addDeclaration(Atom <Identifier_t>&& name, Expression&& body);
void addBinding(Atom <Identifier_t>&& name, Expression&& argument);
Symbol findSymbol(const std::string &name);
static const Expression& findDeclaration(const Symbol& symbol);
~CodeScope();
std::vector<std::string> __bindings;
Expression __body; //TODO move __body to __declarations[0]
std::map<std::string, VID> __identifiers;
/**
* definition of return type has variable index Zero(0)
*/
//TODO move __definitions to SymbolsAttachments data
std::unordered_map<VID, Expression> __declarations;
std::vector<Expression> tags;
std::vector<Expression> contextRules;
private:
VID __vCounter = 0;
CodeScope* __parent;
Symbol registerIdentifier(Atom <Identifier_t>&& name);
};
class Function {
friend class Expression;
friend class CodeScope;
friend class AST;
public:
Function(const Atom<Identifier_t>& name);
void addBinding(Atom <Identifier_t>&& name, Expression&& argument);
void addTag(Expression&& tag, const TagModifier mod);
void setReturnType(const TypeAnnotation& rtyp);
const std::string& getName() const;
const std::map<std::string, Expression>& getTags() const;
CodeScope* getEntryScope() const;
CodeScope* __entry;
std::string __name;
bool isPrefunction = false; //SECTIONTAG adhoc Function::isPrefunction flag
Expression guardContext;
private:
std::map<std::string, Expression> __tags;
};
class ExternData;
struct ExternEntry {
std::string package;
std::vector<std::string> headers;
};
typedef Expanded<TypeAnnotation> ExpandedType;
enum ASTInterface {
CFA, DFA, Extern, Adhoc
};
struct FunctionSpecialization {
std::string guard;
size_t id;
};
struct FunctionSpecializationQuery {
std::unordered_set<std::string> context;
};
template<>
struct AttachmentsStorage<Symbol> {
static Attachments*
get(const Symbol& s) {
return &s.scope->findDeclaration(s).tagsInternal;
}
};
template<>
struct AttachmentsStorage<Expression> {
static Attachments*
get(const Expression& e) {
return &e.tagsInternal;
}
};
class AST {
public:
AST();
//TASK extern and DFA interfaces move into addInterfaceData
/**
* DFA Interface
*/
void addDFAData(Expression&& data);
/**
* Extern Interface
*/
void addExternData(ExternData&& data);
void addInterfaceData(const ASTInterface& interface, Expression&& data);
void add(Function* f);
void add(MetaRuleAbstract* r);
ManagedScpPtr add(CodeScope* scope);
std::string getModuleName();
ManagedPtr<Function> findFunction(const std::string& name);
typedef std::multimap<std::string, unsigned int> FUNCTIONS_REGISTRY;
std::list<ManagedFnPtr> getAllFunctions() const;
std::list<ManagedFnPtr> getFunctionVariants(const std::string& name) const;
template<class Target>
ManagedPtr<Target> begin();
std::vector<ExternEntry> __externdata;
std::list<Expression> __dfadata; //TODO move to more appropriate place
std::list<std::string> __rawImports; //TODO move to more appropriate place
std::multimap<ASTInterface, Expression> __interfacesData; //TODO CFA data here.
private:
std::vector<MetaRuleAbstract*> __rules;
std::vector<Function*> __functions;
std::vector<CodeScope*> __scopes;
FUNCTIONS_REGISTRY __indexFunctions;
// ***** TYPES SECTION *****
public:
std::map<std::string, TypeAnnotation> __indexTypeAliases;
ExpandedType expandType(const TypeAnnotation &t) const;
ExpandedType findType(const std::string& name);
void add(TypeAnnotation t, Atom<Identifier_t> alias);
void recognizeVariantIdentifier(Expression& identifier);
private:
std::map<std::string, std::pair<TypeAnnotation, int>> __dictVariants;
ExpandedType expandType(const TypeAnnotation &t, std::map<std::string, TypeAnnotation> scope,
const std::vector<TypeAnnotation> &args = std::vector<TypeAnnotation>()) const;
// ***** TYPES SECTION END *****
};
template<>
ManagedPtr<Function>
AST::begin<Function>();
template<>
ManagedPtr<CodeScope>
AST::begin<CodeScope>();
template<>
ManagedPtr<MetaRuleAbstract>
AST::begin<MetaRuleAbstract>();
}
#endif // AST_H

Event Timeline