ast.cpp
No OneTemporary

File Metadata

Created
Fri, Mar 13, 7:57 PM
#include "ast.h"
#include "ExternLayer.h"
#include <stdexcept>
#include <iostream>
#include <clasplayer.h>
using namespace std;
namespace xreate{
class ExpressionHints{
public:
static bool
isStringValueValid(const Expression& e){
switch (e.__state){
case Expression::INVALID:
case Expression::VARIANT:
assert(false);
case Expression::IDENT:
case Expression::STRING:
return true;
case Expression::NUMBER:
case Expression::BINDING:
return false;
case Expression::COMPOUND: {
switch (e.op){
case Operator::CALL:
case Operator::INDEX:
return true;
default: return false;
}
}
}
return false;
}
static bool
isDoubleValueValid(const Expression& e){
switch (e.__state){
case Expression::NUMBER:
return true;
case Expression::INVALID:
case Expression::VARIANT:
assert(false);
case Expression::IDENT:
case Expression::STRING:
case Expression::COMPOUND:
case Expression::BINDING:
return false;
}
return false;
}
};
class TypesResolver {
private:
const AST* ast;
std::map<std::string, TypeAnnotation> scope;
std::map<TypeAnnotation, int> signatures;
ExpandedType expandType(const TypeAnnotation &t, const std::vector<TypeAnnotation> &args = std::vector<TypeAnnotation>()){
return TypesResolver(ast, scope, signatures)(t, args);
}
std::vector<TypeAnnotation>
expandOperands(const std::vector<TypeAnnotation>& operands) {
std::vector<TypeAnnotation> pack;
pack.reserve(operands.size());
std::transform(operands.begin(), operands.end(), std::inserter(pack, pack.end()),
[this](const TypeAnnotation& t){
return expandType(t);
});
return pack;
}
public:
TypesResolver(const AST* root, const std::map<std::string, TypeAnnotation>& scopeOuter = std::map<std::string, TypeAnnotation>(),
std::map<TypeAnnotation, int> signaturesOuter = std::map<TypeAnnotation, int>())
: ast(root), scope(scopeOuter), signatures(signaturesOuter) {
}
ExpandedType
operator()(const TypeAnnotation &t, const std::vector<TypeAnnotation> &args = std::vector<TypeAnnotation>())
{
//assert(args.size() == t.bindings.size()); // invalid number of arguments
for (size_t i=0; i<args.size(); ++i)
{
scope[t.bindings.at(i)] = args.at(i);
}
switch (t.__operator)
{
case TypeOperator::ARRAY:
{
assert(t.__operands.size()==1);
Expanded<TypeAnnotation> elTy = expandType(t.__operands.at(0));
return ExpandedType(TypeAnnotation(tag_array, elTy, t.__size));
}
case TypeOperator::STRUCT:
{
assert(t.__operands.size());
std::vector<TypeAnnotation>&& pack = expandOperands(t.__operands);
auto tnew = TypeAnnotation(TypeOperator::STRUCT, move(pack));
tnew.fields = t.fields;
return ExpandedType(move(tnew));
};
case TypeOperator::CALL:
{
std::string alias = t.__valueCustom;
//find in local scope:
TypeAnnotation ty;
if (scope.count(alias)) {
ty = scope.at(alias);
} else if (ast->__indexTypeAliases.count(alias)){
ty = ast->__indexTypeAliases.at(alias);
} else {
assert(false && "Undefined or external type");
}
std::vector<TypeAnnotation>&& operands = expandOperands(t.__operands);
TypeAnnotation signature(TypeOperator::CALL, move(operands));
signature.__valueCustom = alias;
if (signatures.count(signature)) {
auto link = TypeAnnotation(TypeOperator::LINK, {});
link.conjuctionId = signatures.at(signature);
return ExpandedType(move(link));
}
int cid = signatures.size();
signatures[signature] = cid;
TypeAnnotation tyResult = expandType(ty, operands);
tyResult.conjuctionId = cid;
return ExpandedType(move(tyResult));
};
case TypeOperator::CUSTOM:
{
std::string alias = t.__valueCustom;
/*
if (signatures.count(alias)) {
return ExpandedType(TypeAnnotation(TypeOperator::LINK, {t}));
}
signatures[alias].emplace(t);
*/
//find in local scope:
if (scope.count(alias))
{
return expandType(scope.at(alias));
}
// find in general scope:
if(ast->__indexTypeAliases.count(alias)) {
return expandType(ast->__indexTypeAliases.at(t.__valueCustom));
}
//if type is unknown keep it as is.
return ExpandedType(TypeAnnotation(t));
};
case TypeOperator::ACCESS:
{
std::string alias = t.__valueCustom;
ExpandedType tyAlias= ExpandedType(TypeAnnotation());
//find in local scope:
if (scope.count(alias)) {
tyAlias = expandType(scope.at(alias));
//find in global scope:
} else if((ast->__indexTypeAliases.count(alias))) {
tyAlias = expandType(ast->__indexTypeAliases.at(alias));
} else {
assert(false && "Undefined or external type");
}
assert(tyAlias->__operator == TypeOperator::STRUCT);
for (const string& field: t.fields){
auto fieldIt = std::find(tyAlias->fields.begin(), tyAlias->fields.end(), field);
assert(fieldIt != tyAlias->fields.end() && "unknown field");
int fieldId = fieldIt - tyAlias->fields.begin();
tyAlias = expandType(tyAlias->__operands.at(fieldId));
}
return tyAlias;
}
case TypeOperator::TUPLE: {
assert(t.__operands.size());
std::vector<TypeAnnotation> pack;
pack.reserve(t.__operands.size());
std::transform(t.__operands.begin(), t.__operands.end(), std::inserter(pack, pack.end()),
[this](const TypeAnnotation& t){
return expandType(t);
});
return ExpandedType(TypeAnnotation(TypeOperator::TUPLE, move(pack)));
}
case TypeOperator::VARIANT: {
return ExpandedType(TypeAnnotation(t));
}
case TypeOperator::NONE: {
return ExpandedType(TypeAnnotation(t));
}
default:
assert(false);
}
assert(false);
return ExpandedType(TypeAnnotation());
}
};
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 (TypeOperator op, std::vector<TypeAnnotation>&& operands)
: __operator(op), __operands(operands)
{}
TypeAnnotation::TypeAnnotation (llvm_array_tag, TypeAnnotation typ, int size)
:TypeAnnotation(TypeOperator::ARRAY, {typ})
{
__size=size;
}
bool
TypeAnnotation::operator< (const TypeAnnotation& t) const{
if (__operator != t.__operator) return __operator < t.__operator;
if (__operator == TypeOperator::NONE)
return __value < t.__value;
if (__operator == TypeOperator::CALL || __operator == TypeOperator::CUSTOM || __operator == TypeOperator::ACCESS){
if (__valueCustom != t.__valueCustom)
return __valueCustom < t.__valueCustom;
}
return __operands < t.__operands;
}
/*
TypeAnnotation (struct_tag, std::initializer_list<TypeAnnotation>)
{}
*/
void
TypeAnnotation::addBindings(std::vector<Atom<Identifier_t>>&& params)
{
bindings.reserve(bindings.size() + params.size());
std::transform(params.begin(), params.end(), std::inserter(bindings, bindings.end()),
[](const Atom<Identifier_t>& ident){return ident.get(); });
}
void
TypeAnnotation::addFields(std::vector<Atom<Identifier_t>>&& listFields)
{
fields.reserve(fields.size() + listFields.size());
std::transform(listFields.begin(), listFields.end(), std::inserter(fields, fields.end()),
[](const Atom<Identifier_t>& ident){return ident.get(); });
}
Expression::Expression(const Atom<Number_t>& number)
: __state(NUMBER), op(Operator::NONE), __valueD(number.get())
{
}
Expression::Expression(const Atom<String_t>& a)
: __state(STRING), op(Operator::NONE), __valueS(a.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);
operands.insert(operands.end(), params.begin()+1, params.end());
return;
}
operands.insert(operands.end(), params.begin(), params.end());
}
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)
{
addBindings(params.begin(), params.end());
}
void
Expression::bindType(TypeAnnotation t)
{
type = move(t);
}
void
Expression::addBlock(ManagedScpPtr scope)
{
blocks.push_back(scope.operator ->());
}
const std::vector<Expression>&
Expression::getOperands() const
{
return operands;
}
double
Expression::getValueDouble() const
{
return __valueD;
}
const std::string&
Expression::getValueString() const
{
return __valueS;
}
void
Expression::setValue(const Atom<Identifier_t>&& v){
__valueS = v.get();
}
void Expression::setValueDouble(double value){
__valueD = value;
}
bool
Expression::isValid() const{
return (__state != INVALID);
}
bool
Expression::isDefined() const{
return (__state != BINDING);
}
Expression::Expression()
: __state(INVALID), op(Operator::NONE)
{}
bool
Expression::operator==(const Expression& other) const{
assert(!this->blocks.size());
assert(!other.blocks.size());
if (this->__state != other.__state) return false;
if (ExpressionHints::isStringValueValid(*this)){
if (this->__valueS != other.__valueS) return false;
}
if (ExpressionHints::isDoubleValueValid(*this)){
if (this->__valueD != other.__valueD) return false;
}
if (this->__state != Expression::COMPOUND){
return true;
}
if (this->operands.size() != other.operands.size()){
return false;
}
for (size_t i=0; i<this->operands.size(); ++i){
if (!(this->operands[i]==other.operands[i])) return false;
}
return true;
}
AST::AST()
{
}
void
AST::addInterfaceData(const ASTInterface& interface, Expression&& data ) {
__interfacesData.emplace(interface, move(data));
}
void
AST::addDFAData(Expression &&data) {
__dfadata.push_back(data);
}
void
AST::addExternData(ExternData &&data) {
__externdata.insert(__externdata.end(), data.entries.begin(), data.entries.end());
}
void
AST::add(Function* f)
{
__functions.push_back(f);
__indexFunctions.emplace(f->getName(), __functions.size()-1);
}
void
AST::add(MetaRuleAbstract *r)
{
__rules.push_back(r);
}
void
AST::add(TypeAnnotation t, Atom<Identifier_t> alias){
if (t.__operator == TypeOperator::VARIANT){
for (int i=0, size=t.fields.size(); i< size; ++i){
__dictVariants.emplace(t.fields[i], make_pair(t, i));
}
}
__indexTypeAliases.emplace(alias.get(), move(t));
}
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)
{
int count = __indexFunctions.count(name);
if (!count) {
return ManagedFnPtr::Invalid();
}
assert(count ==1);
auto range = __indexFunctions.equal_range(name);
return ManagedPtr<Function>(range.first->second, &this->__functions);
}
std::list<ManagedFnPtr>
AST::getAllFunctions() const{
const size_t size = __functions.size();
std::list<ManagedFnPtr> result;
for (size_t i=0; i<size; ++i){
result.push_back(ManagedFnPtr(i, &this->__functions));
}
return result;
}
//TASK select default specializations
std::list<ManagedFnPtr>
AST::getFunctionVariants(const std::string& name) const{
auto functions = __indexFunctions.equal_range(name);
std::list<ManagedFnPtr> result;
std::transform(functions.first, functions.second, inserter(result, result.end()),
[this](auto f){return ManagedFnPtr(f.second, &this->__functions);});
return result;
}
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);}
Expanded<TypeAnnotation>
AST::expandType(const TypeAnnotation &t) const
{
return TypesResolver(this)(t);
}
Expanded<TypeAnnotation>
AST::findType(const std::string& name){
// find in general scope:
if(__indexTypeAliases.count(name))
return expandType(__indexTypeAliases.at(name));
//if type is unknown keep it as is.
TypeAnnotation t(TypeOperator::CUSTOM, {});
t.__valueCustom = name;
return ExpandedType(move(t));
}
void
AST::recognizeVariantIdentifier(Expression& identifier){
// TODO get rid of findSymbol. Determine symbol while AST parsing. Re-find symbols not found while first pass.
// * move to codescope
// * use findSymbol to find Symbol
// * register var as alias to
// * ident __doubleValue holds VID of an alias
assert(identifier.__state == Expression::IDENT);
std::string name = identifier.getValueString();
if (__dictVariants.count(name)){
auto record = __dictVariants.at(name);
const TypeAnnotation& typ = record.first;
identifier.__state = Expression::VARIANT;
identifier.setValueDouble(record.second);
identifier.type = typ;
}
}
Function::Function(const Atom<Identifier_t>& name)
: __entry(new CodeScope(0))
{
__name = name.get();
}
void
Function::addTag(Expression&& tag, const TagModifier mod)
{
string name = tag.getValueString();
__tags.emplace(move(name), move(tag));
}
const std::map<std::string, Expression>&
Function::getTags() const
{
return __tags;
}
CodeScope*
Function::getEntryScope() const
{
return __entry;
}
void
Function::addBinding(Atom <Identifier_t>&& name, Expression&& argument)
{
__entry->addBinding(move(name), move(argument));
}
void
Function::setReturnType(const TypeAnnotation &rtyp)
{
__entry->__declarations[0].type = rtyp;
}
const std::string&
Function::getName() const
{
return __name;
}
Symbol
CodeScope::registerIdentifier(Atom <Identifier_t> &&name)
{
__identifiers.emplace(name.get(), ++__vCounter);
return {__vCounter, this};
}
void
CodeScope::addBinding(Atom <Identifier_t>&& name, Expression&& argument)
{
__bindings.push_back(name.get());
Symbol binding = registerIdentifier(move(name));
argument.__state = Expression::BINDING;
__declarations[binding.identifier] = move(argument);
}
void
CodeScope::addDeclaration(Atom <Identifier_t>&& name, Expression&& body)
{
Symbol s = registerIdentifier(move(name));
__declarations[s.identifier] = move(body);
}
CodeScope::CodeScope(CodeScope* parent)
:__parent(parent)
{}
CodeScope::~CodeScope()
{}
void
CodeScope::setBody(const Expression &body)
{
__body = body;
}
Symbol
CodeScope::findSymbol(const std::string &name)
{
//search identifier in the current block
if (__identifiers.count(name))
{
VID vId = __identifiers.at(name);
Symbol result{vId, this};
return result;
}
//search in the parent scope
if (__parent)
{
return __parent->findSymbol(name);
}
//exception: Ident not found
std::cout << "Unknown symbol: "<< name << std::endl;
assert(false && "Symbol not found");
}
const Expression&
CodeScope::findDeclaration(const Symbol& symbol)
{
CodeScope* self = symbol.scope;
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)), __message(message.get()), __condition(condition)
{}
RuleWarning::~RuleWarning(){}
void
RuleWarning::compile(ClaspLayer& layer)
{
//TODO restore addRuleWarning
//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