ast.cpp
No OneTemporary

File Metadata

Created
Tue, Jul 7, 9:31 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 &op, std::initializer_list<Expression> params)
: __state(COMPOUND), __op(op)
{
if (op == Operator::CALL || op == Operator::INDEX)
{
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 op)
{
__op = op;
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)
{
bindings.insert(bindings.end(), params);
}
void
Expression::addBlock(CodeScope&& 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::add(Function &f)
{
__functions.push_back(f);
__indexFunctions[f.getName()] = __functions.size()-1;
}
void
AST::add(MetaRuleAbstract *r)
{
__rules.push_back(unique_ptr<MetaRuleAbstract>(r));
}
std::string
AST::getModuleName()
{
const std::string name = "moduleTest";
return name;
}
FID
AST::getFunctionsCount() const
{
return __functions.size();
}
const Function&
AST::getFunctionById(FID id)const
{
assert(id>=0 && id < __functions.size());
return __functions[id];
}
void
AST::run(LLVMLayer &l)
{
llvm::PassManager PM;
PM.add(llvm::createPrintModulePass(llvm::outs()));
PM.run(*l.module);
}
Function::Function(const Atom<Identifier_t>& name)
{
__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;
}
const CodeScope&
Function::getEntryScope() const
{
return __entry;
}
CodeScope&
Function::getEntryScope()
{
return __entry;
}
void
Function::setEntryScope(CodeScope&& scope)
{
__entry = scope;
}
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)
{
__retType = rtyp;
}
const std::string&
Function::getName() const
{
return __name;
}
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;
}
llvm::Value*
CodeScope::findSymbol(const std::string &name, LLVMLayer &l)
{
//search var in current block
if (__vartable.count(name))
{
VID vId = __vartable.at(name);
//search in already compiled vars
if (__rawVars.count(vId))
{
return __rawVars.at(vId);
}
//search in ordinary decls
if (__declarations.count(vId)){
const Expression& e = __declarations.at(vId);
llvm::Value* result = compileExpression(e, l, &name);
__rawVars[vId] = result;
return result;
}
}
//search in parent scope
if (__parent)
{
return __parent->findSymbol(name, l);
}
//exception: Ident not found
assert(false);
}
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);
}
}

Event Timeline