Page Menu
Home
Xreate
Search
Configure Global Search
Log In
Docs
Questions
Repository
Issues
Patches
Internal API
Files
F2731297
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Subscribers
None
File Metadata
Details
File Info
Storage
Attached
Created
Sat, Mar 14, 4:33 AM
Size
20 KB
Mime Type
text/x-diff
Expires
Mon, Mar 16, 4:33 AM (1 d, 18 h)
Engine
blob
Format
Raw Data
Handle
243938
Attached To
rXR Xreate
View Options
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
Log In to Comment