No OneTemporary

File Metadata

Created
Sat, Mar 14, 4:33 AM
diff --git a/config/default.json b/config/default.json
index 6b05add..1cf60ec 100644
--- a/config/default.json
+++ b/config/default.json
@@ -1,71 +1,70 @@
{
"containers": {
"id": {
"implementations": "impl_fulfill_cluster",
"clusters": "var_cluster",
"prototypes": "proto_cluster",
"linkedlist": "linkedlist"
},
"impl": {
"solid": "solid",
"onthefly": "on_the_fly"
}
},
"logging": {
"id": "logging"
},
"function-entry": "entry",
"clasp": {
"bindings" : {
"variable": "bind",
"function": "bind_func",
"scope": "bind_scope",
"function_demand" : "bind_function_demand",
"scope_decision": "bind_scope_decision"
},
"context" : {
"decisions":{
"dependent": "resolution_dependency"
},
},
"nonevalue": "nonevalue",
"ret": {
"symbol": "retv",
"tag": "ret"
}
},
"tests": {
- "template": "containers",
+ "template": "default",
"templates": {
"default": "*-",
"adhocs": "Adhoc.*",
"effects": "Effects.*",
"basic": "Attachments.*",
"ast": "AST.*",
"cfa": "CFA.*",
"dfa": "DFA.*",
"compilation": "Compilation.*",
"diagnostic": "Diagnostic.*",
"ExpressionSerializer": "ExpressionSerializer.*",
"externc": "InterfaceExternC.*",
"types": "Types.*-",
"vendorsAPI/clang": "ClangAPI.*",
"vendorsAPI/xml2": "libxml2*",
"dsl": "Interpretation.*",
"context": "Context.*",
- "containers": "Containers.ListAsArray2"
-
- "loops": "Loop.*",
+ "containers": "Containers.*",
+ "loops": "Loop.*"
}
}
}
diff --git a/core/containers.lp b/core/containers.lp
index 63b7269..16b5432 100644
--- a/core/containers.lp
+++ b/core/containers.lp
@@ -1,58 +1,44 @@
%defines
- impl(solid; on_the_fly; linked_list).
- op(seqaccess; randaccess).
+ impl(llvm_array; llvm_const_array; on_the_fly).
+ op(seqaccess). op(randaccess).
relation(recommends; satisfied; unsupported).
relation_score(satisfied, 0).
relation_score(recommends, 1).
relation_score(unsupported, -1).
score(-1..1).
%domain facts:
relation_op(seqaccess, on_the_fly, recommends).
-
- relation_op(randaccess, solid, recommends).
+ relation_op(randaccess, llvm_const_array, recommends).
relation_op(randaccess, on_the_fly, unsupported).
%dfa analysis:
-%scheme: dfa_connection(Vto, Vfrom, proto);
-%-- dfa_connection(VTo, VFrom, alias);
-%-- dfa_connection(VFormal, VActual, arg);
-%-- dfa_connection(VActual, VFormal, ret)
+% --
%compilation:
%--
%domain rules:
- %aliases:
- var_origin(VAR) :- not dfa_connection(VAR, _, alias), v(VAR).
- var_alias(VAR0, VAR_TO) :- dfa_connection(VAR_TO, VAR0, alias), var_origin(VAR0).
- var_alias(VAR0, VAR_TO2) :- dfa_connection(VAR_TO2, VAR_TO1, alias), var_alias(VAR0, VAR_TO1).
- var_alias(VAR0, VAR0):- var_origin(VAR0).
-
- %prototypes:
- var_proto(V0, Vproto) :- var_origin(V0); var_origin(Vproto); var_alias(Vproto, Vp); dfa_connection(V0, Vp, proto).
-
- %implementations:
-impl_fulfill(OP, IMPL) :- relation_op(OP, IMPL, unsupported).
impl_fulfill(OP, IMPL, SCORE):- SCORE = #sum{SCORE1, (OP, IMPL, RL): relation_op(OP, IMPL, RL),relation_score(RL, SCORE1)}
; op(OP); impl(IMPL); not -impl_fulfill(OP, IMPL).
- -var_impl_fulfill(Var0, Impl) :- var_alias(Var0, Var_Any); bind(Var_Any, op(Op)); -impl_fulfill(Op, Impl).
- var_impl_fulfill(VAR0, IMPL, Score) :-
- Score = #sum{SCORE, (OP, IMPL, VAR_ANY): impl_fulfill(OP, IMPL, SCORE), var_alias(VAR0, VAR_ANY), bind(VAR_ANY, op(OP))}
- ; bind(VAR0, impl(IMPL)); var_origin(VAR0); not -var_impl_fulfill(VAR0, IMPL).
+ cluster_root(VAR) :- not dfa_connection(VAR, _, strong), v(VAR).
+ var_cluster(VAR0, VAR_TO) :- dfa_connection(VAR_TO, VAR0, strong), cluster_root(VAR0).
+ var_cluster(VAR0, VAR_TO2) :- dfa_connection(VAR_TO2, VAR_TO1, strong), var_cluster(VAR0, VAR_TO1).
+ var_cluster(VAR0, VAR0):- cluster_root(VAR0).
- %transfunction implementation:
- %bind(Vactual, op(Op)) :- var_alias(Vformal, V1); bind(V1, op(Op)); dfa_connection(Vformal, Vactual, arg); op(Op).
+ -impl_fulfill_cluster(Var0, Impl) :- var_cluster(Var0, Var_Any); bind(Var_Any, op(Op)); -impl_fulfill(Op, Impl).
+ impl_fulfill_cluster(VAR0, IMPL, Score) :-
+ Score = #sum{SCORE, (OP, IMPL, VAR_ANY): impl_fulfill(OP, IMPL, SCORE), var_cluster(VAR0, VAR_ANY), bind(VAR_ANY, op(OP))}
+ ; bind(VAR0, impl(IMPL)); cluster_root(VAR0); not -impl_fulfill_cluster(VAR0, IMPL).
+
- %bind(Vactual, op(Op)) :- var_alias(VO, Vformal); var_alias(VO, V); bind(V, op(Op)); dfa_connection(Vactual,Vformal, ret); op(Op).
- % --uncomment to add possible implementations(impl) to an actual var
- %bind(Vres, op(Op)) :- var_alias(VO, VA); bind(VA, op(Op)); dfa_connection(VArg,VO, result); op(Op).
+ proto_cluster(V0, Vproto) :- cluster_root(V0); cluster_root(Vproto); var_cluster(Vproto, Vp); dfa_connection(V0, Vp, proto).
%optimization
-% #maximize {SCORE, (VAR0, IMPL) : var_impl_fulfill(VAR0, IMPL, SCORE)}.
+% #maximize {SCORE, (VAR0, IMPL) : impl_fulfill_cluster(VAR0, IMPL, SCORE)}.
-#show var_alias/2.
-#show var_impl_fulfill/3.
-#show proto_alias2.
+#show var_cluster/2.
+#show impl_fulfill_cluster/3.
diff --git a/cpp/src/query/containers.cpp b/cpp/src/query/containers.cpp
index d7dde42..1243cff 100644
--- a/cpp/src/query/containers.cpp
+++ b/cpp/src/query/containers.cpp
@@ -1,165 +1,165 @@
//
// Created by pgess on 3/14/15.
//
#include <clasplayer.h>
#include "query/containers.h"
using namespace std;
using namespace xreate::containers;
using namespace xreate;
Implementation
Query::queryImplementation(xreate::Symbol const &s) {
if (Attachments::exists<Implementation>(s))
{
return Attachments::get<Implementation>(s);
}
return Implementation::create(s);
}
Query::Query(){
Attachments::init<Implementation>();
}
void
Query::init(ClaspLayer* clasp)
{
if (flagIsDataLoaded) return;
map<Symbol, Symbol> prototypes;
map<Symbol, string> roots;
//read all proto data
auto range = clasp->query(Config::get("containers.id.prototypes"));
if (range)
for(ClaspLayer::ModelIterator atom = range->first; atom != range->second; ++atom) {
auto data = ClaspLayer::parse<SymbolPacked, SymbolPacked>(atom->second);
Symbol root = clasp->unpack(get<0> (data));
Symbol prototype = clasp->unpack(get<1> (data));
prototypes[root] = prototype;
}
// fill implementation data for a data sources:
range = clasp->query(Config::get("containers.id.implementations"));
if (range)
for(ClaspLayer::ModelIterator atom = range->first; atom != range->second; ++atom)
{
auto data = ClaspLayer::parse<SymbolPacked, string>(atom->second);
Symbol var = clasp->unpack(get<0>(data));
string implSerialized = get<1>(data);
//data source, has no prototypes:
if (!prototypes.count(var))
{
Implementation impl = Implementation::create(var);
Attachments::put<Implementation>(var, move(impl));
continue;
}
roots.emplace(move(var), move(implSerialized));
}
//fill implementation data for a cluster roots
for (const pair<Symbol, string> & root: roots)
{
Symbol prototype = prototypes[root.first];
while (prototypes.count(prototype)) {
prototype = prototypes.at(prototype);
}
Attachments::put<Implementation>(root.first, Implementation(Attachments::get<Implementation>(prototype)));
}
// read cluster data and fill implementation data for cluster members
range = clasp->query(Config::get("containers.id.clusters"));
if (range)
for(ClaspLayer::ModelIterator atom = range->first; atom != range->second; ++atom)
{
auto info = ClaspLayer::parse<SymbolPacked, SymbolPacked>(atom->second);
Symbol root = clasp->unpack(get<0>(info));
Symbol child = clasp->unpack(get<1>(info));
- if (!(child == root)) {
+ if (!(child == root) && (Attachments::exists<Implementation>(root))) {
Implementation rootImpl = Attachments::get<Implementation>(root);
Attachments::put<Implementation>(child, move(rootImpl));
}
}
flagIsDataLoaded = true;
}
//static ImplementationData* create(Symbol var, std::string implSerialized, const ImplementationData* implPrototype);
Implementation
Implementation::create(const Symbol &var)
{
//TODO review implementation determination strategy
Expression varDecl = CodeScope::getDeclaration(var);
switch (varDecl.op)
{
case Operator::LIST_RANGE: {
ImplementationRec<ON_THE_FLY> rec{var};
return {ON_THE_FLY, rec};
}
case Operator::LIST: {
return {SOLID, ImplementationRec<SOLID> {varDecl.getOperands().size()}};
}
default: break;
};
ImplementationLinkedList ill(var);
if (ill){
return ill.getImplementationData();
}
assert(false && "Unable to determine proper implementation for the symbol");
}
Implementation
Implementation::create(const Symbol& var, const std::string& implSerialized)
{
Expression varDecl = CodeScope::getDeclaration(var);
if (implSerialized == Config::get("containers.impl.solid"))
{
return {SOLID, ImplementationRec<SOLID>{varDecl.operands.size()}};
} else if (implSerialized == Config::get("containers.impl.onthefly")) {
return {ON_THE_FLY, ImplementationRec<ON_THE_FLY>{var}};
}
assert(false && "unable to determine proper implementation for the symbol");
}
ImplementationLinkedList::ImplementationLinkedList(const Symbol& source)
: flagIsValid(false), s(source){
const Expression& sourceExpr = CodeScope::getDeclaration(source);
if (sourceExpr.tags.count(Config::get("containers.id.linkedlist"))){
flagIsValid = true;
Expression tagLinkedlist = sourceExpr.tags.at(Config::get("containers.id.linkedlist"));
assert(tagLinkedlist.operands.size() == 2);
fieldPointer = tagLinkedlist.operands.at(0).getValueString();
terminator = tagLinkedlist.operands.at(1);
}
}
ImplementationLinkedList:: operator bool () const{
return flagIsValid;
}
Implementation
ImplementationLinkedList::getImplementationData() const {
return {ON_THE_FLY, ImplementationRec<ON_THE_FLY>{s}};
}
diff --git a/cpp/tests/adhoc.cpp b/cpp/tests/adhoc.cpp
index 80d9ec5..55b586e 100644
--- a/cpp/tests/adhoc.cpp
+++ b/cpp/tests/adhoc.cpp
@@ -1,195 +1,196 @@
/*
* adhoc-exceptions.cpp
*
* Created on: Nov 19, 2015
* Author: pgess
*/
class Adhoc_pass_Adhoc1_Test;
#define FRIENDS_ADHOC \
friend class ::Adhoc_pass_Adhoc1_Test;
#include "ast.h"
#include "passmanager.h"
#include "gtest/gtest.h"
#include <stdio.h>
#include <memory>
#include <sstream>
#include <stdlib.h>
#include "pass/adhocpass.h"
#include "pass/compilepass.h"
#include "llvmlayer.h"
using namespace xreate;
using namespace std;
TEST(Adhoc, ast_operatorAdhoc1){
PassManager* man = PassManager::prepareForCode (
"test = function:: int {\n"
" ad hoc exception(nonImplemented)\n"
"}");
Expression subject = man->root->findFunction("test")->getEntryScope()->getBody();
ASSERT_EQ(Operator::ADHOC, subject.op);
Expression exception = AdhocExpression(subject).getCommand();
ASSERT_EQ("exception", exception.getValueString());
}
TEST(Adhoc, ast_schemeAdhoc1){
PassManager* man = PassManager::prepareForCode (
"interface(adhoc){\n"
" pre function expectNoErrors:: bool {\n"
" case (Error) {false}\n"
" case (Success) {true}\n"
" }\n"
" }");
assert(man->root->__interfacesData.count(ASTInterface::Adhoc));
Expression adhocData = man->root->__interfacesData.find(ASTInterface::Adhoc)->second;
ASSERT_EQ(Operator::SWITCH, adhocData.operands[0].op);
}
TEST(Adhoc, pass_Adhoc1){
PassManager* man = PassManager::prepareForCode (
"interface(adhoc){\n"
" pre function expectNoErrors:: bool {\n"
" case (Error) {false}\n"
" case (Success) {true}\n"
" }\n"
"}\n"
"main = function::int; entry {0} \n"
);
man->runWithoutCompilation();
AdhocPass* pass = reinterpret_cast<AdhocPass* >(man->getPassById(PassId::AdhocPass));
EXPECT_TRUE(pass->__schemes.size() > 0);
AdhocScheme* scheme = pass->__schemes.begin()->second;
EXPECT_EQ("expectNoErrors", scheme->getName());
}
TEST(Adhoc, full_1){
PassManager* man = PassManager::prepareForCode (
" import raw (\"core/control-context.lp\")\n"
" interface(adhoc){\n"
" pre function expectNoErrors:: bool {\n"
" case (error) {false}\n"
" case (success) {true}\n"
" }\n"
" }\n"
" test1 = pre function {\n"
" context:: expectNoErrors."
" ad hoc success\n"
" }"
"main = function::bool;entry {\n"
" test1()\n"
" }");
bool (*main)() = (bool (*)()) man->run();
bool result = main();
ASSERT_EQ(true, result);
}
TEST(Adhoc, full_2){
PassManager* man = PassManager::prepareForCode (
" import raw (\"core/control-context.lp\")\n"
" interface(adhoc){\n"
" pre function expectNoErrors:: bool {\n"
" case (error) {false}\n"
" case (success) {true}\n"
" }\n"
" pre function expectErrors:: bool {\n"
" case (error) {true}\n"
" case (success) {false}\n"
" }\n"
" }\n"
" test1 = pre function {\n"
" context:: expectNoErrors."
" ad hoc success\n"
" }\n"
" test2 = pre function {\n"
" context:: expectErrors."
" ad hoc success\n"
" }"
"main = function::bool;entry {\n"
" test1() != test2()\n"
"}");
bool (*main)() = (bool (*)()) man->run();
bool result = main();
ASSERT_EQ(true, result);
}
//TODO adhoc type. FDecl sets wrong type in prefunc case(invalid type))
TEST(Adhoc, full_contextExpectNoErrrors){
PassManager* man = PassManager::prepareForCode (
"import raw (\"core/control-context.lp\")\n"
"interface(extern-c){\n"
" xml2 = library:: pkgconfig(\"libxml-2.0\").\n"
" \n"
" include {\n"
" xml2 = [\"stdlib.h\"]\n"
" }.\n"
"}"
"interface(adhoc){\n"
" pre function expectNoErrors:: bool {\n"
" case (error) {false}\n"
" case (success) {true}\n"
" }\n"
"}\n"
"expectErrorCode = pre function(x::int){\n"
" if (x==0)::undef {ad hoc success}\n"
" else {ad hoc error}\n"
"}\n"
"main = function::bool; entry {\n"
" context:: expectNoErrors."
" expectErrorCode(system(\"ls -la\"))\n"
"}" );
int (*main)() = (int (*)()) man->run();
ASSERT_EQ(1, main());
}
+//DEBT Implement compilation of switch adhoc
TEST(Adhoc, ast_switchAdhoc1){
PassManager* man = PassManager::prepareForCode (
"test1 = function:: bool {\n"
" x = 0. \n"
" switch ad hoc (x:: errors)\n"
" case (error) {0}\n"
" case (success) {1}\n"
"\n"
"}"
);
Expression eSwitch = man->root->findFunction("test1")->getEntryScope()->getBody();
EXPECT_EQ(Operator::SWITCH_ADHOC, eSwitch.op);
EXPECT_EQ(3, eSwitch.operands.size());
EXPECT_EQ(1, eSwitch.tags.size());
EXPECT_EQ("errors", eSwitch.tags.begin()->first);
Expression eCondition = eSwitch.getOperands()[0];
EXPECT_EQ("x", eCondition.getValueString());
}
diff --git a/cpp/tests/containers.cpp b/cpp/tests/containers.cpp
index ba9d06c..a9f3c2b 100644
--- a/cpp/tests/containers.cpp
+++ b/cpp/tests/containers.cpp
@@ -1,96 +1,109 @@
/*
* containers.cpp
*
* Created on: Jun 9, 2015
* Author: pgess
*/
#include "passmanager.h"
#include "query/containers.h"
#include "Parser.h"
#include "gtest/gtest.h"
using namespace std;
using namespace xreate;
using namespace containers;
TEST(Containers, ListAsArray){
PassManager* man = PassManager::prepareForCode(
R"Code(
main = function(x:: int):: int;entry {
a = [1, 2, 3]:: [int].
a[x]
}
)Code" );
void* mainPtr = man->run();
int (*main)(int) = (int (*)(int))mainPtr;
ASSERT_EQ(2, main(1));
delete man;
}
TEST(Containers, ListAsArray2){
PassManager* man = PassManager::prepareForCode(
R"Code(
+ // CONTAINERS
+ interface(dfa) {
+ operator map:: (op(seqaccess)) -> impl(solid).
+ operator list_range:: ()->impl(on_the_fly).
+ operator list:: ()->impl(solid).
+ operator fold:: (op(seqaccess)).
+ operator index:: (op(randaccess)).
+ }
+
+ import raw("core/containers.lp")
+
main = function:: int;entry {
+
+
a= [1, 2, 3]:: [int].
b= loop map(a->el:: int):: [int]{
2 * el
}.
sum = loop fold(b->el:: int, 0->acc):: int {
acc + el
}.
sum
}
)Code" );
void* mainPtr = man->run();
int (*main)() = (int (*)())mainPtr;
- ASSERT_EQ(0, main());
+ ASSERT_EQ(12, main());
delete man;
}
TEST(Containers, ContanierLinkedList1){
FILE* input = fopen("scripts/testspass/Containers_Implementation_LinkedList1.xreate","r");
assert(input != nullptr);
Scanner scanner(input);
Parser parser(&scanner);
parser.Parse();
AST& ast = parser.root;
CodeScope* body = ast.findFunction("test")->getEntryScope();
const Symbol symb_chilrenRaw{body->getSymbol("childrenRaw"), body};
containers::ImplementationLinkedList iLL(symb_chilrenRaw);
ASSERT_EQ(true, static_cast<bool>(iLL));
ASSERT_EQ("next", iLL.fieldPointer);
Implementation impl = Implementation::create(symb_chilrenRaw);
ASSERT_NO_FATAL_FAILURE(impl.extract<ON_THE_FLY>());
ImplementationRec<ON_THE_FLY> recOnthefly = impl.extract<ON_THE_FLY>();
ASSERT_EQ(symb_chilrenRaw, recOnthefly.source);
}
TEST(Containers, Implementation_LinkedListFull){
FILE* input = fopen("scripts/testspass/Containers_Implementation_LinkedList1.xreate","r");
assert(input != nullptr);
std::unique_ptr<PassManager> program(PassManager::prepareForCode(input));
void* mainPtr = program->run();
int (*main)() = (int (*)())(intptr_t)mainPtr;
int answer = main();
ASSERT_EQ(17, answer);
fclose(input);
}
diff --git a/scripts/testspass/Containers_Implementation_LinkedList1.xreate b/scripts/testspass/Containers_Implementation_LinkedList1.xreate
index 7a7a039..8340f56 100644
--- a/scripts/testspass/Containers_Implementation_LinkedList1.xreate
+++ b/scripts/testspass/Containers_Implementation_LinkedList1.xreate
@@ -1,47 +1,47 @@
// EXTERN INCLUDES
interface(extern-c){
xml2 = library:: pkgconfig("libxml-2.0").
include {
xml2 = ["libxml/tree.h"]
}.
}
// CONTAINERS
interface(dfa) {
operator map:: (op(seqaccess)) -> impl(solid).
operator list_range:: ()->impl(on_the_fly).
operator list:: ()->impl(solid).
operator fold:: (op(seqaccess)).
- operator index:: (op(randaccess)).
+ /* operator index:: (op(randaccess)). - BREAKS THE ANALYSIS. MAKE tree VIEWED AS COLLECTION */
/* operator map: (op(seqaccess)) -> impl(llvm_array | on_the_fly); */
}
import raw("core/containers.lp")
// PROGRAM
XmlNode = type alias {
tag:: string,
/* attrs:: [string],*/
content:: string
}.
Tree = type Tree(Leaf) [Leaf, [Tree(Leaf)]].
XmlTree = type alias Tree(XmlNode).
test= function:: num; entry {
filename = "scripts/testspass/Containers_Implementation_LinkedList1-data.xml" :: string.
docRaw = xmlParseFile(filename) :: xmlDocPtr.
tree= xmlDocGetRootElement(docRaw) :: xmlNodePtr.
childrenRaw = tree["children"]:: [xmlNodePtr]; linkedlist(next, null).
size = loop fold(childrenRaw->child:: xmlNodePtr, 0->count):: int {
count +1::int
}.
size
}

Event Timeline