ast.cpp
No OneTemporary

File Metadata

Created
Thu, Jul 9, 6:02 AM
#include "ast.h"
#include <stdexcept>
#include <iostream>
#include <QString>
#include <clasplayer.h>
using namespace std;
namespace xreate{
TypeAnnotation::TypeAnnotation()
{
}
TypeAnnotation::TypeAnnotation(const Atom<Type_t> &typ)
: __value(typ.get())
{
;
}
TypeAnnotation::TypeAnnotation (TypePrimitive typ)
: __value(typ)
{}
TypeAnnotation::TypeAnnotation(TypeOperator op, std::initializer_list<TypeAnnotation> operands)
: __operator(op), __operands(operands)
{
}
TypeAnnotation::TypeAnnotation (llvm_array_tag, TypePrimitive typ, int size)
:TypeAnnotation(TypeOperator::LIST, {typ})
{
__size=size;
}
/*
TypeAnnotation (struct_tag, std::initializer_list<TypeAnnotation>)
{}
*/
llvm::Type*
TypeAnnotation::toLLVMType()
{
switch (__operator)
{
case TypeOperator::LIST:
{
assert(__operands.size());
TypeAnnotation elTy = __operands.at(0);
return llvm::ArrayType::get(elTy.toLLVMType(), __size);
}
case TypeOperator::NONE: {
switch (__value) {
case TypePrimitive::Bool:
return llvm::Type::getInt1Ty(llvm::getGlobalContext());
case TypePrimitive::Int:
case TypePrimitive::i32:
case TypePrimitive::Num:
return llvm::Type::getInt32Ty(llvm::getGlobalContext());
case TypePrimitive::Float:
return llvm::Type::getDoubleTy(llvm::getGlobalContext());
default:
assert(false);
}
}
default:
assert(false);
}
assert(false);
return nullptr;
}
Expression::Expression(const Atom<Number_t>& number)
: __state(NUMBER), op(Operator::NONE), __valueD(number.get())
{
}
Expression::Expression(const Atom<Identifier_t> &ident)
: __state(IDENT), op(Operator::NONE), __valueS(ident.get())
{
}
Expression::Expression(const Operator &oprt, std::initializer_list<Expression> params)
: __state(COMPOUND), op(oprt)
{
if (op == Operator::CALL)
{
assert(params.size() > 0);
Expression arg = *params.begin();
assert(arg.__state == Expression::IDENT);
__valueS = std::move(arg.__valueS);
return;
}
operands.insert(operands.end(), params);
}
void
Expression::setOp(Operator oprt)
{
op = oprt;
switch (op)
{
case Operator::NONE:
__state = INVALID;
break;
default:
__state = COMPOUND;
break;
}
}
void
Expression::addArg(Expression &&arg)
{
operands.push_back(arg);
}
void
Expression::addBindings(std::initializer_list<Atom<Identifier_t>> params)
{
std::transform(params.begin(), params.end(), std::inserter(bindings, bindings.end()),
[] (const Atom<Identifier_t> atom){
return atom.get();
});
}
void
Expression::addBlock(ManagedScpPtr scope)
{
blocks.push_back(scope);
}
const std::vector<Expression>&
Expression::getOperands() const
{
return operands;
}
double
Expression::getValueDouble() const
{
return __valueD;
}
const std::string&
Expression::getValueString() const
{
return __valueS;
}
Expression::Expression()
: op(Operator::NONE), __state(INVALID)
{}
AST::AST()
{
}
void
AST::addDFAData(Expression &&data) {
__dfadata.push_back(data);
}
void
AST::add(Function* f)
{
__functions.push_back(f);
__indexFunctions[f->getName()] = __functions.size()-1;
}
void
AST::add(MetaRuleAbstract *r)
{
__rules.push_back(r);
}
ManagedScpPtr
AST::add(CodeScope* scope)
{
this->__scopes.push_back(scope);
return ManagedScpPtr(this->__scopes.size()-1, &this->__scopes);
}
std::string
AST::getModuleName()
{
const std::string name = "moduleTest";
return name;
}
ManagedPtr<Function>
AST::findFunction(const std::string& name)
{
assert (__indexFunctions.count(name));
return ManagedPtr<Function>(__indexFunctions.at(name), &__functions);
}
void
AST::run(LLVMLayer &l)
{
llvm::PassManager<llvm::Module> PM;
PM.addPass(llvm::PrintModulePass(llvm::outs(), "banner"));
PM.run(*l.module);
}
template<>
ManagedPtr<Function>
AST::begin<Function>()
{return ManagedPtr<Function>(0, &this->__functions);}
template<>
ManagedPtr<CodeScope>
AST::begin<CodeScope>()
{return ManagedPtr<CodeScope>(0, &this->__scopes);}
template<>
ManagedPtr<MetaRuleAbstract>
AST::begin<MetaRuleAbstract>()
{return ManagedPtr<MetaRuleAbstract>(0, &this->__rules);}
Function::Function(const Atom<Identifier_t>& name)
: __entry(new CodeScope(0))
{
__name = name.get();
}
void
Function::addTag(Expression&& tag, const TagModifier mod)
{
__tags.emplace_back(tag, mod);
}
const std::vector<Tag>&
Function::getAnnotations() const
{
return __tags;
}
CodeScope*
Function::getEntryScope() const
{
return __entry;
}
void
CodeScope::addArg(Atom <Identifier_t>&& name, TypeAnnotation&& typ)
{
VID id = registerVar(std::move(const_cast<std::string&>(name.get())), std::move(typ));
__args.push_back(name.get());
}
;
void
Function::addArg(Atom <Identifier_t>&& name, TypeAnnotation&& typ)
{
__entry->addArg(move(name), move(typ));
}
void
Function::setReturnType(const TypeAnnotation &rtyp)
{
__entry->__definitions[0] = rtyp;
}
const std::string&
Function::getName() const
{
return __name;
}
CodeScope::CodeScope(CodeScope* parent)
:__parent(parent)
{}
CodeScope::~CodeScope()
{}
VID
CodeScope::registerVar(std::string&& name, TypeAnnotation &&typ)
{
__vartable[name] = ++__vCounter;
__definitions[__vCounter] = typ;
return __vCounter;
}
void
CodeScope::bindArg(llvm::Value* var, std::string&& name)
{
assert(__vartable.count(name));
VID id = __vartable.at(name);
__rawVars[id] = var;
}
void
CodeScope::addDeclaration(const Atom <Identifier_t> &&name, TypeAnnotation &&typ, Expression&& body)
{
VID id = registerVar(std::move(const_cast<string&>(name.get())), move(typ));
__declarations[id] = body;
}
void
CodeScope::setBody(const Expression &body)
{
__body = body;
}
TypeAnnotation&
CodeScope::findDefinition(const Symbol& symbol)
{
CodeScope* self = symbol.scope;
self->__definitions[symbol.identifier];
}
Symbol
CodeScope::findSymbol(const std::string &name, LLVMLayer &l, bool forceCompile)
{
//search var in current block
if (__vartable.count(name))
{
VID vId = __vartable.at(name);
Symbol result{vId, this};
if (!forceCompile)
{
return result;
}
//search in already compiled vars
if (__rawVars.count(vId))
{
return result;
}
if (!__declarations.count(vId)) {
//error: symbol is uncompiled scope arg
assert(false);
}
const Expression& e = __declarations.at(vId);
__rawVars[vId] = compileExpression(e, l, name);
return result;
}
//search in parent scope
if (__parent)
{
return __parent->findSymbol(name, l);
}
//exception: Ident not found
assert(false);
}
bool
CodeScope:: hasDeclaration(const Symbol& symbol)
{
CodeScope* self = symbol.scope;
return (self->__declarations.count(symbol.identifier));
}
llvm::Value*
CodeScope::compileExpression(const Symbol& s, LLVMLayer& l, std::string hintRetVar)
{
CodeScope* self = s.scope;
if (self->__rawVars.count(s.identifier))
{
return self->__rawVars[s.identifier];
}
return self->__rawVars[s.identifier] = self->compileExpression(findDeclaration(s), l, hintRetVar);
}
const Expression&
CodeScope::findDeclaration(const Symbol& symbol)
{
CodeScope* self = symbol.scope;
if (! self->__declarations.count(symbol.identifier))
{
// no declaration exists
assert(false);
}
return self->__declarations[symbol.identifier];
}
void
RuleArguments::add(const Atom<Identifier_t> &arg, DomainAnnotation typ)
{
emplace_back(arg.get(), typ);
}
void
RuleGuards::add(Expression&& e)
{
push_back(e);
}
MetaRuleAbstract::
MetaRuleAbstract(RuleArguments&& args, RuleGuards&& guards)
: __args(std::move(args)), __guards(std::move(guards))
{}
MetaRuleAbstract::~MetaRuleAbstract(){}
RuleWarning::
RuleWarning(RuleArguments&& args, RuleGuards&& guards, Expression&& condition, Atom<String_t>&& message)
: MetaRuleAbstract(std::move(args), std::move(guards)), __condition(condition), __message(message.get())
{}
RuleWarning::~RuleWarning(){}
void
RuleWarning::compile(ClaspLayer& layer)
{
layer.addRuleWarning(*this);
}
bool operator< (const Symbol& s1, const Symbol& s2)
{
return (s1.scope < s2.scope) || (s1.scope==s2.scope && s1.identifier<s2.identifier);
}
bool operator== (const Symbol& s1, const Symbol& s2)
{
return (s1.scope == s2.scope) && (s1.identifier==s2.identifier);
}
}

Event Timeline