polymorph.cpp
No OneTemporary

File Metadata

Created
Tue, Jul 7, 8:25 AM

polymorph.cpp

/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/
*
* polymorph.cpp
*
* Author: pgess <v.melnychenko@xreate.org>
* Created on October 11, 2017, 8:37 PM
*/
#include "xreatemanager.h"
#include "ast.h"
#include "transcendlayer.h"
#include "aux/latereasoning.h"
#include <list>
#include "gtest/gtest.h"
#include "query/polymorph.h"
#include "supplemental/docutils.h"
using namespace xreate;
using namespace xreate::latereasoning;
using namespace xreate::polymorph;
using namespace std;
TEST(Polymorphs, ast1) {
xreate::XreateManager* man = xreate::XreateManager::prepare(
R"CODE(
guard:: a {
test = function:: int {0}
}
guard:: b {
test = function:: int {1}
}
main = function:: int; entry { test() }
)CODE");
const std::list<ManagedFnPtr>& specs = man->root->getFunctionSpecializations("test");
ASSERT_EQ(2, specs.size());
auto itSpecs = specs.begin();
ASSERT_EQ("a", (*itSpecs)->guard.getValueString());
itSpecs++;
ASSERT_EQ("b", (*itSpecs)->guard.getValueString());
}
TEST(Polymorphs, PolymorphQuery_Static_1) {
xreate::details::tier1::XreateManager* man = xreate::details::tier1::XreateManager::prepare(
R"CODE(
import raw("scripts/dfa/polymorphism.lp").
guard:: a {
test = function:: int {0}
}
guard:: b {
test = function:: int {1}
}
main = function:: int; entry { test()::int; callguard(b); dfa_polym(ret)}
)CODE");
man->analyse();
PolymorphQuery* query = dynamic_cast<PolymorphQuery*> (man->transcend->getQuery(QueryId::PolymorphQuery));
const Expression& bodyE = man->root->findFunction("main")->getEntryScope()->getBody();
LateAnnotation decisionLA = query->get(bodyE);
ASSERT_EQ(1, decisionLA.guardedContent.size());
auto decisionOptSymb = decisionLA.select({}, man->root, man->transcend);
ASSERT_TRUE(decisionOptSymb);
decisionOptSymb->print(cout);
cout << endl;
string guard = query->getValue(*decisionOptSymb).getValueString();
ASSERT_STREQ("b", guard.c_str());
}
TEST(Polymorphs, PolymorphQuery_Late_1){
xreate::details::tier1::XreateManager* man = xreate::details::tier1::XreateManager::prepare(
R"CODE(
Late = type variant{a, b}.
main = function:: int; entry{key= a():: Late; test. key::int}
)CODE");
man->transcend->addRawScript(
R"RULE(
late(S, S, a, dfa_callguard(S, a)):-
bind(S, test).
late(S, S, b, dfa_callguard(S, b)):-
bind(S, test).
)RULE");
man->analyse();
PolymorphQuery* query = dynamic_cast<PolymorphQuery*> (man->transcend->getQuery(QueryId::PolymorphQuery));
CodeScope* scopeMain = man->root->findFunction("main")->getEntryScope();
Symbol keyS = Symbol{scopeMain->getSymbol("key"), scopeMain};
Expression keyE = scopeMain->getDefinition(keyS);
latereasoning::LateAnnotation answerLA = query->get(keyE);
Expression valueB(Operator::VARIANT, {}); valueB.setValueDouble(1);
auto answerRaw = answerLA.select({valueB}, man->root, man->transcend);
ASSERT_TRUE(answerRaw);
Expression answerE = query->getValue(*answerRaw);
ASSERT_STREQ("b", answerE.getValueString().c_str());
}
TEST(Polymorphs, PSCU_1){
auto man = details::tier1::XreateManager::prepare(R"Code(
Dom = type variant {guard1, guard2}.
guard:: guard1 {
compute = function :: int
{0}
}
guard:: guard2 {
compute = function :: int
{1}
}
test = function:: int; entry
{
xLate = guard2():: Dom.
y1= switch late (xLate:: Dom; alias(xLate)):: int
{
compute():: int; guardkey(xLate)
}.
y1
}
)Code");
man->transcend->addRawScript(R"RAW(
dom(guard1; guard2).
late(Target, Key, Variant, dfa_callguard(Target, Variant)):-
bind(Target, guardkey(Alias));
bind(Key, alias(Alias));
dom(Variant).
)RAW");
man->analyse();
int (*program)() = (int (*)())man->run();
int result = program();
ASSERT_EQ(1, result);
}
TEST(Polymorphs, Doc_FnLvlPoly_1){
string example = getDocumentationExampleById("documentation/Concepts/polymorphism.xml", "FnLvlPoly_1");
auto man = XreateManager::prepare(move(example));
ASSERT_TRUE(true);
}
TEST(Polymorphs, Doc_LatePoly_1){
string example = getDocumentationExampleById("documentation/Concepts/polymorphism.xml", "LatePoly_1");
auto man = XreateManager::prepare(move(example));
ASSERT_TRUE(true);
}

Event Timeline