Page Menu
Home
Xreate
Search
Configure Global Search
Log In
Docs
Questions
Repository
Issues
Patches
Internal API
Files
F2718194
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
Sun, Feb 15, 5:10 PM
Size
147 KB
Mime Type
text/x-diff
Expires
Tue, Feb 17, 5:10 PM (1 d, 17 h)
Engine
blob
Format
Raw Data
Handle
237794
Attached To
rXR Xreate
View Options
diff --git a/config/default.json b/config/default.json
index d52c52a..c5f1fcf 100644
--- a/config/default.json
+++ b/config/default.json
@@ -1,74 +1,75 @@
{
"containers": {
"id": {
"implementations": "containers_impl",
"linkedlist": "linkedlist"
},
"impl": {
"solid": "solid",
"onthefly": "onthefly"
}
},
"logging": {
"id": "logging"
},
"function-entry": "entry",
"transcend": {
"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": "default",
"templates": {
"troubleshooting":"*",
"documentation":"Modules.Doc_*:Modules_API.Doc_*:Interpretation.Doc_*:AST.Doc_*:Loop.Doc_*:LateReasoning.Doc_*:Latex.Doc_*:Polymorphs.Doc_*:Transcend.Doc_*:ASTCorrespondence.Doc_*:Virtualization.Doc_*:Exploitation.Doc_*:Communication.Doc_*:Introduction.*",
"default": "*",
+ "universal": "Universal.*",
"ast": "AST.*",
"effects": "Effects.*",
"basic": "Attachments.*",
"compilation": "Compilation.*",
"communication": "Communication.*",
"cfa": "CFA.*",
"containers": "Containers.*",
"dfa": "DFA.*",
"diagnostic": "Diagnostic.*",
"dsl": "Association.*:Interpretation.*",
"exploitation": "Exploitation.*",
"ExpressionSerializer": "ExpressionSerializer.*",
"externc": "InterfaceExternC.*",
"loops": "Loop.*",
"latereasoning": "LateReasoning.*",
"latex": "Latex.*",
"modules": "Modules.*",
"polymorphs": "Polymorphs.*",
"intrinsic-query": "Types.SlaveTypes*:Association.TypedQuery*",
"types": "Types.*",
"virtualization": "Virtualization.*",
"vendorsAPI/clang": "ClangAPI.*",
"vendorsAPI/xml2": "libxml2.*"
}
}
}
diff --git a/cpp/src/CMakeLists.txt b/cpp/src/CMakeLists.txt
index 44d1d1c..ff23a2c 100644
--- a/cpp/src/CMakeLists.txt
+++ b/cpp/src/CMakeLists.txt
@@ -1,238 +1,247 @@
cmake_minimum_required(VERSION 2.8.11)
project(xreate)
cmake_policy(SET CMP0022 NEW)
message("MODULES" ${CMAKE_MODULE_PATH})
# LLVM
#======================
FIND_PACKAGE (LLVM REQUIRED)
set(LLVM_VERSION ${LLVM_VERSION_MAJOR}.${LLVM_VERSION_MINOR})
message(STATUS "Found LLVM ${LLVM_PACKAGE_VERSION}")
message("LLVM LIB PATH:" ${LLVM_LIBRARY_DIRS})
message(STATUS "Using LLVMConfig.cmake in: ${LLVM_DIR}")
INCLUDE_DIRECTORIES(${LLVM_INCLUDE_DIRS})
message(STATUS "INCLUDE DIR: ${LLVM_INCLUDE_DIRS}")
add_definitions(${LLVM_DEFINITIONS})
message(STATUS "LLVM DEFS: " ${LLVM_DEFINITIONS})
execute_process(
COMMAND llvm-config --libs
OUTPUT_VARIABLE LLVM_LIBS
OUTPUT_STRIP_TRAILING_WHITESPACE)
message(STATUS "LLVM LIBS: " ${LLVM_LIBS})
# CLANG
#======================
set(CLANG_LIBS
clangCodeGen
clangASTMatchers
clangQuery
clangTooling
clangFrontend
clangSerialization
clangDriver
clangParse
clangSema
clangAnalysis
clangAST
clangEdit
clangLex
clangBasic
)
# POTASSCO
#======================
set(CLINGO_PATH "/opt/potassco/clingo" CACHE PATH "Path to potassco sources")
set(POTASSCO_INCLUDE_PATH
${CLINGO_PATH}/libgringo
${CLINGO_PATH}/libclasp
${CLINGO_PATH}/libclingo
${CLINGO_PATH}/libprogram_opts
${CLINGO_PATH}/liblp
)
INCLUDE_DIRECTORIES(${POTASSCO_INCLUDE_PATH})
set(LIBCLASP_LIBS
clingo
clasp
gringo
program_opts
reify
lp
)
message("CLASP LIBS: " ${LIBCLASP_LIBS})
# OTHER DEPENDENCIES
#===========================
set(JEAYESON_INCLUDE_PATH
${CMAKE_HOME_DIRECTORY}/../vendors/jeayeson/include/
)
INCLUDE_DIRECTORIES(${JEAYESON_INCLUDE_PATH})
# COCO
#===========================
set(COCO_EXECUTABLE "" CACHE PATH "Path to coco executable")
set(COCO_FRAMES_PATH "" CACHE PATH "Path to coco frames")
set(COCO_GRAMMAR_PATH ${CMAKE_HOME_DIRECTORY}/../grammar/)
set(COCO_SOURCE_FILES_MAIN
${COCO_GRAMMAR_PATH}/main/Parser.cpp
${COCO_GRAMMAR_PATH}/main/Scanner.cpp
)
set(COCO_SOURCE_FILES_MODULES
${COCO_GRAMMAR_PATH}/modules/Parser.cpp
${COCO_GRAMMAR_PATH}/modules/Scanner.cpp
)
-set(COCO_SOURCE_FILES ${COCO_SOURCE_FILES_MODULES} ${COCO_SOURCE_FILES_MAIN})
+set(COCO_SOURCE_FILES_UNIVERSAL
+ ${COCO_GRAMMAR_PATH}/universal/Parser.cpp
+ ${COCO_GRAMMAR_PATH}/universal/Scanner.cpp
+)
+
+set(COCO_SOURCE_FILES
+ ${COCO_SOURCE_FILES_MODULES}
+ ${COCO_SOURCE_FILES_MAIN}
+ ${COCO_SOURCE_FILES_UNIVERSAL}
+)
INCLUDE_DIRECTORIES(${COCO_GRAMMAR_PATH})
add_custom_command(OUTPUT ${COCO_SOURCE_FILES_MAIN}
COMMAND ${COCO_GRAMMAR_PATH}/gen-grammar main ${COCO_EXECUTABLE} ${COCO_FRAMES_PATH}
WORKING_DIRECTORY ${COCO_GRAMMAR_PATH}
MAIN_DEPENDENCY ${COCO_GRAMMAR_PATH}/xreate.ATG
)
add_custom_command(OUTPUT ${COCO_SOURCE_FILES_MODULES}
COMMAND ${COCO_GRAMMAR_PATH}/gen-grammar modules ${COCO_EXECUTABLE} ${COCO_FRAMES_PATH}
WORKING_DIRECTORY ${COCO_GRAMMAR_PATH}
MAIN_DEPENDENCY ${COCO_GRAMMAR_PATH}/modules.ATG
)
message(STATUS "COCO GRAMMAR BUILD STATUS:" ${COCO_OUTPUT})
# XREATE
#======================
set(SOURCE_FILES
analysis/temporalseqgraph.cpp
pass/cfatemporalseqpass.cpp
analysis/cfagraph.cpp
pass/cfapass.cpp
modules.cpp
compilation/interpretation-instructions.cpp
ExternLayer.cpp
analysis/cfagraph.cpp
compilation/latetranscend.cpp
analysis/interpretation.cpp
query/latex.cpp
query/polymorph.cpp
compilation/polymorph.cpp
aux/latereasoning.cpp
compilation/latex.cpp
analysis/typeinference.cpp
xreatemanager.cpp
transcendlayer.cpp
analysis/dfagraph.cpp
llvmlayer.cpp
pass/compilepass.cpp
analysis/utils.cpp
pass/dfapass.cpp
compilation/targetinterpretation.cpp
pass/interpretationpass.cpp
ast.cpp
aux/xreatemanager-decorators.cpp
compilation/operators.cpp
compilation/transformations.cpp
compilation/transformersaturation.cpp
pass/versionspass.cpp
attachments.cpp
compilation/containers.cpp
compilation/advancedinstructions.cpp
utils.cpp
pass/abstractpass.cpp
contextrule.cpp
query/containers.cpp
aux/serialization/expressionserializer.cpp
)
set(XREATE_INCLUDE_DIRS
${CMAKE_CURRENT_SOURCE_DIR}/
)
INCLUDE_DIRECTORIES(${XREATE_INCLUDE_DIRS})
set(XREATE_PRIVATE_INCLUDE_DIRS
${XREATE_INCLUDE_DIRS}
${COCO_GRAMMAR_PATH}
${JEAYESON_INCLUDE_PATH}
${LLVM_INCLUDE_DIRS}
${POTASSCO_INCLUDE_PATH}
)
add_library(${PROJECT_NAME} SHARED ${COCO_SOURCE_FILES} ${SOURCE_FILES})
target_link_libraries(${PROJECT_NAME})
target_include_directories(${PROJECT_NAME} INTERFACE
${XREATE_INCLUDE_DIRS}
${COCO_GRAMMAR_PATH}
${JEAYESON_INCLUDE_PATH}
${LLVM_INCLUDE_DIRS}
${POTASSCO_INCLUDE_PATH}
)
get_directory_property(DEFINITIONS_ALL DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} COMPILE_DEFINITIONS)
message("definitions all: " ${DEFINITIONS_ALL})
target_compile_definitions(${PROJECT_NAME} INTERFACE ${DEFINITIONS_ALL})
get_directory_property(COMPILATION_OPTIONS_ALL DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} COMPILE_OPTIONS)
message("compilations all: " ${COMPILATION_OPTIONS_ALL})
target_compile_options(${PROJECT_NAME} INTERFACE ${COMPILATION_OPTIONS_ALL})
SET_PROPERTY(TARGET ${PROJECT_NAME} PROPERTY
INTERFACE_LINK_LIBRARIES ${LIBCLASP_LIBS} ${CLANG_LIBS} ${LLVM_LIBS} tbb boost_system boost_filesystem
)
#${CLANG_LIBS}
#set (LINK_INTERFACE_LIBRARIES "")
# FUNCTION(PREPEND var prefix)
# SET(listVar "")
# FOREACH(f ${ARGN})
# LIST(APPEND listVar "${prefix}/${f}")
# ENDFOREACH(f)
# SET(${var} "${listVar}" PARENT_SCOPE)
# ENDFUNCTION(PREPEND)
#set(COTIRE_UNITY_SOURCE_MAXIMUM_NUMBER_OF_INCLUDES "-j4")
#cotire(xreate)
# MACRO (ADD_PCH_RULE _header_filename _src_list)
# SET(_gch_filename "${_header_filename}.gch")
# LIST(APPEND ${_src_list} ${_gch_filename})
# SET (_args ${CMAKE_CXX_FLAGS})
# LIST(APPEND _args -c ${_header_filename} -o ${_gch_filename})
# GET_DIRECTORY_PROPERTY(DIRINC INCLUDE_DIRECTORIES)
# foreach (_inc ${DIRINC})
# LIST(APPEND _args "-I" ${_inc})
# endforeach(_inc ${DIRINC})
# SEPARATE_ARGUMENTS(_args)
# add_custom_command(OUTPUT ${_gch_filename}
# COMMAND rm -f ${_gch_filename}
# COMMAND ${CMAKE_CXX_COMPILER} ${CMAKE_CXX_COMPILER_ARG1} ${_args}
# DEPENDS ${_header_filename})
# ENDMACRO(ADD_PCH_RULE _header_filename _src_list)
# ADD_PCH_RULE (${CMAKE_HOME_DIRECTORY}/src/ast.h SOURCE_FILES)
# ADD_PCH_RULE (${CMAKE_HOME_DIRECTORY}/src/llvmlayer.h SOURCE_FILES)
# ADD_PCH_RULE (${CMAKE_HOME_DIRECTORY}/src/clasplayer.h SOURCE_FILES)
# ADD_PCH_RULE (${CMAKE_HOME_DIRECTORY}/src/pass/abstractpass.h SOURCE_FILES)
diff --git a/cpp/src/analysis/cfagraph.cpp b/cpp/src/analysis/cfagraph.cpp
index 17639e3..2e24ca2 100644
--- a/cpp/src/analysis/cfagraph.cpp
+++ b/cpp/src/analysis/cfagraph.cpp
@@ -1,191 +1,181 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* File: CFAGraph.cpp
* Author: pgess <v.melnychenko@xreate.org>
*
* Created on June 27, 2016, 2:09 PM
*/
/**
* \file cfagraph.h
* \brief Control Flow Analysis(CFA) graph representation
*/
#include "analysis/cfagraph.h"
#include "analysis/utils.h"
using namespace xreate::cfa;
using namespace std;
void
CFAGraph::print(std::ostringstream& output) const {
const std::string& atomBinding = Config::get("transcend.bindings.function");
const std::string& atomBindingScope = Config::get("transcend.bindings.scope");
output << endl << "%\t\tStatic analysis: CFA" << endl;
output << __outputPrecomputed.str();
//show function tags
int counterTags = 0;
- std::ostringstream bufFunctionNames;
- boost::format formatFunction("function(%1%).");
- boost::format formatBind(atomBinding + "(%1%, %2%).");
+ boost::format formatFunction("function(\"%1%\").");
+ boost::format formatBind(atomBinding + "(\"%1%\", %2%).");
for (auto function : this->__fnNodes.left) {
const auto tags = this->__fnTags.equal_range(function.first);
- if (tags.first == tags.second) {
- //no tags
- bufFunctionNames << "; " << function.second ;
- continue;
- }
-
output << formatFunction % (function.second) << std::endl;
+
for (const auto& tag_ : boost::make_iterator_range(tags)) {
const Expression& tag = tag_.second;
list<string> tagRaw = xreate::analysis::compile(tag);
assert(tagRaw.size() == 1);
output << formatBind
% (function.second)
% (tagRaw.front())
<< endl;
++counterTags;
}
}
- if (bufFunctionNames.tellp()) {
- output << formatFunction % (bufFunctionNames.str().substr(2)) << std::endl;
- }
-
if (counterTags == 0) {
output << "%no function tags at all" << endl;
}
//declare scopes
boost::format formatScope("scope(0..%1%).");
output << formatScope % (__transcend->getScopesCount() - 1) << std::endl;
//show context rules:
for (auto rule : this->__contextRules) {
output << ContextRule(rule.second).compile(rule.first) << std::endl;
};
//show scope tags:
counterTags = 0;
boost::format formatScopeBind(atomBindingScope + "(%1%, %2%, strong).");
for (auto entry : this->__scopeTags) {
ScopePacked scopeId = entry.first;
const Expression& tag = entry.second;
list<string> tagRaw = xreate::analysis::compile(tag);
assert(tagRaw.size() == 1);
output << formatScopeBind % scopeId % (tagRaw.front()) << endl;
++counterTags;
}
if (counterTags == 0) {
output << "%scope tags: no tags at all" << endl;
}
//parent connections
//TOTEST CFG parent function
- boost::format formatFunctionParent("cfa_parent(%1%, function(%2%)).");
+ boost::format formatFunctionParent("cfa_parent(%1%, function(\"%2%\")).");
for (const auto &relation : this->__parentFnRelation) {
const string& function = this->__fnNodes.left.at(relation.right);
output << formatFunctionParent % relation.left % function << endl;
}
//TOTEST CFG parent scope
boost::format formatScopeParent("cfa_parent(%1%, scope(%2%)).");
for (const auto &relation : this->__parentScopeRelation) {
output << formatScopeParent % relation.first % relation.second << endl;
}
//call connections
- boost::format formatCall("cfa_call(%1%, %2%).");
+ boost::format formatCall("cfa_call(%1%, \"%2%\").");
for (const auto &relation : this->__callRelations) {
const ScopePacked scopeFrom = relation.left;
const string& functionTo = this->__fnNodes.left.at(relation.right);
output << formatCall % (scopeFrom) % (functionTo) << endl;
}
//function specializations description
- boost::format formatSpecializations("cfa_function_specializations(%1%, %2%).");
+ boost::format formatSpecializations("cfa_function_specializations(\"%1%\", %2%).");
const list<ManagedFnPtr>& functions = __transcend->ast->getAllFunctions();
for (auto f : functions) {
if (f->guard.isValid()) {
list<string> guardRaw = xreate::analysis::compile(f->guard);
assert(guardRaw.size() == 1);
output << formatSpecializations % (f->getName()) % (guardRaw.front()) << endl;
}
}
}
void
CFAGraph::addFunctionAnnotations(const std::string& fn, const std::map<std::string, Expression>& tags) {
unsigned int fid = registerNodeFunction(fn);
for (auto& tag : tags) {
__fnTags.emplace(fid, tag.second);
}
}
void
CFAGraph::addScopeAnnotations(const ScopePacked& scope, const std::vector<Expression>& tags) {
for (Expression tag : tags) {
__scopeTags.emplace(scope, tag);
}
}
void
CFAGraph::addContextRules(const ScopePacked& scope, const std::vector<Expression>& rules) {
for (Expression rule : rules) {
__contextRules.emplace(scope, rule);
}
}
void
CFAGraph::addCallConnection(const ScopePacked& callerScope, const std::string& calleeFn) {
unsigned int idFuncTo = registerNodeFunction(calleeFn);
__callRelations.insert(CALL_RELATIONS::value_type(callerScope, idFuncTo));
}
void
CFAGraph::addParentConnection(const ScopePacked& scopeEntry, const std::string& fnParent) {
__parentFnRelation.insert(PARENT_FUNCTION_RELATIONS::value_type(scopeEntry, registerNodeFunction(fnParent)));
}
void
CFAGraph::addParentConnection(const ScopePacked& scopeChild, const ScopePacked& scopeParent) {
__parentScopeRelation.emplace(scopeChild, scopeParent);
}
unsigned int
CFAGraph::registerNodeFunction(const std::string& fname) {
auto pos = __fnNodes.left.insert(make_pair(__fnNodes.size(), fname));
return pos.first->first;
}
void
CFAGraph::addScope(CodeScope* scope) {
boost::format formatScopeBinding("ast_scope_binding(%1%, %2%, \"%3%\").");
ScopePacked scopeId = __transcend->pack(scope);
__scopesCount = max(scopeId + 1, __scopesCount);
for (int id = 0, size = scope->__bindings.size(); id < size; ++id) {
__outputPrecomputed << formatScopeBinding
% scopeId
% id
% scope->__bindings.at(id)
<< endl;
}
}
diff --git a/cpp/src/analysis/dfagraph.cpp b/cpp/src/analysis/dfagraph.cpp
index 7eebd53..2ced918 100644
--- a/cpp/src/analysis/dfagraph.cpp
+++ b/cpp/src/analysis/dfagraph.cpp
@@ -1,244 +1,244 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* File: DFAGraph.h
* Author: pgess <v.melnychenko@xreate.org>
*
*/
/**
* \file dfagraph.h
* \brief Data Flow Analysis(DFA) graph representation
*
*/
#include "analysis/dfagraph.h"
#include "analysis/utils.h"
using namespace std;
using namespace xreate::analysis;
namespace xreate { namespace dfa {
void
DFACallInstance::print(std::ostringstream& output) const{
boost::format formatArgs;
- boost::format formatInstance("dfa_callfn(%1%, %2%).");
+ boost::format formatInstance("dfa_callfn(%1%, \"%2%\").");
switch (type) {
case WEAK:
formatArgs = boost::format("weak(dfa_callargs(%1%, %2%, %3%)).");
break;
case STRONG:
formatArgs = boost::format("weak(dfa_callargs(%1%, %2%, %3%)).\ndfa_callargs(%1%, %2%, %3%).");
break;
}
output << formatInstance
% analysis::writeSymbolNode(retActual)
% fnName
<< endl;
for(std::pair<SymbolPacked, SymbolNode> rec: args) {
SymbolNode argFormal(rec.first);
output << formatArgs
% analysis::writeSymbolNode(retActual)
% analysis::writeSymbolNode(argFormal)
% analysis::writeSymbolNode(rec.second)
<< endl;
}
}
void
DFAGraph::addDependency(const SymbolNode& node, const SymbolNode& subnode){
__dependencies.emplace(node, subnode);
if (boost::get<SymbolPacked>(&node)){
__usedSymbols.insert(node);
}
if (boost::get<SymbolPacked>(&subnode)){
__usedSymbols.insert(node);
}
}
void
DFAGraph::printDependencies(std::ostringstream& output) const{
for(const SymbolNode& root: __roots){
printDependency(output, root, root);
}
}
void
DFAGraph::printDependency(std::ostringstream& output, const SymbolNode& nodeCurrent, const SymbolNode& nodeDependent) const {
auto range = __dependencies.equal_range(nodeCurrent);
for (auto it = range.first; it != range.second; ++it){
if (boost::get<SymbolAnonymous>(&it->second)){
if (!__usedSymbols.count(it->second)){
printDependency(output, it->second, nodeDependent);
continue;
}
}
boost::format formatDependency("dfa_depends(%1%, %2%).");
output << formatDependency
% analysis::writeSymbolNode(nodeDependent)
% analysis::writeSymbolNode(it->second)
<< endl;
printDependency(output, it->second, it->second);
}
}
void
DFAGraph::printInplaceAnnotation(const SymbolNode& node, const Expression& expression) {
// write down in-place expression tags:
boost::format formatBind("bind(%1%, %2%).");
__usedSymbols.insert(node);
for (const string& tag: xreate::analysis::compile(expression)) {
__output << formatBind
% analysis::writeSymbolNode(node)
% tag
<< endl;
}
}
void
DFAGraph::printLateAnnotation(const SymbolNode& node,
const Expression& expression,
const std::list<latereasoning::LateParameter>& symbols,
const std::list<std::string>& domains){
boost::format formatLateAnnotation("late(%1%, (%2%), (%3%), %4%):- %5%.");
boost::format formatDom("%1%(%2%)");
std::list<std::string> exprSerialized = xreate::analysis::compile(expression);
assert(exprSerialized.size() == 1);
list<string> identSymbols, identNames, domainsSerialised;
auto domainI = domains.begin();
for(auto symbol: symbols){
identSymbols.push_back(analysis::writeSymbolNode(symbol.second).str());
identNames.push_back(symbol.first);
domainsSerialised.push_back((formatDom % *domainI % symbol.first).str());
++domainI;
}
__output << formatLateAnnotation
% analysis::writeSymbolNode(node)
% boost::algorithm::join(identSymbols, ", ")
% boost::algorithm::join(identNames, ", ")
% exprSerialized.front()
% boost::algorithm::join(domainsSerialised, "; ")
<< endl;
}
void
DFAGraph::printAlias(const SymbolNode& symbFormal, const SymbolNode& symbActual){
__usedSymbols.insert(symbFormal); __usedSymbols.insert(symbActual);
boost::format formatAlias("dfa_alias(%1%, %2%).");
__output << formatAlias
% analysis::writeSymbolNode(symbFormal)
% analysis::writeSymbolNode(symbActual)
<< endl;
}
void
DFAGraph::printWeakAlias(const SymbolNode& symbFormal, const SymbolNode& symbActual){
__usedSymbols.insert(symbFormal); __usedSymbols.insert(symbActual);
boost::format formatAlias("weak(dfa_alias(%1%, %2%)).");
__output << formatAlias
% analysis::writeSymbolNode(symbFormal)
% analysis::writeSymbolNode(symbActual)
<< endl;
}
void
DFAGraph::printFunctionRet(ManagedFnPtr function, const SymbolNode& symbolRet){
- boost::format formatRet("dfa_fnret(%1%, %2%).");
+ boost::format formatRet("dfa_fnret(\"%1%\", %2%).");
__usedSymbols.insert(symbolRet);
__output << formatRet
% function->getName()
% analysis::writeSymbolNode(symbolRet)
<< endl;
__roots.insert(symbolRet);
}
void
DFAGraph::addCallInstance(DFACallInstance&& instance){
__usedSymbols.insert(instance.retActual);
for(const auto arg: instance.args){
__usedSymbols.insert(SymbolNode(arg.first));
__usedSymbols.insert(arg.second);
}
__callInstances.push_back(std::move(instance));
}
void
DFAGraph::print(std::ostringstream& output) const{
output << endl << "%\t\tStatic analysis: DFA" << endl;
//Dependencies
printDependencies(output);
//Add generated report
output << __output.str() << endl;
//Call instances
for(const DFACallInstance& instance: __callInstances){
instance.print(output);
}
output << endl;
}
void
DFAGraph::printSymbols(TranscendLayer* transcend){
boost::format formatHint("shint(%1%, \"%2%\").");
for (const SymbolNode& node : __usedSymbols) {
__output << "v(" << analysis::writeSymbolNode(node) << "). ";
if (const SymbolPacked* symbol = boost::get<SymbolPacked>(&node)){
__output << formatHint % analysis::writeSymbolNode(node) % transcend->getHintForPackedSymbol(*symbol);
}
__output << endl;
}
}
void
DFAGraph::printOperator(Operator op, std::list<SymbolNode>&& operands, int dataOpListSize){
std::string opStr;
switch(op){
case Operator::MAP: opStr = "map"; break;
case Operator::FOLD: opStr = "fold"; break;
case Operator::LIST: opStr = "list"; break;
case Operator::LIST_RANGE: opStr = "list_range"; break;
case Operator::INDEX: opStr = "index"; break;
default: assert(false);
}
std::ostringstream bufOperands;
for(const SymbolNode& operand: operands){
__usedSymbols.insert(operand);
bufOperands << analysis::writeSymbolNode(operand) << ", ";
}
if(op == Operator::LIST){
bufOperands << dataOpListSize << ", ";
}
boost::format formatOperator("ast_op_%1%(%2%).");
__output << (formatOperator % opStr % bufOperands.str().substr(0, bufOperands.str().size() - 2)) << endl;
}
}} //end of namespace xreate::dfa
diff --git a/cpp/src/aux/universal.h b/cpp/src/aux/universal.h
new file mode 100644
index 0000000..6468eae
--- /dev/null
+++ b/cpp/src/aux/universal.h
@@ -0,0 +1,15 @@
+#include <iostream>
+#include "utils.h"
+#include <cwchar>
+#include <cstdlib>
+#include <cstdio>
+
+#define wprintf(format, ...) \
+ char __buffer[100]; \
+ wcstombs(__buffer, format, 100); \
+ fprintf(stderr, __buffer, __VA_ARGS__)
+
+void
+send(const std::wstring& message){
+ std::cout << wstring_to_utf8(message) << std::endl;
+}
\ No newline at end of file
diff --git a/cpp/src/aux/xreatemanager-decorators.cpp b/cpp/src/aux/xreatemanager-decorators.cpp
index 2b4038d..37ec862 100644
--- a/cpp/src/aux/xreatemanager-decorators.cpp
+++ b/cpp/src/aux/xreatemanager-decorators.cpp
@@ -1,77 +1,77 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* xreatemanager-decorators.cpp
*
* Author: pgess <v.melnychenko@xreate.org>
* Created on July 16, 2017, 4:40 PM
*/
/**
* \file xreatemanager-decorators.h
* \brief \ref xreate::XreateManager decorators to provide various functionality
*/
#include "aux/xreatemanager-decorators.h"
#include "main/Parser.h"
#include "pass/compilepass.h"
#include "pass/cfapass.h"
#include "pass/dfapass.h"
#include "pass/interpretationpass.h"
#include "pass/versionspass.h"
#include "pass/cfatemporalseqpass.h"
namespace xreate{
void
XreateManagerDecoratorBase::initPasses() { }
void
XreateManagerDecoratorBase::prepareCode(std::string&& code) {
- grammar::main::Scanner scanner(reinterpret_cast<const unsigned char*> (code.c_str()), code.size());
- grammar::main::Parser parser(&scanner);
- parser.Parse();
- assert(!parser.errors->count && "Parser errors");
+ grammar::main::Scanner scanner(reinterpret_cast<const unsigned char*> (code.c_str()), code.size());
+ grammar::main::Parser parser(&scanner);
+ parser.Parse();
+ assert(!parser.errors->count && "Parser errors");
- PassManager::prepare(parser.root->finalize());
+ PassManager::prepare(parser.root->finalize());
}
void
-XreateManagerDecoratorBase::prepareCode(FILE* code) {
- grammar::main::Scanner scanner(code);
- grammar::main::Parser parser(&scanner);
- parser.Parse();
- assert(!parser.errors->count && "Parser errors");
+XreateManagerDecoratorBase::prepareCode(FILE* code){
+ grammar::main::Scanner scanner(code);
+ grammar::main::Parser parser(&scanner);
+ parser.Parse();
+ assert(!parser.errors->count && "Parser errors");
- PassManager::prepare(parser.root->finalize());
+ PassManager::prepare(parser.root->finalize());
}
void
XreateManagerDecoratorBase::analyse() {
CompilePass::prepareQueries(transcend);
transcend->run();
}
void
XreateManagerDecoratorFull::initPasses() {
cfa::CFAPass* passCFG = new cfa::CFAPass(this);
registerPass(new dfa::DFAPass(this), PassId::DFAPass);
registerPass(passCFG, PassId::CFAPass);
registerPass(new interpretation::InterpretationPass(this), PassId::InterpretationPass);
registerPass(new versions::VersionsPass(this), PassId::VersionsPass);
registerPass(new cfa::CFATemporalSeqPass(this), PassId::CFATemporalSeqPass);
}
void*
XreateManagerDecoratorFull::run() {
transcend->deleteReports();
std::unique_ptr<CompilePass> compiler(new compilation::CompilePassCustomDecorators<>(this));
compiler->run();
llvm->print();
llvm->initJit();
return llvm->getFunctionPointer(compiler->getEntryFunction());
}
} //namespace xreate
diff --git a/cpp/src/compilation/latex.h b/cpp/src/compilation/latex.h
index e35ffeb..cbb7529 100644
--- a/cpp/src/compilation/latex.h
+++ b/cpp/src/compilation/latex.h
@@ -1,144 +1,145 @@
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
/*
* Author: pgess <v.melnychenko@xreate.org>
* Created on June 23, 2018, 2:51 PM
*
* \file latex.h
* \brief latex
*/
#ifndef LATEX_H
#define LATEX_H
#include "compilation/latetranscend.h"
#include "compilation/interpretation-instructions.h"
#include "query/latex.h"
#include "pass/compilepass.h"
#include "analysis/interpretation.h"
#include "compilation/targetinterpretation.h"
namespace xreate{
namespace latex{
ExpandedType
-getSubjectDomain(const std::string& subject, LatexQuery* query);
+getSubjectDomain(const std::string &subject, LatexQuery *query);
/** \brief Latex(Late Context)-aware decorator for \ref xreate::compilation::IFunctionUnit
* \extends xreate::compilation::IFunctionUnit
*/
template<class Parent>
-class LatexBruteFunctionDecorator: public Parent{
+class LatexBruteFunctionDecorator : public Parent{
public:
- LatexBruteFunctionDecorator(ManagedFnPtr f, CompilePass* p)
- : Parent(f, p){
- __query = reinterpret_cast<LatexQuery*> (Parent::pass->man->transcend->getQuery(QueryId::LatexQuery));
- }
+ LatexBruteFunctionDecorator(ManagedFnPtr f, CompilePass *p)
+ : Parent(f, p){
+ __query = reinterpret_cast<LatexQuery *> (Parent::pass->man->transcend->getQuery(QueryId::LatexQuery));
+ }
protected:
- std::vector<llvm::Type*>
- prepareSignature(){
- std::vector<llvm::Type*>&& signature = Parent::prepareSignature();
-
- const Demand& demand = __query->getFnDemand(Parent::function->getName());
- signature.reserve(signature.size() + demand.size());
-
- int subjectId = __query->LatexParametersOffset;
- for(const std::string& subject: demand){
- const ExpandedType& subjectT = getSubjectDomain(subject, __query);
- Expression bindingE;
- bindingE.type = subjectT;
- std::string argCaption = std::string("latex_") + subject;
- Parent::function->addBinding(
- Atom<Identifier_t>(std::string(argCaption)),
- std::move(bindingE),
- subjectId++);
-
- llvm::Type* subjectTRaw = Parent::pass->man->llvm->toLLVMType(subjectT);
- signature.push_back(subjectTRaw);
- }
-
- return signature;
- }
+ std::vector<llvm::Type *>
+ prepareSignature(){
+ std::vector<llvm::Type *> &&signature = Parent::prepareSignature();
+
+ const Demand &demand = __query->getFnDemand(Parent::function->getName());
+ signature.reserve(signature.size() + demand.size());
+
+ int subjectId = __query->LatexParametersOffset;
+ for(const std::string &subject: demand){
+ const ExpandedType &subjectT = getSubjectDomain(subject, __query);
+ Expression bindingE;
+ bindingE.type = subjectT;
+ std::string argCaption = std::string("latex_") + subject;
+ Parent::function->addBinding(
+ Atom<Identifier_t>(std::string(argCaption)),
+ std::move(bindingE),
+ subjectId++);
+
+ llvm::Type *subjectTRaw = Parent::pass->man->llvm->toLLVMType(subjectT);
+ signature.push_back(subjectTRaw);
+ }
+
+ return signature;
+ }
public:
- LatexQuery* __query;
+ LatexQuery *__query;
};
/** \brief %Function invocation operator decorator to handle latex enabled functions with hidden extra arguments */
-class ExtraArgsFnInvocation: public compilation::IFnInvocation{
+class ExtraArgsFnInvocation : public compilation::IFnInvocation{
public:
- ExtraArgsFnInvocation(std::vector<llvm::Value*> argsLatex, compilation::IFnInvocation* parent)
- : __argsLatex(argsLatex), __parent(parent){ }
+ ExtraArgsFnInvocation(std::vector<llvm::Value *> argsLatex, compilation::IFnInvocation *parent)
+ : __argsLatex(argsLatex), __parent(parent){}
- llvm::Value* operator()(std::vector<llvm::Value *>&& args, const std::string& hintDecl = "");
+ llvm::Value *operator()(std::vector<llvm::Value *> &&args, const std::string &hintDecl = "");
private:
- std::vector<llvm::Value*> __argsLatex;
- compilation::IFnInvocation* __parent;
+ std::vector<llvm::Value *> __argsLatex;
+ compilation::IFnInvocation *__parent;
};
/**
* \brief Latex aware \ref xreate::compilation::ICodeScopeUnit decorator
* \implements xreate::compilation::ICodeScopeUnit
*/
template<class Parent>
-class LatexBruteScopeDecorator: public Parent{
+class LatexBruteScopeDecorator : public Parent{
public:
- LatexBruteScopeDecorator(const CodeScope * const codeScope, compilation::IFunctionUnit* f, CompilePass* compilePass)
- : Parent(codeScope, f, compilePass){ }
-
- compilation::IFnInvocation*
- findFunction(const Expression& opCall){
- compilation::IFnInvocation* invocDefault = Parent::findFunction(opCall);
- const std::string& calleeName = opCall.getValueString();
- LatexQuery* query = reinterpret_cast<LatexQuery*> (Parent::pass->man->transcend->getQuery(QueryId::LatexQuery));
-
- const Demand& fnCalleeDemand = query->getFnDemand(calleeName);
- if(!fnCalleeDemand.size()) return invocDefault;
-
- //prepare latex arguments
- std::vector<llvm::Value*> argsLatex;
- argsLatex.reserve(fnCalleeDemand.size());
-
- for(const std::string& subject: fnCalleeDemand){
- ExpandedType subjectT = getSubjectDomain(subject, query);
- llvm::Type* subjectTRaw = Parent::pass->man->llvm->toLLVMType(subjectT);
- const latereasoning::LateAnnotation& decision = query->getDecision(subject, Parent::scope);
-
- compilation::Context ctx{this, Parent::function, Parent::pass};
- interpretation::InterpretationScope* scopeIntrpr =
- Parent::pass->targetInterpretation->transformContext(ctx);
- latereasoning::LateReasoningCompiler* compiler
- = new latereasoning::LateReasoningCompiler(dynamic_cast<interpretation::InterpretationFunction*>(scopeIntrpr->function), ctx);
-
- llvm::Value* subjectRaw = compiler->compileAutoExpand(
- decision,
- subjectTRaw,
- subject,
- [&](const Gringo::Symbol & decisionRaw){
- const Expression& decisionE = interpretation::representTransExpression(
- decisionRaw.args()[2], subjectT, Parent::pass->man->transcend);
+ LatexBruteScopeDecorator(const CodeScope *const codeScope, compilation::IFunctionUnit *f, CompilePass *compilePass)
+ : Parent(codeScope, f, compilePass){}
+
+ compilation::IFnInvocation *
+ findFunction(const Expression &opCall){
+ compilation::IFnInvocation *invocDefault = Parent::findFunction(opCall);
+ const std::string &calleeName = opCall.getValueString();
+ LatexQuery *query = reinterpret_cast<LatexQuery *> (Parent::pass->man->transcend->getQuery(QueryId::LatexQuery));
+
+ const Demand &fnCalleeDemand = query->getFnDemand(calleeName);
+ if(!fnCalleeDemand.size()) return invocDefault;
+
+ //prepare latex arguments
+ std::vector<llvm::Value *> argsLatex;
+ argsLatex.reserve(fnCalleeDemand.size());
+
+ for(const std::string &subject: fnCalleeDemand){
+ ExpandedType subjectT = getSubjectDomain(subject, query);
+ llvm::Type *subjectTRaw = Parent::pass->man->llvm->toLLVMType(subjectT);
+ const latereasoning::LateAnnotation &decision = query->getDecision(subject, Parent::scope);
+
+ compilation::Context ctx{this, Parent::function, Parent::pass};
+ interpretation::InterpretationScope *scopeIntrpr =
+ Parent::pass->targetInterpretation->transformContext(ctx);
+ latereasoning::LateReasoningCompiler *compiler
+ = new latereasoning::LateReasoningCompiler(
+ dynamic_cast<interpretation::InterpretationFunction *>(scopeIntrpr->function), ctx);
+
+ llvm::Value *subjectRaw = compiler->compileAutoExpand(
+ decision,
+ subjectTRaw,
+ subject,
+ [&](const Gringo::Symbol &decisionRaw){
+ const Expression &decisionE = interpretation::representTransExpression(
+ decisionRaw.args()[2], subjectT, Parent::pass->man->transcend);
Attachments::put<TypeInferred>(decisionE, subjectT);
return Parent::process(decisionE, subject);
- });
+ });
- argsLatex.push_back(subjectRaw);
- }
+ argsLatex.push_back(subjectRaw);
+ }
- return new ExtraArgsFnInvocation(std::move(argsLatex), invocDefault);
- }
+ return new ExtraArgsFnInvocation(std::move(argsLatex), invocDefault);
+ }
};
}
} //end of namespace xreate::context
#endif /* LATEX_H */
diff --git a/cpp/tests/CMakeLists.txt b/cpp/tests/CMakeLists.txt
index 2890e4b..188831b 100644
--- a/cpp/tests/CMakeLists.txt
+++ b/cpp/tests/CMakeLists.txt
@@ -1,60 +1,61 @@
cmake_minimum_required(VERSION 2.8.11)
project(xreate-tests)
find_package(GTest REQUIRED)
INCLUDE_DIRECTORIES(${GTEST_INCLUDE_DIRS})
INCLUDE_DIRECTORIES("/usr/include/libxml2")
INCLUDE_DIRECTORIES($<TARGET_PROPERTY:xreate,INCLUDE_DIRECTORIES>)
# TESTS
#=========================
FIND_PACKAGE (LLVM REQUIRED)
message("LLVM_LIBRARY_DIRS: " ${LLVM_LIBRARY_DIRS})
link_directories(${LLVM_LIBRARY_DIRS})
-set (LIBCLASP_PATH ${POTASSCO_PATH}/build/debug)
+set (LIBCLASP_PATH ${CLINGO_PATH}/build/debug)
link_directories(${LIBCLASP_PATH})
#aux_source_directory(. TEST_FILES)
set(TEST_FILES
+ universal.cpp
introduction.cpp
unit-test-example.cpp
transcend-ast.cpp
supplemental/docutils
latetranscend.cpp
cfa.cpp
latex.cpp
polymorph.cpp
transcend.cpp
virtualization.cpp
exploitation.cpp
effects-communication.cpp
association.cpp
main.cpp
modules.cpp
attachments.cpp
ast.cpp
dfa.cpp
compilation.cpp
ExpressionSerializer.cpp
externc.cpp
types.cpp
#vendorsAPI/clangAPI.cpp
#vendorsAPI/xml2.cpp
#vendorsAPI/json.cpp
containers.cpp
interpretation.cpp
loops.cpp
#supplemental/versions-algorithm-data_dependency.cpp
effects-versions.cpp
)
add_executable(${PROJECT_NAME} ${TEST_FILES})
target_link_libraries(${PROJECT_NAME} xreate ${GTEST_LIBRARIES} pthread xml2 gcov)
add_custom_target (coverage
COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/src/code-coverage.sh
WORKING_DIRECTORY ${CMAKE_BINARY_DIR})
diff --git a/cpp/tests/ast.cpp b/cpp/tests/ast.cpp
index 1a6c65a..15c70c9 100644
--- a/cpp/tests/ast.cpp
+++ b/cpp/tests/ast.cpp
@@ -1,254 +1,264 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/
*
* ast.cpp
*
* Created on: Jun 11, 2015
* Author: pgess <v.melnychenko@xreate.org>
*/
#include "supplemental/docutils.h"
#include "xreatemanager.h"
#include "main/Parser.h"
#include "supplemental/defines.h"
#include "gtest/gtest.h"
using namespace std;
using namespace xreate;
using namespace xreate::grammar::main;
TEST(AST, Containers1) {
FILE* input = fopen("scripts/containers/Containers_Implementation_LinkedList1.xreate", "r");
Scanner scanner(input);
Parser parser(&scanner);
parser.Parse();
assert(!parser.errors->count && "Parser errors");
fclose(input);
}
TEST(AST, InterfacesDataCFA) {
XreateManager* man = XreateManager::prepare
("interface(cfa){\n"
" operator map :: annotation1.\n"
"}");
auto answer = man->root->__interfacesData.equal_range(CFA);
EXPECT_EQ(1, std::distance(answer.first, answer.second));
Expression&& scheme = move(answer.first->second);
EXPECT_EQ(Operator::MAP, scheme.op);
EXPECT_EQ("annotation1", scheme.getOperands().at(0).getValueString());
}
TEST(AST, syntax_recognizeIdentifiers) {
XreateManager* man = XreateManager::prepare(R"Code(
test= function(a:: num):: num; entry {
a = b:: int.
b = 8:: int.
a
}
)Code");
}
TEST(AST, syntax_operatorIndex) {
XreateManager* man = XreateManager::prepare(R"Code(
test= function(a:: num):: num; entry {
b = a[1].
b
}
)Code");
}
+TEST(AST, IdentHyphen1){
+ XreateManager* man = XreateManager::prepare(R"Code(
+ my-fn = function(m-n:: num):: num; entry
+ {
+ b = m-n-1:: int.
+ b
+ }
+ )Code");
+}
+
TEST(AST, Variants_switch) {
XreateManager* man = XreateManager::prepare(R"Code(
Color = type variant{Blue, White, Green}.
main = function:: int {
x = White()::Color.
switch variant(x)::int
case (Green) {0}
case (White) {1}
case (Blue){2}
}
)Code");
Expression e = man->root->findFunction("main")->getEntryScope()->getBody();
ASSERT_EQ(4, e.getOperands().size());
ASSERT_EQ(3, e.blocks.size());
}
TEST(AST, DISABLED_InterfacesDataDFA) { }
TEST(AST, DISABLED_InterfacesDataExtern) { }
TEST(AST, Doc_LiteralsAndExpressions) {
XreateManager* man = XreateManager::prepare(
R"Code(
Record1 = type {year:: int, month:: string}.
isOdd = function(x :: int) :: bool {true}
test = function:: bool; entry {
x1 = 5 :: int.
x2 = "Nimefurahi kukujua":: string.
x3 = {year = 1934, month = "april"}:: Record1.
x4 = {16, 8, 3} :: [int].
x41 = [1..18]:: [int].
x5 = 8>=3:: bool.
x6 = "Blue" <> "Green" :: bool.
x7 = -true:: bool.
colors = {"Green", "Blue"} :: [string].
color = colors[0] :: string.
date = {year = 1934, month = "april"}:: Record1. year = date["year"] :: int.
a = 0::int. b = 0 :: int.
x7 = a - b:: int.
result = isOdd(6) :: bool.
true
}
)Code");
ASSERT_TRUE(true);
}
TEST(AST, Doc_CodeBlocks1) {
XreateManager* man = XreateManager::prepare(
getDocumentationExampleById("documentation/Syntax/syntax.xml", "CodeBlocks1"));
FnNoArgs resultFn = (FnNoArgs) man->run();
int resultExpected = resultFn();
ASSERT_EQ(12, resultExpected);
}
TEST(AST, Doc_Functions1) {
XreateManager* man = XreateManager::prepare(
getDocumentationExampleById("documentation/Syntax/syntax.xml", "Functions1"));
ASSERT_TRUE(true);
}
TEST(AST, Doc_FunctionSpecializations1) {
XreateManager* man = XreateManager::prepare(
getDocumentationExampleById("documentation/Syntax/syntax.xml", "FunctionSpecialization1"));
ASSERT_TRUE(true);
}
TEST(AST, Doc_BranchStatements) {
string code_IfStatement1 = getDocumentationExampleById("documentation/Syntax/syntax.xml", "IfStatement1");
string code_SwitchStatement1 = getDocumentationExampleById("documentation/Syntax/syntax.xml", "SwitchStatement1");
string code =
R"Code(
test = function:: int; entry
{
question = "Favorite color?":: string.
monthNum = 2:: int.
%IfStatement1
%SwitchStatement1
monthName
}
)Code";
replace(code, "%IfStatement1", code_IfStatement1);
replace(code, "%SwitchStatement1", code_SwitchStatement1);
XreateManager* man = XreateManager::prepare(move(code));
ASSERT_TRUE(true);
}
TEST(AST, Doc_LoopStatements) {
string code_LoopStatement1 = getDocumentationExampleById("documentation/Syntax/syntax.xml", "LoopStatement1");
string code_LoopStatement2 = getDocumentationExampleById("documentation/Syntax/syntax.xml", "LoopStatement2");
string code_FoldStatement1 = getDocumentationExampleById("documentation/Syntax/syntax.xml", "FoldStatement1");
string code_MapStatement1 = getDocumentationExampleById("documentation/Syntax/syntax.xml", "MapStatement1");
string code =
R"Code(
test = function:: int; entry
{
%LoopStatement1
%LoopStatement2
%FoldStatement1
%MapStatement1
min
}
)Code";
replace(code, "%LoopStatement1", code_LoopStatement1);
replace(code, "%LoopStatement2", code_LoopStatement2);
replace(code, "%FoldStatement1", code_FoldStatement1);
replace(code, "%MapStatement1", code_MapStatement1);
XreateManager::prepare(move(code));
ASSERT_TRUE(true);
}
TEST(AST, Doc_Types){
string code = getDocumentationExampleById("documentation/Syntax/syntax.xml", "Types1");
XreateManager::prepare(move(code));
ASSERT_TRUE(true);
}
TEST(AST, Doc_Variants1){
string code_Variants1 = getDocumentationExampleById("documentation/Syntax/syntax.xml", "Variants1");
XreateManager::prepare(move(code_Variants1));
ASSERT_TRUE(true);
}
TEST(AST, Doc_VariantsSwitch1){
string code_Variants1 = getDocumentationExampleById("documentation/Syntax/syntax.xml", "VariantsSwitch1");
XreateManager::prepare(move(code_Variants1));
ASSERT_TRUE(true);
}
TEST(AST, Doc_RecField1){
string code_Variants1 = getDocumentationExampleById("documentation/Syntax/syntax.xml", "RecField1");
XreateManager::prepare(move(code_Variants1));
ASSERT_TRUE(true);
}
TEST(AST, Doc_RecUpdate1){
string code_Variants1 = getDocumentationExampleById("documentation/Syntax/syntax.xml", "RecUpdate1");
XreateManager::prepare(move(code_Variants1));
ASSERT_TRUE(true);
}
TEST(AST, Doc_Versions1){
string code_Variants1 = getDocumentationExampleById("documentation/Syntax/syntax.xml", "Versions1_1");
string code_Variants2 = getDocumentationExampleById("documentation/Syntax/syntax.xml", "Versions1_2");
string code = R"Code(
test = function:: int; entry
{
<BODY>
y
})Code";
{
XreateManager* man = XreateManager::prepare(move(code_Variants1));
man->run();
delete man;
ASSERT_TRUE(true);
}
{
replace(code, "<BODY>", code_Variants2);
auto man = details::tier1::XreateManager::prepare(move(code));
ASSERT_DEATH(man->analyse(), ".*versions graph.*");
}
}
\ No newline at end of file
diff --git a/cpp/tests/latex.cpp b/cpp/tests/latex.cpp
index be55f08..7fea3ef 100644
--- a/cpp/tests/latex.cpp
+++ b/cpp/tests/latex.cpp
@@ -1,358 +1,358 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/
*
* Author: pgess <v.melnychenko@xreate.org>
* Created on June 25, 2018, 5:42 PM
*
* \file latex.cpp
* \brief Testing of latex
*/
#include "xreatemanager.h"
#include "pass/compilepass.h"
#include "transcendlayer.h"
#include "query/latex.h"
#include "compilation/latex.h"
#include "aux/xreatemanager-decorators.h"
#include "compilation/scopedecorators.h"
#include "llvmlayer.h"
#include "supplemental/docutils.h"
#include "supplemental/defines.h"
#include <boost/format.hpp>
#include <gtest/gtest.h>
using namespace xreate::latex;
using namespace xreate::latereasoning;
using namespace xreate::compilation;
using namespace xreate;
using namespace std;
TEST(Latex, Script_NestedScopePropagation_1) {
std::string program =
R"CODE(
import raw("scripts/cfa/context.lp").
fn = function:: int; entry
{
context:: test1.
if(1==11)::int {2} else {3}
}
)CODE";
std::unique_ptr<details::tier1::XreateManager> man(details::tier1::XreateManager::prepare(move(program)));
CodeScope* blockTrue = man->root->findFunction("fn")->getEntryScope()->getBody().blocks.front();
auto blockTrueP = man->transcend->pack(blockTrue);
boost::format formatAlias("alias(%1%, %2%).");
man->transcend->addRawScript((formatAlias % blockTrueP % "block1").str());
man->transcend->addRawScript(
R"SCRIPT(
success1:- bind_scope(Block1, test1, strong); alias(Block1, block1).
)SCRIPT");
man->analyse();
ASSERT_EQ(1, man->transcend->query("success1").size());
}
TEST(Latex, Script_DemAndDecision_1) {
std::string program =
R"CODE(
import raw("scripts/cfa/context.lp").
a = function:: int
{
context:: forC(a).
c()
}
b = function:: int
{
context:: forC(b).
c()
}
c = function:: int {0}
main = function:: int; entry
{
a() + b()
}
)CODE";
std::unique_ptr<details::tier1::XreateManager> man(details::tier1::XreateManager::prepare(move(program)));
CodeScope* blockC = man->root->findFunction("c")->getEntryScope();
auto blockCP = man->transcend->pack(blockC);
boost::format formatAlias("alias(%1%, %2%).");
man->transcend->addRawScript((formatAlias % blockCP % "blockC").str());
man->transcend->addRawScript(
R"SCRIPT(
latex_scope_demand(BlockC, forC):- alias(BlockC, blockC).
latex_registered_subjects(forC, Variant):- bind_scope(_, Variant, strong); Variant = forC(_).
)SCRIPT");
man->analyse();
ASSERT_EQ(1, man->transcend->query("latex_fn_demand").size());
ASSERT_EQ(2, man->transcend->query("latex_decision").size());
}
TEST(Latex, LatexQuery_getFnDemand_1){
std::string program =
R"CODE(
import raw("scripts/cfa/context.lp").
main = function:: int; entry
{
context:: alias(blockMain).
0
}
)CODE";
std::unique_ptr<details::tier1::XreateManager> man(details::tier1::XreateManager::prepare(move(program)));
man->transcend->addRawScript(
R"SCRIPT(
latex_scope_demand(BlockC, forC):- bind_scope(BlockC, alias(blockMain), strong).
latex_registered_subjects(forC, decisionSome).
)SCRIPT");
LatexQuery* query = new LatexQuery();
man->transcend->registerQuery(query, QueryId::LatexQuery);
man->analyse();
Demand demand = query->getFnDemand("main");
ASSERT_EQ(1, demand.size());
ASSERT_STREQ("forC", demand.front().c_str());
}
TEST(Latex, LatexQuery_getDecision_static_1){
std::string program =
R"CODE(
import raw("scripts/cfa/context.lp").
a = function:: int {context::decisionSome. c()}
b = function:: int {c()}
c = function:: int {context:: alias(blockC). 0}
)CODE";
std::unique_ptr<details::tier1::XreateManager> man(details::tier1::XreateManager::prepare(move(program)));
man->transcend->addRawScript(
R"SCRIPT(
latex_scope_demand(BlockC, forC):- bind_scope(BlockC, alias(blockC), strong).
latex_registered_subjects(forC, decisionSome).
)SCRIPT");
LatexQuery* query = new LatexQuery();
man->transcend->registerQuery(query, QueryId::LatexQuery);
man->analyse();
LateAnnotation decisionLA = query->getDecision("forC", man->root->findFunction("a")->getEntryScope());
auto decisionGS = decisionLA.select({}, man->root, man->transcend);
ASSERT_TRUE(decisionGS);
decisionGS->print(cout);
cout << endl;
auto decisionTuple = man->transcend->parse<Gringo::Symbol, Gringo::Symbol, string>(*decisionGS);
string decision = get<2>(decisionTuple);
ASSERT_STREQ("decisionSome", decision.c_str());
}
TEST(Latex, Compilation_1) {
std::string program =
R"CODE(
a = function:: int
{0}
main = function:: int; entry
{
a()
}
)CODE";
string script =
R"SCRIPT(
latex_fn_demand(%1%, subject1).
latex_decision(%2%, subject1, 5).
latex_registered_subjects(subject1, 1).
latex_registered_subjects(subject1, 5).
)SCRIPT";
typedef LatexBruteFunctionDecorator<compilation::BasicFunctionUnit> FnImpl;
typedef LatexBruteScopeDecorator<compilation::CachedScopeDecorator<compilation::BasicCodeScopeUnit>> ScopeImpl;
std::unique_ptr<details::tier1::XreateManager> man(details::tier1::XreateManager::prepare(move(program)));
ScopePacked scopeMainP = man->transcend->pack(man->root->findFunction("main")->getEntryScope());
boost::format format(script);
man->transcend->addRawScript((format % "a" % scopeMainP).str());
man->transcend->registerQuery(new LatexQuery(), QueryId::LatexQuery);
man->analyse();
std::unique_ptr<CompilePass> compiler(new compilation::CompilePassCustomDecorators<FnImpl, ScopeImpl>(man.get()));
compiler->run();
man->llvm->initJit();
int(*fnMain)() = (int(*)())man->llvm->getFunctionPointer(compiler->getEntryFunction());
ASSERT_EQ(0, fnMain());
}
//
//TEST(Latex, Full1) {
// std::string program =
// R"CODE(
// import raw("scripts/cfa/context.lp").
//
// a = function:: int
// {
// context:: forC(a).
// c()
// }
//
// b = function:: int
// {
// context:: forC(b).
// c()
// }
//
// c = function:: int {0}
//
// main = function:: int; entry
// {
// a() + b()
// }
// )CODE";
//
// string script =
// R"SCRIPT(
// alias(%1%, scopeC).
// latex_scope_demand(ScopeC, forC) :- alias(ScopeC, scopeC).
// latex_registered_subjects(forC, forC(a)).
// latex_registered_subjects(forC, forC(b)).
// )SCRIPT";
//
// typedef LatexBruteFunctionDecorator<compilation::BasicFunctionUnit> FnImpl;
// typedef LatexBruteScopeDecorator<compilation::CachedScopeDecorator<compilation::BasicCodeScopeUnit>> ScopeImpl;
//
// std::unique_ptr<details::tier1::XreateManager> man(details::tier1::XreateManager::prepare(move(program)));
// ScopePacked scopeMainP = man->transcend->pack(man->root->findFunction("main")->getEntryScope());
// auto scopeCP = man->transcend->pack(man->root->findFunction("c")->getEntryScope());
// boost::format format(script);
// man->transcend->addRawScript((format %scopeCP).str());
// man->transcend->registerQuery(new LatexQuery(), QueryId::LatexQuery);
// man->analyse();
//
// std::unique_ptr<CompilePass> compiler(new compilation::CompilePassCustomDecorators<FnImpl, ScopeImpl>(man.get()));
// compiler->run();
// man->llvm->print();
//}
//
TEST(Latex, Compilation_TransitFn1){
std::string program =
R"CODE(
import raw("scripts/cfa/context.lp").
branchA = function:: int
{
context:: sink_a.
fnTransit()
}
branchB = function:: int
{
context:: sink_b.
fnTransit()
}
fnSink = function:: int {0}
fnTransit = function:: int {fnSink()}
main = function:: int; entry
{
branchA() + branchB()
}
)CODE";
string script =
R"SCRIPT(
alias(scopeSink, %1%).
latex_scope_demand(ScopeSink, sink):- alias(scopeSink, ScopeSink).
latex_registered_subjects(sink, sink_a).
latex_registered_subjects(sink, sink_b).
)SCRIPT";
typedef LatexBruteFunctionDecorator<compilation::BasicFunctionUnit> FnImpl;
typedef LatexBruteScopeDecorator<compilation::CachedScopeDecorator<compilation::BasicCodeScopeUnit>> ScopeImpl;
std::unique_ptr<details::tier1::XreateManager> man(details::tier1::XreateManager::prepare(move(program)));
CodeScope* scopeSink = man->root->findFunction("fnSink")->getEntryScope();
auto scopeSinkP = man->transcend->pack(scopeSink);
ScopedSymbol argLatexSS{1, -1};
Symbol argLatexS{argLatexSS, scopeSink};
man->transcend->pack(argLatexS);
boost::format format(script);
man->transcend->addRawScript((format %scopeSinkP).str());
man->transcend->registerQuery(new LatexQuery(), QueryId::LatexQuery);
man->analyse();
std::unique_ptr<CompilePass> compiler(new compilation::CompilePassCustomDecorators<FnImpl, ScopeImpl>(man.get()));
compiler->run();
man->llvm->print();
man->llvm->initJit();
int(*fnMain)() = (int(*)()) man->llvm->getFunctionPointer(compiler->getEntryFunction());
int valueActual = fnMain();
ASSERT_EQ(0, valueActual);
}
TEST(Latex, Doc_Examples1){
std::string program = getDocumentationExampleById("documentation/Concepts/context.xml", "Examples_1");
std::unique_ptr<details::tier1::XreateManager> man(details::tier1::XreateManager::prepare(move(program)));
}
TEST(Latex, Doc_Examples2){
std::string program = getDocumentationExampleById("documentation/Concepts/context.xml", "Examples_2");
std::unique_ptr<details::tier1::XreateManager> man(details::tier1::XreateManager::prepare(move(program)));
}
TEST(Latex, Doc_ContextPropagation1){
std::string program =getDocumentationExampleById("documentation/Concepts/context.xml", "ContextPropagation1");
std::unique_ptr<details::tier1::XreateManager> man(details::tier1::XreateManager::prepare(move(program)));
}
TEST(Latex, Doc_ContextPropagation2){
std::string program = getDocumentationExampleById("documentation/Concepts/context.xml", "ContextPropagation2");
std::unique_ptr<details::tier1::XreateManager> man(details::tier1::XreateManager::prepare(move(program)));
}
TEST(Latex, Doc_Latex1){
std::string program = getDocumentationExampleById("documentation/Concepts/context.xml", "Latex1");
string script =
R"SCRIPT(
- latef(compute).
+ latef("compute").
latex_scope_demand(Scope, f_guarded(F)):-
cfa_call(Scope, F);
latef(F).
latex_registered_subjects(f_guarded(F), Guard):-
cfa_function_specializations(F, Guard);
latef(F).
late(TargetS, LatexParam, Guard, dfa_callguard(TargetS, Guard)):-
dfa_callfn(TargetS, FnGuarded);
latef(FnGuarded);
latex_symbol(FnCallerBody, f_guarded(FnGuarded), LatexParam);
TargetS=s(_,_, TargetScope);
scope_fnbody(TargetScope, FnCallerBody);
cfa_function_specializations(FnGuarded, Guard).
)SCRIPT";
auto man(XreateManager::prepare(move(program)));
man->transcend->addRawScript(move(script));
Fn3args fn = (Fn3args) man->run();
int resultActual = fn(1, 4, 3);
ASSERT_EQ(7, resultActual);
resultActual = fn(0, 4, 3);
ASSERT_EQ(1, resultActual);
}
\ No newline at end of file
diff --git a/cpp/tests/transcend-ast.cpp b/cpp/tests/transcend-ast.cpp
index c8c6044..4fe628f 100644
--- a/cpp/tests/transcend-ast.cpp
+++ b/cpp/tests/transcend-ast.cpp
@@ -1,77 +1,77 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/
*
* AST-Transcend Correspondence Tests
*
* Created on: Dec 2, 2018
* Author: pgess <v.melnychenko@xreate.org>
*/
#include <pass/cfapass.h>
#include "xreatemanager.h"
#include "pass/dfapass.h"
#include "supplemental/docutils.h"
#include <boost/algorithm/string.hpp>
#include "gtest/gtest.h"
using namespace xreate;
using namespace std;
struct TestRec {
string refExample;
string refOutput;
PassId pass;
};
std::list<TestRec> tests = {
{"ExprAnn_1", "Output_ExprAnn_1", PassId::DFAPass},
{"CodeBlock_1", "Output_CodeBlock_1", PassId::CFAPass},
{"CodeBlockAnns_1", "Output_CodeBlockAnns_1", PassId::CFAPass},
{"CodeBlockBinds_1", "Output_CodeBlockBinds_1", PassId::CFAPass},
{"CodeBlockParents_1", "Output_CodeBlockParents_1",PassId::CFAPass},
{"Fn_1", "Output_Fn_1", PassId::CFAPass},
{"FnAnns_1", "Output_FnAnns_1", PassId::CFAPass},
{"FnSpecs_1", "Output_FnSpecs_1", PassId::CFAPass},
{"FnEntry_1", "Output_FnEntry_1", PassId::CFAPass},
{"FnResult_1", "Output_FnResult_1", PassId::CFAPass},
{"OpInvoc_1", "Output_OpInvoc_1", (PassId) 1000},
{"OpLoops_1", "Output_OpLoops_1", PassId::DFAPass}
};
TEST(ASTCorrespondence, Doc_BasicTests) {
for(auto test: tests) {
string program = getDocumentationExampleById("documentation/Transcend/ast-api.xml", test.refExample);
string outputExpected = getDocumentationExampleById("documentation/Transcend/ast-api.xml", test.refOutput);
std::unique_ptr<details::tier2::XreateManager> man(details::tier2::XreateManager::prepare(move(program)));
switch(test.pass) {
case PassId::CFAPass:
man->registerPass(new cfa::CFAPass(man.get()), test.pass);
break;
case PassId::DFAPass:
man->registerPass(new dfa::DFAPass(man.get()), test.pass);
break;
default:
man->registerPass(new dfa::DFAPass(man.get()), PassId::DFAPass);
man->registerPass(new cfa::CFAPass(man.get()), PassId::CFAPass);
break;
}
man->registerPass(new dfa::DFAPass(man.get()), test.pass);
man->executePasses();
cout << "Test: " << test.refExample << endl;
testing::internal::CaptureStdout();
man->analyse();
std::string outputActual = testing::internal::GetCapturedStdout();
- //cout << outputActual << endl;
+ cout << outputActual << endl;
//check every line independently if outputActual is multi-line string
std::vector<std::string> lines;
boost::split(lines, outputExpected, [](char c){return c == '\n';});
for(auto line: lines) {
ASSERT_NE(std::string::npos, outputActual.find(line));
}
}
}
diff --git a/cpp/tests/transcend.cpp b/cpp/tests/transcend.cpp
index 022b105..e7a53ac 100644
--- a/cpp/tests/transcend.cpp
+++ b/cpp/tests/transcend.cpp
@@ -1,92 +1,93 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/
*
* Author: pgess <v.melnychenko@xreate.org>
* Created on June 7, 2018, 3:35 PM
*
* \file transcend.cpp
* \brief Transcend's tests
*/
#include "xreatemanager.h"
#include "transcendlayer.h"
#include "supplemental/docutils.h"
#include <gtest/gtest.h>
using namespace xreate;
using namespace std;
TEST(Transcend, Parse1) {
std::string script =
R"Code(
)Code";
std::unique_ptr<details::tier1::XreateManager> man(details::tier1::XreateManager::prepare(std::move(script)));
std::string scriptTranscend =
R"Code(
test1((1)).
test2((1, 2)).
)Code";
man->transcend->addRawScript(move(scriptTranscend));
man->analyse();
StaticModel solution = man->transcend->query("test1");
Gringo::Symbol symbTest1 = solution.begin()->second;
auto answer1 = man->transcend->parse<list<int>>(symbTest1);
ASSERT_EQ(1, get<0>(answer1).size());
solution = man->transcend->query("test2");
Gringo::Symbol symbTest2 = solution.begin()->second;
auto answer2 = get<0>(man->transcend->parse<list<int>>(symbTest2));
ASSERT_EQ(2, answer2.size());
}
TEST(Transcend, Doc_Expressions1) {
string code = getDocumentationExampleById("documentation/Transcend/transcend.xml", "Expressions1");
XreateManager* man = XreateManager::prepare(move(code));
man->run();
delete man;
ASSERT_TRUE(true);
}
TEST(Transcend, Doc_SlaveTypes1){
string code = getDocumentationExampleById("documentation/Transcend/transcend.xml", "Codeblocks1");
XreateManager::prepare(move(code));
ASSERT_TRUE(true);
}
TEST(Transcend, Doc_Codeblocks1) {
string code = getDocumentationExampleById("documentation/Transcend/transcend.xml", "Codeblocks1");
XreateManager::prepare(move(code));
ASSERT_TRUE(true);
}
TEST(Transcend, Doc_Diagnostics1) {
string code = getDocumentationExampleById("documentation/Transcend/transcend.xml", "Diagnostics1");
string scriptTranscend = getDocumentationExampleById("documentation/Transcend/transcend.xml", "Diagnostics1_Rules");
string scriptSupport =
R"Code(
scope_func_dict(S, Fn):-
cfa_parent(S, function(Fn)).
scope_func_dict(S1, Fn):-
cfa_parent(S1, scope(S2));
scope_func_dict(S2, Fn).
)Code";
auto man = XreateManager::prepare(move(code));
man->transcend->addRawScript(move(scriptTranscend));
man->transcend->addRawScript(move(scriptSupport));
testing::internal::CaptureStdout();
man->run();
delete man;
std::string outputActual = testing::internal::GetCapturedStdout();
- string outputExpected = "warning(\"Visibility violation\",test,sum)";
+ std::cout << outputActual << std::endl;
+ string outputExpected = "warning(\"Visibility violation\",\"test\",\"sum\")";
ASSERT_NE(std::string::npos, outputActual.find(outputExpected));
}
\ No newline at end of file
diff --git a/cpp/tests/unit-test-example.cpp b/cpp/tests/unit-test-example.cpp
index 17151bb..d1b0b5b 100644
--- a/cpp/tests/unit-test-example.cpp
+++ b/cpp/tests/unit-test-example.cpp
@@ -1,43 +1,43 @@
#include "xreatemanager.h" //main Xreate header
#include "transcendlayer.h"
#include <gtest/gtest.h>
using namespace xreate;
using namespace std;
TEST(Example, Example1){
//Your custom transcend rules if any
string rules =
R"SCRIPT(
- bind_func(sum, entry).
+ bind_func("sum", entry).
)SCRIPT";
//Your custom program
string example =
R"CODE(
//Custom code
sum = function(a:: int, b:: int):: int
{
a + b
}
)CODE";
//Initialize compiler
unique_ptr<XreateManager> man(XreateManager::prepare(move(example)));
//Add transcend part:
man->transcend->addRawScript(move(rules));
//Define signature of your entry function:
typedef int (*ENTRYFN)(int, int);
//Compile the example and get a pointer to the entry function:
ENTRYFN yourEntryFn = (ENTRYFN) man->run();
//Now execute function and check the result
int resultActual = yourEntryFn(5, 7);
int resultExpected = 5 + 7;
ASSERT_EQ(resultExpected, resultActual);
}
diff --git a/cpp/tests/universal.cpp b/cpp/tests/universal.cpp
new file mode 100644
index 0000000..f296166
--- /dev/null
+++ b/cpp/tests/universal.cpp
@@ -0,0 +1,22 @@
+//
+// Created by pgess on 1/6/20.
+//
+
+#include "universal/Parser.h"
+#include "gtest/gtest.h"
+#include <iostream>
+
+using namespace xreate::universal;
+
+TEST(Universal, DISABLED_Test1)
+{
+ //testing::internal::CaptureStdout();
+ FILE* input = fopen("/private/prg/code/xreate/design/sprint-III/universal-syntax.xreate","r");
+ assert(input != nullptr);
+ Scanner scanner(input);
+ Parser parser(&scanner);
+ parser.Parse();
+ std::string outputActual = testing::internal::GetCapturedStdout();
+ //std::cout << outputActual << std::endl;
+ ASSERT_EQ(parser.errors->count, 0);
+}
\ No newline at end of file
diff --git a/documentation/Transcend/ast-api.xml b/documentation/Transcend/ast-api.xml
index c757ee2..aa2afbd 100644
--- a/documentation/Transcend/ast-api.xml
+++ b/documentation/Transcend/ast-api.xml
@@ -1,495 +1,495 @@
<?xml version="1.0" encoding="UTF-8"?>
<chapter version="5.1" xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:xila="http://www.w3.org/2001/XInclude/local-attributes"
xmlns:xi="http://www.w3.org/2001/XInclude"
xmlns:trans="http://docbook.org/ns/transclusion"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns:m="http://www.w3.org/1998/Math/MathML"
xmlns:html="http://www.w3.org/1999/xhtml"
xmlns:db="http://docbook.org/ns/docbook">
<title>AST API</title>
<para>In order to reason about program, code model is translated into form
suited for processing by Transcend. Translation details are described
below.</para>
<section>
<title>Expression Annotations: 'bind'</title>
<synopsis>SYNTAX:
**bind**(//symbol-ref//, //annotation//)</synopsis>
<itemizedlist>
<listitem>
<para><emphasis>symbol-ref</emphasis> reference to the expression or
identifier</para>
</listitem>
<listitem>
<para><emphasis>annotation</emphasis> expression's annotation</para>
</listitem>
</itemizedlist>
<para>Declares expression's annotations.</para>
<para>Example:</para>
<programlisting xml:id="ExprAnn_1">name="tests/transcend-ast.cpp: ASTCorrespondence.Doc_BasicTests"
test = function:: int
{
x = 5:: int; expected(even_number).
x
}</programlisting>
<para>gets translated into:</para>
<programlisting xml:id="Output_ExprAnn_1">bind(s(1,-2,0),expected(even_number)) </programlisting>
</section>
<section>
<title>Code Block: 'scope'</title>
<synopsis>SYNTAX:
**scope**(//scope-ref//)</synopsis>
<itemizedlist>
<listitem>
<para><emphasis>scope-ref</emphasis> reference to the code
block</para>
</listitem>
</itemizedlist>
<para>Declares code block under its unique reference identifier.</para>
<para>Example:</para>
<programlisting xml:id="CodeBlock_1">name="tests/transcend-ast.cpp: ASTCorrespondence.Doc_BasicTests"
test = function:: float
{
x = 3:: float.
y = 8:: float.
x + y
}</programlisting>
<para>Translation result: <code
xml:id="Output_CodeBlock_1">scope(0)</code></para>
</section>
<section>
<title>Code Block Annotations: 'bind_scope'</title>
<warning>
<para>Pending syntax changes</para>
</warning>
<synopsis>SYNTAX:
**bind_scope**(//scope-ref//, //annotation//, strong) (1)
**bind_scope**(//scope-ref//, //annotation//, weak(..)) (2)
</synopsis>
<itemizedlist>
<listitem>
<para><emphasis>scope-ref</emphasis> child block's reference</para>
</listitem>
<listitem>
<para><emphasis>annotation</emphasis> code block's annotation</para>
</listitem>
</itemizedlist>
<para>Declares code block's annotations called
<emphasis>context</emphasis>. There are two forms for different context'
type:</para>
<itemizedlist>
<listitem>
<para><emphasis>strong</emphasis> context known at compile time</para>
</listitem>
<listitem>
<para><emphasis>weak</emphasis> possible context, can't be decided for
sure at compile time</para>
</listitem>
</itemizedlist>
<para>Example:</para>
<programlisting xml:id="CodeBlockAnns_1">name="tests/transcend-ast.cpp: ASTCorrespondence.Doc_BasicTests"
test = function:: float
{
context:: arithmetic(fast).
x = 3:: float.
y = 8:: float.
x + y
}</programlisting>
<para>Translation's result:</para>
<programlisting xml:id="Output_CodeBlockAnns_1">bind_scope(0,arithmetic(fast),strong)</programlisting>
</section>
<section>
<title>Code Block Bindings: 'ast_scope_binding'</title>
<synopsis>SYNTAX:
**ast_scope_binding**(//scope-ref//, //binding-id//, //binding-alias//)</synopsis>
<itemizedlist>
<listitem>
<para><emphasis>scope-ref</emphasis> code block's reference</para>
</listitem>
<listitem>
<para><emphasis>binding-id</emphasis> number of code block's
binding</para>
</listitem>
<listitem>
<para><emphasis>binding-alias</emphasis> name of a binding</para>
</listitem>
</itemizedlist>
<para>Code blocks have zero or more <emphasis>bindings</emphasis>, i.e.
Identifiers that have special meaning within the block. Predicate declares
such code block's bindings. Bindings organized into ordered list. Order is
conveyed by specifying <emphasis>binding-id</emphasis> for each
<emphasis>binding-alias.</emphasis></para>
<para>Example:</para>
<programlisting xml:id="CodeBlockBinds_1">name="tests/transcend-ast.cpp: ASTCorrespondence.Doc_BasicTests"
test = function:: int
{
loop ( 0 -> acc ):: int
{
if(acc > 10):: int {acc:: int; final} else {acc + 1}
}
}</programlisting>
<para>Translation result: <code
xml:id="Output_CodeBlockBinds_1">ast_scope_binding(1,0,"acc")</code></para>
</section>
<section>
<title>Code Block Parents: 'cfa_parent'</title>
<synopsis>SYNTAX:
**cfa_parent**(//scope-ref//, **scope**(//scope-parent-ref//))</synopsis>
<itemizedlist>
<listitem>
<para><emphasis>scope-ref</emphasis> child block's reference</para>
</listitem>
<listitem>
<para><emphasis>scope-parent-ref</emphasis> parent block's
reference</para>
</listitem>
</itemizedlist>
<para>Represents nested code blocks structure in terms of
<emphasis>child-parent</emphasis> relation.</para>
<para>Example:</para>
<programlisting xml:id="CodeBlockParents_1">name="tests/transcend-ast.cpp: ASTCorrespondence.Doc_BasicTests"
test = function:: int
{
x = 19:: int.
if (x>5):: int {x + 1} else {x - 1}
}</programlisting>
<para>Translation's result:</para>
<programlisting xml:id="Output_CodeBlockParents_1">cfa_parent(1, scope(0)).
cfa_parent(2, scope(0)).</programlisting>
</section>
<section>
<title>Function: 'function'</title>
<synopsis>SYNTAX:
**function**(//fn-name//)</synopsis>
<itemizedlist>
<listitem>
<para><emphasis>fn-name</emphasis> function name</para>
</listitem>
</itemizedlist>
<para>Declares function identified by its name.</para>
<para>Example:</para>
<programlisting xml:id="Fn_1">name="tests/transcend-ast.cpp: ASTCorrespondence.Doc_BasicTests"
test = function:: int {0}</programlisting>
<para>Translation's result: <code
- xml:id="Output_Fn_1">function(test)</code></para>
+ xml:id="Output_Fn_1">function("test")</code></para>
</section>
<section>
<title>Function's Annotations: 'bind_func'</title>
<synopsis>SYNTAX:
**bind_func**(//fn-name//, //annotation//)</synopsis>
<itemizedlist>
<listitem>
<para><emphasis>fn-name</emphasis> function's name</para>
</listitem>
</itemizedlist>
<para>Declares function's annotations.</para>
<para>Example:</para>
<programlisting xml:id="FnAnns_1">name="tests/transcend-ast.cpp: ASTCorrespondence.Doc_BasicTests"
test = function:: int; status(obsolete) {0}</programlisting>
<para>Translation's result: <code
- xml:id="Output_FnAnns_1">bind_func(test,status(obsolete))</code></para>
+ xml:id="Output_FnAnns_1">bind_func("test",status(obsolete))</code></para>
</section>
<section>
<title>Function's Specialization: 'cfa_function_specializations'</title>
<synopsis>SYNTAX:
**cfa_function_specializations**(//fn-name//, //guard//)</synopsis>
<itemizedlist>
<listitem>
<para><emphasis>fn-name</emphasis> name of function</para>
</listitem>
<listitem>
<para><emphasis>guard</emphasis> specialization guard</para>
</listitem>
</itemizedlist>
<para>There is a possibility to have several functions with the same name
called specializations. Each specialization is uniquely determined by
annotation of special kind called <emphasis>guard</emphasis>.</para>
<para>Example:</para>
<programlisting xml:id="FnSpecs_1">name="tests/transcend-ast.cpp: ASTCorrespondence.Doc_BasicTests"
guard:: arch(amd64)
{
test = function:: i64 {0}
}</programlisting>
<para>Translation's result: <code
- xml:id="Output_FnSpecs_1">cfa_function_specializations(test,arch(amd64))</code><note>
+ xml:id="Output_FnSpecs_1">cfa_function_specializations("test",arch(amd64))</code><note>
<para>See also <link
xlink:href="/d/syntax/#function-specializations">specializations
syntax</link></para>
</note></para>
</section>
<section>
<title>Function's Entry: 'cfa_parent'</title>
<synopsis>SYNTAX:
**cfa_parent**(//scope-entry-ref//, functon(//fn-name//))</synopsis>
<itemizedlist>
<listitem>
<para><emphasis>scope-entry-ref</emphasis> function's entry code block
reference</para>
</listitem>
<listitem>
<para><emphasis>fn-name</emphasis> function's name</para>
</listitem>
</itemizedlist>
<para>Each function has a single <emphasis>entry</emphasis> code block and
is declared in terms of <emphasis>child-parent</emphasis> relation between
entry block(which is top-level in blocks hierarchy of the given function)
and the function itself.</para>
<para>Example:</para>
<programlisting xml:id="FnEntry_1">name="tests/transcend-ast.cpp: ASTCorrespondence.Doc_BasicTests"
test = function:: int {0}</programlisting>
<para>Translation's result: <code
- xml:id="Output_FnEntry_1">cfa_parent(0,function(test))</code></para>
+ xml:id="Output_FnEntry_1">cfa_parent(0,function("test"))</code></para>
</section>
<section>
<title>Function's Result: 'dfa_fnret'</title>
<synopsis>SYNTAX:
**dfa_fnret**(//fn-name//, //symbol-ret-ref//)</synopsis>
<itemizedlist>
<listitem>
<para>symbol-ret-ref reference to a function's return
expression</para>
</listitem>
</itemizedlist>
<para>Specifies which expression is used to compute function's return
value.</para>
<para>Example:</para>
<programlisting xml:id="FnResult_1">name="tests/transcend-ast.cpp: ASTCorrespondence.Doc_BasicTests"
test = function:: int {0}</programlisting>
<para>Translation's result: <code
- xml:id="Output_FnResult_1">dfa_fnret(test,s(0,-2,0))</code></para>
+ xml:id="Output_FnResult_1">dfa_fnret("test",s(0,-2,0))</code></para>
</section>
<section>
<title>Operations. Invocation: 'cfa_call', 'dfa_callfn',
'dfa_callargs'</title>
<synopsis>SYNTAX:
**cfa_call**(//scope-caller-ref//, //fn-callee-name//) (1)
**dfa_callfn**(//symbol-ref//, //fn-callee-name//) (2)
**dfa_callargs**(//symbol-ref//, //arg-formal-name//, //arg-actual-ref//) (3)
**weak**(**dfa_callargs**(//symbol-ref//, //arg-formal-name//, //arg-actual-ref//)) (4)
</synopsis>
<itemizedlist>
<listitem>
<para><emphasis>scope-caller-ref</emphasis> caller's code block's
reference</para>
</listitem>
<listitem>
<para><emphasis>fn-callee-name</emphasis> callee function name</para>
</listitem>
<listitem>
<para><emphasis>symbol-ref</emphasis> invocation operation
reference</para>
</listitem>
<listitem>
<para><emphasis>arg-formal-name</emphasis> function's formal
argument</para>
</listitem>
<listitem>
<para><emphasis>arg-actual-ref</emphasis> actual argument
reference</para>
</listitem>
</itemizedlist>
<para>Each function invocation is transformed into several transcend facts
as explained below:</para>
<informaltable>
<tgroup cols="2">
<colspec colwidth="225*"/>
<colspec colwidth="775*"/>
<tbody>
<row>
<entry>(1) <code>cfa_call</code></entry>
<entry>Specifies caller's code block and callee function
name</entry>
</row>
<row>
<entry>(2) <code>dfa_callfn</code></entry>
<entry>Declares unique reference to a particular invocation
site.The reference used by other facts to supply additional
information</entry>
</row>
<row>
<entry>(3) <code>dfa_callargs</code></entry>
<entry>Declares assignment relations between actual arguments and
formal arguments</entry>
</row>
<row>
<entry>(4) <code>weak(dfa_callargs)</code></entry>
<entry>The same as form (3). <emphasis>Weak</emphasis> relation
used in cases when there is no enough information at compile time.
One such case is when several function specializations exist and
it's impossible to say which exactly specialization is
called</entry>
</row>
</tbody>
</tgroup>
</informaltable>
<para>Example:</para>
<programlisting xml:id="OpInvoc_1">name="tests/transcend-ast.cpp: ASTCorrespondence.Doc_BasicTests"
inc = function (x::int):: int
{
x + 1
}
main = function:: int
{
arg = 10:: int.
inc(arg)
}</programlisting>
<para>After translation following transcend facts are present:</para>
- <programlisting xml:id="Output_OpInvoc_1">cfa_call(1,inc)
-dfa_callfn(s(0,-2,1),inc)
+ <programlisting xml:id="Output_OpInvoc_1">cfa_call(1,"inc")
+dfa_callfn(s(0,-2,1),"inc")
weak(dfa_callargs(s(0,-2,1),s(1,-2,0),s(1,-2,1)))
dfa_callargs(s(0,-2,1),s(1,-2,0),s(1,-2,1))</programlisting>
</section>
<section>
<title>Operations. Loops</title>
<synopsis>**ast_op_map**(//symbol-result-ref//, //symbol-source-ref//, //loop-body-ref//)
**ast_op_fold**(//symbol-result-ref//, //symbol-source-ref//, //symbol-acc-ref//, //loop-body-ref//)</synopsis>
<itemizedlist>
<listitem>
<para>symbol-source-ref input list reference</para>
</listitem>
<listitem>
<para>symbol-acc-ref accumulator reference</para>
</listitem>
<listitem>
<para>symbol-result-ref result list reference</para>
</listitem>
<listitem>
<para>loop-body-ref refers to a loop body expression</para>
</listitem>
</itemizedlist>
<para>Facts declare loop operations.</para>
<para>Example:</para>
<programlisting xml:id="OpLoops_1">name="tests/transcend-ast.cpp: ASTCorrespondence.Doc_BasicTests"
test = function:: int; entry
{
singles = {1, 2, 3}:: [int].
doubles = loop map(singles->element:: int)::[int] {2 * element}.
doubles[0]
}</programlisting>
<para>produces fact: <code
xml:id="Output_OpLoops_1">ast_op_map(s(2,-2,0),s(1,-2,0),s(0,-2,1))</code></para>
</section>
</chapter>
diff --git a/documentation/build.xml b/documentation/build.xml
index 2f61382..4fa76c8 100644
--- a/documentation/build.xml
+++ b/documentation/build.xml
@@ -1,275 +1,275 @@
<?xml version="1.0" encoding="UTF-8"?>
<chapter version="5.1" xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:xila="http://www.w3.org/2001/XInclude/local-attributes"
xmlns:xi="http://www.w3.org/2001/XInclude"
xmlns:trans="http://docbook.org/ns/transclusion"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns:m="http://www.w3.org/1998/Math/MathML"
xmlns:html="http://www.w3.org/1999/xhtml"
xmlns:db="http://docbook.org/ns/docbook">
<?xxe-sn 2ckdfwgr1fk 1?>
<title><?xxe-sn 2ckdfwgr1fk 2?>Installation</title>
<section>
<?xxe-sn 2ckdfwgr1fk 6?>
<title><?xxe-sn 2ckdfwgr1fk 7?>Build on Linux</title>
<para><?xxe-sn 2ckdfwgr1fk 8?>Major dependencies:</para>
<itemizedlist>
<?xxe-sn 2ckdfwgr1fk 9?>
<listitem>
<?xxe-sn 2ckdfwgr1fk a?>
<para><?xxe-sn 2ckdfwgr1fk b?>gcc 7</para>
</listitem>
<listitem>
<?xxe-sn 2ckdfwgr1fk c?>
<para><?xxe-sn 2ckdfwgr1fk d?>llvm 5, clang 5</para>
</listitem>
<listitem>
<?xxe-sn 2ckdfwgr1fk e?>
<para><?xxe-sn 2ckdfwgr1fk f?>boost 1.66</para>
</listitem>
<listitem>
<?xxe-sn 2ckdfwgr1fk g?>
<para><?xxe-sn 2ckdfwgr1fk h?>coco</para>
</listitem>
<listitem>
<?xxe-sn 2ckdfwgr1fk i?>
<para><?xxe-sn 2ckdfwgr1fk j?>clingo</para>
</listitem>
</itemizedlist>
<para><?xxe-sn 2ckdfwgr1fk k?>Building tested on <emphasis
role="bold"><?xxe-sn 2ckdfwgr1fk l?>OpenSuse Leap 15</emphasis>. Please
change commands accordingly if using other distributions.</para>
<para><?xxe-sn 2ckdfwgr1fk m?>Pull sources directly from
repository:</para>
<literallayout><?xxe-sn 2ckdfwgr1fk n?>git clone --recursive http://xreate.org/diffusion/XR/xreate.git</literallayout>
<para><?xxe-sn 2ckdfwgr1fk o?>Enter into the source directory and run the
following script to prepare building environment. Script will install the
required system packages as well as Coco and Clingo from sources:</para>
<remark><?xxe-sn 2ckdfwgr1fk p?>"Enter into source directory" - тут перед
directory явно нужен артикль. Гугл говорит, что определенный -
the</remark>
<important>
<?xxe-sn 2ckdfwgr1fk q?>
<para><?xxe-sn 2ckdfwgr1fk r?>Carefully inspect scripts before
run</para>
</important>
<para><?xxe-sn 2ckdfwgr1fk s?>On <emphasis role="bold"><?xxe-sn 2ckdfwgr1fk t?>OpenSuse
Leap 15</emphasis>:</para>
<literallayout><?xxe-sn 2ckdfwgr1fk u?>./installation/prepare-opensuse-leap15</literallayout>
<para><?xxe-sn 2ckdfwgr1fk v?>That was one time operation to prepare
environment. After that enter into <code><?xxe-sn 2ckdfwgr1fk w?>build</code>
directory and start actual tests building:</para>
<remark><?xxe-sn 2ckdfwgr1fk x?>"build directory": здесь ты все-таки
вначале указываешь имя объекта (build), и лишь потом родовое название
(directory)</remark>
<literallayout><?xxe-sn 2ckdfwgr1fk y?>cd build
make</literallayout>
<para><?xxe-sn 2ckdfwgr1fk z?>After successful build you can run xreate
tests:</para>
<literallayout><?xxe-sn 2ckdfwgr1fk 10?>cd ..
./build/tests/xreate-tests</literallayout>
<note>
<?xxe-sn 2ckdfwgr1fk 11?>
<para><?xxe-sn 2ckdfwgr1fk 12?>Please pay attention that the working
directory should be the repository root</para>
</note>
<para><?xxe-sn 2ckdfwgr1fk 13?>For consequent rebuilds after updates etc
invoke <code><?xxe-sn 2ckdfwgr1fk 14?>cmake</code> as follows:</para>
<literallayout><?xxe-sn 2ckdfwgr1fk 15?>#working dir build
cmake -DCMAKE_BUILD_TYPE=Debug \
-DBUILD_XREATE_TESTS=1 \
-DCOCO_EXECUTABLE=<FILE> \
-DCLINGO_PATH=<DIR> \
-DCOCO_FRAMES_PATH=../vendors/coco/generator/ \
-DCMAKE_CXX_COMPILER=g++ ../cpp
make</literallayout>
<para><?xxe-sn 2ckdfwgr1fk 16?><code><?xxe-sn 2coi7ojavb4 a?>cmake</code>'s
selected parameters:</para>
<itemizedlist>
<?xxe-sn 2ckdfwgr1fk 17?>
<listitem>
<?xxe-sn 2ckdfwgr1fk 18?>
<para><?xxe-sn 2ckdfwgr1fk 19?>BUILD_XREATE_TESTS Determines whether
to build tests</para>
</listitem>
<listitem>
<?xxe-sn 2ckdfwgr1fk 1a?>
<para><?xxe-sn 2ckdfwgr1fk 1b?>COCO_EXECUTABLE Full filename of Coco
executable</para>
</listitem>
<listitem>
<?xxe-sn 2ckdfwgr1fk 1c?>
<para><?xxe-sn 2ckdfwgr1fk 1d?>CLINGO_PATH Installed Clingo
directory</para>
<remark><?xxe-sn 2ckdfwgr1fk 1e?>"Directory of Clingo installation":
может, with Clingo installation? (это если речь идет о папке, где
хранятся инсталляционные файлы) Если наоборот, куда будет
устанавливаться - тогда Directory for installing Clingo. Оригинальный
вариант ("of Clingo installation") немного сбивает с толку.</remark>
</listitem>
</itemizedlist>
</section>
<section>
<?xxe-sn 2coi7ojavb4 1?>
<title condition="demo"><?xxe-sn 2coi7ojavb4 2?>Experimenting</title>
<para><?xxe-sn 2coi7ojavb4 3?>At this point the only executable produced
by <code><?xxe-sn 2coi7ojavb4 x?>make</code> is a collection of the unit
tests. There are many existing unit tests located in the <code><?xxe-sn 2coi7ojavb4 y?>cpp/tests</code>
to check correctness of various compilation aspects. Unit tests are
configured via the file <code><?xxe-sn 2coi7ojavb4 5?>config/default.json</code>
with the relevant settings located in the section <code><?xxe-sn 2coi7ojavb4 6?>tests</code>.
The section looks like this:</para>
<literallayout><?xxe-sn 2coi7ojavb4 b?>"tests": {
"template": "default",
"templates": {
"default": "*",
"documentation": "Modules.Doc_*:Modules_API.Doc_*",
"ast": "AST.*",
...
}
}</literallayout>
<para><?xxe-sn 2coi7ojavb4 c?>Key <code><?xxe-sn 2coi7ojavb4 d?>tests.template</code>
determines which group of unit tests should be executed, while section
<code><?xxe-sn 2coi7ojavb4 e?>test.templates</code> describes all
available groups. Note, that exact syntax of unit tests selection is
described in the Google Tests library documentation. By modifying this
configuration you can choose which tests you want to execute. </para>
<para><?xxe-sn 2coi7ojavb4 f?>In order to experiment with the compiler you
need to write your own unit-tests. There are several steps to complete to
add and run new unit tests:</para>
<itemizedlist>
<?xxe-sn 2coi7ojavb4 g?>
<listitem>
<?xxe-sn 2coi7ojavb4 h?>
<para><?xxe-sn 2coi7ojavb4 i?>Add new file to the <code><?xxe-sn 2coi7ojavb4 j?>cpp/tests</code>.</para>
</listitem>
<listitem>
<?xxe-sn 2coi7ojavb4 k?>
<para><?xxe-sn 2coi7ojavb4 l?>Register test by adding its filename to
the variable <code><?xxe-sn 2coi7ojavb4 10?>TEST_FILES</code> in the
<code><?xxe-sn 2coi7ojavb4 m?>test/CMakeLists.txt</code>.</para>
</listitem>
<listitem>
<?xxe-sn 2coi7ojavb4 n?>
<para><?xxe-sn 2coi7ojavb4 o?>Change <code><?xxe-sn 2coi7ojavb4 p?>config/default.json</code>
accordingly.</para>
</listitem>
</itemizedlist>
<para><?xxe-sn 2coi7ojavb4 q?>Below is a bare bones example of a unit-test
as a starting point to get an idea:</para>
<literallayout><?xxe-sn 2coi7ojavb4 r?>name="tests/unit-test-example: Example.Example1", lines=15
#include "xreatemanager.h" //main Xreate header
#include "transcendlayer.h"
#include <gtest/gtest.h>
using namespace xreate;
using namespace std;
TEST(Example, Example1){
//(Optional) Your custom transcend rules if any
string rules =
R"SCRIPT(
- bind_func(sum, entry).
+ bind_func("sum", entry).
)SCRIPT";
//Your custom program
string example =
R"CODE(
//Custom code
sum = function(a:: int, b:: int):: int
{
a + b
}
)CODE";
//Initialize compiler
unique_ptr<XreateManager> man(XreateManager::prepare(move(example)));
//Add transcend part:
man->transcend->addRawScript(move(rules));
//Define signature of your entry function:
typedef int (*ENTRYFN)(int, int);
//Compile the example and get a pointer to the entry function:
ENTRYFN yourEntryFn = (ENTRYFN) man->run();
//Now execute function and check the result
int resultActual = yourEntryFn(5, 7);
int resultExpected = 5 + 7;
ASSERT_EQ(resultExpected, resultActual);
}</literallayout>
<para><?xxe-sn 2coi7ojavb4 u?>It outlines common unit test structure:
defines a program and optional transcend rules(in this case to designate
<code><?xxe-sn 2coi7ojavb4 w?>sum</code> as an entry function). Then the
program is compiled, executed and the result is checked against expected
value. </para>
<para><?xxe-sn 2coi7ojavb4 11?>Have a look at other existing unit tests
and see <link xlink:href="/api"><?xxe-sn 2coi7ojavb4 z?>Internal
API</link> to know more. </para>
</section>
</chapter>
diff --git a/documentation/index.xml b/documentation/index.xml
index 38c577d..6bd404c 100644
--- a/documentation/index.xml
+++ b/documentation/index.xml
@@ -1,434 +1,434 @@
<?xml version="1.0" encoding="UTF-8"?>
<chapter version="5.1" xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:xila="http://www.w3.org/2001/XInclude/local-attributes"
xmlns:xi="http://www.w3.org/2001/XInclude"
xmlns:trans="http://docbook.org/ns/transclusion"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns:m="http://www.w3.org/1998/Math/MathML"
xmlns:html="http://www.w3.org/1999/xhtml"
xmlns:db="http://docbook.org/ns/docbook">
<?xxe-sn 2b06cb2u4g0 1?>
<title><?xxe-sn 2b06cb2u4g0 2?>Xreate Manual</title>
<para><?xxe-sn 2b06cb2u4g0 6?>Xreate is an open source general purpose high
level programming language designed to write efficient and safe computer
programs.</para>
<para><?xxe-sn 2b06cb2u4g0 8?>Here "high level" refers to the developer
oriented side meaning exactly an ability to easily write, read, reuse, as
well as adapt software to a constantly changing environment or business
goals. In this respect, any software product can be evaluated on the basis
of three dimensions: efficiency, safety, and flexibility. Unfortunately,
those properties are proved to be largely contradictory, for it is
manageable to write either efficient (yet unsafe) or safe (yet impractical)
code, but not both. Thus, the ultimate goal of the language is to allow
developers to produce code that would have all these properties at the same
time. Blending features of seemingly incompatible programming paradigms is a
basis of Xreate's design principles.</para>
<para><?xxe-sn 2b06cb2u4g0 7?>To achieve the aforementioned design goals,
Xreate consists of three distinctive layers:</para>
<itemizedlist>
<?xxe-sn 2b06cb2u4g0 e?>
<listitem>
<?xxe-sn 2b06cb2u4g0 f?>
<para><?xxe-sn 2b06cb2u4g0 g?><link xlink:href="/d/syntax/"><?xxe-sn 2b06cb2u4g0 o?>Brute</link>.
The lowest layer is called <emphasis><?xxe-sn 2b06cb2u4g0 p?>Brute
</emphasis>— this is code that is intended to be actually compiled. Code
on this level implements actual software functionality. It resembles the
usual imperative languages' apparatus and consists of executable
instructions such as arithmetic, branching, input / output, etc.</para>
</listitem>
<listitem>
<?xxe-sn 2b06cb2u4g0 i?>
<para><?xxe-sn 2b06cb2u4g0 j?><link xlink:href="/d/transcend/"><?xxe-sn 2b06cb2u4g0 q?>Transcend</link>.
Brute alone is not enough to constitute a full-fledged language since
code requires various non-executable metadata to express developer's
intents, check correctness, validity and perform other types of
analyses. In Xreate everything of this sort belongs to a declarative
type layer called <emphasis><?xxe-sn 2b06cb2u4g0 s?>Transcend</emphasis>.
Transcend is a logic reasoner that is appropriate to do management-type
work — it analyzes, oversees and controls Brute by guiding compilation
process. More precisely, everything on this level, logic or transcend
facts and rules, is gathered and sent to an external logic solver to
make solutions that are brought back in order to guide compilation.
Unlike usual static analysis tools, Transcend directly controls
compilation(see <link xlink:href="#basic-example"><?xxe-sn 2dc49lhpp1c 4?>Basic
Example</link>) and able to make decisions even based on data available
only at runtime(see <link
xlink:href="/d/transcend/late-transcend/"><?xxe-sn 2dc49lhpp1c 5?>Late
Transcend</link>)</para>
</listitem>
<listitem>
<?xxe-sn 2b06cb2u4g0 l?>
<para><?xxe-sn 2b06cb2u4g0 m?><link
xlink:href="/d/concepts/interpretation/"><?xxe-sn 2b06cb2u4g0 r?>Interpretation</link>.
There is also <emphasis><?xxe-sn 2b06cb2u4g0 t?>Interpretation</emphasis>
— the intermediate level resembling dynamically typed languages that is
used as a contact point and interpreter between Brute and Transcend. See
an <link
xlink:href="/d/concepts/interpretation/#querying-example-gui"><?xxe-sn 2fxwo1r89a8 r?>example</link>.</para>
</listitem>
</itemizedlist>
<para><?xxe-sn 2b06cb2u4g0 u?>On a syntactic level, Xreate is a procedural
language with extensive use of <emphasis><?xxe-sn 2b06cb2u4g0 v?><link
xlink:href="/d/transcend/"><?xxe-sn 2b06cb2u4g0 w?>annotations</link></emphasis>
— arbitrary unconstrained metadata that a software developer can attach to
different language constructs, variables and code blocks. Annotations are
completely invisible for the compiler proper and used by Transcend more as a
suggestion conveying additional information.</para>
<remark><?xxe-sn 2ccp2iy80zj 1td6aqezxvj7l?>"a different language
constructs": если подразумевается "конструкции разных языков", тогда лучше
"different languages' constructs". Если конструкции языка, в целом, то тогда
артикль a не нужен</remark>
<para><?xxe-sn 2da0r0b6680 2?>There are several extensions already
implemented to give a feeling what does this structure can be used for.
<link xlink:href="/d/concepts/containers/"><?xxe-sn 2da0r0b6680 3?>Containers</link>
chapter describes that it is possible to reason about and automatically
choose the most appropriate data structure's implementation depending on how
it is used in the code. Look at the example below:</para>
<programlisting><?xxe-sn 2da0r0b6680 4?>x = [1, 2, 3]:: [int].</programlisting>
<para><?xxe-sn 2da0r0b6680 5?>Container <code><?xxe-sn 2da0r0b6680 6?>x</code>
does not have well defined implementation just yet. Only by looking how it
is used throughout the code, the compiler is able to decide how exactly to
store container's data.</para>
<para><?xxe-sn 2da0r0b6680 7?>Interaction of different components and joint
use of external resources is covered by <link
xlink:href="/d/exploitation/"><?xxe-sn 2da0r0b6680 8?>Exploitation</link>:</para>
<programlisting><?xxe-sn 2da0r0b6680 9?>logger = createFileLogger("/some/file"):: Logger.
...
write(logger, "First log entry").
...
write(logger, "Last log entry").</programlisting>
<para><?xxe-sn 2da0r0b6680 a?>Exploitation reasoning allows to determine
when it is the <emphasis><?xxe-sn 2dc0uidlnnk 1?>first</emphasis>,
<emphasis><?xxe-sn 2dc0uidlnnk 2?>last</emphasis> access to resources such
as files, in other words, it infers access order. As a result it is possible
to automatically initialize / destruct related resources. Unlike RAII, an
another related technique, Exploitation is reserved to manage resources
usage that spans across different parts of a program: modules, plugins,
etc.</para>
<para><?xxe-sn 2dc0uidlnnk 8?><link
xlink:href="/d/virtualization/"><?xxe-sn 2dc0uidlnnk 4?>Virtualization</link>
reasoning also helps to work with external resources by enabling access
control <emphasis><?xxe-sn 2dc0uidlnnk 5?>if and when it is needed
only</emphasis>. Example:</para>
<programlisting><?xxe-sn 2dc0uidlnnk 6?>openFile("/some/file"):: string; assign_sizo(zoneA).
openFile("/some/file"):: string; assign_sizo(zoneB).</programlisting>
<para><?xxe-sn 2dc0uidlnnk 7?>If the compiler recognizes file access from
the different zones, as in this example, it applies an appropriate
virtualization strategy enough to ensure that instructions that belong to
different zones do not interfere with each other.</para>
<para><?xxe-sn 2cdtco54w00 3?>Unlike "pure", academic languages, Xreate
targets safe and reliable usage of effectful computations such as IO that is
covered above as well as mutable structures described in the <link
xlink:href="/d/communication/"><?xxe-sn 2b3f3osfk74 l?>Communication</link>
chapter.</para>
<para><?xxe-sn 2dc49lhpp1c 2?>Note, that the described extensions are not
part of the compiler and developers can write their own custom transcend
rules to cover other aspects.</para>
<section>
<?xxe-sn 2b06cb2u4g0 3?>
<title><?xxe-sn 2b06cb2u4g0 4?>Basic Example</title>
<para><?xxe-sn 2b06cb2u4g0 5?>To demonstrate what Xreate is all about,
basic example is given below:</para>
<programlisting xml:id="Example_1"><?xxe-sn 2b06cb2u4g0 x?>name="tests/introduction.cpp: Introduction.Doc_Example_1", lines=15
guard:: iAmVeryFast
{
div = function(a:: int, b:: int):: int
{
a / b
}
}
guard:: iAmVerySafe
{
div = function(a:: int, b:: int):: int
{
if ( b == 0 ):: int { zeroDivisionErrCode() } else { a / b }
}
}
test = function:: int; entry; iAmVerySecure
{
div(10, 5)
}</programlisting>
<para><?xxe-sn 2b06cb2u4g0 y?>Here entry point of the program is a
function <code><?xxe-sn 2b06cb2u4g0 z?>test</code> recognized so by the
compiler because of annotation <code><?xxe-sn 2b06cb2u4g0 10?>entry</code>
in its signature. There are also two functions with the same name
<code><?xxe-sn 2b06cb2u4g0 11?>div</code> called <emphasis><?xxe-sn 2b06cb2u4g0 12?>specializations</emphasis>.
Each specialization has a guard that defines a <emphasis><?xxe-sn 2dc49lhpp1c 1?>condition</emphasis>
that has to be met in order to invoke this particular specialization. In
the example, specializations of <code><?xxe-sn 2b06cb2u4g0 13?>div</code>
have <code><?xxe-sn 2b06cb2u4g0 14?>iAmVeryFast</code> and <code><?xxe-sn 2b06cb2u4g0 15?>iAmVerySafe</code>
guards, respectively. Let's say that a code author writes two
specializations where the first one is a very fast division
implementation, while the second one is a very safe division
implementation since it checks division by zero, being "unacceptably slow"
due to an extra check instruction, though. This is a basis of <link
xlink:href="/d/concepts/polymorphism/"><?xxe-sn 2b3f3osfk74 2?>polymorphism</link>
— client's code <code><?xxe-sn 2b3f3osfk74 3?>test</code> is able to work
with any specialization, and the compiler must decide which one to invoke
with the only hint it has — annotation <code><?xxe-sn 2b3f3osfk74 5?>iAmVerySecure</code>
in the function <code><?xxe-sn 2b3f3osfk74 7?>test</code>'s
signature.</para>
<remark><?xxe-sn 2ccp2iy80zj 1td6aqezxvj7n?>"provides two specializations"
- возможно, лучший вариант "designates/assigns/allocates two
specializations". Или даже просто specifies/indicates. (PS заменил на
specifies)</remark>
<remark><?xxe-sn 2ccp2iy80zj 1td6aqezxvj7m?>"unbearably slow" - я бы
заменил на более нейтральное "too slow". Unbearable - это скорее об
ощущениях человека. Или, если под "unbearably" имеется в виду "недопустимо
медленный", тогда - unacceptably slow.</remark>
<note>
<?xxe-sn 2b3f3osfk74 n?>
<para><?xxe-sn 2b3f3osfk74 o?>All annotations (except <code><?xxe-sn 2b3f3osfk74 m?>entry</code>)
are custom defined by developer itself.</para>
</note>
<para><?xxe-sn 2b3f3osfk74 6?>This is when Transcend comes into play. By
adding a transcend rule as shown below it is possible to associate
annotation <code><?xxe-sn 2b3f3osfk74 8?>iAmVerySecure</code> with
invocation of specialization guarded by <code><?xxe-sn 2b3f3osfk74 9?>iAmVerySafe:</code></para>
<programlisting xml:id="Transcend_Example_1"><?xxe-sn 2b3f3osfk74 a?>name="tests/introduction.cpp: Introduction.Doc_Example_1", lines=15
dfa_callguard(SiteInv, iAmVerySafe):-
- dfa_callfn(SiteInv, div);
+ dfa_callfn(SiteInv, "div");
SiteInv = s(_, _, ScopeInv);
cfa_parent(ScopeInv, function(FnInv));
bind_func(FnInv, iAmVerySecure).</programlisting>
<para><?xxe-sn 2b3f3osfk74 b?>Transcend rules are written in ASP syntax —
common syntax to write logic programs. This particular rule reads that for
any function annotated with <code><?xxe-sn 2b3f3osfk74 c?>iAmVerySecure</code>,
certain specialization <code><?xxe-sn 2b3f3osfk74 d?>iAmVerySafe</code> is
chosen for <code><?xxe-sn 2b3f3osfk74 e?>div</code> invocation.</para>
<note>
<?xxe-sn 2b3f3osfk74 p?>
<para><?xxe-sn 2b3f3osfk74 q?>In this example an appropriate
specialization is statically resolved, so the other specialization isn't
even compiled.</para>
<remark><?xxe-sn 2ccp2iy80zj 1td6aqezxvj7o?>the, потому что их всего
две.</remark>
</note>
<para><?xxe-sn 2b3f3osfk74 f?>By providing custom rules it is possible to
implement any polymorphism strategy, be it performed statically or
dynamically. The example demonstrates basic workflow: Transcend gathers
available information about a program such as annotations and using custom
rules makes decisions to guide various aspects of compilation process,
particularly by selecting appropriate specializations as in the above
example.</para>
</section>
<section>
<?xxe-sn 2fchdmt7vgg 1?>
<title><?xxe-sn 2fchdmt7vgg 2?>More Advanced Example</title>
<para><?xxe-sn 2fchdmt7vgg 3?>Suppose we write a program to generate a web
page consisting of several blocks(e.g. a header, a footer) constructed
independently by different parts of our program. In order to organise the
code, we express our <emphasis><?xxe-sn 2fs1xxghz93 -wunr7fl0rw8v?>intention</emphasis>
that all blocks should be sent to a client in a very specific order: first
a header, then a body and footer, as below:</para>
<programlisting xml:id="ExampleEov_1_Expectation"><?xxe-sn 2fchdmt7vgg 4?>name="tests/exploitation.cpp: Exploitation.Doc_ExampleEov_1", lines=15
eov_expect(
webpage, header, body; %we expect body to be sent after header
webpage, body, footer %.. and footer after body
).</programlisting>
<para><?xxe-sn 2fchdmt7vgg 5?>This is similar to <link
xlink:href="/d/exploitation/"><?xxe-sn 2fchdmt7vgg a?>Exploitation</link>:
we are working with the external resource <code><?xxe-sn 2fchdmt7vgg b?>webpage</code>
and want to take into account an exact order of resource exploiting
operations. Then, we write code like this:</para>
<programlisting><?xxe-sn 2fchdmt7vgg c?>send("Header"):: Content; eov_checkpoint(webpage, header).</programlisting>
<para><?xxe-sn 2fchdmt7vgg d?>We mark the operations we are interesting in
as <emphasis><?xxe-sn 2fchdmt7vgg e?>checkpoints</emphasis>(here
<code><?xxe-sn 2fds09lgw74 1?>header</code> is the name of a checkpoint
and <code><?xxe-sn 2fds09lgw74 3?>webpage</code> is the resource the
checkpoint refers to) and want to know are checkpoints executed in the
expected(as defined above) order.</para>
<para><?xxe-sn 2fchdmt7vgg f?>If it so happens that these blocks are
constructed in the correct order in our program we <emphasis><?xxe-sn 2fchdmt7vgg 6?>may</emphasis>
send them immediately. Otherwise, we must cache already constructed
content till a whole page is generated to ensure correctness. In other
words, clearly, there is an opportunity for optimizations for caching has
not only memory overhead but delays response latency(time before the first
block is sent) as well. We write two implementations <code><?xxe-sn 2fchdmt7vgg 7?>immediate_output</code>
and <code><?xxe-sn 2fchdmt7vgg 8?>cached_output</code> each for the
corresponding case:</para>
<programlisting xml:id="ExampleEov_1_Specializations"><?xxe-sn 2fchdmt7vgg 9?>name="tests/exploitation.cpp: Exploitation.Doc_ExampleEov_1", lines=15
//type to store either sending error code or cached content
Content = type variant {
errcode:: int,
message:: string
}.
//Send immediately:
guard:: immediate_output
{
send = function(content:: string):: Content
{
errcode(printf("%s", content))
}
}
//Cache content to send it later:
guard:: cached_output
{
send = function(content:: string):: Content
{
message(content)
}
}</programlisting>
<para><?xxe-sn 2fchdmt7vgg g?>These implementations should be registered
for the compiler to know which one to use:</para>
<programlisting xml:id="ExampleEov_1_Registration"><?xxe-sn 2fchdmt7vgg h?>name="tests/exploitation.cpp: Exploitation.Doc_ExampleEov_1", lines=15
eov_analysis(
success, immediate_output;
fail, cached_output
).</programlisting>
<para><?xxe-sn 2fchdmt7vgg i?>Predicate <code><?xxe-sn 2fchdmt7vgg j?>eov_analysis</code>
compares actual checkpoints execution order with the expected one and
chooses either of two implementations depending on the result. This way,
it is guarantied that immediate sending is chosen only if it is safe to do
so to avoid unnecessary caching.</para>
<para><?xxe-sn 2fchdmt7vgg k?>Thus we can safely change and adapt our
program knowing that clients always receive web page's content in the
correct order by automatically employing the most efficient content
delivery strategy depending on particular circumstances.</para>
</section>
<section>
<?xxe-sn 2fs1xxghz93 -wunr7fl0rw8u?>
<title><?xxe-sn 2fs1xxghz93 -wunr7fl0rw8t?>Differences from other
languages</title>
<para><?xxe-sn 2fs1xxghz93 -wunr7fl0rw8s?>it is convenient to talk about
<emphasis><?xxe-sn 2fs1xxghz93 -wunr7fl0rw88?>intentions</emphasis> in
order to outline a vast landscape of programming languages and point out
the place of Xreate on it, i.e. to compare languages depending on do they
allow to express a developer's intentions along with raw code that can be
used on many occasions, e.g. to validate the code's correctness.
Traditionally type system is used to declare intentions. At closer look,
types in (imperative) statically typed languages contain inseparable
combination of the following:</para>
<itemizedlist>
<?xxe-sn 2fs1xxghz93 -wunr7fl0rw8q?>
<listitem>
<?xxe-sn 2fs1xxghz93 -wunr7fl0rw8p?>
<para><?xxe-sn 2fs1xxghz93 -wunr7fl0rw8o?>Intentions, such as "that
variable is a string".</para>
</listitem>
<listitem>
<?xxe-sn 2fs1xxghz93 -wunr7fl0rw8n?>
<para><?xxe-sn 2fs1xxghz93 -wunr7fl0rw8m?>Usage patterns: a new code
should play nicely with the rest of a program, e.g. if a program works
with unicode, a new string variable should be also of unicode family
type(even if this is not necessary for a given part of code)</para>
</listitem>
<listitem>
<?xxe-sn 2fs1xxghz93 -wunr7fl0rw8l?>
<para><?xxe-sn 2fs1xxghz93 -wunr7fl0rw8k?>Platform constraints, e.g.
if a platform supports wide strings natively, a new string variable
should also be a wide string.</para>
</listitem>
</itemizedlist>
<para><?xxe-sn 2fs1xxghz93 -wunr7fl0rw8j?>In this regard, in general,
statically typed languages are <emphasis><?xxe-sn 2fs1xxghz93 -wunr7fl0rw8i?>overconstrained</emphasis>,
they require developers to provide more information than they intend to.
This usually hinders code reuse and adaptation; to work on a new platform,
software requires porting: a process of re-expressing underlying
intentions once again with the new platform's constraints.</para>
<para><?xxe-sn 2fs1xxghz93 -wunr7fl0rw8h?>On the other side, dynamically
typed languages are <emphasis><?xxe-sn 2fs1xxghz93 -wunr7fl0rw8g?>underconstrained</emphasis>,
since they do not allow to express all desirable intentions. This leads to
disastrous inefficiency and code fragility because any errors can be
caught only at runtime.</para>
<para><?xxe-sn 2fs1xxghz93 -wunr7fl0rw8f?>As an example, OOP languages are
hugely successful among other reasons because they provide
<emphasis><?xxe-sn 2fs1xxghz93 -wunr7fl0rw8e?>classes</emphasis> to more
finely express intentions, e.g. <code><?xxe-sn 2fs1xxghz93 -wunr7fl0rw8d?>String</code>,
<code><?xxe-sn 2fs1xxghz93 -wunr7fl0rw8c?>UnicodeString</code>,
<code><?xxe-sn 2fs1xxghz93 -wunr7fl0rw8b?>Utf8String</code> with exact
behaviour being hidden in implementation details.</para>
<para><?xxe-sn 2fs1xxghz93 -wunr7fl0rw8a?>Xreate in its turn is based on
the idea to allow developers express as much or as little intentions as
they want to. This is a way to reach one of the the language's goals to
facilitate writing of easily reusable and adaptable software. On a syntax
level, annotations are used to express intentions, e.g. <code><?xxe-sn 2fs1xxghz93 -wunr7fl0rw87?>string;i_dont_need(utf8)</code>(note
the modality, annotations can express boundaries, preferences, etc. ).
</para>
<para><?xxe-sn 2fxwo1r89a8 1?>This approach obviously leads to problems
with software's performance and efficiency. For most high level languages,
compilers rely on defaults to fill in unspecified by the developer gaps in
the exact implementation details. Usually languages provide standard,
default data structures the developer have no control over. However Xreate
follows another approach: to resolve this contradiction, the compiler
determines necessary implementation details not only depending on
annotations, but also by looking at usage patterns along with platform
properties trying to infer most efficient implementations in any given
circumstances.</para>
</section>
</chapter>
diff --git a/grammar/universal.ATG b/grammar/universal.ATG
new file mode 100644
index 0000000..a2ac29c
--- /dev/null
+++ b/grammar/universal.ATG
@@ -0,0 +1,60 @@
+#include "aux/universal.h"
+
+COMPILER Universal
+
+bool checkTokenAfterIdent(int key){
+ if (la->kind != _ident) return false;
+ return scanner->Peek()->kind == key;
+}
+
+bool checkAssignment()
+{
+ return checkTokenAfterIdent(_assign);
+}
+
+CHARACTERS
+ letter = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".
+ digit = "0123456789".
+ any = ANY - '"'.
+ cr = '\r'.
+ lf = '\n'.
+ tab = '\t'.
+
+TOKENS
+ string = '"' { any } '"'.
+ ident = (letter | '_') {letter | digit | '_'}.
+ assign = '='.
+ lp = '('.
+ rp = ')'.
+ tagcolon = "::".
+
+COMMENTS FROM "/*" TO "*/" NESTED
+COMMENTS FROM "//" TO lf
+
+IGNORE cr + lf + tab
+
+PRODUCTIONS
+
+ArgList = lp { Expr [','] } rp.
+Block = '{' '}'.
+
+MetaExpr = ident [MetaArgList].
+MetaArgList = lp { MetaExpr [','] } rp.
+MetaExprList = {MetaExpr ';'}.
+
+Expr =
+ ident (. send(std::wstring(L"Expr: ") + t->val); .)
+ [ArgList]
+ [tagcolon MetaExprList]
+ {ident Block} [Block]
+.
+
+Decl =
+ (IF(checkAssignment()) ident (. send(std::wstring(L"Decl: ") + t->val); .)
+ assign | )
+ Expr
+.
+
+Universal = {Decl ['.']} .
+
+END Universal.
diff --git a/grammar/xreate.ATG b/grammar/xreate.ATG
index abdb3f0..84ac92c 100644
--- a/grammar/xreate.ATG
+++ b/grammar/xreate.ATG
@@ -1,707 +1,707 @@
//TODO add ListLiteral
//TODO ExprTyped: assign default(none) type
#include "ast.h"
#include "ExternLayer.h"
#include <string>
#include <stack>
#define wprintf(format, ...) \
char __buffer[100]; \
wcstombs(__buffer, format, 100); \
fprintf(stderr, __buffer, __VA_ARGS__)
using namespace std;
COMPILER Xreate
details::inconsistent::AST* root = nullptr; // current program unit
void ensureInitalizedAST(){
if (root == nullptr) root = new details::inconsistent::AST();
}
struct {
std::stack<CodeScope*> scopesOld;
CodeScope* scope = nullptr;
} context;
void pushContextScope(CodeScope* scope){
context.scopesOld.push(context.scope);
context.scope = scope;
}
void popContextScope(){
context.scope = context.scopesOld.top();
context.scopesOld.pop();
}
int nextToken()
{
scanner->ResetPeek();
return scanner->Peek()->kind;
}
bool checkTokenAfterIdent(int key){
if (la->kind != _ident) return false;
return nextToken() == key;
}
bool checkParametersList()
{
return la->kind == _ident && nextToken() == _lparen;
}
bool checkInfix()
{
return la->kind == _ident && nextToken() == _ident;
}
bool checkIndex()
{
return la->kind == _ident && nextToken() == _lbrack;
}
bool checkFuncDecl()
{
if (la->kind != _ident) return false;
int token2 = nextToken();
int token3 = scanner->Peek()->kind;
return token2 == _assign && (token3 == _function || token3 == _pre);
}
bool checkAssignment()
{
if (la->kind != _ident) return false;
scanner->ResetPeek();
int token2 = scanner->Peek()->kind;
if (token2 == _lcurbrack) {
scanner->Peek();
int token3 = scanner->Peek()->kind;
if (token3 != _rcurbrack) return false;
int token4 = scanner->Peek()->kind;
return token4 == _assign;
}
return token2 == _assign;
}
void recognizeIdentifier(Expression& i){
if (!context.scope->recognizeIdentifier(i)){
root->postponeIdentifier(context.scope, i);
}
}
enum SwitchKind{SWITCH_NORMAL, SWITCH_META};
CHARACTERS
letter = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".
any = ANY - '"'.
digit = "0123456789".
cr = '\r'.
lf = '\n'.
tab = '\t'.
TOKENS
- ident = (letter | '_') {letter | digit | '_'}.
- number = (digit | '-' digit) {digit}.
+ ident = (letter ['-' letter] | '_') {letter ['-' letter] | digit | '_' }.
+ number = digit{digit}.
string = '"' { any } '"'.
function = "function".
pre = "pre".
comma = ','.
period = '.'.
lparen = '('.
rparen = ')'.
lbrack = '['.
rbrack = ']'.
lcurbrack = '{'.
rcurbrack = '}'.
equal = "==".
assign = '='.
implic = '-' '>'.
colon = ':'.
context = "context".
tagcolon = "::".
lse = "<=".
lss = "<".
gte = ">=".
gtr = ">".
ne1 = "!=".
ne2= "<>".
COMMENTS FROM "/*" TO "*/" NESTED
COMMENTS FROM "//" TO lf
IGNORE cr + lf + tab
PRODUCTIONS
Xreate = (. Function* function; ensureInitalizedAST(); .)
{( //RuleDecl
InterfaceData | Imprt | GuardSection
| IF(checkFuncDecl()) FDecl<function> (. root->add(function); .)
| TDecl
| SkipModulesSection
)} (. .)
.
Ident<std::wstring& name>
= ident (. name = t->val; .).
VarIdent<Expression& e>
= ident (. e = Expression(Atom<Identifier_t>(t->val)); .)
[ lcurbrack (
ident (. SemErr(coco_string_create("var version as ident is not implemented yet")); .)
| number (. Attachments::put<versions::VariableVersion>(e, Atom<Number_t>(t->val).get()); .)
) rcurbrack ]
.
FDecl<Function*& f> = (. std::wstring fname; std::wstring argName; TypeAnnotation typIn; TypeAnnotation typOut; bool flagIsPrefunct = false; Expression binding; .)
Ident<fname> assign
[pre (. flagIsPrefunct = true; .)]
function (. f = new Function(fname); f->isPrefunction = flagIsPrefunct; CodeScope* entry = f->getEntryScope(); .)
[lparen Ident<argName> tagcolon ExprAnnotations<binding> (. f->addBinding(Atom<Identifier_t>(argName), move(binding)); .)
{comma Ident<argName> tagcolon ExprAnnotations<binding> (. f->addBinding(Atom <Identifier_t>(argName), move(binding));.)
} rparen]
[ tagcolon
( IF(flagIsPrefunct) FnTag<f>
| Type<typOut>
)
{';' FnTag<f> }]
BDecl<entry> (. const_cast<Expression&>(entry->getBody()).bindType(move(typOut));.)
.
GuardSection<>= (. Expression guard; Function* f; .)
"guard" tagcolon MetaSimpExpr<guard>
lcurbrack { FDecl<f> (. f->guard = guard; root->add(f); .)
} rcurbrack.
/**
* TYPES
*
*/
TypeTerm<TypePrimitive& typ> = (. std::wstring tid; .)
("string" (. typ = TypePrimitive::String;.)
| "num" (. typ = TypePrimitive::Num;.)
| "int" (. typ = TypePrimitive::Int;.)
| "float" (. typ = TypePrimitive::Float;.)
| "bool" (. typ = TypePrimitive::Bool; .)
| "i8" (. typ = TypePrimitive::I8; .)
| "i32" (. typ = TypePrimitive::I32; .)
| "i64" (. typ = TypePrimitive::I64; .)
).
Type<TypeAnnotation& typ> = (. TypeAnnotation typ2; TypePrimitive typ3; std::wstring tid; std::string field; .)
(
TList<typ>
| TRecord<typ>
| TVariant<typ>
| TSlave<typ>
| TypeTerm<typ3> (. typ = typ3; .)
| IF (checkIndex()) Ident<tid> lbrack
TypeIndex<field> (. typ = TypeAnnotation(TypeOperator::ACCESS, {}); typ.__valueCustom = Atom<Identifier_t>(tid).get(); typ.fields.push_back(field); .)
{comma TypeIndex<field> (. typ.fields.push_back(field); .)
} rbrack
| Ident<tid> (. typ = TypeAnnotation(TypeOperator::CUSTOM, {}); typ.__valueCustom = Atom<Identifier_t>(tid).get(); .)
[lparen Type<typ2> (. typ.__operator = TypeOperator::CALL; typ.__operands.push_back(typ2); .)
{comma Type<typ2> (. typ.__operands.push_back(typ2); .)
} rparen]
| '*' (.typ = TypeAnnotation(); .)
) .
TypeIndex<std::string& name> =
(
number (. name = Atom<Identifier_t>(t->val).get(); .)
| string (. name = Atom<String_t>(t->val).get(); .)
)
.
TList<TypeAnnotation& typ> = (. TypeAnnotation ty; .)
lbrack Type<ty> rbrack (. typ = TypeAnnotation(TypeOperator::LIST_ARRAY, {ty}); .)
.
TRecord<TypeAnnotation& typ> = (. TypeAnnotation t; std::wstring key; size_t keyCounter=0; .)
lcurbrack
(
IF(checkTokenAfterIdent(_tagcolon)) Ident<key> tagcolon Type<t>
| Type<t> (. key = to_wstring(keyCounter++); .)
) (. typ = TypeAnnotation(TypeOperator::LIST_RECORD, {t}); typ.fields.push_back(Atom<Identifier_t>(key).get()); .)
{comma (
IF(checkTokenAfterIdent(_tagcolon)) Ident<key> tagcolon Type<t>
| Type<t> (. key = to_wstring(keyCounter++); .)
) (. typ.__operands.push_back(t); typ.fields.push_back(Atom<Identifier_t>(key).get()); .)
} rcurbrack.
TVariant<TypeAnnotation& typ>= (. TypeAnnotation t, typVoid; std::vector<TypeAnnotation> operands; std::vector<Atom<Identifier_t>> keys; std::wstring variant; .)
"variant" lcurbrack
Ident<variant> (. t=typVoid; .)
[tagcolon Type<t>] (. keys.push_back(Atom<Identifier_t>(variant)); operands.push_back(t); .)
{comma Ident<variant> (. t=typVoid; .)
[tagcolon Type<t>] (. keys.push_back(Atom<Identifier_t>(variant)); operands.push_back(t); .)
}
rcurbrack (. typ = TypeAnnotation(TypeOperator::VARIANT, {}); typ.__operands = operands; typ.addFields(std::move(keys)); .)
.
TSlave<TypeAnnotation& typ>= (. std::wstring identMaster; .)
"slave" Ident<identMaster> (. typ = TypeAnnotation(TypeOperator::SLAVE, {}); typ.__valueCustom = Atom<Identifier_t>(identMaster).get(); .)
.
TDecl = (. TypeAnnotation t; std::wstring tname, arg; std::vector<Atom<Identifier_t>> args; .)
Ident<tname> assign "type"
[lparen Ident<arg> (. args.push_back(Atom<Identifier_t>(arg)); .)
{comma Ident<arg> (. args.push_back(Atom<Identifier_t>(arg)); .)
} rparen]
Type<t>period (. t.addBindings(move(args)); root->add(move(t), Atom<Identifier_t>(tname)); .)
.
ContextDecl<CodeScope * scope> = (. Expression tag; .)
context tagcolon
MetaSimpExpr<tag> (. scope->tags.push_back(tag); .)
{';' MetaSimpExpr<tag> (. scope->tags.push_back(tag); .)
}.
VDecl<CodeScope* f> = (. std::wstring vname; Expression var, value;.)
VarIdent<var> assign ExprTyped<value> (. Symbol identSymbol = f->addDefinition(move(var), move(value));
Attachments::put<SymbolAlias>(value, identSymbol);
.)
.
BDecl<CodeScope* scope> = lcurbrack (. Expression body; pushContextScope(scope); .)
{(IF(checkAssignment()) VDecl<scope> period
// | RuleContextDecl<scope>
| ContextDecl<scope>period
| ExprTyped<body> (. scope->setBody(body); Attachments::put<SymbolAlias>(body, Symbol{ScopedSymbol::RetSymbol, scope});.)
)}
rcurbrack (. popContextScope(); .)
.
IfDecl<Expression& e> = (. Expression cond; ManagedScpPtr blockTrue = root->add(new CodeScope(context.scope)); ManagedScpPtr blockFalse = root->add(new CodeScope(context.scope)); .)
"if" lparen Expr<cond> rparen (. e = Expression(Operator::IF, {cond}); .)
tagcolon ExprAnnotations<e>
BDecl<&*blockTrue> "else" BDecl<&*blockFalse> (. e.addBlock(blockTrue); e.addBlock(blockFalse); .)
.
LoopDecl<Expression& e> =
(.
Expression eIn, eAcc, eFilters; std::wstring varEl, varAcc, contextClass; Expression tagsEl;
ManagedScpPtr block = root->add(new CodeScope(context.scope));
.)
"loop"
(
"map" lparen Expr<eIn> implic Ident<varEl>
(. e = Expression(Operator::MAP, {eIn}); .)
tagcolon ExprAnnotations<tagsEl> rparen tagcolon ExprAnnotations<e>
(.
e.addBindings({Atom<Identifier_t>(varEl)});
block->addBinding(Atom<Identifier_t>(varEl), move(tagsEl));
.)
BDecl<&*block>
(. e.addBlock(block); .)
| "fold" lparen Expr<eIn> implic Ident<varEl> tagcolon ExprAnnotations<tagsEl>
['|' Expr<eFilters> ] comma Expr<eAcc> implic Ident<varAcc>rparen
(.
e = Expression(Operator::FOLD, {eIn, eAcc});
e.addBindings({Atom<Identifier_t>(varEl), Atom<Identifier_t>(varAcc)});
.)
tagcolon ExprAnnotations<e>
(.
block->addBinding(Atom<Identifier_t>(varEl), move(tagsEl));
block->addBinding(Atom<Identifier_t>(varAcc), Expression());
.)
BDecl<&*block>
(. e.addBlock(block); .)
| lparen Expr<eAcc> implic Ident<varAcc> rparen
(.
e = Expression(Operator::INF, {eAcc});
e.addBindings({Atom<Identifier_t>(varAcc)});
block->addBinding(Atom<Identifier_t>(varAcc), Expression());
.)
tagcolon ExprAnnotations<e> BDecl<&*block>
(. e.addBlock(block); .)
).
// Switches
SwitchDecl<Expression& eSwitch, SwitchKind flagSwitchKind> = (. TypeAnnotation typ; eSwitch = Expression(Operator::SWITCH, {}); Expression eCondition; Expression tag;.)
"switch"
(
SwitchVariantDecl<eSwitch>
| SwitchLateDecl<eSwitch>
| lparen ExprTyped<eCondition> rparen tagcolon ExprAnnotations<eSwitch> (. eSwitch.operands.push_back(eCondition);.)
CaseDecl<eSwitch, flagSwitchKind> {CaseDecl<eSwitch, flagSwitchKind>}
)
.
CaseDecl<Expression& outer, SwitchKind flagSwitchKind> = (. ManagedScpPtr scope = root->add(new CodeScope(context.scope)); Expression condition; .)
"case"
( IF(flagSwitchKind == SWITCH_META)
lparen MetaSimpExpr<condition> rparen BDecl<&*scope> (. Expression exprCase(Operator::CASE, {}); exprCase.addTags({condition}); exprCase.addBlock(scope); outer.addArg(move(exprCase));.)
| "default" BDecl<&*scope> (. Expression exprCase(Operator::CASE_DEFAULT, {});
exprCase.addBlock(scope);
outer.operands.insert(++outer.operands.begin(), exprCase); .)
| lparen CaseParams<&*scope> rparen (. ManagedScpPtr scopeBody = root->add(new CodeScope(&*scope)); Expression exprCase(Operator::CASE, {}); .)
BDecl<&*scopeBody> (. exprCase.addBlock(scope); exprCase.addBlock(scopeBody); outer.addArg(move(exprCase)); .)
).
CaseParams<CodeScope* scope> = (. Expression condition; Expression guard(Operator::LOGIC_AND, {}); pushContextScope(scope); .)
ExprTyped<condition> (. guard.addArg(Expression(condition)); .)
{comma ExprTyped<condition> (. guard.addArg(Expression(condition)); .)
} (. scope->setBody(guard); popContextScope(); .)
.
SwitchLateDecl<Expression& expr> =
(.
std::wstring aliasCondition; Expression exprCondition, aliasAnns;
expr = Expression(Operator::SWITCH_LATE, {});
ManagedScpPtr scope = root->add(new CodeScope(context.scope));
.)
"late" lparen Expr<exprCondition> [implic Ident<aliasCondition>] [tagcolon ExprAnnotations<aliasAnns>] rparen
tagcolon ExprAnnotations<expr> BDecl<&*scope>
(.
expr.addArg(Expression(exprCondition));
expr.addBlock(scope);
std::string alias;
if(aliasCondition.empty()){
if(exprCondition.__state != Expression::IDENT){
SemErr(coco_string_create("An identifier expected in the short form"));
return;
}
//Use exprCondition as identifier
alias = exprCondition.getValueString();
} else {
//Use aliasCondition
alias = Atom<Identifier_t>(move(aliasCondition)).get();
}
expr.addBindings({Atom<Identifier_t>(string(alias))});
scope->addBinding(Atom<Identifier_t>(move(alias)), move(aliasAnns));
.)
.
SwitchVariantDecl<Expression& expr> =
(. Expression varTested; std::wstring varAlias; bool flagAliasFound = false; expr = Expression(Operator::SWITCH_VARIANT, {}); .)
"variant" lparen Expr<varTested> [implic Ident<varAlias>
(. flagAliasFound = true; .)
] [tagcolon ExprAnnotations<varTested>] rparen tagcolon ExprAnnotations<expr>
(. expr.addArg(std::move(varTested));
if (flagAliasFound) {
expr.addBindings({Atom<Identifier_t>(varAlias)});
} else {
if(varTested.__state == Expression::IDENT){
expr.addBindings({Atom<Identifier_t>(string(varTested.getValueString()))});
}
}
.)
CaseVariantDecl<expr> {CaseVariantDecl<expr>}
.
CaseVariantDecl<Expression& expr> = (. ManagedScpPtr scope = root->add(new CodeScope(context.scope)); std::wstring key; scope->addBinding(Atom<Identifier_t>(string(expr.bindings.front())), Expression()); .)
"case" lparen Ident<key> rparen (. expr.addArg(root->recognizeVariantConstructor(Atom<Identifier_t>(std::move(key)))); .)
BDecl<&*scope> (. expr.addBlock(scope); .)
.
IntrinsicDecl<Expression& outer>= (. std::wstring name; .)
"intrinsic"
(
Ident< name> (. outer = Expression(Operator::CALL_INTRINSIC, {}); outer.setValue(Atom<Identifier_t>(name)); .)
lparen [CalleeParams<outer>] rparen
| "query" (. outer = Expression(Operator::QUERY, {}); .)
(
"late" IntrinsicQueryLateDecl<outer>
| lparen [CalleeParams<outer>] rparen
)
).
IntrinsicQueryLateDecl<Expression& expr> =
(.
std::wstring predicateAlias; Expression predicateE, predicateAnns;
expr = Expression(Operator::QUERY_LATE, {});
ManagedScpPtr scope = root->add(new CodeScope(context.scope));
.)
lparen Expr<predicateE> implic Ident<predicateAlias> tagcolon ExprAnnotations<predicateAnns> rparen
tagcolon ExprAnnotations<expr> BDecl<&*scope>
(.
expr.addArg(move(predicateE));
expr.addBindings({Atom<Identifier_t>(wstring(predicateAlias))});
scope->addBinding(Atom<Identifier_t>(move(predicateAlias)), move(predicateAnns));
expr.addBlock(scope);
.)
.
SequenceDecl<Expression& sequence> = (. sequence = Expression(); sequence.setOp(Operator::SEQUENCE); ManagedScpPtr scope = root->add(new CodeScope(context.scope)); .)
"seq" BDecl<&*scope> (. sequence.blocks.push_back(&*scope); scope = root->add(new CodeScope(&*scope)); .)
{ (. scope = root->add(new CodeScope(&*scope)); .)
BDecl<&*scope> (. sequence.blocks.push_back(&*scope); .)
}.
/*============================ INTERFACES ===============================*/
Imprt<> =
"import" "raw" lparen string (. root->__rawImports.push_back(Atom<String_t>(t->val).get()); .)
rparen period.
InterfaceData<> = "interface" lparen
( "dfa" rparen InterfaceDFA
| "extern-c" rparen InterfaceExternC
| "cfa" rparen InterfaceCFA
).
InterfaceExternC<> = (. ExternData data; .)
lcurbrack {IncludeExternDecl<data> | LibExternDecl<data> } rcurbrack
(. root->addExternData(move(data)); .)
.
LibExternDecl<ExternData& data> = (. std::wstring pkgname, libname; .)
Ident<libname> assign "library" tagcolon "pkgconfig"
lparen string (. pkgname = t->val; .)
rparen period (. data.addLibrary(Atom<Identifier_t>(libname), Atom<String_t>(pkgname)); .)
.
IncludeExternDecl<ExternData& data> = (. Expression inc; .)
"include" ListLiteral<inc> period (. data.addIncludeDecl(move(inc)); .)
.
InterfaceDFA<> = lcurbrack { InstructDecl } rcurbrack .
InstructDecl = (.Operator op; Expression tag;
Expression scheme;
std::vector<Expression>& tags = scheme.operands;
tags.push_back(Expression()); /* return value */ .)
"operator" InstructAlias<op> tagcolon lparen (.scheme.setOp(op); .)
[
MetaSimpExpr<tag> (. tags.push_back(tag); .)
{
comma MetaSimpExpr<tag> (. tags.push_back(tag); .)
}
] rparen [ implic MetaSimpExpr<tag> (. tags[0] = tag; .)
] (. root->addDFAData(move(scheme)); .)
period.
InstructAlias<Operator& op> =
(
"map" (. op = Operator::MAP; .)
| "list_range" (. op = Operator::LIST_RANGE; .)
| "list" (. op = Operator::LIST; .)
| "fold" (. op = Operator::FOLD; .)
| "index" (. op = Operator::INDEX; .)
).
InterfaceCFA<> = lcurbrack { InstructCFADecl } rcurbrack .
InstructCFADecl<> = (.Operator op; Expression tag;
Expression scheme;
std::vector<Expression>& tags = scheme.operands; .)
"operator" InstructAlias<op> tagcolon (. scheme.setOp(op); .)
[
MetaSimpExpr<tag> (. tags.push_back(tag); .)
{
comma MetaSimpExpr<tag> (. tags.push_back(tag); .)
}
] period (. root->addInterfaceData(CFA, move(scheme)); .).
/*============================ METAPROGRAMMING ===============================*/
// TagsDecl<CodeScope* f> = (. Expression tag; TagModifier mod = TagModifier::NONE; .)
// ':' { MetaSimpExpr<tag> (. /*f.addTag(std::move(tag), mod); */ .)
// }.
FnTag<Function* f> = (. Expression tag; TagModifier mod = TagModifier::NONE; .)
MetaSimpExpr<tag>
['-' TagMod<mod>] (. f->addTag(std::move(tag), mod); .).
TagMod<TagModifier& mod> =
( "assert" (. mod = TagModifier::ASSERT; .)
| "require" (. mod = TagModifier::REQUIRE; .)
).
// RuleDecl<> =
// "rule" tagcolon (. RuleArguments args; RuleGuards guards; DomainAnnotation typ; std::wstring arg; .)
// lparen Ident<arg> tagcolon Domain<typ> (. args.add(arg, typ); .)
// {comma Ident<arg> tagcolon Domain<typ> (. args.add(arg, typ); .)
// } rparen
// ["case" RGuard<guards> {comma RGuard<guards>}]
// lcurbrack RBody<args, guards> rcurbrack .
/* - TODO use RGuard for guards-*/
// RuleContextDecl<CodeScope* scope> = (.Expression eHead, eGuards, eBody; .)
// "rule" "context" tagcolon MetaSimpExpr<eHead>
// "case" lparen MetaSimpExpr<eGuards> rparen
// lcurbrack MetaSimpExpr<eBody> rcurbrack (.scope->contextRules.push_back(Expression(Operator::CONTEXT_RULE, {eHead, eGuards, eBody})); .).
// Domain<DomainAnnotation& dom> =
// (
// "function" (. dom = DomainAnnotation::FUNCTION; .)
// | "variable" (. dom = DomainAnnotation::VARIABLE; .)
// ).
// RGuard<RuleGuards& guards>= (. Expression e; .)
// MetaExpr<e> (. guards.add(std::move(e)); .).
// MetaExpr<Expression& e>= (.Operator op; Expression e2; .)
// MetaExpr2<e>
// [MetaOp<op> MetaExpr2<e2> (. e = Expression(op, {e, e2}); .)
// ].
// MetaExpr2<Expression& e>=
// (
// lparen MetaExpr<e> rparen
// | MetaSimpExpr<e>
// ).
MetaSimpExpr<Expression& e>= (. std::wstring i1, infix; Expression e2; .)
( '-' MetaSimpExpr<e2> (. e = Expression(Operator::NEG, {e2}); .)
| IF(checkParametersList()) Ident<i1> (. e = Expression(Operator::CALL, {Expression(Atom<Identifier_t>(i1))}); .)
lparen [ MetaCalleeParams<e> ] rparen
| IF(checkInfix()) Ident<i1> Ident<infix> MetaSimpExpr<e2>
(. e = Expression(Operator::CALL, {Expression(Atom<Identifier_t>(infix))});
e.addArg(Expression(Atom<Identifier_t>(i1)));
e.addArg(std::move(e2));
.)
| Ident<i1> (. e = Expression(Operator::CALL, {Atom<Identifier_t>(i1)}); .)
).
MetaCalleeParams<Expression& e> = (. Expression e2; .)
MetaSimpExpr<e2> (. e.addArg(Expression(e2)); .)
{comma MetaSimpExpr<e2> (. e.addArg(Expression(e2)); .)
}.
// RBody<const RuleArguments& args, const RuleGuards& guards> =
// (. Expression e; std::wstring msg; .)
// "warning" MetaExpr<e> ["message" string (. msg = t->val; .)
// ] (. root->add(new RuleWarning(RuleArguments(args), RuleGuards(guards), std::move(e), Atom<String_t>(msg))); .)
// .
// MetaOp< Operator& op> =
// implic (. op = Operator::IMPL; .)
// .
/*============================ Expressions ===============================*/
ExprAnnotations<Expression& e> = (. TypeAnnotation typ; std::list<Expression> tags; Expression tag; e.tags.clear();.)
Type<typ> (. e.bindType(move(typ)); .)
{';' MetaSimpExpr<tag> (. tags.push_back(tag); .)
} (. e.addTags(tags); .)
.
ExprTyped<Expression&e> = Expr<e> [tagcolon ExprAnnotations<e>].
Expr< Expression& e> (. Operator op; Expression e2; .)
= ExprArithmAdd<e>
[ RelOp<op>
ExprArithmAdd<e2> (. e = Expression(op, {e, e2}); .)
].
ExprArithmAdd< Expression& e>= (. Operator op; Expression e2; .)
ExprArithmMul< e>
[ AddOp< op>
ExprArithmAdd< e2> (. e = Expression(op, {e, e2});.)
].
ExprArithmMul< Expression& e> (. Operator op; Expression e2; .)
= ExprPostfix< e>
[ MulOp< op>
ExprArithmMul< e2> (. e = Expression(op, {e, e2}); .)
].
ExprPostfix<Expression& e>
= Term<e>
[ (. e = Expression(Operator::INDEX, {e}); .)
{lbrack CalleeParams<e> rbrack }
].
Term< Expression& e> (. std::wstring name; e = Expression(); .)
=
(IF (checkParametersList()) Ident< name>
(. e = Expression(Operator::CALL, {Atom<Identifier_t>(name)}); root->recognizeVariantConstructor(e); .)
lparen [CalleeParams<e>] rparen
| VarIdent<e> (. recognizeIdentifier(e); .)
| ListLiteral<e>
| ListRangeLiteral<e>
| LoopDecl<e>
| IfDecl<e>
| SwitchDecl<e, SWITCH_NORMAL>
| IntrinsicDecl<e>
| SequenceDecl<e>
| number (. e = Expression(Atom<Number_t>(t->val)); .)
| string (. e = Expression(Atom<String_t>(t->val)); .)
| "true" (. e = Expression(Atom<Number_t>(1)); e.bindType(TypePrimitive::Bool); .)
| "false" (. e = Expression(Atom<Number_t>(0)); e.bindType(TypePrimitive::Bool); .)
| "undef" (. e = Expression(Operator::UNDEF, {}); .)
| '-' Term<e> (. e = Expression(Operator::NEG, {e}); .)
| lparen ExprTyped<e> rparen
).
ListLiteral<Expression& e> = (. std::wstring key; Expression val; std::list<Atom<Identifier_t>> keys; size_t keyCounter=0; .)
lcurbrack
(IF(checkTokenAfterIdent(_assign)) Ident<key> assign Expr<val>
| Expr<val> (. key = to_wstring(keyCounter++); .)
) (. keys.push_back(Atom<Identifier_t>(key)); e = Expression(Operator::LIST, {val}); .)
{comma (IF(checkTokenAfterIdent(_assign)) Ident<key> assign Expr<val>
| Expr<val> (. key = to_wstring(keyCounter++); .)
) (. e.addArg(Expression(val)); keys.push_back(Atom<Identifier_t>(key)); .)
} rcurbrack (. e.addBindings(keys.begin(), keys.end()); .)
.
ListRangeLiteral<Expression& e> = (. Expression eFrom, eTo; .)
lbrack Expr<eFrom> ".." Expr<eTo> rbrack (. e = Expression(Operator::LIST_RANGE, {eFrom, eTo}); .)
.
CalleeParams<Expression& e> = (. Expression e2; .)
ExprTyped<e2> (. e.addArg(Expression(e2)); .)
{comma ExprTyped<e2> (. e.addArg(Expression(e2)); .)
}.
AddOp< Operator& op>
= (. op = Operator::ADD; .)
( '+'
| '-' (. op = Operator::SUB; .)
).
MulOp< Operator& op>
= (. op = Operator::MUL; .)
( '*'
| '/' (. op = Operator::DIV; .)
).
RelOp< Operator& op>
= (. op = Operator::EQU; .)
( equal
| (ne1 | ne2) (. op = Operator::NE; .)
| lse (. op = Operator::LSE; .)
| lss (. op = Operator::LSS; .)
| gte (. op = Operator::GTE; .)
| gtr (. op = Operator::GTR; .)
).
SkipModulesSection = "module" {ANY} (lcurbrack {ANY} rcurbrack | '.').
END Xreate.
diff --git a/installation/prepare-opensuse-leap15 b/installation/prepare-opensuse-leap15
index e17360a..b04d03d 100755
--- a/installation/prepare-opensuse-leap15
+++ b/installation/prepare-opensuse-leap15
@@ -1,67 +1,77 @@
#!/bin/bash
# VERSIONS OF MAJOR DEPENDENCIES:
# OPENSUSE LEAP 15
# LLVM: 5.0.1
# CLANG: 5.0.1
# GCC: 7.3.1
-
-CLINGO_PATH=/opt/potassco/clingo
-COCO_PATH=/opt/coco
-CLASP_VERSION=95cc1182f
SCRIPT=`realpath $0`
XREATE_PATH=`dirname $SCRIPT`/..
+#Provide ABSOLUTE path
+CLINGO_PATH=${XREATE_PATH}/build/vendors/clingo
+COCO_PATH=${XREATE_PATH}/build/vendors/coco
+
+CLASP_VERSION=95cc1182f
+
+pause(){
+ read -n1 -rsp "$1 "$'Press any key to continue or Ctrl+C to exit...\n'
+}
+
# PREREQUISITES
#
sudo zypper in \
git wget unzip make \
gcc7-c++ scons bison re2c\
llvm5-devel libboost_headers1_66_0-devel \
cmake gtest tbb-devel clang5-devel \
- libxml2-devel libboost_system1_66_0-devel libboost_filesystem1_66_0-devel
+ libxml2-devel libbsd-devel\
+ libboost_system1_66_0-devel libboost_filesystem1_66_0-devel
# COCO CPP
# The Compiler Generator Coco/R
# http://www.ssw.uni-linz.ac.at/coco/#CPP
#
-mkdir $COCO_PATH
+pause "Preparing Coco.."
+mkdir -p $COCO_PATH
cd $COCO_PATH
wget http://www.ssw.uni-linz.ac.at/coco/CPP/CocoSourcesCPP.zip
unzip ./CocoSourcesCPP.zip
make
# CLINGO
# A grounder and solver for logic programs.
# https://github.com/potassco/clingo
#
+pause "Preparing Clingo.."
mkdir -p $CLINGO_PATH
cd $CLINGO_PATH
git clone https://github.com/potassco/clingo.git ./ &&\
git reset --hard $CLASP_VERSION
git apply $XREATE_PATH/installation/docker/patches/potassco-patch-95cc11
scons configure --build-dir=debug &&\
sed -i "s/, '-fvisibility=hidden'//" build/debug.py &&\
sed -i "s/CXXFLAGS = \[\(.*\)\]/CXXFLAGS = \['-fPIC', \1\]/" build/debug.py &&\
sed -i "s/WITH_LUA = 'auto'/WITH_LUA = None/" build/debug.py &&\
sed -i "s/WITH_PYTHON = 'auto'/WITH_PYTHON = None/" build/debug.py &&\
sed -i "s/'-std=c++11'/'-std=c++14'/" build/debug.py &&\
cat build/debug.py &&\
scons --build-dir=debug
# XREATE
#
+pause "Preparing Xreate.."
cd $XREATE_PATH/vendors/jeayeson
git pull
./configure
mkdir ../../build
cd ../../build
ln -s $COCO_PATH/Copyright.frame $XREATE_PATH/vendors/coco/generator/Copyright.frame
ln -s $COCO_PATH/Scanner.frame $XREATE_PATH/vendors/coco/generator/Scanner.frame
mkdir $XREATE_PATH/grammar/main $XREATE_PATH/grammar/modules
cmake -DCMAKE_BUILD_TYPE=Debug -DBUILD_XREATE_TESTS=1 -DCOCO_EXECUTABLE=$COCO_PATH/Coco -DCLINGO_PATH=$CLINGO_PATH -DCOCO_FRAMES_PATH=$XREATE_PATH/vendors/coco/generator/ -DCMAKE_CXX_COMPILER=g++ ../cpp
diff --git a/pom.xml b/pom.xml
deleted file mode 100644
index 463d822..0000000
--- a/pom.xml
+++ /dev/null
@@ -1,62 +0,0 @@
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
-
- <groupId>org.xreate</groupId>
- <artifactId>xreate</artifactId>
- <version>1.0-SNAPSHOT</version>
- <packaging>jar</packaging>
-
- <name>xreate</name>
- <url>http://maven.apache.org</url>
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-compiler-plugin</artifactId>
- <version>2.3.2</version>
- <configuration>
- <source>1.6</source>
- <target>1.6</target>
- </configuration>
- </plugin>
- </plugins>
- </build>
- <properties>
- <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
- </properties>
-
- <dependencies>
- <dependency>
- <groupId>junit</groupId>
- <artifactId>junit</artifactId>
- <version>4.10</version>
- <type>jar</type>
- </dependency>
- <dependency>
- <groupId>org.antlr</groupId>
- <artifactId>antlr</artifactId>
- <version>3.2</version>
- </dependency>
- <dependency>
- <groupId>org.antlr</groupId>
- <artifactId>antlr-runtime</artifactId>
- <version>3.2</version>
- </dependency>
- <dependency>
- <groupId>com.google.guava</groupId>
- <artifactId>guava</artifactId>
- <version>11.0.2</version>
- </dependency>
- <dependency>
- <groupId>javolution</groupId>
- <artifactId>javolution</artifactId>
- <version>5.5.1</version>
- </dependency>
- <dependency>
- <groupId>jllvm</groupId>
- <artifactId>jllvm</artifactId>
- <version>2.8</version>
- </dependency>
- </dependencies>
-</project>
diff --git a/vendors/coco/generator/Copyright.frame b/vendors/coco/generator/Copyright.frame
index 708b5d5..6cac1e1 120000
--- a/vendors/coco/generator/Copyright.frame
+++ b/vendors/coco/generator/Copyright.frame
@@ -1 +1 @@
-/usr/share/coco-cpp/Copyright.frame
\ No newline at end of file
+/private/prg/code/xreate/build/vendors/coco/Copyright.frame
\ No newline at end of file
diff --git a/vendors/coco/generator/Scanner.frame b/vendors/coco/generator/Scanner.frame
index d1ee132..2489dd2 120000
--- a/vendors/coco/generator/Scanner.frame
+++ b/vendors/coco/generator/Scanner.frame
@@ -1 +1 @@
-/usr/share/coco-cpp/Scanner.frame
\ No newline at end of file
+/private/prg/code/xreate/build/vendors/coco/Scanner.frame
\ No newline at end of file
Event Timeline
Log In to Comment