No OneTemporary

File Metadata

Created
Sun, Feb 15, 5:09 PM
diff --git a/config/default.json b/config/default.json
index 8043ba5..631feec 100644
--- a/config/default.json
+++ b/config/default.json
@@ -1,74 +1,74 @@
{
"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":"Example.Example1",
+ "troubleshooting":"Exploitation.Doc_ExampleEov_1",
"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": "*",
"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/aux/xreatemanager-decorators.cpp b/cpp/src/aux/xreatemanager-decorators.cpp
index 07bd480..2b4038d 100644
--- a/cpp/src/aux/xreatemanager-decorators.cpp
+++ b/cpp/src/aux/xreatemanager-decorators.cpp
@@ -1,75 +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");
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");
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/pass/compilepass.cpp b/cpp/src/pass/compilepass.cpp
index 55384ef..06049f2 100644
--- a/cpp/src/pass/compilepass.cpp
+++ b/cpp/src/pass/compilepass.cpp
@@ -1,780 +1,788 @@
/* 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>
*
* compilepass.cpp
*/
/**
* \file compilepass.h
* \brief Main compilation routine. See \ref xreate::CompilePass
*/
#include "compilepass.h"
#include "transcendlayer.h"
#include <ast.h>
#include "llvmlayer.h"
#include "query/containers.h"
#include "compilation/containers.h"
#include "ExternLayer.h"
#include "compilation/targetinterpretation.h"
#include "pass/versionspass.h"
#include "compilation/scopedecorators.h"
#include "compilation/operators.h"
#include "compilation/latex.h"
#include "analysis/typeinference.h"
#include <boost/optional.hpp>
#include <memory>
#include <iostream>
using namespace std;
using namespace llvm;
namespace xreate{
namespace compilation{
std::string
BasicFunctionUnit::prepareName() {
AST* ast = IFunctionUnit::pass->man->root;
string name = ast->getFunctionSpecializations(IFunctionUnit::function->__name).size() > 1 ?
IFunctionUnit::function->__name + std::to_string(IFunctionUnit::function.id()) :
IFunctionUnit::function->__name;
return name;
}
std::vector<llvm::Type*>
BasicFunctionUnit::prepareSignature() {
LLVMLayer* llvm = IFunctionUnit::pass->man->llvm;
AST* ast = IFunctionUnit::pass->man->root;
CodeScope* entry = IFunctionUnit::function->__entry;
std::vector<llvm::Type*> signature;
std::transform(entry->__bindings.begin(), entry->__bindings.end(), std::inserter(signature, signature.end()),
[llvm, ast, entry](const std::string & arg)->llvm::Type* {
assert(entry->__identifiers.count(arg));
ScopedSymbol argid{entry->__identifiers.at(arg), versions::VERSION_NONE};
return llvm->toLLVMType(ast->expandType(entry->__declarations.at(argid).type));
});
return signature;
}
llvm::Type*
BasicFunctionUnit::prepareResult() {
LLVMLayer* llvm = IFunctionUnit::pass->man->llvm;
AST* ast = IFunctionUnit::pass->man->root;
CodeScope* entry = IFunctionUnit::function->__entry;
return llvm->toLLVMType(ast->expandType(entry->__declarations.at(ScopedSymbol::RetSymbol).type));
}
llvm::Function::arg_iterator
BasicFunctionUnit::prepareBindings() {
CodeScope* entry = IFunctionUnit::function->__entry;
ICodeScopeUnit* entryCompilation = IFunctionUnit::getScopeUnit(entry);
llvm::Function::arg_iterator fargsI = IFunctionUnit::raw->arg_begin();
for (std::string &arg : entry->__bindings) {
ScopedSymbol argid{entry->__identifiers[arg], versions::VERSION_NONE};
entryCompilation->bindArg(&*fargsI, argid);
fargsI->setName(arg);
++fargsI;
}
return fargsI;
}
//DEBT compiler rigidly depends on exact definition of DefaultFunctionUnit
typedef latex::LatexBruteFunctionDecorator<
compilation::BasicFunctionUnit>
BruteFunctionDefault;
ICodeScopeUnit::ICodeScopeUnit(const CodeScope * const codeScope, IFunctionUnit* f, CompilePass* compilePass)
: pass(compilePass), function(f), scope(codeScope), currentBlockRaw(nullptr) { }
llvm::Value*
BruteFnInvocation::operator()(std::vector<llvm::Value *>&& args, const std::string& hintDecl) {
llvm::Function* calleeInfo = dyn_cast<llvm::Function>(__callee);
if (calleeInfo) {
auto argsFormal = calleeInfo->args();
size_t sizeArgsF = std::distance(argsFormal.begin(), argsFormal.end());
assert(args.size() >= sizeArgsF);
assert(calleeInfo->isVarArg() || args.size() == sizeArgsF);
auto argFormal = argsFormal.begin();
for(size_t argId = 0; argId < args.size(); ++argId){
if(argFormal != argsFormal.end()){
args[argId] = typeinference::doAutomaticTypeConversion(
args.at(argId), argFormal->getType(), llvm->builder);
++argFormal;
}
}
}
//Do not name function call that returns Void.
std::string nameStatement = hintDecl;
if (calleeInfo->getReturnType()->isVoidTy()) {
nameStatement.clear();
}
return llvm->builder.CreateCall(__calleeTy, __callee, args, nameStatement);
}
//DESABLEDFEATURE implement inlining
class CallStatementInline : public IFnInvocation{
public:
CallStatementInline(IFunctionUnit* caller, IFunctionUnit* callee, LLVMLayer* l)
: __caller(caller), __callee(callee), llvm(l) { }
llvm::Value* operator()(std::vector<llvm::Value *>&& args, const std::string& hintDecl) {
//TOTEST inlining
// CodeScopeUnit* entryCompilation = outer->getScopeUnit(function->__entry);
// for(int i=0, size = args.size(); i<size; ++i) {
// entryCompilation->bindArg(args.at(i), string(entryCompilation->scope->__bindings.at(i)));
// }
//
//
// return entryCompilation->compile();
return nullptr;
}
private:
IFunctionUnit* __caller;
IFunctionUnit* __callee;
LLVMLayer* llvm;
bool
isInline() {
// Symbol ret = Symbol{0, function->__entry};
// bool flagOnTheFly = SymbolAttachments::get<IsImplementationOnTheFly>(ret, false);
//TODO consider inlining
return false;
}
} ;
BasicCodeScopeUnit::BasicCodeScopeUnit(const CodeScope * const codeScope, IFunctionUnit* f, CompilePass* compilePass)
: ICodeScopeUnit(codeScope, f, compilePass) { }
llvm::Value*
BasicCodeScopeUnit::processSymbol(const Symbol& s, std::string hintRetVar) {
Expression declaration = CodeScope::getDefinition(s);
const CodeScope* scopeExternal = s.scope;
ICodeScopeUnit* scopeBruteExternal = ICodeScopeUnit::function->getScopeUnit(scopeExternal);
assert(scopeBruteExternal->currentBlockRaw);
llvm::Value* resultRaw;
llvm::BasicBlock* blockOwn = pass->man->llvm->builder.GetInsertBlock();
if (scopeBruteExternal->currentBlockRaw == blockOwn) {
resultRaw = scopeBruteExternal->process(declaration, hintRetVar);
scopeBruteExternal->currentBlockRaw = currentBlockRaw =
pass->man->llvm->builder.GetInsertBlock();
} else {
pass->man->llvm->builder.SetInsertPoint(scopeBruteExternal->currentBlockRaw);
resultRaw = scopeBruteExternal->processSymbol(s, hintRetVar);
pass->man->llvm->builder.SetInsertPoint(blockOwn);
}
return resultRaw;
}
IFnInvocation*
BasicCodeScopeUnit::findFunction(const Expression& opCall) {
const std::string& calleeName = opCall.getValueString();
LLVMLayer* llvm = pass->man->llvm;
const std::list<ManagedFnPtr>& specializations = pass->man->root->getFunctionSpecializations(calleeName);
//if no specializations registered - check external function
if (specializations.size() == 0) {
llvm::Function* external = llvm->layerExtern->lookupFunction(calleeName);
llvm::outs() << "Debug/External function: " << calleeName;
external->getType()->print(llvm::outs(), true);
llvm::outs() << "\n";
return new BruteFnInvocation(external, llvm);
}
//There should be only one specialization without any valid guards at this point
return new BruteFnInvocation(pass->getFunctionUnit(
pass->man->root->findFunction(calleeName))->compile(),
llvm);
}
//DISABLEDFEATURE transformations
// if (pass->transformations->isAcceptable(expr)){
// return pass->transformations->transform(expr, result, ctx);
// }
llvm::Value*
BasicCodeScopeUnit::process(const Expression& expr, const std::string& hintVarDecl) {
#define DEFAULT(x) (hintVarDecl.empty()? x: hintVarDecl)
llvm::Value *left;
llvm::Value *right;
LLVMLayer& l = *pass->man->llvm;
xreate::compilation::AdvancedInstructions instructions = xreate::compilation::AdvancedInstructions({this, function, pass});
switch (expr.op) {
case Operator::SUB: case Operator::MUL:
case Operator::DIV: case Operator::EQU: case Operator::LSS:
case Operator::GTR: case Operator::NE: case Operator::LSE:
case Operator::GTE:
assert(expr.__state == Expression::COMPOUND);
assert(expr.operands.size() == 2);
left = process(expr.operands[0]);
right = process(expr.operands[1]);
break;
default:;
}
switch (expr.op) {
case Operator::ADD:
{
left = process(expr.operands[0]);
Context context{this, function, pass};
llvm::Value* resultSU = StructUpdate::add(expr.operands[0], left, expr.operands[1], context, DEFAULT("tmp_add"));
if (resultSU) return resultSU;
right = process(expr.operands[1]);
llvm::Value* resultAddPA = pointerarithmetic::PointerArithmetic::add(left, right, context, DEFAULT("tmp_add"));
if (resultAddPA) {
return resultAddPA;
}
return l.builder.CreateAdd(left, right, DEFAULT("tmp_add"));
break;
}
case Operator::SUB:
return l.builder.CreateSub(left, right, DEFAULT("tmp_sub"));
break;
case Operator::MUL:
return l.builder.CreateMul(left, right, DEFAULT("tmp_mul"));
break;
case Operator::DIV:
if (left->getType()->isIntegerTy()) return l.builder.CreateSDiv(left, right, DEFAULT("tmp_div"));
if (left->getType()->isFloatingPointTy()) return l.builder.CreateFDiv(left, right, DEFAULT("tmp_div"));
break;
case Operator::EQU: {
if (left->getType()->isIntegerTy()) return l.builder.CreateICmpEQ(left, right, DEFAULT("tmp_equ"));
if (left->getType()->isFloatingPointTy()) return l.builder.CreateFCmpOEQ(left, right, DEFAULT("tmp_equ"));
const ExpandedType& leftT = pass->man->root->getType(expr.operands[0]);
const ExpandedType& rightT = pass->man->root->getType(expr.operands[0]);
if(leftT->__operator == TypeOperator::VARIANT && rightT->__operator == TypeOperator::VARIANT){
llvm::Type* selectorT = llvm::cast<llvm::StructType>(left->getType())->getElementType(0);
llvm::Value* leftUnwapped = typeinference::doAutomaticTypeConversion(left, selectorT, l.builder);
llvm::Value* rightUnwapped = typeinference::doAutomaticTypeConversion(right, selectorT, l.builder);
return l.builder.CreateICmpEQ(leftUnwapped, rightUnwapped, DEFAULT("tmp_equ"));
}
break;
}
case Operator::NE:
return l.builder.CreateICmpNE(left, right, DEFAULT("tmp_ne"));
break;
case Operator::LSS:
return l.builder.CreateICmpSLT(left, right, DEFAULT("tmp_lss"));
break;
case Operator::LSE:
return l.builder.CreateICmpSLE(left, right, DEFAULT("tmp_lse"));
break;
case Operator::GTR:
return l.builder.CreateICmpSGT(left, right, DEFAULT("tmp_gtr"));
break;
case Operator::GTE:
return l.builder.CreateICmpSGE(left, right, DEFAULT("tmp_gte"));
break;
case Operator::NEG:
+ {
left = process(expr.operands[0]);
- return l.builder.CreateNeg(left, DEFAULT("tmp_neg"));
+ ExpandedType leftTy = pass->man->root->getType(expr.operands[0]);
+
+ if (leftTy->__value == TypePrimitive::Bool){
+ return l.builder.CreateNot(left, DEFAULT("tmp_not"));
+ } else {
+ return l.builder.CreateNeg(left, DEFAULT("tmp_neg"));
+ }
break;
+ }
case Operator::CALL:
{
assert(expr.__state == Expression::COMPOUND);
shared_ptr<IFnInvocation> callee(findFunction(expr));
const std::string& nameCallee = expr.getValueString();
//prepare arguments
std::vector<llvm::Value *> args;
args.reserve(expr.operands.size());
std::transform(expr.operands.begin(), expr.operands.end(), std::inserter(args, args.end()),
[this](const Expression & operand) {
return process(operand);
}
);
return (*callee)(move(args), DEFAULT("res_" + nameCallee));
}
case Operator::IF:
{
return instructions.compileIf(expr, DEFAULT("tmp_if"));
}
case Operator::SWITCH:
{
return instructions.compileSwitch(expr, DEFAULT("tmp_switch"));
}
case Operator::LOGIC_AND:
{
assert(expr.operands.size() == 1);
return process(expr.operands[0]);
}
case Operator::LIST:
{
ExpandedType exprT = l.ast->getType(expr);
bool flagIsArray;
do {
if (exprT->__operator == TypeOperator::CUSTOM){
if (l.layerExtern->isArrayType(exprT->__valueCustom)){
flagIsArray = true;
break;
}
if (l.layerExtern->isRecordType(exprT->__valueCustom)){
flagIsArray = false;
break;
}
assert(false && "Inapproriate external type");
}
if (exprT->__operator != TypeOperator::LIST_ARRAY && exprT->__operator != TypeOperator::LIST_RECORD){
assert(false && "Inapproriate type");
}
flagIsArray = exprT->__operator == TypeOperator::LIST_ARRAY;
} while(false);
if(flagIsArray){
return instructions.compileListAsSolidArray(expr, DEFAULT("tmp_list"));
}
const std::vector<string> fieldsFormal = (exprT.get().__operator == TypeOperator::CUSTOM) ?
l.layerExtern->getStructFields(l.layerExtern->lookupType(exprT.get().__valueCustom))
: exprT.get().fields;
std::map<std::string, size_t> indexFields;
for (size_t i = 0, size = fieldsFormal.size(); i < size; ++i) {
indexFields.emplace(fieldsFormal[i], i);
}
llvm::StructType* tyLiteralRaw = llvm::cast<llvm::StructType>(l.toLLVMType(exprT));
llvm::Value* record = llvm::UndefValue::get(tyLiteralRaw);
for (size_t i = 0; i < expr.operands.size(); ++i) {
const Expression& operand = expr.operands.at(i);
unsigned int fieldId = indexFields.at(expr.bindings.at(i));
llvm::Value* result = process(operand);
assert(result);
record = l.builder.CreateInsertValue(record, result, llvm::ArrayRef<unsigned>({fieldId}));
}
return record;
};
case Operator::LIST_RANGE:
{
assert(false); //no compilation phase for a range list
// return InstructionList(this).compileConstantArray(expr, l, hintRetVar);
};
case Operator::MAP:
{
assert(expr.blocks.size());
return instructions.compileMapSolidOutput(expr, DEFAULT("map"));
};
case Operator::FOLD:
{
return instructions.compileFold(expr, DEFAULT("fold"));
};
case Operator::INF:
{
return instructions.compileFoldInf(expr, DEFAULT("fold"));
};
case Operator::INDEX:
{
//TASK allow multiindex compilation
assert(expr.operands.size() == 2);
assert(expr.operands[0].__state == Expression::IDENT);
const std::string& hintIdent = expr.operands[0].getValueString();
Symbol s = Attachments::get<IdentifierSymbol>(expr.operands[0]);
const ExpandedType& t2 = pass->man->root->getType(expr.operands[0]);
llvm::Value* aggr = processSymbol(s, hintIdent);
switch (t2.get().__operator) {
case TypeOperator::LIST_RECORD: case TypeOperator::CUSTOM:
{
std::string idxField;
const Expression& idx = expr.operands.at(1);
switch (idx.__state) {
//named struct field
case Expression::STRING:
idxField = idx.getValueString();
break;
//anonymous struct field
case Expression::NUMBER:
idxField = to_string((int) idx.getValueDouble());
break;
default:
assert(false && "Wrong index for a struct");
}
return instructions.compileStructIndex(aggr, t2, idxField);
};
case TypeOperator::LIST_ARRAY:
{
std::vector<llvm::Value*> indexes;
std::transform(++expr.operands.begin(), expr.operands.end(), std::inserter(indexes, indexes.end()),
[this] (const Expression & op) {
return process(op);
}
);
return instructions.compileArrayIndex(aggr, indexes, DEFAULT(string("el_") + hintIdent));
};
default:
assert(false);
}
};
case Operator::CALL_INTRINSIC:
{
const std::string op = expr.getValueString();
if (op == "copy") {
llvm::Value* result = process(expr.getOperands().at(0));
auto decoratorVersions = Decorators<VersionsScopeDecoratorTag>::getInterface(this);
llvm::Value* storage = decoratorVersions->processIntrinsicInit(result->getType());
decoratorVersions->processIntrinsicCopy(result, storage);
return l.builder.CreateLoad(storage, hintVarDecl);
}
assert(false && "undefined intrinsic");
}
case Operator::QUERY:
case Operator::QUERY_LATE:
{
assert(false && "Should be processed by interpretation");
}
case Operator::VARIANT:
{
const ExpandedType& typVariant = pass->man->root->getType(expr);
llvm::Type* typVariantRaw = l.toLLVMType(typVariant);
llvm::Type* typIdRaw = llvm::cast<llvm::StructType>(typVariantRaw)->getElementType(0);
uint64_t id = expr.getValueDouble();
llvm::Value* variantRaw = llvm::UndefValue::get(typVariantRaw);
variantRaw = l.builder.CreateInsertValue(variantRaw, llvm::ConstantInt::get(typIdRaw, id), llvm::ArrayRef<unsigned>({0}));
const bool flagDoReference = expr.operands.size();
if (flagDoReference) {
const ExpandedType& subtyp = ExpandedType(typVariant->__operands.at(id));
llvm::Type* subtypRaw = l.toLLVMType(subtyp);
Attachments::put<TypeInferred>(expr.operands.at(0), subtyp);
llvm::Value* subtypValue = process(expr.operands.at(0));
llvm::Type* typStorageRaw = llvm::cast<llvm::StructType>(typVariantRaw)->getElementType(1);
llvm::Value* addrAsStorage = l.builder.CreateAlloca(typStorageRaw);
llvm::Value* addrAsSubtyp = l.builder.CreateBitOrPointerCast(addrAsStorage, subtypRaw->getPointerTo());
l.builder.CreateStore(subtypValue, addrAsSubtyp);
llvm::Value* storageRaw = l.builder.CreateLoad(typStorageRaw, addrAsStorage);
variantRaw = l.builder.CreateInsertValue(variantRaw, storageRaw, llvm::ArrayRef<unsigned>({1}));
}
return variantRaw;
}
case Operator::SWITCH_VARIANT:
{
return instructions.compileSwitchVariant(expr, DEFAULT("tmpswitch"));
}
case Operator::SWITCH_LATE:
{
assert(false && "Instruction's compilation should've been redirected to interpretation");
return nullptr;
}
case Operator::SEQUENCE:
{
return instructions.compileSequence(expr);
}
case Operator::UNDEF:
{
llvm::Type* typExprUndef = l.toLLVMType(typeinference::getType(expr, *pass->man->root));
return llvm::UndefValue::get(typExprUndef);
}
case Operator::INVALID:
assert(expr.__state != Expression::COMPOUND);
switch (expr.__state) {
case Expression::IDENT:
{
Symbol s = Attachments::get<IdentifierSymbol>(expr);
return processSymbol(s, expr.getValueString());
}
case Expression::NUMBER:
{
llvm::Type* typConst = l.toLLVMType(typeinference::getType(expr, *pass->man->root));
int literal = expr.getValueDouble();
if (typConst->isFloatingPointTy()) return llvm::ConstantFP::get(typConst, literal);
if (typConst->isIntegerTy()) return llvm::ConstantInt::get(typConst, literal);
assert(false && "Can't compile literal");
}
case Expression::STRING:
{
return instructions.compileConstantStringAsPChar(expr.getValueString(), DEFAULT("tmp_str"));
};
default:
{
break;
}
};
break;
default: break;
}
assert(false && "Can't compile expression");
return 0;
}
llvm::Value*
BasicCodeScopeUnit::compile(const std::string& hintBlockDecl) {
LLVMLayer* llvm = pass->man->llvm;
if (!hintBlockDecl.empty()) {
llvm::BasicBlock *block = llvm::BasicBlock::Create(llvm->llvmContext, hintBlockDecl, function->raw);
pass->man->llvm->builder.SetInsertPoint(block);
}
currentBlockRaw = pass->man->llvm->builder.GetInsertBlock();
Symbol symbScope = Symbol{ScopedSymbol::RetSymbol, scope};
return processSymbol(symbScope);
}
ICodeScopeUnit::~ICodeScopeUnit() { }
IFunctionUnit::~IFunctionUnit() { }
llvm::Function*
IFunctionUnit::compile() {
if (raw != nullptr) return raw;
LLVMLayer* llvm = pass->man->llvm;
llvm::IRBuilder<>& builder = llvm->builder;
string&& functionName = prepareName();
std::vector<llvm::Type*>&& types = prepareSignature();
llvm::Type* expectedResultType = prepareResult();
llvm::FunctionType *ft = llvm::FunctionType::get(expectedResultType, types, false);
raw = llvm::cast<llvm::Function>(llvm->module->getOrInsertFunction(functionName, ft));
prepareBindings();
const std::string&blockName = "entry";
llvm::BasicBlock* blockCurrent = builder.GetInsertBlock();
llvm::Value* result = getScopeUnit(function->__entry)->compile(blockName);
assert(result);
//SECTIONTAG types/convert function ret value
builder.CreateRet(typeinference::doAutomaticTypeConversion(result, expectedResultType, llvm->builder));
if (blockCurrent) {
builder.SetInsertPoint(blockCurrent);
}
llvm->moveToGarbage(ft);
return raw;
}
ICodeScopeUnit*
IFunctionUnit::getScopeUnit(const CodeScope * const scope) {
if (__scopes.count(scope)) {
auto result = __scopes.at(scope).lock();
if (result) {
return result.get();
}
}
std::shared_ptr<ICodeScopeUnit> unit(pass->buildCodeScopeUnit(scope, this));
if (scope->__parent != nullptr) {
auto parentUnit = Decorators<CachedScopeDecoratorTag>::getInterface(getScopeUnit(scope->__parent));
parentUnit->registerChildScope(unit);
} else {
__orphanedScopes.push_back(unit);
}
if (!__scopes.emplace(scope, unit).second) {
__scopes[scope] = unit;
}
return unit.get();
}
ICodeScopeUnit*
IFunctionUnit::getScopeUnit(ManagedScpPtr scope) {
return getScopeUnit(&*scope);
}
ICodeScopeUnit*
IFunctionUnit::getEntry() {
return getScopeUnit(function->getEntryScope());
}
template<>
compilation::IFunctionUnit*
CompilePassCustomDecorators<void, void>
::buildFunctionUnit(const ManagedFnPtr& function) {
return new BruteFunctionDefault(function, this);
}
template<>
compilation::ICodeScopeUnit*
CompilePassCustomDecorators<void, void>
::buildCodeScopeUnit(const CodeScope * const scope, IFunctionUnit* function) {
return new DefaultCodeScopeUnit(scope, function, this);
}
} // end of compilation
compilation::IFunctionUnit*
CompilePass::getFunctionUnit(const ManagedFnPtr& function) {
unsigned int id = function.id();
if (!functions.count(id)) {
compilation::IFunctionUnit* unit = buildFunctionUnit(function);
functions.emplace(id, unit);
return unit;
}
return functions.at(id);
}
void
CompilePass::run() {
//Initialization:
managerTransformations = new xreate::compilation::TransformationsManager();
targetInterpretation = new interpretation::TargetInterpretation(this->man->root, this);
//Determine entry function:
StaticModel model = man->transcend->query(Config::get("function-entry"));
assert(model.size() && "Error: No entry function found");
assert(model.size() == 1 && "Error: Ambiguous entry function");
string nameMain = std::get<0>(TranscendLayer::parse<std::string>(model.begin()->second));
compilation::IFunctionUnit* unitMain = getFunctionUnit(man->root->findFunction(nameMain));
//Compilation itself:
entry = unitMain->compile();
}
llvm::Function*
CompilePass::getEntryFunction() {
assert(entry);
return entry;
}
void
CompilePass::prepareQueries(TranscendLayer* transcend) {
transcend->registerQuery(new containers::Query(), QueryId::ContainersQuery);
transcend->registerQuery(new polymorph::PolymorphQuery(), QueryId::PolymorphQuery);
transcend->registerQuery(new latex::LatexQuery(), QueryId::LatexQuery);
}
} //end of namespace xreate
/**
* \class xreate::CompilePass
* \brief The owner of the compilation process. Performs fundamental compilation activities along with the xreate::compilation's routines
*
* xreate::CompilePass traverses over xreate::AST tree and produces executable code.
* The pass performs compilation using the following data sources:
* - %Attachments: the data gathered by the previous passes. See \ref xreate::Attachments.
* - Transcend solutions accessible via queries. See \ref xreate::IQuery, \ref xreate::TranscendLayer.
*
* The pass generates a bytecode by employing \ref xreate::LLVMLayer(wrapper over LLVM toolchain).
* Many compilation activities are delegated to more specific routines. Most notable delegated compilation aspects are:
* - Containers support. See \ref xreate::containers.
* - Latex compilation. See \ref xreate::latex.
* - Interpretation support. See \ref xreate::interpretation.
* - Loop saturation support. See \ref xreate::compilation::TransformationsScopeDecorator.
* - External code interaction support. See \ref xreate::ExternLayer (wrapper over Clang library).
*
* \section adaptability_sect Adaptability
* xreate::CompilePass's behaviour can be adapted in several ways:
* - %Function Decorators to alter function-level compilation. See \ref xreate::compilation::IFunctionUnit
* - Code Block Decorators to alter code block level compilation. See \ref xreate::compilation::ICodeScopeUnit.
* Default functionality defined by \ref xreate::compilation::DefaultCodeScopeUnit
* - Targets to allow more versitile extensions.
* Currently only xreate::interpretation::TargetInterpretation use Targets infrastructure. See \ref xreate::compilation::Target.
* - Altering %function invocation. See \ref xreate::compilation::IFnInvocation.
*
* Clients are free to construct a compiler instantiation with the desired decorators by using \ref xreate::compilation::CompilePassCustomDecorators.
* As a handy alias, `CompilePassCustomDecorators<void, void>` constructs the default compiler.
*
*/
diff --git a/cpp/tests/association.cpp b/cpp/tests/association.cpp
index ce5964e..df36c38 100644
--- a/cpp/tests/association.cpp
+++ b/cpp/tests/association.cpp
@@ -1,124 +1,138 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/
*
* association.cpp
*
* Author: pgess <v.melnychenko@xreate.org>
* Created on August 12, 2017, 9:28 PM
*/
#include "xreatemanager.h"
#include "transcendlayer.h"
#include "pass/interpretationpass.h"
+#include "supplemental/docutils.h"
#include <gtest/gtest.h>
using namespace xreate::interpretation;
using namespace xreate;
using namespace std;
TEST(Association, TypedQuery_1) {
auto man = ::xreate::details::tier1::XreateManager::prepare(R"Code(
AtomNumT = type slave atomNumT.
AtomStrT = type slave atomStrT.
CompListT = type slave compListT.
CompArithT = type slave compArithT.
test = function:: num; entry
{
query1 = intrinsic query("atomNumT")::[AtomNumT].
query2 = intrinsic query("atomStrT")::[AtomStrT].
query3 = intrinsic query("compListT")::[CompListT].
query4 = intrinsic query("compArithT")::[CompArithT].
test1 = query1[0] == 5:: bool.
test2 = query2[1] == "y":: bool.
test3 = query3[0, 1] == "x" :: bool.
test4 = query4[0, 0, 0] == 1:: bool.
test1 + test2 + test3 + test4
}
)Code");
man->transcend->addRawScript(R"RAW(
atomNumT(5; 8).
atomStrT("x"; "y").
compListT(5, "x").
compListT(8, "y").
compArithT(add(1, 2)).
compArithT(mul(5, 6)).
)RAW");
man->analyse();
int (*test)() = (int (*)())man->run();
int result = test();
ASSERT_EQ(4, result);
}
TEST(Association, QueryLate_ast_1){
auto man = XreateManager::prepare(
R"Code(
test = function:: num; entry
{
intrinsic query late("dict"->x:: bool)::bool
{
(x == true)
}
}
)Code");
}
TEST(Association, QueryLate_pass_1){
auto man = ::xreate::details::tier1::XreateManager::prepare(
R"Code(
test = function:: num; entry
{
intrinsic query late("dict"->x:: bool)::bool
{
(x == true)
}
}
)Code");
man->analyse();
Expression instructionE = man->root->findFunction("test")->getEntryScope()->getBody();
InterpretationData instructionData = Attachments::get<InterpretationData>(instructionE);
ASSERT_EQ(QUERY_LATE, instructionData.op);
}
TEST(Association, QueryLate_target_1){
auto man = ::xreate::details::tier1::XreateManager::prepare(
R"Code(
Equipment = type variant {dresser, sink, stove}.
Room = type variant{kitchen, bedroom, bathroom}.
test = function:: num; entry
{
room = bedroom() :: Room; room.
equipment = intrinsic query late("whatshere"->x:: Equipment)::int; equipment
{ if (x == dresser()):: int {1} else {0} }.
equipment + (room::int)
}
)Code");
man->transcend->addRawScript(
R"RAW(
room(kitchen; bedroom; bathroom).
equipment(dresser;sink;stove).
interior(kitchen, stove).
interior(bedroom, dresser).
interior(bathroom, sink).
late(VarTarget, VarRoom, Room, whatshere(Equipment)):-
bind(VarTarget, equipment);
bind(VarRoom, room);
interior(Room, Equipment);
equipment(Equipment);
room(Room).
)RAW");
man->analyse();
int (*result)() = (int (*)()) man->run();
ASSERT_EQ(2, result());
}
-
-
+TEST(Association, Doc_IntrinsicQuery_2){
+ string scriptGUI = getDocumentationExampleById("documentation/Concepts/interpretation.xml", "IntrinsicQuery_2_GUI");
+ string scriptPlatform = getDocumentationExampleById("documentation/Concepts/interpretation.xml", "IntrinsicQuery_2_Platform");
+ string scriptRules = getDocumentationExampleById("documentation/Concepts/interpretation.xml", "IntrinsicQuery_2_Rules");
+ string code = getDocumentationExampleById("documentation/Concepts/interpretation.xml", "IntrinsicQuery_2_Code");
+
+ auto man = xreate::details::tier1::XreateManager::prepare(move(code));
+ man->transcend->addRawScript(move(scriptGUI));
+ man->transcend->addRawScript(move(scriptPlatform));
+ man->transcend->addRawScript(move(scriptRules));
+ man->analyse();
+
+ delete man;
+ ASSERT_TRUE(true);
+}
diff --git a/cpp/tests/ast.cpp b/cpp/tests/ast.cpp
index 2c5ce06..5072b32 100644
--- a/cpp/tests/ast.cpp
+++ b/cpp/tests/ast.cpp
@@ -1,204 +1,229 @@
/* 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, 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"));
- ASSERT_TRUE(true);
+ 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_Variants){
+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);
}
\ No newline at end of file
diff --git a/cpp/tests/compilation.cpp b/cpp/tests/compilation.cpp
index 21c1d12..f098e2f 100644
--- a/cpp/tests/compilation.cpp
+++ b/cpp/tests/compilation.cpp
@@ -1,228 +1,243 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/
*
* compilation.cpp
*
* Created on: -
* Author: pgess <v.melnychenko@xreate.org>
*/
#include "xreatemanager.h"
+#include "supplemental/defines.h"
+
#include "gtest/gtest.h"
+
using namespace xreate;
//DEBT implement no pkgconfig ways to link libs
//TOTEST FunctionUnit::compileInline
TEST(Compilation, functionEntry1){
std::unique_ptr<XreateManager> program(XreateManager::prepare(
"func1 = function(a:: int):: int {a+8} \
func2 = function::int; entry {12 + func1(4)} \
"));
void* entryPtr = program->run();
int (*entry)() = (int (*)())(intptr_t)entryPtr;
int answer = entry();
ASSERT_EQ(24, answer);
}
TEST(Compilation, full_IFStatementWithVariantType){
XreateManager* man = XreateManager::prepare(
"Color = type variant {RED, BLUE, GREEN}.\n"
"\n"
" main = function(x::int):: bool; entry {\n"
" color = if (x == 0 )::Color {RED()} else {BLUE()}.\n"
" if (color == BLUE())::bool {true} else {false}\n"
" }"
);
bool (*main)(int) = (bool (*)(int)) man->run();
ASSERT_FALSE(main(0));
ASSERT_TRUE(main(1));
}
TEST(Compilation, full_Variant1){
XreateManager* man = XreateManager::prepare(R"Code(
OneArgument = type{x::int}.
TwoArguments = type{x::int, y::int}.
Command= type variant{
Add::TwoArguments,
Dec::OneArgument
}.
main = function::Command; entry {
Dec({x=2})::Command
}
)Code");
void (*main)() = (void (*)()) man->run();
}
TEST(Compilation, full_SwitchVariant1){
XreateManager* man = XreateManager::prepare(R"Code(
OneArgument = type{x::int}.
TwoArguments = type{x::int, y::int}.
Command= type variant{
Add::TwoArguments,
Dec::OneArgument
}.
main = function::int; entry {
//command = Dec({x = 8}):: Command.
command = Add({x= 3, y= 5}):: Command.
switch variant(command)::int
case(Add){command["x"] + command["y"]}
case(Dec){command["x"]}
}
)Code");
int (*mainFn)() = (int (*)()) man->run();
int result = mainFn();
ASSERT_EQ(8, result);
}
TEST(Compilation, full_SwitchVariantNoArguments2){
XreateManager* man = XreateManager::prepare(R"Code(
Command= type variant{Add, Dec}.
main = function::int; entry {
command = Dec():: Command.
switch variant(command)::int
case(Add){0}
case(Dec){1}
}
)Code");
int (*mainFn)() = (int (*)()) man->run();
int result = mainFn();
ASSERT_EQ(1, result);
}
TEST(Compilation, full_SwitchVariantMixedArguments3){
XreateManager* man = XreateManager::prepare(R"Code(
TwoArguments = type{x::int, y::int}.
Command= type variant{
Add::TwoArguments,
Dec
}.
main = function(arg::int):: int; entry {
command = if (arg > 0)::Command {Dec()} else {Add({x=1,y=2})}.
switch variant(command)::int
case(Add){0}
case(Dec){1}
}
)Code");
int (*mainFn)(int) = (int (*)(int)) man->run();
int result = mainFn(5);
ASSERT_EQ(1, result);
}
TEST(Compilation, full_StructUpdate){
XreateManager* man = XreateManager::prepare(
R"Code(
Rec = type {
a :: int,
b:: int
}.
test= function:: int; entry {
a = {a = 18, b = 20}:: Rec.
b = a + {a = 11}:: Rec.
b["a"]
}
)Code");
int (*main)() = (int (*)()) man->run();
int result = main();
ASSERT_EQ(11, result);
}
TEST(Compilation, AnonymousStruct_init_index){
std::string code =
R"Code(
main = function:: int; entry {
x = {10, 15} :: {int, int}.
x[1]
}
)Code";
std::unique_ptr<XreateManager> man(XreateManager::prepare(move(code)));
int (*main)() = (int (*)()) man->run();
EXPECT_EQ(15, main());
}
TEST(Compilation, AnonymousStruct_init_update){
std::string code =
R"Code(
main = function:: int; entry {
x = {10, 15} :: {int, int}.
y = x + {6}:: {int, int}.
y[0]
}
)Code";
std::unique_ptr<XreateManager> man(XreateManager::prepare(move(code)));
int (*main)() = (int (*)()) man->run();
EXPECT_EQ(6, main());
}
TEST(Compilation, BugIncorrectScopes1){
std::string code =
R"Code(
init = function:: int {10}
main = function(cmd:: int):: int; entry {
x = init():: int.
if(cmd > 0):: int { x + 1 } else { x }
}
)Code";
std::unique_ptr<XreateManager> man(XreateManager::prepare(move(code)));
int (*mainFn)(int) = (int (*)(int)) man->run();
EXPECT_EQ(11, mainFn(1));
}
TEST(Compilation, Sequence1){
std::string code =
R"Code(
interface(extern-c){
libbsd = library:: pkgconfig("libbsd").
include {
libbsd = {"bsd/stdlib.h", "string.h"}
}.
}
start = function:: i32; entry {
seq {
nameNew = "TestingSequence":: string.
setprogname(nameNew)
} {strlen(getprogname())}::i32
}
)Code";
std::unique_ptr<XreateManager> man(XreateManager::prepare(move(code)));
int (*startFn)() = (int (*)()) man->run();
int nameNewLen = startFn();
ASSERT_EQ(15, nameNewLen);
}
+TEST(Compilation, BoolInstructions1){
+ std::string code =
+R"Code(
+test = function (a:: bool, b:: bool):: bool; entry
+{
+ -a
+}
+)Code";
+
+ std::unique_ptr<XreateManager> man(XreateManager::prepare(move(code)));
+ Fn2args startFn = (Fn2args) man->run();
+}
\ No newline at end of file
diff --git a/cpp/tests/exploitation.cpp b/cpp/tests/exploitation.cpp
index 217f1a4..8316438 100644
--- a/cpp/tests/exploitation.cpp
+++ b/cpp/tests/exploitation.cpp
@@ -1,38 +1,63 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/
*
* exploitation.cpp
*
* Author: pgess <v.melnychenko@xreate.org>
* Created on February 15, 2018, 6:17 PM
*/
#include "xreatemanager.h"
#include "analysis/cfagraph.h"
#include "pass/cfapass.h"
#include "pass/cfatemporalseqpass.h"
#include "supplemental/docutils.h"
-
+#include "supplemental/defines.h"
#include "gtest/gtest.h"
using namespace xreate;
using namespace xreate::cfa;
using namespace std;
TEST(Exploitation, Doc_ResourceInit_1) {
string example = getDocumentationExampleFromFile("scripts/exploitation/test1.xreate");
string body = getDocumentationExampleById("documentation/exploitation.xml", "ResourceInit_1");
replace(example, "<BODY>", body);
details::tier1::XreateManager* man = details::tier1::XreateManager::prepare(move(example));
CFATemporalSeqPass* pass = new CFATemporalSeqPass(man);
man->registerPass(pass, PassId::CFATemporalSeqPass);
man->analyse();
int (* main)() = (int (*)()) man->run();
int result = main();
delete pass;
delete man;
ASSERT_EQ(1, result);
+}
+
+TEST(Exploitation, Doc_ExampleEov_1){
+ string code = getDocumentationExampleFromFile("scripts/execution-order/test-1.xreate");
+ string codeSpecializations = getDocumentationExampleById("documentation/index.xml", "ExampleEov_1_Specializations");
+
+ string script = getDocumentationExampleFromFile("/private/prg/code/xreate/scripts/execution-order/test-1.assembly.lp");
+ string scriptExpectation = getDocumentationExampleById("documentation/index.xml", "ExampleEov_1_Expectation");
+ string scriptRegistration = getDocumentationExampleById("documentation/index.xml", "ExampleEov_1_Registration");
+
+ replace(script, "<insert ExampleEov_1_Expectation>", scriptExpectation);
+ replace(script, "<insert ExampleEov_1_Registration>", scriptRegistration);
+ replace(code, "<insert ExampleEov_1_Specializations>", codeSpecializations);
+
+ auto man = details::tier1::XreateManager::prepare(move(code));
+ man->transcend->addRawScript(move(script));
+
+ man->analyse();
+ FnNoArgs program = (FnNoArgs)man->run();
+ delete man;
+
+ testing::internal::CaptureStdout();
+ program();
+ std::string outputActual = testing::internal::GetCapturedStdout();
+ ASSERT_NE(std::string::npos, outputActual.find("HeaderBodyFooter"));
}
\ No newline at end of file
diff --git a/cpp/tests/transcend.cpp b/cpp/tests/transcend.cpp
index 7795d83..022b105 100644
--- a/cpp/tests/transcend.cpp
+++ b/cpp/tests/transcend.cpp
@@ -1,58 +1,92 @@
/* 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);
+ 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)";
+ ASSERT_NE(std::string::npos, outputActual.find(outputExpected));
}
\ No newline at end of file
diff --git a/documentation/Concepts/interpretation.xml b/documentation/Concepts/interpretation.xml
index 50b46cb..e102841 100644
--- a/documentation/Concepts/interpretation.xml
+++ b/documentation/Concepts/interpretation.xml
@@ -1,638 +1,869 @@
<?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 26cy4nalqsw pu35zrt1aby9?>
<title><?xxe-sn 26cy4nalqsw pu35zrt1abya?>Interpretation</title>
<para><?xxe-sn 26cy4nalqsw pu35zrt1abyb?>Interpretation is a compiler's mode
reserved to evaluate, expand and simplify parts of a given program based on
information available in this mode. On the other hand, Interpretation is a
middle man, or an intermediate level, between the Transcend and Brute
levels, as it facilitates communication between those by means of
interpreting data of respective layers. It can be further divided into Upper
and Lower Interpretations depending on the interaction with the layer we are
focused on at the moment.</para>
<remark><?xxe-sn 26stp2g6sxs p?><emphasis role="bold"><?xxe-sn 26stp2g6sxs q?>mode
whereby - как это перевести? - это режим с помощью которого xreate
интерпретирует? Авторский смысл: это режим(компилятора) В КОТОРОМ компилятор
интерпретирует. </emphasis></remark>
<remark><?xxe-sn 26stp2g6sxs 1?>Program: Речь идет о компьютерной программе,
или может приложении для смартфона, или алгоритме? Тогда лучше употребить
соответственно software ('piece of software') / app / algorithm. Вообще
"наши" компьютерные программы - это у них software, а не programs - -
<emphasis role="bold"><?xxe-sn 26stp2g6sxs 2?>ДА ТУТ СЛОВО PROGRAM ПОДХОДИТ,
особенно в контексте обработки программы с какимито целями, как здесь, чтоб
ее интерпретировать.</emphasis></remark>
<programlisting xml:id="Intr_1"><?xxe-sn 26cy4nalqsw pu35zrt1abyd?>name="tests/interpretation.cpp: Interpretation.Doc_Intr_1"
main= function:: int; entry
{
x= "a":: string.
y= if (x=="b"):: string; i12n(on)
{1} else {0}.
y
}</programlisting>
<para><?xxe-sn 26cy4nalqsw pu35zrt1abye?>In this example, the identifier
<code><?xxe-sn 26cy4nalqsw pu35zrt1abyf?>y</code> has an attached annotation
<code><?xxe-sn 26cy4nalqsw pu35zrt1abyg?>i12(on)</code> which indicates that
the compiler should use compile-time interpretation to evaluate
<code><?xxe-sn 26cy4nalqsw pu35zrt1abyh?>y</code>. Once the simplification
process is over, the function returns <code><?xxe-sn 26cy4nalqsw pu35zrt1abyi?>0</code>,
with neither memory allocations for the string variable <code><?xxe-sn 26cy4nalqsw pu35zrt1abyj?>x</code>
nor any computation at runtime.</para>
<remark><?xxe-sn 26stp2g6sxs 3?>Annotation - может лучше value или
parameter? - <emphasis role="bold"><?xxe-sn 26stp2g6sxs 4?>да Annotation
подходит</emphasis></remark>
<para><?xxe-sn 26cy4nalqsw pu35zrt1abyk?>There are two annotations reserved
to control the interpretation process:</para>
<itemizedlist>
<?xxe-sn 26cy4nalqsw pu35zrt1abyl?>
<listitem>
<?xxe-sn 26cy4nalqsw pu35zrt1abym?>
<para><?xxe-sn 26cy4nalqsw pu35zrt1abyn?><code><?xxe-sn 26cy4nalqsw pu35zrt1abyo?>i12n(on)</code>
Forces compiler to interpret the annotated expression, function, or
function argument. It yields error if the expression is impossible to
interpret.</para>
</listitem>
<listitem>
<?xxe-sn 26cy4nalqsw pu35zrt1abyp?>
<para><?xxe-sn 26cy4nalqsw pu35zrt1abyq?><code><?xxe-sn 26cy4nalqsw pu35zrt1abyr?>i12n(off)</code>
Disables interpretation for the annotated expression.</para>
</listitem>
</itemizedlist>
<section>
<?xxe-sn 26cy4nalqsw pu35zrt1abys?>
<title><?xxe-sn 26cy4nalqsw pu35zrt1abyt?>Eligible Expressions</title>
<para><?xxe-sn 26cy4nalqsw pu35zrt1abyu?>Currently the compiler is able to
interpret the following expressions:</para>
<itemizedlist>
<?xxe-sn 26cy4nalqsw pu35zrt1abyv?>
<listitem>
<?xxe-sn 26cy4nalqsw pu35zrt1abyw?>
<para><?xxe-sn 26cy4nalqsw pu35zrt1abyx?>Atomic instructions: numbers,
strings, identifiers.</para>
</listitem>
<listitem>
<?xxe-sn 26cy4nalqsw pu35zrt1abyy?>
<para><?xxe-sn 26cy4nalqsw pu35zrt1abyz?>Relational and logic
operators e.g. <code><?xxe-sn 26cy4nalqsw pu35zrt1abz0?>x==true</code>,
<code><?xxe-sn 26cy4nalqsw pu35zrt1abz1?>x!=0</code>.</para>
</listitem>
<listitem>
<?xxe-sn 26cy4nalqsw pu35zrt1abz2?>
<para><?xxe-sn 26cy4nalqsw pu35zrt1abz3?><code><?xxe-sn 26cy4nalqsw pu35zrt1abz4?>if</code>,
<code><?xxe-sn 26cy4nalqsw pu35zrt1abz5?>switch</code> statements.
[[#late-interpretation-or-e|Statement expansion]] allowed.</para>
</listitem>
<listitem>
<?xxe-sn 26cy4nalqsw pu35zrt1abz6?>
<para><?xxe-sn 26cy4nalqsw pu35zrt1abz7?>Loop statements.
[[#late-interpretation-or-e|Statement expansion]] allowed.</para>
</listitem>
<listitem>
<?xxe-sn 26cy4nalqsw pu35zrt1abz8?>
<para><?xxe-sn 26cy4nalqsw pu35zrt1abz9?>Functions.
[[#function-interpretation|Function calls]],
[[#partial-or-late-function|Partial function call
interpretation]].</para>
<remark><?xxe-sn 26stp2g6sxs 5?>interpreta - это так и нужно, или
неполное слово? - <emphasis role="bold"><?xxe-sn 26stp2g6sxs 6?>этот
кусок текста на сайте превратится в ссылку, это адрес ссылки, такой
должен быть</emphasis></remark>
</listitem>
<listitem>
<?xxe-sn 26cy4nalqsw pu35zrt1abza?>
<para><?xxe-sn 26cy4nalqsw pu35zrt1abzb?>Index operator e.g.
<code><?xxe-sn 26cy4nalqsw pu35zrt1abzc?>x = {1, 2, 3}.
y = x[0]</code>, <code><?xxe-sn 26t7ih8bitc 1?>info = {planet="Earth"}.
x = info["planet"]</code>.</para>
</listitem>
<listitem>
<?xxe-sn 26cy4nalqsw pu35zrt1abze?>
<para><?xxe-sn 26cy4nalqsw pu35zrt1abzf?>List operators e.g.
<code><?xxe-sn 26t7ih8bitc 2?>x = [1..10]. y={"day",
"night"}</code>.</para>
</listitem>
</itemizedlist>
</section>
<section>
<?xxe-sn 26cy4nalqsw pu35zrt1abzh?>
<title><?xxe-sn 26cy4nalqsw pu35zrt1abzi?>Function Interpretation</title>
<para><?xxe-sn 26cy4nalqsw pu35zrt1abzj?>The whole function body may be
subject to interpretation if it consists of interpretable expressions
only.</para>
<programlisting xml:id="FnIntr_1"><?xxe-sn 26cy4nalqsw pu35zrt1abzk?>name="tests/interpretation.cpp: Interpretation.Doc_FnIntr_1"
unwrap = function(data::unknType, keys::unknType):: unknType; i12n(on)
{
loop fold(keys-&gt;key::string, data-&gt;record):: unknType
{
record[key]
}
}
test = function:: bool; entry
{
book = unwrap({
Library = {
Shelf = {
Book = "Aristotle's Politics"
}}}, {"Library", "Shelf", "Book"}):: unknType.
book == "Aristotle's Politics"
}</programlisting>
<para><?xxe-sn 26cy4nalqsw pu35zrt1abzl?>The above example demonstrates
the <code><?xxe-sn 26cy4nalqsw pu35zrt1abzm?>unwrap</code> function which
is intended to be fully interpretable, as indicated by the function
header's annotation. Obviously, the interpretable function requires that
all its arguments are also interpretable. In this case the compiler is
able to calculate the function's result at compile time with no byte code
produced. Here is what the compiled code looks like (which will be also
optimized out during the consequent compilation phases):</para>
<programlisting xml:id="Alt_FnIntr_1"><?xxe-sn 26cy4nalqsw pu35zrt1abzn?>name="tests/interpretation.cpp: Interpretation.Doc_FnIntr_1"
test = function:: bool; entry
{
book = "Aristotle's Politics":: string; i12n(on).
book == "Aristotle's Politics"
}</programlisting>
<para><?xxe-sn 26cy4nalqsw pu35zrt1abzo?>The example also reveals a number
of similarities with dynamically typed programming languages:</para>
<remark><?xxe-sn 26stp2g6sxs 7?>number of similarities - тут точно нужен
артикль, неопределенный (a) если в смысле "много схожестей", и
определенный (the) - если речь идет о точном их количестве. a dynamically
typed - неопределенный артикль никогда не употребляется при множественных
объектах - <emphasis role="bold"><?xxe-sn 26stp2g6sxs 8?>OK</emphasis></remark>
<itemizedlist>
<?xxe-sn 26cy4nalqsw pu35zrt1abzp?>
<listitem>
<?xxe-sn 26cy4nalqsw pu35zrt1abzq?>
<para><?xxe-sn 26cy4nalqsw pu35zrt1abzr?><emphasis><?xxe-sn 26cy4nalqsw pu35zrt1abzs?>Relaxed
types</emphasis>. Notice <code><?xxe-sn 26cy4nalqsw pu35zrt1abzt?>unknType</code>
type which has not been defined. It's interpreted well because the
compiler completely ignores the type system since everything can be
checked at compile time anyway. The Interpretation mode is exactly the
level where the relaxed type system is possible without any
performance penalties or safety concerns.</para>
</listitem>
<listitem>
<?xxe-sn 26cy4nalqsw pu35zrt1abzu?>
<para><?xxe-sn 26cy4nalqsw pu35zrt1abzv?><emphasis><?xxe-sn 26cy4nalqsw pu35zrt1abzw?>Introspection
abilities</emphasis>. Notice how it is allowed to treat list fields as
string keys, so functions like <code><?xxe-sn 26cy4nalqsw pu35zrt1abzx?>unwrap</code>
can get list field name as a parameter. Possible errors, such as the
list not having the requested field are easily spotted by the compiler
during interpretation and there are no concealed runtime bugs. In a
sense, it is a fair trade off between introspection expressiveness and
possible compilation errors.</para>
<remark><?xxe-sn 26stp2g6sxs 9?>no hard to catch runtime bugs - не
вполне ясно. В смысле, "легко заметить баги проявившиеся во время
операции"? Тогда лучше "its is easy to see runtime bugs", или может
"the runtime bugs are possible" (если смысл такой, что могут
проявиться ошибки/баги"). It's и другие подобные сокращения: лучше
употреблять полную форму - it is, так как it's это разговорный вариант
- <emphasis role="bold"><?xxe-sn 26stp2g6sxs a?>OK</emphasis>.</remark>
</listitem>
</itemizedlist>
<note>
<?xxe-sn 26cy4nalqsw pu35zrt1abzy?>
<para><?xxe-sn 26cy4nalqsw pu35zrt1abzz?>Additional reason for the
arbitrary undefined type <code><?xxe-sn 26cy4nalqsw pu35zrt1ac00?>unknType</code>
being used in the example is to ensure that no compilation occurs and
everything is done at the interpretation mode.</para>
</note>
<para><?xxe-sn 26cy4nalqsw pu35zrt1ac01?>In simple cases interpretation
analysis could determine that a function is subject to interpretation with
no annotation hints provided.</para>
<programlisting xml:id="FnIntr_2"><?xxe-sn 26tbgov1xq8 1?>name="tests/interpretation.cpp: Interpretation.Doc_FnIntr_2"
unwrap = function(data::unknType, keys::unknType):: unknType
{
loop fold(keys-&gt;key::string, data-&gt;record):: unknType
{
record[key]
}
}
test = function:: bool; entry
{
book = unwrap({
Library = {
Shelf = {
Book = "Aristotle's Politics"
}}}, {"Library", "Shelf", "Book"}):: unknType; i12n(on).
book == "Aristotle's Politics"
}</programlisting>
<para><?xxe-sn 26cy4nalqsw pu35zrt1ac03?>The only difference from the
example above is the lack of annotation hint for <code><?xxe-sn 26cy4nalqsw pu35zrt1ac04?>unwrap</code>.
It can be seen that interpretation of the variable <code><?xxe-sn 26cy4nalqsw pu35zrt1ac05?>book</code>
is required which in its turn depends on <code><?xxe-sn 26cy4nalqsw pu35zrt1ac06?>unwrap</code>.
In this case analysis is capable enough to determine that <code><?xxe-sn 26cy4nalqsw pu35zrt1ac07?>unwrap</code>
is indeed possible to interpret, so no errors occur.</para>
<remark><?xxe-sn 26stp2g6sxs b?>"Developer requires interpretation" - тут
речь о разработчике-программисте? Не вполне понятен смысл, поэтому пока
оставляю как есть. - <emphasis role="bold"><?xxe-sn 26stp2g6sxs c?>да
программист, исправил</emphasis></remark>
<para><?xxe-sn 26cy4nalqsw pu35zrt1ac08?>There are, however, more
complicated cases for interpretation analysis:</para>
<itemizedlist>
<?xxe-sn 26cy4nalqsw pu35zrt1ac09?>
<listitem>
<?xxe-sn 26cy4nalqsw pu35zrt1ac0a?>
<para><?xxe-sn 26cy4nalqsw pu35zrt1ac0b?>Direct recursion.
Interpretation analysis is able to correctly determine whether a
function involving direct recursion (where the function calls itself)
is subject to interpretation or not.</para>
</listitem>
<listitem>
<?xxe-sn 26cy4nalqsw pu35zrt1ac0c?>
<para><?xxe-sn 26cy4nalqsw pu35zrt1ac0d?>Indirect recursion.
Currently, when processing the indirect recursion (where a function is
called not by itself but rather by another function), the analysis
usually fails and relies on manually provided annotation hints.</para>
</listitem>
</itemizedlist>
<para><?xxe-sn 26cy4nalqsw pu35zrt1ac0e?>Below is an example of a direct
recursion:</para>
<programlisting xml:id="FnIntr_3"><?xxe-sn 26cy4nalqsw pu35zrt1ac0f?>name="tests/interpretation.cpp: Interpretation.Doc_FnIntr_3"
unwrap = function(data:: X):: bool
{
if (data[0] == "the-end"):: bool
{true} else {unwrap(data[0])}
}
entry = function:: bool; entry
{
unwrap({{{{"the-end"}}}}):: bool; i12n(on)
}</programlisting>
<para><?xxe-sn 26cy4nalqsw pu35zrt1ac0g?>Function <code><?xxe-sn 26cy4nalqsw pu35zrt1ac0h?>unwrap</code>
unwraps the nested list until the desired value is found. No function
level annotation is required.</para>
</section>
<section>
<?xxe-sn 26cy4nalqsw pu35zrt1ac0i?>
<title><?xxe-sn 26cy4nalqsw pu35zrt1ac0j?>Late Interpretation or
Expansion</title>
<para><?xxe-sn 26cy4nalqsw pu35zrt1ac0k?><emphasis><?xxe-sn 26stp2g6sxs d?>Late
Interpretation</emphasis> can be conceptualized as a <emphasis><?xxe-sn 26stp2g6sxs e?>partial</emphasis>
expansion, i.e. a simplification or elimination of interpretable parts of
certain statements.</para>
<programlisting xml:id="LateIntr_1"><?xxe-sn 26cy4nalqsw pu35zrt1ac0l?>name="tests/interpretation.cpp: Interpretation.Doc_LateIntr_1"
test = function(x:: int):: int; entry
{
comm= "inc":: string; i12n(on).
y= if (comm == "inc"):: int
{x + 1} else {x}.
y
}</programlisting>
<para><?xxe-sn 26cy4nalqsw pu35zrt1ac0m?>In this example, computation of
<code><?xxe-sn 26cy4nalqsw pu35zrt1ac0n?>y</code> depends on
<code><?xxe-sn 26cy4nalqsw pu35zrt1ac0o?>comm</code> and <code><?xxe-sn 26cy4nalqsw pu35zrt1ac0p?>x</code>.
On the one hand, <code><?xxe-sn 26cy4nalqsw pu35zrt1ac0q?>comm</code> has
an annotation that requires interpretation, while on the other hand
<code><?xxe-sn 26cy4nalqsw pu35zrt1ac0r?>x</code> is unknown at the
compile-time and thus cannot be interpreted. In this case the only way to
satisfy contradictory requirements is to <emphasis><?xxe-sn 26cy4nalqsw pu35zrt1ac0s?>expand</emphasis>
the <code><?xxe-sn 26cy4nalqsw pu35zrt1ac0t?>if</code> statement, since it
is only possible to interpret condition part of the statement, leaving
conditional blocks unchanged. In other words, the <code><?xxe-sn 26cy4nalqsw pu35zrt1ac0u?>if</code>
statement is <emphasis><?xxe-sn 26cy4nalqsw pu35zrt1ac0v?>expanded</emphasis>
which results in only one of the child blocks being compiled,
<code><?xxe-sn 26cy4nalqsw pu35zrt1ac0w?>x+1</code> in this example, based
on already known fact that the <code><?xxe-sn 26stp2g6sxs f?>else</code>
block would never be executed.</para>
<remark><?xxe-sn 26stp2g6sxs g?>"to interpret condition part of the
statement" - это не смог понять. - <emphasis role="bold"><?xxe-sn 26stp2g6sxs h?>`if
(...) {..} else {...}` is a statement. It consists of condition part `if
(..)`, and two blocks - "if-true" block and "if-false" block
</emphasis></remark>
<para><?xxe-sn 26cy4nalqsw pu35zrt1ac0x?>Due to the fact that expansion,
as opposed to "pure interpretation", leaves some portion of the code for
subsequent compilation it can also be called <emphasis><?xxe-sn 26cy4nalqsw pu35zrt1ac0y?>late
interpretation</emphasis> for the result depends on runtime information
and has memory and performance footprint.</para>
<remark><?xxe-sn 26stp2g6sxs i?>as having runtime footprint - не понял.
Что-то связанное с требованиями к памяти? Но это кажется о программах, а
не о interpretation - <emphasis role="bold"><?xxe-sn 26stp2g6sxs j?>переписал
фразу</emphasis></remark>
<para><?xxe-sn 26cy4nalqsw pu35zrt1ac0z?>Below is a more complex example
of a loop expansion:</para>
<programlisting xml:id="LateIntr_2"><?xxe-sn 26cy4nalqsw pu35zrt1ac10?>name="tests/interpretation.cpp: Interpretation.Doc_LateIntr_2"
main = function(x:: int):: int; entry
{
commands = {"inc", "double", "dec"}:: [string]; i12n(on).
loop fold(commands-&gt;comm::string, x-&gt;operand):: int
{
switch(comm):: int
case ("inc") {operand + 1}
case ("dec") {operand - 1}
case ("double") {operand * 2}
}
}
</programlisting>
<para><?xxe-sn 26cy4nalqsw pu35zrt1ac11?>Identifier <code><?xxe-sn 26cy4nalqsw pu35zrt1ac12?>commands</code>
contains a list of operations that need to be interpreted as indicated by
the corresponding annotation. Operand <code><?xxe-sn 26cy4nalqsw pu35zrt1ac13?>x</code>
is assigned at runtime. This is the same situation as in previous example,
and it triggers expansion as expected. The result after expansion looks as
follows:</para>
<programlisting xml:id="Alt_LateIntr_2"><?xxe-sn 26cy4nalqsw pu35zrt1ac14?>name="tests/interpretation.cpp: Interpretation.Doc_LateIntr_2"
main = function(x:: int):: int; entry
{
x{1} = x + 1:: int.
x{2} = x{1} * 2:: int.
x{3} = x{2} * 1:: int.
x{3}
}</programlisting>
<para><?xxe-sn 26cy4nalqsw pu35zrt1ac15?>In other words, this mimics the
well known loop unrolling technique by putting several copies of the loop
body in a row, each one for every item in the list <code><?xxe-sn 26stp2g6sxs k?>commands</code>.</para>
<para><?xxe-sn 26cy4nalqsw pu35zrt1ac16?>As of now, the following
statements support late interpretation:</para>
<itemizedlist>
<?xxe-sn 26cy4nalqsw pu35zrt1ac17?>
<listitem>
<?xxe-sn 26cy4nalqsw pu35zrt1ac18?>
<para><?xxe-sn 26cy4nalqsw pu35zrt1ac19?>Branching statements:
<code><?xxe-sn 26cy4nalqsw pu35zrt1ac1a?>if</code>, <code><?xxe-sn 26cy4nalqsw pu35zrt1ac1b?>switch</code>,
<code><?xxe-sn 26cy4nalqsw pu35zrt1ac1c?>switch variant</code>,
<code><?xxe-sn 26cy4nalqsw pu35zrt1ac1d?>switch late</code>.</para>
</listitem>
<listitem>
<?xxe-sn 26cy4nalqsw pu35zrt1ac1e?>
<para><?xxe-sn 26cy4nalqsw pu35zrt1ac1f?>Loop statements:
<code><?xxe-sn 26cy4nalqsw pu35zrt1ac1g?>loop fold</code>.</para>
</listitem>
<listitem>
<?xxe-sn 26cy4nalqsw pu35zrt1ac1h?>
<para><?xxe-sn 26cy4nalqsw pu35zrt1ac1i?>Functions.</para>
</listitem>
<listitem>
<?xxe-sn 26cy4nalqsw pu35zrt1ac1j?>
<para><?xxe-sn 26cy4nalqsw pu35zrt1ac1k?>Other operators:
<code><?xxe-sn 26cy4nalqsw pu35zrt1ac1l?>query late</code>.</para>
</listitem>
</itemizedlist>
</section>
<section>
<?xxe-sn 26cy4nalqsw pu35zrt1ac1m?>
<title><?xxe-sn 26cy4nalqsw pu35zrt1ac1n?>Partial or Late Function
Interpretation</title>
<para><?xxe-sn 26cy4nalqsw pu35zrt1ac1o?>Xreate supports cases where a
function has mixed arguments in terms of interpretation, some of which
need to be interpreted, while others need to be compiled.</para>
<programlisting xml:id="LateFnIntr_1"><?xxe-sn 26cy4nalqsw pu35zrt1ac1p?>name="tests/interpretation.cpp: Interpretation.Doc_LateFnIntr_1"
evaluate= function(argument:: num, code:: string; i12n(on)):: num
{
switch(code):: num
case ("inc") {argument + 1}
case ("dec") {argument - 1}
case ("double") {argument * 2}
case default {argument}
}
main = function(init::int):: int; entry
{
commands= {"inc", "double", "dec"}:: [string]; i12n(on).
loop fold(commands-&gt;comm::string, init-&gt;operand):: int
{
evaluate(operand, comm)
}
}</programlisting>
<para><?xxe-sn 26cy4nalqsw pu35zrt1ac1q?>Looking at the function
<code><?xxe-sn 26cy4nalqsw pu35zrt1ac1r?>evaluate</code>'s signature in
this example we can see only one argument <code><?xxe-sn 26cy4nalqsw pu35zrt1ac1s?>code</code>
that requires interpretation. This means that the function <code><?xxe-sn 26cy4nalqsw pu35zrt1ac1t?>evaluate</code>
is subject to a partial interpretation or, in other words,
<emphasis><?xxe-sn 26cy4nalqsw pu35zrt1ac1u?>late function
interpretation</emphasis>.</para>
<para><?xxe-sn 26stp2g6sxs n?>In general, to enable late interpretation
for a function, at least one of its arguments should be annotated as
<code><?xxe-sn 26cy4nalqsw pu35zrt1ac1v?>i12n(on)</code>. What compiler
does next is to generate a number of distinctive <emphasis><?xxe-sn 26cy4nalqsw pu35zrt1ac1w?>function
specializations</emphasis>. Each unique combination of interpretable
argument values corresponds to its own function specialization. This
should be used with cautiousness, since compiler can generate large
amounts of code in some cases.</para>
<remark><?xxe-sn 26stp2g6sxs l?>What compiler does next is to generate
number - то же самое, что в примеч. ниже (a number - несколько, the number
- конкретное число).To enable late interpretation for function - тут перед
function обязательно нужен артикль - определенный (the), если речь идет о
evaluate, или неопределенный (а) если речь идет о любой функции (я указал
the) - <emphasis role="bold"><?xxe-sn 26stp2g6sxs m?>OK</emphasis></remark>
<para><?xxe-sn 26cy4nalqsw pu35zrt1ac1x?>Based on the above example, three
different <code><?xxe-sn 26cy4nalqsw pu35zrt1ac1y?>evaluate</code>
specializations are generated as follows:</para>
<programlisting xml:id="Alt_LateFnIntr_1"><?xxe-sn 26cy4nalqsw pu35zrt1ac1z?>name="tests/interpretation.cpp: Interpretation.Doc_LateFnIntr_1"
main= function(init::int):: int; entry
{
operand = init:: int.
operand{1} = evaluate1(operand):: int.
operand{2} = evaluate2(operand{1})::int.
operand{3} = evaluate3(operand{2})::int.
operand(3)
}</programlisting>
</section>
+ <section>
+ <?xxe-sn 2f6e093xhxc 1?>
+
+ <title><?xxe-sn 2f6e093xhxc 2?>Transcend and Interpretation</title>
+
+ <synopsis><?xxe-sn 2f6e093xhxc 3?>SYNTAX:
+**intrinsic query** (//predicate//):: type; [//annotations-list//]</synopsis>
+
+ <itemizedlist>
+ <?xxe-sn 2f6e093xhxc 4?>
+
+ <listitem>
+ <?xxe-sn 2f6e093xhxc 5?>
+
+ <para><?xxe-sn 2f6e093xhxc 6?><emphasis><?xxe-sn 2f6e093xhxc 7?>predicate</emphasis>
+ Denotes a Transcend predicate.</para>
+ </listitem>
+ </itemizedlist>
+
+ <para><?xxe-sn 2f6e093xhxc a?>Represents the value of the Transcend
+ predicate <emphasis><?xxe-sn 2f6e093xhxc b?>predicate</emphasis> in the
+ format as follows:</para>
+
+ <itemizedlist>
+ <?xxe-sn 2f6e093xhxc g?>
+
+ <listitem>
+ <?xxe-sn 2f6e093xhxc h?>
+
+ <para><?xxe-sn 2f6e093xhxc i?>If a predicate has only one argument,
+ returns a list of elements of an appropriate type: <code><?xxe-sn 2f6e093xhxc j?>int</code>,
+ <code><?xxe-sn 2f6e093xhxc k?>string</code>, variant or tuple.</para>
+ </listitem>
+
+ <listitem>
+ <?xxe-sn 2f6e093xhxc l?>
+
+ <para><?xxe-sn 2f6e093xhxc m?>in case of several arguments, the
+ arguments comprise a record. The function returns a list of
+ records.</para>
+ </listitem>
+
+ <listitem>
+ <?xxe-sn 2f6e093xhxc n?>
+
+ <para><?xxe-sn 2f6e093xhxc o?>Predicates correspond to
+ variants.</para>
+ </listitem>
+ </itemizedlist>
+
+ <para><?xxe-sn 2f6e093xhxc 8?>Interpretation can be viewed as the middle
+ ground between high level Transcend and low level Brute. In essence, the
+ principal role of Interpretation is to serve as a link between them by
+ <emphasis><?xxe-sn 2f6e093xhxc 9?>interpreting</emphasis> data for Brute
+ from Transcend. The special built-in function <code><?xxe-sn 2f6e093xhxc c?>intrinsic query</code>
+ is provided to query data from Transcend allowing to process it
+ further.</para>
+
+ <para><?xxe-sn 2f6e093xhxc d?>As a short example, assume that we have
+ Transcend facts as follows:</para>
+
+ <programlisting><?xxe-sn 2f6e093xhxc e?>person("Ben").</programlisting>
+
+ <para><?xxe-sn 2f6e093xhxc f?>This data can be queried as below:</para>
+
+ <programlisting><?xxe-sn 2f6e093xhxc p?>Persons = type [string]. //we expect a list of strings
+persons = function:: Persons
+{
+ intrinsic query("person"):: Persons
+}</programlisting>
+
+ <para><?xxe-sn 2f6e093xhxc q?>The <code><?xxe-sn 2f6e093xhxc r?>persons</code>
+ function in this example returns a list of persons supplied by Transcend.
+ The example can be slightly rewritten using <link
+ xlink:href="/d/syntax/#slave-types"><?xxe-sn 2f6e093xhxc s?>slave
+ types</link> which are reserved to automatically identify an appropriate
+ type for the returned value. The next excerpt is equivalent to the
+ previous one:</para>
+
+ <programlisting><?xxe-sn 2f6e093xhxc t?>Person = type slave person. //equivalent to string
+Persons = type [Person]
+
+persons = function:: Persons
+{
+ intrinsic query("person"):: Persons
+}</programlisting>
+
+ <para><?xxe-sn 2f6e093xhxc u?>Querying allows to use powerful Transcend
+ capabilities to solve convoluted problems, consequently retrieving
+ reasoning solutions by Brute for efficient processing. Consider a more
+ complicated example dealing with a GUI.</para>
+
+ <para><?xxe-sn 2f6e093xhxc v?>First, let us start off defining more or
+ less semantically an application's GUI on Transcend level:</para>
+
+ <programlisting xml:id="IntrinsicQuery_2_GUI"><?xxe-sn 2f6e093xhxc w?>name="tests/association.cpp: Association.Doc_IntrinsicQuery_2", lines=15
+%Layout consists of two blocks:
+block(my_content; my_nav).
+
+%Assign roles to the blocks:
+role(my_content, body).
+role(my_nav, navigation).
+
+%Navigation block can be in either an iconized or expanded form:
+form(none; expanded; iconized).
+allowed_form(my_nav, (expanded; iconized)).
+
+%Visual theme:
+background(my_content, color(blue)).
+background(my_nav, color(grey)).</programlisting>
+
+ <para><?xxe-sn 2f6e093xhxc x?>Above we have described GUI consisting of
+ two blocks: main content and navigation blocks. The same application can
+ look differently depending on platform or viewport properties. Let us
+ define a platform:</para>
+
+ <programlisting xml:id="IntrinsicQuery_2_Platform"><?xxe-sn 2f6e093xhxc y?>name="tests/association.cpp: Association.Doc_IntrinsicQuery_2", lines=15
+% The height is greater than the viewport's width:
+orientation(portrait).</programlisting>
+
+ <para><?xxe-sn 2f6e093xhxc z?>Having an application's semantic description
+ as well as a platform's description we can now combine them using
+ additional rules to produce the final result: how the application should
+ look like on the given platform.</para>
+
+ <programlisting xml:id="IntrinsicQuery_2_Rules"><?xxe-sn 2f6e093xhxc 10?>name="tests/association.cpp: Association.Doc_IntrinsicQuery_2", lines=15
+% Portrait orientation rules:
+
+%Determine appopriate navigation list's form:
+form(Nav, iconized):-
+ orientation(portrait);
+ allowed_form(Nav, iconized);
+ role(Nav, navigation).
+
+%Determine blocks' layout:
+align(Nav, bottom_of(Body)):-
+ orientation(portrait);
+ role(Nav, navigation);
+ role(Body, body).
+
+% Landscape orientation rules:
+form(Nav, expanded):-
+ orientation(landscape);
+ allowed_form(Nav, expanded);
+ role(Nav, navigation).
+
+align(Nav, left_of(Body)):-
+ orientation(landscape);
+ role(Nav, navigation);
+ role(Body, body).</programlisting>
+
+ <para><?xxe-sn 2f6e093xhxc 11?>In short, the rules above read that we
+ place the expanded navigation block <code><?xxe-sn 2f6e093xhxc 12?>my_nav</code>
+ and the content block <code><?xxe-sn 2f6e093xhxc 13?>my_content</code> in
+ a row for wide displays; conversely, <code><?xxe-sn 2f6e093xhxc 14?>my_content</code>
+ and iconized <code><?xxe-sn 2f6e093xhxc 15?>my_nav</code> on top of each
+ other for narrow displays.</para>
+
+ <para><?xxe-sn 2f6e093xhxc 16?>After Transcend has decided actual forms
+ and blocks alignment, the next step is to retrieve solutions denoted by
+ the <code><?xxe-sn 2f6e093xhxc 17?>align</code> and <code><?xxe-sn 2f6e093xhxc 18?>form</code>
+ predicates and to actually draw GUI elements:</para>
+
+ <programlisting xml:id="IntrinsicQuery_2_Code"><?xxe-sn 2f6e093xhxc 19?>name="tests/association.cpp: Association.Doc_IntrinsicQuery_2", lines=15
+//Define types:
+Block = type slave block.
+Role = type variant {body, navigation}.
+Alignment = type variant{
+ bottom_of:: Block,
+ left_of::Block
+}.
+Layout = type {Role, Alignment}.
+
+//Determine role and form:
+drawBlock = function(block:: Block):: Drawing
+{
+ forms = intrinsic query ("form"):: [Form].
+ formCurrent = getBlockForm(forms, block):: Form.
+
+ roles = intrinsic query ("role"):: [Role].
+ roleCurrent = getBlockRole(block):: Role.
+
+ switch variant (roleCurrent):: Drawing
+ case (body)
+ {drawBody(formCurrent)}
+
+ case (navigation)
+ {drawNavigation(formCurrent)}
+}
+
+//Determine layout
+draw = function:: Drawing; entry
+{
+ layout = intrinsic query ("layout"):: Layout.
+ blockA = layout[0]:: Block.
+
+ switch variant (layout[1]-&gt;blockB):: Drawing
+ case (bottom_of)
+ {drawVerical(blockA, blockB)}
+
+ case (left_of)
+ {drawHorizontal(blockA, blockB)}
+}</programlisting>
+
+ <para><?xxe-sn 2f7yw0s6vb4 1?>Notice that the <code><?xxe-sn 2f7yw0s6vb4 2?>draw</code>
+ and <code><?xxe-sn 2f7yw0s6vb4 3?>drawBlock</code> functions work with
+ compile time data from Transcend, thus all this code after interpretation
+ gets simplified into the following:</para>
+
+ <programlisting><?xxe-sn 2f7yw0s6vb4 4?>drawVertical(drawBody(none()), drawNavigation(iconized())).</programlisting>
+
+ <para><?xxe-sn 2f7yw0s6vb4 5?>The example above demonstrates the
+ possibility to delegate to Transcend <emphasis><?xxe-sn 2f7yw0s6vb4 6?>intelligent
+ tasks</emphasis>, such as adapting a GUI to a particular platform, and
+ leaving Brute with efficient implementation matters.</para>
+ </section>
+
<section>
<?xxe-sn 26cy4nalqsw pu35zrt1ac20?>
<title><?xxe-sn 26cy4nalqsw pu35zrt1ac21?>Domain Specific Languages and
Interpretation</title>
<para><?xxe-sn 26cy4nalqsw pu35zrt1ac22?>DSL is an idea of expressing
various concepts in a lapidary and concise form. Xreate recognizes and
acknowledges very successful and beneficial DSL usage in certain areas,
primarily to express <emphasis><?xxe-sn 26cy4nalqsw pu35zrt1ac23?>queries</emphasis>
and <emphasis><?xxe-sn 26cy4nalqsw pu35zrt1ac24?>configs</emphasis>, to
name a few. It is possible to use interpretation abilities to emulate DSL.
Developer can express the desired functionality in the form of nested
lists of numbers, variants and strings which are then processed by a
partially interpreted function. Such function in its turn transforms the
input data into a set of low level compilation instructions so there is no
runtime overhead.</para>
</section>
<section>
<?xxe-sn 26cy4nalqsw pu35zrt1ac25?>
<title><?xxe-sn 26cy4nalqsw pu35zrt1ac26?>On Interpretation
Analysis</title>
<para><?xxe-sn 26cy4nalqsw pu35zrt1ac27?>Analysis follows classical
<emphasis><?xxe-sn 26stp2g6sxs o?>type reconstruction</emphasis>
algorithms to determine which expressions are subject to interpretation
and check the correctness of reconstruction w.r.t. developer-provided
annotations. Analysis consists of two general parts:</para>
<itemizedlist>
<?xxe-sn 26cy4nalqsw pu35zrt1ac28?>
<listitem>
<?xxe-sn 26cy4nalqsw pu35zrt1ac29?>
<para><?xxe-sn 26cy4nalqsw pu35zrt1ac2a?><emphasis><?xxe-sn 26cy4nalqsw pu35zrt1ac2b?>Inference</emphasis>.
Infers if it is possible to interpret an expression based on its
already inferred argument's decisions.</para>
</listitem>
<listitem>
<?xxe-sn 26cy4nalqsw pu35zrt1ac2c?>
<para><?xxe-sn 26cy4nalqsw pu35zrt1ac2d?><emphasis><?xxe-sn 26cy4nalqsw pu35zrt1ac2e?>Unification</emphasis>.
Assigns an appropriate decision w.r.t. previously inferred
expectations and developer-provided hints as well.</para>
</listitem>
</itemizedlist>
</section>
</chapter>
<?xxe-revisions
+#9 2019-05-16T14:57:00Z pgess
+#8 2019-05-15T14:56:03Z pgess
+1sPEAAABgoB4AC2CgHcAABQSc4HLSiMEE4tOEwcTB1MHMyFDqSUAgdY4gctKga9vhRKHQexAhEg=
+
+#7 2019-05-14T17:52:28Z pgess
+1sPEAAABgoB7AINMgfUKABqBcYE4LiBBaXc/PmZ5Pz4lIEhsb25nZW50ZXh0OSBzgbxmE4NIEwQT
+CkMEYwUBA1MJUwlDG1OCYRMKYxFjgi8zgVtTBxMGQ4JQEwRjBlMMQwYBAWMMQwQzBTMIQwYzBWNE
+QwUTCWMGcwpjBzMFQwVDBFMEY4EmIxYBA0M8Y0VjdUMZUxZTCDMMYzpTgQEBAWNTgxYBBjMJ3QEC
+Y4EyM4EPgxZDBGMGAQEzhGwTB0NmExFjggpDBEMQqTMLMwxzEVMMQ1FDBTMHUwQTCIMKgxFTFeFj
+CFMPYxEzF0MFQxxjSnMFMxxTRmMcIwkTCDNqkwUTFiMOcwcBAWMRcwUzF1NBYxsjCXMIEwgzbRMU
+M496AIG8aNt9hiaPBQ7kTzqBnh4smj2CDGuCOsJWljiBaYR/kBuBk2ueRpJ4qQX2NpgUiUHRKrFs
+ozS4C6AUJoEBcoHZB5QfhRWBsAKJT4Imgik6eDoMIoECP4ECaoFfDguBN2qBRU0HgaRIhHKTb32Q
+PoJNh3iBw2GBlDLvmAuWCV2sN41igbovPZKBmW+pEKBqgU8QEJBUGx0/Th1PAYHlbCQ/gcRYAeyD
+ST8VGEoB7IGfayuBiiiGKg==
#6 2018-12-15T16:59:22Z pgess
+1sPEAAABgfUPABeBxBEAAAkHc4G0NSMWI49GAIG8f4HEEQ==
#5 2018-12-15T16:52:17Z pgess
1sPEAAABgcQRADKBw2wAABoRc6Y2IwkTgR+DCYNeM0RDBBMLQx4TCDOBmi4A3R2mTqpOghXYbqY6
UpIdLg==
-
#4 2018-12-15T16:19:00Z pgess
1sPEAAABgcNsAEyBw2AAACYfc8wdExoTkBhDCmMEEwRTG1M3EwljhFITF0MlQ+BbUxVDEFMLMwsA
zUnMM5IgrEa+b5AnJJckN4sitEqFIJF9gXKROuEM
#3 2018-12-15T14:05:19Z pgess
1sPEAAABgcNhAIVpgb9cADODNIF5ZD8+PSB7MSwgMiwgPSA9ID0ga2MwMj8+NC0gMXB6MT0gICsg
MTIqIDIzLTF9KDEpMygyc5EoEyEBA0MUIwtTBzMGMwpTC2MSMxdDElMFIzhjmhYBCUMFAQJTDmMj
AQIzEyMEQ4E1AQJjgnczIQEBQwgzMGMZM0dTCEMRYz0zEkMWUxZjGCMIMyJTNGMIEwVjIpM4U4Qm
gyAzBEMEYzKTEpMJUzMTBGOYfYMfAQUjBjM0Mw2TCGNLIw6TEWMHYwcjBZMEkzKTDpMOEwRjECMI
UxIjCjMSIwxzIiMJMy+DCGMKcwVjCUMcIwZDN2ONe4MfUwUjGDMMUwaTBjMuQ0lTDhMEY4Vdgx9D
BVMEgwxjF3MEUxpzEHMFMxpjCDMYcwUjOkOSGoMfMwVzBIMMcwxTI3MEU0kzPpMIUzBzCGMmQyZT
JGODYiMhAQFDHTMLcwQzDkMFUxEzBGMO7ZMGMzxDjFpDIQEBUwoTCkMxcwRDPWMGMyNDI1MjYw8z
RCMbQ0NjQpMIMx6TP1OONnMhAQFzCgEDUwmDDxMEMwRzBAEBUwrNEwgBASMxAQOTBJMIAQGDMdVz
DjMOgwtzBEMJkwljBzMFkwoBAkMUcwSTDDMTAQMjDwEBQwszCQECUwhDDGMFgxQTM1OPRgCDKY5u
xjQX2CsKFAkUFRDMNTyaJAoPKL8zGoE6h3kig3AuF9A2Sg87EBIQARgejyuSUkH5WamEXI45ozrM
3IdgkwxBqaJGoGOBA1QZVYKCHV8R4pzM5ygWARABEgEWgV8j36YoUqUcpCilV0GkSamOLJJiWoE4
WQQqR5I2EamGEI4581Q2GmlSLxwEjpcqVKmSTRfzQ142JkdUBKg2IiIihwAiy1U2/EQeA1YgjLv2
a2GSMSKSG41nNjQ/BCEhIRKXO1xBVEb0Wk1vlwEDkmQtNopXojCEaUGUaSgyF4GNdck2kmIf/QBW
bjGMbg0nEDUWAiCxgZoESw==
#2 2018-12-15T11:27:17Z pgess
1sPEAAABgb9cAIE1gb9cAARlRXpkLmdznFkTgVyTFUODOJM/Y4FCkz5DgVOTPmMuQwVjNpM+Q4Eh
EyZDgxVjBGNrExQBAkMrAQFTCJM+Yy4TBEM3AQFTICMecxBD1zkzJkOKFVM/U3mDbBMIQz5DfJMV
cxAzi14TBGOddwCcWlqBclqDeFqCAVqCEoxBgR1agSiIL4FItBSDGYM1dpAgWnKRIIYrX4FRTE7C
IZVJi0+KVa6RUs4vgTNaTIEihhaLYg==
#1 2018-12-07T16:28:26Z Acer2
1sPEAAABgb9gAIckgbYGAEGDeoJgeWNzIHdhcnJpYzJmZ29jMjJpMmtob25vJ3MybWMybj8+SW9w
MnI/PjJ0SUZjMnZjMnhnZW9mIGBgMzMxYzJ6Pz5zhE0TDSMHQyoBAkMLUw0TEGMHEwgBATMIIwdD
BiMEYwlDBUMRYwRTBmMNMwZTBUMEMwYjBbXbE4JtQyQBAyMpAQFTgxUjCWMJEwZDQEOETgEBU2Bj
J4MkAQIzBEMlAQIzPJMJkywzj3gjJlMpAQKTT5MJkwgTNVOLUTMEUxkzgT9jB1MJYwSDB0MHAQJD
BAECMwVTCBMIAQJDBVM0MwQzg0ZzJhMEgyUBAlOCC5MaExMBBVOBI5MJkwhDhCAzCBMHExGTNUOC
MgEBYwaTBEMHQwZTCEMNYwRjBRMEQwUTCJMFMwdjBFMekwkjJgEBUykBATOCe5MJkwiDJhMEUyUB
BDOBPiMKkwiTDEMQg4IaMwdjBFMNUwUTBZMJk0ETDkMJU4Z6YwljD0NHM2RDCUMLEw8TJTMXUzMj
JkMEgyUBAmOBVJMJky5jMoMOIwlTgTSTCYOBEmM+Y4E/kwlDPhMVcxBjhUhTCWMJgzxjBXMJQwZT
CEMIY4dcAQITEmOBLiMUIwQzK0OBG0MmEwYzBVMiIyZjKAEDQ1WTCZMuM4FnYxuDMBMoAQNjgUqT
CZMuY4USU3kBAjMFY4QerPlTC0OTOkMiYwRDg2eTJdMjJQECM4E2kwmTCJMmEygBBZOCOZMJky1D
jVEzE0ODV4MGUwkTCIMEEw2DPlOCHACJB6x4vjugO4xKhQ+nIIRpCJAODpEOCMRQEZIJqwoRhEGP
QJRehmW9d9Bwnm2FS5ZljgSGDKs7gj6FGYVKSIRUYaCZG7xbRbbegUmROsEJwrbenGOCZo1ii1cb
myGNMacvzp5AVpN80nSRUwyoIY9CPJ+aMfuDZLaDNYINtt6BboQsukKXNGNZhHuh3AGCValMEMQ0
khq5Ra1AhEsSl1yrTq4ntoxnJ4Evtt4wnUO6HbE3hXjeY4FooNcerGiZGJAWhhO23oN4ljZYtFWQ
docWU9wJhwnUPZMriRgejyuLWftRtt6CXviEL0koqLALgVEogUycWktkhV+pZ/g3iMcDsnSlAIFs
pVaHcIFCk2jQC4FxgRyFVIFhV5pmwUFAtt6CToJnjaEkgmW23oJWhRWdZX6GVIYP6GKEWJlNrkiU
ER+IUpdyhAW23h+iQsm23oMpjXQfYYN3xkzBuF+zjAM=
?>
\ No newline at end of file
diff --git a/documentation/Syntax/syntax.xml b/documentation/Syntax/syntax.xml
index 2f3e370..c079908 100644
--- a/documentation/Syntax/syntax.xml
+++ b/documentation/Syntax/syntax.xml
@@ -1,959 +1,1232 @@
<?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 26yv439af40 59?>
<title><?xxe-sn 26yv439af40 5a?>Syntax</title>
- <para><?xxe-sn 26yv439af40 5b?><informaltable>
- <?xxe-sn 26yv439af40 5c?>
-
- <tgroup cols="3">
- <?xxe-sn 26yv439af40 5d?>
-
- <tbody>
- <?xxe-sn 26yv439af40 5e?>
-
- <row>
- <?xxe-sn 26yv439af40 5f?>
-
- <entry><?xxe-sn 26yv439af40 5g?>Literals, Expressions, Basic
- Statements</entry>
-
- <entry><?xxe-sn 26yv439af40 5h?>Annotations</entry>
-
- <entry><?xxe-sn 26yv439af40 5i?>Intrinsics: query</entry>
- </row>
-
- <row>
- <?xxe-sn 26yv439af40 5j?>
-
- <entry><?xxe-sn 26yv439af40 5k?>Identifiers, Code Blocks</entry>
-
- <entry><?xxe-sn 26yv439af40 5l?>Branch Statements</entry>
-
- <entry><?xxe-sn 26yv439af40 5m?>Interfaces: Extern-C</entry>
- </row>
-
- <row>
- <?xxe-sn 26yv439af40 5n?>
-
- <entry><?xxe-sn 26yv439af40 5o?>Functions</entry>
-
- <entry><?xxe-sn 26yv439af40 5p?>Loops</entry>
-
- <entry><?xxe-sn 26yv439af40 5q?>Other: Transcend, Versions</entry>
- </row>
-
- <row>
- <?xxe-sn 26yv439af40 5r?>
-
- <entry><?xxe-sn 26yv439af40 5s?>Types</entry>
-
- <entry><?xxe-sn 26yv439af40 5t?>Variants</entry>
-
- <entry><?xxe-sn 26yv439af40 5u?></entry>
- </row>
- </tbody>
- </tgroup>
- </informaltable></para>
-
- <para><?xxe-sn 26yv439af40 5v?>There are number of principles Xreate syntax
- based on:</para>
+ <para><?xxe-sn 26yv439af40 5v?>There is a number of principles the Xreate
+ syntax is based on:</para>
<itemizedlist>
<?xxe-sn 26yv439af40 5w?>
<listitem>
<?xxe-sn 26yv439af40 5x?>
- <para><?xxe-sn 26yv439af40 5y?>Follows SSA form: each identifier is
- defined only once and no redefinitions allowed</para>
+ <para><?xxe-sn 26yv439af40 5y?>Follows SSA(single assignment) form: each
+ identifier is defined only once and no redefinitions allowed.</para>
</listitem>
<listitem>
<?xxe-sn 26yv439af40 5z?>
- <para><?xxe-sn 26yv439af40 60?>Order in which identifiers are defined
- does not influence computation order. Identifiers are computed in order
- based on dependencies between expressions. Order in which identifiers
- are defines reflects personal preferences and what is convenient for a
- developer.</para>
+ <para><?xxe-sn 26yv439af40 60?>Follows literate programming principles
+ where possible. For example, identifiers can be defined in any order
+ reflecting personal preferences and convenience for a developer.
+ Regardless of the definition order, expressions are computed based on
+ dependencies between them. Literate programming principles from a
+ practical point of view simplify code testing, support, catching
+ regressions, etc.</para>
</listitem>
</itemizedlist>
<section>
<?xxe-sn 26yv439af40 61?>
- <title><?xxe-sn 26yv439af40 62?>Literals and expressions</title>
+ <title><?xxe-sn 26yv439af40 62?>Literals and Expressions</title>
<para><?xxe-sn 26yv439af40 63?>Xreate expressions have a form:</para>
<synopsis><?xxe-sn 26yv439af40 64?>SYNTAX:
//expression// [:: //type//; //annotations-list// ]</synopsis>
<itemizedlist>
<?xxe-sn 26yv439af40 fd?>
<listitem>
<?xxe-sn 26yv439af40 fe?>
<para><?xxe-sn 26yv439af40 ff?><emphasis><?xxe-sn 26yv439af40 fg?>annotation-list</emphasis>
is a list of annotations delimited by semicolon.</para>
</listitem>
</itemizedlist>
<para><?xxe-sn 26yv439af40 67?>Expressions consist of literals and various
operations as follows:</para>
<informaltable>
<?xxe-sn 26yv439af40 68?>
<tgroup cols="2">
<?xxe-sn 26yv439af40 69?>
<colspec colwidth="115*"><?xxe-sn 26yv439af40 6a?></colspec>
<colspec colwidth="885*"><?xxe-sn 26yv439af40 6b?></colspec>
<tbody>
<?xxe-sn 26yv439af40 6c?>
<row>
<?xxe-sn 26yv439af40 6d?>
<entry><?xxe-sn 26yv439af40 6e?>Literals</entry>
- <entry><?xxe-sn 26yv439af40 6f?>numbers, strings: <code><?xxe-sn 26yv439af40 6g?>5,
- "Nimefurahi kukujua"</code></entry>
+ <entry><?xxe-sn 26yv439af40 6f?>numbers, strings: <code><?xxe-sn 2ese8ot7ke8 e?>5</code>,
+ <code><?xxe-sn 2ese8ot7ke8 f?>"Nimefurahi kukujua"</code>.</entry>
</row>
<row>
<?xxe-sn 26yv439af40 6h?>
<entry><?xxe-sn 26yv439af40 6i?>Lists, records</entry>
- <entry><?xxe-sn 26yv439af40 6j?>Record is a collection of elements
- of different types — <code><?xxe-sn 26yv439af40 6k?>{year = 1934,
- month = "april"}</code>. List is a collection of elements of the
- same type without keys — <code><?xxe-sn 26yv439af40 6l?>{16, 8,
- 3}</code>. Range of elements — <code><?xxe-sn 2apiasqubk0 4?>[1..18]</code>.</entry>
+ <entry><?xxe-sn 26yv439af40 6j?><emphasis><?xxe-sn 2ese8ot7ke8 c?>Record</emphasis>
+ is a collection of elements of different types - <code><?xxe-sn 26yv439af40 6k?>{year = 1934, month = "april"}</code>.
+ <emphasis><?xxe-sn 2ese8ot7ke8 d?>List</emphasis> is a collection
+ of elements of the same type without keys - <code><?xxe-sn 26yv439af40 6l?>{16, 8, 3}</code>.
+ Range is a specific form of a list - <code><?xxe-sn 2apiasqubk0 4?>[1..18]</code>.</entry>
</row>
<row>
<?xxe-sn 26yv439af40 6m?>
<entry><?xxe-sn 26yv439af40 6n?>Arithmetic operations</entry>
<entry><?xxe-sn 26yv439af40 6o?>Basic arithmetic operations:
- <code><?xxe-sn 26yv439af40 6p?>+, -, *, /</code></entry>
+ <code><?xxe-sn 2ese8ot7ke8 g?>+</code>, <code><?xxe-sn 2ese8ot7ke8 h?>-</code>,
+ <code><?xxe-sn 2ese8ot7ke8 i?>*</code>, <code><?xxe-sn 2ese8ot7ke8 j?>/</code>.</entry>
+ </row>
+
+ <row>
+ <?xxe-sn 2evpzktyvg7 -wunr7fl0rw8j?>
+
+ <entry><?xxe-sn 2evpzktyvg7 -wunr7fl0rw8i?>Boolean
+ operations</entry>
+
+ <entry><?xxe-sn 2evpzktyvg7 -wunr7fl0rw8h?>Negation example:
+ <code><?xxe-sn 2evpzktyvg7 -wunr7fl0rw8g?>-isEmty()</code>.</entry>
</row>
<row>
<?xxe-sn 26yv439af40 6q?>
<entry><?xxe-sn 26yv439af40 6r?>Relations</entry>
- <entry><?xxe-sn 26yv439af40 6s?><code><?xxe-sn 26yv439af40 6t?>==,
- !=, &lt;&gt;, &lt;, &lt;=, &gt;, &gt;=</code>. Both
- <code><?xxe-sn 26yv439af40 6u?>!=, &lt;&gt;</code> mean
- <emphasis><?xxe-sn 26yv439af40 6v?>not equal</emphasis> relation.
- Examples: <code><?xxe-sn 26yv439af40 6w?>8&gt;=3, "Blue" &lt;&gt;
- "Green"</code></entry>
+ <entry><?xxe-sn 26yv439af40 6s?><code><?xxe-sn 2ese8ot7ke8 r?>==</code>,
+ <code><?xxe-sn 2ese8ot7ke8 s?>!=</code>, <code><?xxe-sn 2ese8ot7ke8 t?>&lt;&gt;</code>,
+ <code><?xxe-sn 2ese8ot7ke8 u?>&lt;</code>, <code><?xxe-sn 2ese8ot7ke8 v?>&lt;=</code>,
+ <code><?xxe-sn 2ese8ot7ke8 w?>&gt;</code>, <code><?xxe-sn 2ese8ot7ke8 x?>&gt;=</code>.
+ Both <code><?xxe-sn 2ese8ot7ke8 y?>!=</code>, <code><?xxe-sn 2ese8ot7ke8 z?>&lt;&gt;</code>
+ mean <emphasis><?xxe-sn 26yv439af40 6v?>not equal</emphasis>
+ relation. Examples: <code><?xxe-sn 2ese8ot7ke8 10?>8&gt;=3</code>,
+ <code><?xxe-sn 2ese8ot7ke8 11?>"Blue" &lt;&gt; "Green"</code>.</entry>
</row>
<row>
<?xxe-sn 26yv439af40 6x?>
- <entry><?xxe-sn 26yv439af40 6y?>List and struct operations</entry>
+ <entry><?xxe-sn 26yv439af40 6y?>List and record operations</entry>
- <entry><?xxe-sn 26yv439af40 6z?><emphasis><?xxe-sn 26yv439af40 70?>index</emphasis>
- operation to access individual elements of a list or a record.
- Example: <code><?xxe-sn 26yv439af40 71?>colors = {"Green",
- "Blue"}::[string]. color = colors[0]:: string.</code> Record's
- element access: <code><?xxe-sn 26yv439af40 72?>date = {year =
- 1934, month = "april"}. year = date["year"]</code></entry>
+ <entry><?xxe-sn 26yv439af40 6z?>The <emphasis><?xxe-sn 26yv439af40 70?>index</emphasis>
+ operation to access individual elements of a list or record.
+ Example: <code><?xxe-sn 2ese8ot7ke8 12?>colors = {"Green", "Blue"}::[string]. color = colors[0]:: string.</code>
+ Accesing a record's element: <code><?xxe-sn 2ese8ot7ke8 13?>date = {year = 1934, month = "april"}. year = date["year"].</code></entry>
</row>
<row>
<?xxe-sn 26yv439af40 73?>
<entry><?xxe-sn 26yv439af40 74?>Identifiers</entry>
- <entry><?xxe-sn 26yv439af40 75?>Example: <code><?xxe-sn 26yv439af40 76?>a
- - b</code></entry>
+ <entry><?xxe-sn 26yv439af40 75?>Example: <code><?xxe-sn 26yv439af40 76?>a - b</code></entry>
</row>
<row>
<?xxe-sn 26yv439af40 77?>
<entry><?xxe-sn 26yv439af40 78?>Functions</entry>
- <entry><?xxe-sn 26yv439af40 79?>Example: <code><?xxe-sn 26yv439af40 7a?>result
- = isOdd(6).</code></entry>
+ <entry><?xxe-sn 26yv439af40 79?>Example: <code><?xxe-sn 26yv439af40 7a?>result = isOdd(6):: bool.</code></entry>
</row>
</tbody>
</tgroup>
</informaltable>
</section>
+ <section>
+ <?xxe-sn 2evpzktyvg7 -wunr7fl0rw8v?>
+
+ <title><?xxe-sn 2evpzktyvg7 -wunr7fl0rw8u?>Annotations</title>
+
+ <para><?xxe-sn 2evpzktyvg7 -wunr7fl0rw8t?>This chapter is about Brute
+ syntax. See <link xlink:href="/d/transcend/"><?xxe-sn 2evpzktyvg7 -wunr7fl0rw8l?>Transcend</link>
+ for details regarding Transcend and annotations syntax.</para>
+ </section>
+
<section>
<?xxe-sn 26yv439af40 7b?>
<title><?xxe-sn 26yv439af40 7c?>Code Blocks</title>
- <para><?xxe-sn 26yv439af40 7d?>Block is a list of expressions delimited by
- period. It has a <emphasis><?xxe-sn 26yv439af40 7e?>body</emphasis> - main
- expression and optionally some identifier definitions.</para>
+ <para><?xxe-sn 26yv439af40 7d?>Code block is a list of expressions
+ delimited by a period. It has a <emphasis><?xxe-sn 26yv439af40 7e?>body</emphasis>
+ - the main expression along with optional identifiers' definitions.</para>
<synopsis><?xxe-sn 26yv439af40 7f?>SYNTAX:
{
- [//ident// = //expression// . | //body-expression// . ]..
+ [//ident// = //expression//. | //body-expression//. ]..
}</synopsis>
- <para><?xxe-sn 26yv439af40 7g?>Code block consists of <emphasis><?xxe-sn 26yv439af40 7h?>body
- expression</emphasis> and optional set of assignments to define
- identifiers used in body expression. Block's computation is defined as a
- result of associated body expression's computation. Identifiers are
- computed before expressions they are used in.</para>
+ <para><?xxe-sn 26yv439af40 7g?>Code blocks consist of <emphasis><?xxe-sn 26yv439af40 7h?>a
+ body expression</emphasis> and an optional set of assignments to define
+ identifiers used in the body expression. A code block's computation result
+ is defined as a result of computing its body expression. Identifiers are
+ computed before expressions they are appear in, regardless of a
+ definitions' order.</para>
<programlisting xml:id="CodeBlocks1"><?xxe-sn 26yv439af40 7i?>name="tests/ast.cpp: AST.Doc_CodeBlocks1"
-test = function:: int
+test = function:: int; entry
{
+ a + b:: int
+
a = 10:: int.
b = 2:: int.
-
- a + b:: int
}</programlisting>
- <para><?xxe-sn 26yv439af40 7j?>Above is an example of code block which
- have <code><?xxe-sn 26yv439af40 7k?>a+b</code> as a body expression. In
- this case body depends on identifiers <code><?xxe-sn 26yv439af40 7l?>a</code>,
- <code><?xxe-sn 26yv439af40 7m?>b</code> so compiler computes both of them
- beforehand.</para>
+ <para><?xxe-sn 26yv439af40 7j?>Above is an example of the code block with
+ <code><?xxe-sn 26yv439af40 7k?>a+b</code> as its body expression(because
+ it does not have a form of an assignment). In this case the body depends
+ on the identifiers <code><?xxe-sn 26yv439af40 7l?>a</code>,
+ <code><?xxe-sn 26yv439af40 7m?>b</code> so the compiler computes both of
+ them beforehand.</para>
- <para><?xxe-sn 26yv439af40 7n?>Computation order depends only on
+ <para><?xxe-sn 26yv439af40 7n?>A computation order depends only on
dependencies between expressions. This approach has properties as
follows:</para>
<itemizedlist>
<?xxe-sn 26yv439af40 7o?>
<listitem>
<?xxe-sn 26yv439af40 7p?>
<para><?xxe-sn 26yv439af40 7q?>Mutually independent identifiers can be
- evaluated in any order</para>
+ evaluated in any order.</para>
</listitem>
<listitem>
<?xxe-sn 26yv439af40 7r?>
- <para><?xxe-sn 26yv439af40 7s?>Identifier gets computed only if it's
- required(even transitively) by block's body expression.</para>
+ <para><?xxe-sn 26yv439af40 7s?>An identifier computed only if it is
+ required(at least transitively) by a code block's body
+ expression.</para>
</listitem>
</itemizedlist>
</section>
<section>
<?xxe-sn 26yv439af40 7t?>
<title><?xxe-sn 26yv439af40 7u?>Functions</title>
<synopsis><?xxe-sn 26yv439af40 7v?>SYNTAX:
-//function-name// = **function** ([//argument//:: //type//[; //annotation-list//]]...):: //return-type// [; //annotations//]...
+//function-name// **=** **function** **(**[//argument//:: //type//[; //annotation-list//]]...**)::** //return-type// [; //annotations//]...
//function-block//</synopsis>
<itemizedlist>
<?xxe-sn 26yv439af40 7w?>
<listitem>
<?xxe-sn 26yv439af40 7x?>
<para><?xxe-sn 26yv439af40 7y?><emphasis><?xxe-sn 26yv439af40 7z?>function-name</emphasis>
- name of function</para>
+ Name of a function.</para>
</listitem>
<listitem>
<?xxe-sn 26yv439af40 80?>
<para><?xxe-sn 26yv439af40 81?><emphasis><?xxe-sn 26yv439af40 82?>argument</emphasis>
- formal parameter. Arguments are delimited by comma.</para>
+ Formal parameters. Arguments are delimited by comma.</para>
</listitem>
<listitem>
<?xxe-sn 26yv439af40 83?>
<para><?xxe-sn 26yv439af40 84?><emphasis><?xxe-sn 26yv439af40 85?>type</emphasis>,
- <emphasis><?xxe-sn 26yv439af40 86?>return-type</emphasis> formal
- parameter and returning value types</para>
+ <emphasis><?xxe-sn 26yv439af40 86?>return-type</emphasis> Formal
+ parameter's and returning value's types.</para>
</listitem>
<listitem>
<?xxe-sn 26yv439af40 87?>
<para><?xxe-sn 26yv439af40 88?><emphasis><?xxe-sn 26yv439af40 89?>function-block</emphasis>
- code block that acts as a function's definition</para>
+ Code block that acts as a function's definition.</para>
</listitem>
<listitem>
<?xxe-sn 26yv439af40 8a?>
<para><?xxe-sn 26yv439af40 8b?><emphasis><?xxe-sn 26yv439af40 8c?>annotations</emphasis>
- list of annotations delimited by semicolon</para>
+ List of annotations delimited by semicolon.</para>
</listitem>
</itemizedlist>
- <para><?xxe-sn 26yv439af40 8d?>Below is an example of a function
- <code><?xxe-sn 26yv439af40 8e?>sum</code>. It takes two arguments and
- returns their sum. Also it defines several annotations. First annotation
- <code><?xxe-sn 26yv439af40 8f?>entry</code> has a special meaning — it
- depicts entry point or main function in a program. Second annotation
- <code><?xxe-sn 26yv439af40 8g?>status(needs_review)</code> is a
- demonstration that developers can annotate function using custom
- annotations to express different properties.</para>
+ <para><?xxe-sn 26yv439af40 8d?>Below is an example of the function
+ <code><?xxe-sn 26yv439af40 8e?>sum</code> returning sum of its two
+ arguments. Moreover there are several annotations defined. First
+ annotation <code><?xxe-sn 26yv439af40 8f?>entry</code> has a special
+ meaning — it depicts an entry point or a main function in a program.
+ Second annotation <code><?xxe-sn 26yv439af40 8g?>status(needs_review)</code>
+ is a demonstration that developers can annotate functions using custom
+ annotations to express related intentions or properties.</para>
<programlisting xml:id="Functions1"><?xxe-sn 26yv439af40 8h?>name="tests/ast.cpp: AST.Doc_Functions1"
sum = function(x:: int, y:: int):: int; entry; status(needs_review)
{
- x+y
+ x + y
}</programlisting>
</section>
<section>
<?xxe-sn 26yv439af40 8i?>
<title><?xxe-sn 26yv439af40 8j?>Function Specializations</title>
<synopsis><?xxe-sn 26yv439af40 8k?>SYNTAX:
-**guard**:: //annotation//
+**guard::** //annotation//
{
//functions-list//
}</synopsis>
<itemizedlist>
<?xxe-sn 26yv439af40 8l?>
<listitem>
<?xxe-sn 26yv439af40 8m?>
<para><?xxe-sn 26yv439af40 8n?><emphasis><?xxe-sn 26yv439af40 8o?>annotation</emphasis>
- Guard expressed by annotation</para>
+ Guard expressed in the form of an annotation.</para>
</listitem>
<listitem>
<?xxe-sn 26yv439af40 8p?>
<para><?xxe-sn 26yv439af40 8q?><emphasis><?xxe-sn 26yv439af40 8r?>functions-list</emphasis>
- one or more function that share the same guard</para>
+ One or more functions that share the same guard.</para>
</listitem>
</itemizedlist>
- <para><?xxe-sn 26yv439af40 8s?>Xreate allows several functions to share
- the same name. In which case they are called <emphasis><?xxe-sn 26yv439af40 fk?>
- specializations</emphasis>. This is syntactic foundation for
- <emphasis><?xxe-sn 26yv439af40 8u?>function level polymorphism</emphasis>,
- i.e. ability for compiler to decide which exactly function is called out
- of several options. Polymorphism resolution can happen during compilation
- or at run-time.</para>
+ <para><?xxe-sn 26yv439af40 8s?>Specializations is a crucial Xreate concept
+ serving as the principal connection between Transcend and Brute levels.
+ Xreate allows several functions to share the same name; in this case they
+ are called <emphasis><?xxe-sn 26yv439af40 fk?> specializations</emphasis>.
+ This is a syntactic foundation for <emphasis><?xxe-sn 26yv439af40 8u?>function
+ level <link xlink:href="/d/concepts/polymorphism/"><?xxe-sn 2evpzktyvg7 -wunr7fl0rw8k?>polymorphism</link></emphasis>,
+ i.e. ability for the compiler to decide which exactly function is called
+ out of several available options. The polymorphism resolution can happen
+ during compilation(early polymorphism) or at run-time(late
+ polymorphism).</para>
<para><?xxe-sn 26yv439af40 8v?>Functions with the same name, i.e.
- different specializations should have additional unique identifiers called
- <emphasis><?xxe-sn 26yv439af40 8w?>guards</emphasis>. When function is
- actually called it's expected that resolution is already done at some
- point before and supplies correct guard to uniquely specify which exactly
- specialization to call.</para>
+ different specializations must have identifiers called <emphasis><?xxe-sn 26yv439af40 8w?>guards</emphasis>
+ to uniquely define a specialization. In this sense, a shared name is just
+ a placeholder, which only along with a guard comprise the fully qualified
+ exact function identifier. On the Brute level it is possible to specify
+ only a function's shared name for invocation. On the other hand, Transcend
+ is responsible to supply a guard part. When a function is actually called
+ by its name in a program it's expected that the resolution is already done
+ by Transcend at some time earlier and it supplies the correct guard to
+ uniquely specify which exactly specialization to call. This gives
+ Transcend a deep control over an actual program behaviour.</para>
+
+ <para><?xxe-sn 26yv439af40 8x?>An example:</para>
+
+ <programlisting xml:id="FunctionSpecialization1"><?xxe-sn 26yv439af40 8y?>name="tests/ast.cpp: AST.Doc_FunctionSpecializations1", lines=15
+guard:: safe_enviroment
+{
+ sum = function (a::int, b::int):: int
+ {
+ result = a + b:: int.
- <para><?xxe-sn 26yv439af40 8x?>Example:</para>
+ if (-isLastOpOverflow(result)):: int
+ {
+ result
+ }
+ else
+ {
+ overflowErrorCode()
+ }
+ }
+}
- <programlisting xml:id="FunctionSpecialization1"><?xxe-sn 26yv439af40 8y?>name="tests/ast.cpp: AST.Doc_FunctionSpecializations1"
-guard:: safe_enviroment
+guard:: fast_enviroment
{
sum = function (a::int, b::int) :: int
{
- a + b
+ a + b
}
}</programlisting>
+ <para><?xxe-sn 2evpzktyvg7 -wunr7fl0rw8f?>To alter existing code behaviour
+ it's always possible to add new specializations and adjust Transcend rules
+ to specify situations when a new specialization should(or should not) be
+ used.</para>
+
<note>
<?xxe-sn 26yv439af40 8z?>
<para><?xxe-sn 26yv439af40 90?>See <link
xlink:href="/d/transcend/ast-api/#function-s-specializatio"><?xxe-sn 26yv439af40 91?>API</link>
- to get more information on how guards are processed</para>
+ to get more detailed information on how guards are processed on the
+ Transcend side.</para>
</note>
</section>
<section>
<?xxe-sn 26yv439af40 92?>
<title><?xxe-sn 26yv439af40 93?>Branch Statements</title>
<section>
<?xxe-sn 26yv439af40 94?>
<title><?xxe-sn 26yv439af40 95?>IF Statement</title>
<synopsis><?xxe-sn 26yv439af40 96?>SYNTAX:
-**if** (//condition//):: //type// [; //annotations// ]..
+**if (** //condition// **)::** //type// [; //annotations// ]..
//block-true//
**else**
//block-false//</synopsis>
- <para><?xxe-sn 26yv439af40 97?><code><?xxe-sn 26yv439af40 fh?>IF</code>
+ <para><?xxe-sn 26yv439af40 97?>The <code><?xxe-sn 26yv439af40 fh?>if</code>
statement executes <emphasis><?xxe-sn 26yv439af40 98?>block-true</emphasis>
or <emphasis><?xxe-sn 26yv439af40 99?>block-false</emphasis> depending
- on <emphasis><?xxe-sn 26yv439af40 9a?>condition</emphasis> evaluation
- result.</para>
+ on the <emphasis><?xxe-sn 26yv439af40 9a?>condition</emphasis>
+ evaluation's result.</para>
<para><?xxe-sn 26yv439af40 9b?>Example:</para>
<programlisting xml:id="IfStatement1"><?xxe-sn 26yv439af40 9c?>name="tests/ast.cpp: AST.Doc_BranchStatements"
answer = if (question == "Favorite color?"):: string
{"Yellow"} else {"Don't know"}.</programlisting>
</section>
<section>
<?xxe-sn 26yv439af40 9d?>
<title><?xxe-sn 26yv439af40 9e?>SWITCH Statement</title>
<synopsis><?xxe-sn 26yv439af40 9f?>SYNTAX:
-**switch** ( //condition// ) :: //type// [; //annotations//]..
-[**case** ( //guard// ) code-block]..
+**switch (** //condition// **)** :: //type// [; //annotations//]..
+[**case (** //guard// **)** code-block]..
**case default** //default-code-block//
</synopsis>
<itemizedlist>
<?xxe-sn 26yv439af40 9g?>
<listitem>
<?xxe-sn 26yv439af40 9h?>
- <para><?xxe-sn 26yv439af40 9i?><emphasis><?xxe-sn 26yv439af40 9j?>condition</emphasis>'s
- result is used to decide which branch to execute next</para>
+ <para><?xxe-sn 26yv439af40 9i?><emphasis><?xxe-sn 26yv439af40 9j?>condition</emphasis>
+ Expression to to decide which branch to execute next.</para>
</listitem>
<listitem>
<?xxe-sn 26yv439af40 9k?>
<para><?xxe-sn 26yv439af40 9l?><emphasis><?xxe-sn 26yv439af40 9m?>guard</emphasis>
- value to match against <emphasis><?xxe-sn 26yv439af40 9n?>condition</emphasis></para>
+ Value to match against <emphasis><?xxe-sn 26yv439af40 9n?>condition.</emphasis></para>
</listitem>
<listitem>
<?xxe-sn 26yv439af40 9o?>
<para><?xxe-sn 26yv439af40 9p?><emphasis><?xxe-sn 26yv439af40 9q?>default-code-block</emphasis>
- executed if no appropriate case found</para>
+ Executed if no appropriate case found.</para>
</listitem>
</itemizedlist>
- <para><?xxe-sn 26yv439af40 9r?>SWITCH statement evaluation's result is
- that of branch whose <emphasis><?xxe-sn 26yv439af40 9s?>guard</emphasis>
- matches <emphasis><?xxe-sn 26yv439af40 9t?>condition</emphasis>.</para>
+ <para><?xxe-sn 26yv439af40 9r?>The <code><?xxe-sn 2evpzktyvg7 -wunr7fl0rw8e?>switch</code>
+ statement evaluation's result is that of the branch whose
+ <emphasis><?xxe-sn 26yv439af40 9s?>guard</emphasis> matches the
+ <emphasis><?xxe-sn 26yv439af40 9t?>condition</emphasis>.</para>
- <para><?xxe-sn 26yv439af40 9u?>Example:</para>
+ <para><?xxe-sn 26yv439af40 9u?>An example:</para>
<programlisting xml:id="SwitchStatement1"><?xxe-sn 26yv439af40 9v?>name="tests/ast.cpp: AST.Doc_BranchStatements"
monthName = switch(monthNum) :: string
case (1) {"Jan"}
case (2) {"Feb"}
- case default {"Strange.. Don't know this month"}.</programlisting>
+ case default {"It's strange..an unexpected month"}.</programlisting>
</section>
</section>
<section>
<?xxe-sn 26yv439af40 9w?>
- <title><?xxe-sn 26yv439af40 9x?>Loop Statements</title>
+ <title><?xxe-sn 26yv439af40 9x?>Loops</title>
+
+ <para><?xxe-sn 2evpzktyvg7 -wunr7fl0rw8d?>Xreate loops are constructed in
+ such a way that they hide actually mutable operations semantic under an
+ immutable facade compatible with a single assignment form.</para>
<section>
<?xxe-sn 26yv439af40 9y?>
<title><?xxe-sn 26yv439af40 9z?>LOOP Statement</title>
<synopsis><?xxe-sn 26yv439af40 a0?>SYNTAX:
-**loop** ( //init-value// -&gt; //accumulator// ):: //type// [; //annotations//] //loop-body//</synopsis>
+**loop (** //init-value// **-&gt;** //accumulator// **)::** //type// [; //annotations//] //loop-body//</synopsis>
<itemizedlist>
<?xxe-sn 26yv439af40 a1?>
<listitem>
<?xxe-sn 26yv439af40 a2?>
<para><?xxe-sn 26yv439af40 a3?><emphasis><?xxe-sn 26yv439af40 a4?>init-value</emphasis>
- initial value loop starts from</para>
+ Initial value a loop starts from.</para>
</listitem>
<listitem>
<?xxe-sn 26yv439af40 a5?>
<para><?xxe-sn 26yv439af40 a6?><emphasis><?xxe-sn 26yv439af40 a7?>accumulator</emphasis>
- identifier which holds loop's result after each iteration</para>
+ Identifier which holds loop's result after each iteration.</para>
</listitem>
</itemizedlist>
<para><?xxe-sn 26yv439af40 a8?>For each iteration <emphasis><?xxe-sn 26yv439af40 a9?>accumulator</emphasis>
- assumes result of previous iteration or <emphasis><?xxe-sn 26yv439af40 aa?>init-value</emphasis>
- during first iteration. Result of the <emphasis><?xxe-sn 26yv439af40 ab?>loop-body</emphasis>
- evaluation is used as <emphasis><?xxe-sn 26yv439af40 ac?>accumulator</emphasis>'s
- next iteration value and as overall loop statement result after the last
- iteration.</para>
+ assumes the result of a previous iteration or <emphasis><?xxe-sn 26yv439af40 aa?>init-value</emphasis>
+ for the first iteration. The result of <emphasis><?xxe-sn 26yv439af40 ab?>loop-body</emphasis>
+ evaluation is used as a <emphasis><?xxe-sn 26yv439af40 ac?>accumulator</emphasis>'s
+ next iteration value and as an overall loop statement result after the
+ last iteration.</para>
- <para><?xxe-sn 26yv439af40 ad?>This notation does not have termination
- condition. Compiler relies on loop body's fixed point in order to decide
- when to interrupt loop. Let's consider example:</para>
+ <para><?xxe-sn 26yv439af40 ad?>Note, that this notation does not have an
+ explicit termination condition! The compiler relies on the loop body's
+ fixed point in order to decide when to interrupt the loop. Consider an
+ example:</para>
<programlisting xml:id="LoopStatement1"><?xxe-sn 26yv439af40 ae?>COUNTEREXAMPLE, name="tests/ast.cpp: AST.Doc_LoopStatements"
-//infinite loop
-answer = loop (2-&gt;x) :: int
+//an infinite loop
+answer = loop (2 -&gt; x) :: int
{
if(IsPerfect(x)):: int {x} else {x+1}
}.</programlisting>
<para><?xxe-sn 26yv439af40 af?>The example tests numbers for being
- perfect(sum of all proper divisors equals to the number itself). While
- iterating accumulator <code><?xxe-sn 26yv439af40 ag?>x</code> assumes
- values as follows: 2, 3, 4, 5, 6, 6 ... After it founds first perfect
- number any further iteration do not change result anymore since there is
- no increment and it continues to test the same number again and again.
- Obviously, <code><?xxe-sn 26yv439af40 ah?>x=6</code> is a fixed point in
- this example. There is no point to continue going through further
- iterations once fixed point is evaluated and hence loop can be safely
- interrupted.</para>
-
- <para><?xxe-sn 26yv439af40 ai?>Compiler relies on manually provided
- annotations to recognize when fixed point is reached. There is special
- annotation <code><?xxe-sn 26yv439af40 aj?>final</code> to specify fixed
- point for loops. Once expression marked as <code><?xxe-sn 26yv439af40 ak?>final</code>
- gets evaluated it's assumed to be a fixed point or in other words
- compiler knows it's the very last iteration after which loop ends.
- Correct code for the example above is:</para>
+ perfect(sum of all proper divisors equals to the number itself). During
+ iterations the accumulator <code><?xxe-sn 26yv439af40 ag?>x</code>
+ assumes values as follows: 2, 3, 4, 5, 6, 6... After the first perfect
+ number is found, no further iteration will change the result anymore
+ since there is no increment, so the loop continues to go through the
+ same number again and again, making this an infinite loop. Obviously,
+ <code><?xxe-sn 26yv439af40 ah?>x=6</code>(the first perfect number) is a
+ fixed point in this example. It does not make any sense to continue
+ going through further iterations once a fixed point is reached because
+ the result is not going to be changed anymore, thus the loop can be
+ safely interrupted at this point.</para>
+
+ <para><?xxe-sn 26yv439af40 ai?>The compiler relies on manually provided
+ annotations to recognize when a fixed point is reached. There is a
+ special annotation <code><?xxe-sn 26yv439af40 aj?>final</code> reserved
+ to specify a fixed point for loops. Once an expression that marked as
+ <code><?xxe-sn 26yv439af40 ak?>final</code> gets evaluated it's assumed
+ that a fixed point is reached or in words the compiler knows it's the
+ very last iteration after which loop can be terminated safely. The
+ correct code for the example above is:</para>
<programlisting xml:id="LoopStatement2"><?xxe-sn 26yv439af40 al?>name="tests/ast.cpp: AST.Doc_LoopStatements"
-//loop exits after first perfect number is found
+//a loop exits after the first perfect number is found
answer2 = loop (2-&gt;x) :: int
{
if(IsPerfect(x))::int {x:: int; final} else {x+1}
}.</programlisting>
- <para><?xxe-sn 26yv439af40 am?>In this case compiler able to recognize
- when fixed point is reached to exit loop. After loops is done
- <code><?xxe-sn 26yv439af40 an?>answer</code> is <code><?xxe-sn 26yv439af40 ao?>6</code>.</para>
+ <para><?xxe-sn 26yv439af40 am?>In this case the compiler is able to
+ recognize that a fixed point is reached in order to know when it is safe
+ to terminate the loop. In the example, the final result <code><?xxe-sn 26yv439af40 an?>answer2</code>
+ is <code><?xxe-sn 26yv439af40 ao?>6</code>.</para>
</section>
<section>
<?xxe-sn 26yv439af40 ap?>
<title><?xxe-sn 26yv439af40 aq?>LOOP FOLD Statement</title>
<synopsis><?xxe-sn 26yv439af40 ar?>SYNTAX:
-**loop fold** (//list// **-&gt;** //element//:: //type// [; //annotations//], //init-value// **-&gt;** //accumulator//):: //type// [; //annotations//]
+**loop fold (** //list// **-&gt;** //element//:: //type// [; //annotations//], //init-value// **-&gt;** //accumulator//**)**:: //type// [; //annotations//]
//loop-body//</synopsis>
<itemizedlist>
<?xxe-sn 26yv439af40 as?>
<listitem>
<?xxe-sn 26yv439af40 at?>
<para><?xxe-sn 26yv439af40 au?><emphasis><?xxe-sn 26yv439af40 av?>list</emphasis>
- to iterate through</para>
+ Container to iterate over.</para>
</listitem>
<listitem>
<?xxe-sn 26yv439af40 aw?>
<para><?xxe-sn 26yv439af40 ax?><emphasis><?xxe-sn 26yv439af40 ay?>element</emphasis>
- identifier that assumes value of currently processed list
- element</para>
+ Identifier that assumes value of a currently processing list
+ element.</para>
</listitem>
<listitem>
<?xxe-sn 26yv439af40 az?>
<para><?xxe-sn 26yv439af40 b0?><emphasis><?xxe-sn 26yv439af40 b1?>type</emphasis>,
- <emphasis><?xxe-sn 26yv439af40 b2?>annotations</emphasis> expression
- types and optional annotations delimited by semicolon</para>
+ <emphasis><?xxe-sn 26yv439af40 b2?>annotations</emphasis> Expression
+ types and optional annotations delimited by semicolon.</para>
</listitem>
<listitem>
<?xxe-sn 26yv439af40 b3?>
<para><?xxe-sn 26yv439af40 b4?><emphasis><?xxe-sn 26yv439af40 b5?>init-value</emphasis>
- accumulator's initial value loop starts with</para>
+ Accumulator's initial value loop starts from.</para>
</listitem>
<listitem>
<?xxe-sn 26yv439af40 b6?>
<para><?xxe-sn 26yv439af40 b7?><emphasis><?xxe-sn 26yv439af40 b8?>accumulator</emphasis>
- identifier assumes loop-body evaluation result after each
- iteration</para>
+ Identifier that assumes loop-body evaluation result after each
+ iteration.</para>
</listitem>
</itemizedlist>
- <para><?xxe-sn 26yv439af40 b9?>Iterates over <emphasis><?xxe-sn 26yv439af40 ba?>list</emphasis>
- in order to accumulate result by applying <emphasis><?xxe-sn 26yv439af40 bb?>loop-body</emphasis>
+ <para><?xxe-sn 26yv439af40 b9?>The <code><?xxe-sn 2evpzktyvg7 -wunr7fl0rw87?>loop fold</code>
+ statement is a commonly used particular instance of <code><?xxe-sn 2evpzktyvg7 -wunr7fl0rw85?>loop</code>
+ to Iterate over <emphasis><?xxe-sn 26yv439af40 ba?>list</emphasis> in
+ order to accumulate the result by applying the <emphasis><?xxe-sn 26yv439af40 bb?>loop-body</emphasis>
transformation to each <emphasis><?xxe-sn 26yv439af40 bc?>element</emphasis>
- and intermediate <emphasis><?xxe-sn 26yv439af40 bd?>accumulator</emphasis>.
- Overall loop value is a accumulator's value after the last iteration. If
- fixed point is found an execution terminates earlier.</para>
+ and an intermediate <emphasis><?xxe-sn 26yv439af40 bd?>accumulator</emphasis>.
+ The result of a current iteration is used as the <emphasis><?xxe-sn 2evpzktyvg7 -wunr7fl0rw8b?>accumulator</emphasis>
+ value for a next iteration. Accordingly, the overall loop value equals
+ that of <emphasis><?xxe-sn 2evpzktyvg7 -wunr7fl0rw8c?>accumulator</emphasis>
+ after the last iteration. If a fixed point is found evaluation
+ terminates earlier.</para>
- <para><?xxe-sn 26yv439af40 be?>Example shows code excerpt that looks for
- a minimal element in the given list(and less then initial value
- <code><?xxe-sn 26yv439af40 bf?>10</code>).</para>
+ <para><?xxe-sn 26yv439af40 be?>Example shows a code excerpt that looks
+ for the minimal element in a given list(and less then the initial value
+ <code><?xxe-sn 26yv439af40 bf?>10</code>):</para>
<programlisting xml:id="FoldStatement1"><?xxe-sn 26yv439af40 bg?>name="tests/ast.cpp: AST.Doc_LoopStatements"
numbers = {4, 8, 7, 1, 5}:: [int].
min = loop fold(numbers-&gt;x:: int, 10-&gt;acc):: int
{
if (acc &gt; x):: int {x} else {acc}
}.</programlisting>
</section>
<section>
<?xxe-sn 26yv439af40 bh?>
<title><?xxe-sn 26yv439af40 bi?>LOOP MAP Statement</title>
<synopsis><?xxe-sn 26yv439af40 bj?>SYNTAX:
-**loop map** (//list// **-&gt;** //element// :: //type// [; //annotations// ] ) :: //type// [; //annotations// ]
+**loop map (**//list// **-&gt;** //element// :: //type// [; //annotations// ] ) :: //type// [; //annotations// ]
//loop-body//</synopsis>
<itemizedlist>
<?xxe-sn 26yv439af40 bk?>
<listitem>
<?xxe-sn 26yv439af40 bl?>
<para><?xxe-sn 26yv439af40 bm?><emphasis><?xxe-sn 26yv439af40 bn?>list</emphasis>
- to iterate through</para>
+ Container to iterate over.</para>
</listitem>
<listitem>
<?xxe-sn 26yv439af40 bo?>
<para><?xxe-sn 26yv439af40 bp?><emphasis><?xxe-sn 26yv439af40 bq?>element</emphasis>
- identifier that assumes value of currently processed list
- element</para>
+ Identifier that assumes value of a currently processed list
+ element.</para>
</listitem>
<listitem>
<?xxe-sn 26yv439af40 br?>
<para><?xxe-sn 26yv439af40 bs?><emphasis><?xxe-sn 26yv439af40 bt?>type</emphasis>,
- <emphasis><?xxe-sn 26yv439af40 bu?>annotations</emphasis> type and
+ <emphasis><?xxe-sn 26yv439af40 bu?>annotations</emphasis> Type and
optional annotations delimited by semicolon.</para>
</listitem>
-
- <listitem>
- <?xxe-sn 26yv439af40 bv?>
-
- <para><?xxe-sn 26yv439af40 bw?><emphasis><?xxe-sn 26yv439af40 bx?>loop-body</emphasis></para>
- </listitem>
</itemizedlist>
- <para><?xxe-sn 26yv439af40 by?>Iterates over input <emphasis><?xxe-sn 26yv439af40 bz?>list</emphasis>
- and applies <emphasis><?xxe-sn 26yv439af40 c0?>loop-body</emphasis>
- transformation to each element. Result is a list that consists of all
- transformed elements.</para>
+ <para><?xxe-sn 26yv439af40 by?>The <code><?xxe-sn 2evpzktyvg7 -wunr7fl0rw84?>loop fold</code>
+ statement is a commonly used particular instance of <code><?xxe-sn 2evpzktyvg7 -wunr7fl0rw83?>loop</code>
+ to Iterate over <emphasis><?xxe-sn 26yv439af40 bz?>list</emphasis> and
+ applying the <emphasis><?xxe-sn 26yv439af40 c0?>loop-body</emphasis>
+ transformation to each element. The result is a list that consists of
+ all the transformed elements.</para>
+
+ <para><?xxe-sn 2evpzktyvg7 -wunr7fl0rw8a?>An example below demonstrates
+ creating the <code><?xxe-sn 2evpzktyvg7 -wunr7fl0rw89?>even_number</code>
+ list by multiplying by 2 every element of <code><?xxe-sn 2evpzktyvg7 -wunr7fl0rw88?>odd_numbers</code>:</para>
<programlisting xml:id="MapStatement1"><?xxe-sn 26yv439af40 c1?>name="tests/ast.cpp: AST.Doc_LoopStatements"
odd_numbers = {1, 3, 5}:: [int].
-even_numbers = loop map(odd_numbers-&gt;number::int) :: [int]
+even_numbers = loop map(odd_numbers -&gt; number:: int) :: [int]
{ 2 * number }.</programlisting>
-
- <para><?xxe-sn 26yv439af40 c2?>Example demonstrates creating
- <code><?xxe-sn 26yv439af40 c3?>even_number</code> list by multiplying by
- 2 every element of <code><?xxe-sn 26yv439af40 c4?>odd_numbers</code>.</para>
</section>
</section>
<section>
<?xxe-sn 26yv439af40 c5?>
<title><?xxe-sn 26yv439af40 c6?>Types</title>
- <para><?xxe-sn 26yv439af40 c7?>Primitive Types</para>
+ <para><?xxe-sn 26yv439af40 c7?>Primitive Types:</para>
<informaltable>
<?xxe-sn 26yv439af40 c8?>
<tgroup cols="2">
<?xxe-sn 26yv439af40 c9?>
<colspec colwidth="173*"><?xxe-sn 26yv439af40 ca?></colspec>
<colspec colwidth="827*"><?xxe-sn 26yv439af40 cb?></colspec>
<tbody>
<?xxe-sn 26yv439af40 cc?>
<row>
- <?xxe-sn 26yv439af40 cd?>
-
- <entry><?xxe-sn 26yv439af40 ce?><code><?xxe-sn 26yv439af40 cf?>num</code></entry>
-
- <entry><?xxe-sn 26yv439af40 cg?><code><?xxe-sn 26yv439af40 ch?>i32</code>
- alias. Reserved as a placeholder for auto detected appropriate
- either integral of floating-point type</entry>
- </row>
-
- <row>
- <?xxe-sn 26yv439af40 ci?>
+ <?xxe-sn 2ey6qxf8um8 1?>
- <entry><?xxe-sn 26yv439af40 cj?><code><?xxe-sn 26yv439af40 ck?>int</code></entry>
+ <entry><?xxe-sn 2ey6qxf8um8 2?><code><?xxe-sn 2ey6qxf8um8 7?>bool</code></entry>
- <entry><?xxe-sn 26yv439af40 cl?><code><?xxe-sn 26yv439af40 cm?>i32</code>
- alias. Reserved as a placeholder for auto detected appropriate
- integral type</entry>
+ <entry><?xxe-sn 2ey6qxf8um8 8?>Booleans.</entry>
</row>
<row>
- <?xxe-sn 26yv439af40 cn?>
+ <?xxe-sn 2ey6qxf8um8 3?>
- <entry><?xxe-sn 26yv439af40 co?><code><?xxe-sn 26yv439af40 cp?>float</code></entry>
+ <entry><?xxe-sn 2ey6qxf8um8 4?><code><?xxe-sn 2ey6qxf8um8 9?>i8</code>,
+ <code><?xxe-sn 2ey6qxf8um8 a?>i32</code>, <code><?xxe-sn 2ey6qxf8um8 b?>i64</code></entry>
- <entry><?xxe-sn 26yv439af40 cq?>Double precision floating-point
- number</entry>
+ <entry><?xxe-sn 2ey6qxf8um8 c?>Signed integers; 8, 32, 64 bit wide
+ respectively.</entry>
</row>
<row>
- <?xxe-sn 26yv439af40 cr?>
+ <?xxe-sn 2ey6qxf8um8 5?>
- <entry><?xxe-sn 26yv439af40 cs?><code><?xxe-sn 26yv439af40 ct?>bool</code></entry>
+ <entry><?xxe-sn 2ey6qxf8um8 6?><code><?xxe-sn 2ey6qxf8um8 f?>int</code>,
+ <code><?xxe-sn 2ey6qxf8um8 g?>num</code></entry>
- <entry><?xxe-sn 26yv439af40 cu?>Boolean type</entry>
+ <entry><?xxe-sn 2ey6qxf8um8 d?>Currently <code><?xxe-sn 2ey6qxf8um8 e?>i32</code>
+ aliases. Reserved as placeholders for an auto detected appropriate
+ integral type and for auto detected appropriate either integral of
+ floating-point type, respectively.</entry>
</row>
<row>
- <?xxe-sn 26yv439af40 cv?>
+ <?xxe-sn 26yv439af40 ci?>
- <entry><?xxe-sn 26yv439af40 cw?><code><?xxe-sn 26yv439af40 cx?>i8,
- i32, i64</code></entry>
+ <entry><?xxe-sn 26yv439af40 cj?><code><?xxe-sn 26yv439af40 ck?>float</code></entry>
- <entry><?xxe-sn 26yv439af40 cy?>Signed integers. 8, 32, 64 bit
- wide respectively</entry>
+ <entry><?xxe-sn 26yv439af40 cl?>Double precision floating-point
+ numbers.</entry>
</row>
<row>
<?xxe-sn 26yv439af40 cz?>
<entry><?xxe-sn 26yv439af40 d0?><code><?xxe-sn 26yv439af40 d1?>string</code></entry>
- <entry><?xxe-sn 26yv439af40 d2?>Pointer to a null terminated ANSI
- char string. Reserved for auto detected most appropriate string
- type.</entry>
+ <entry><?xxe-sn 26yv439af40 d2?>Currently null terminated ANSI
+ char string. Reserved to be generic type with no particular
+ implementation. A concrete implementation is to be determined
+ similarly to the <link
+ xlink:href="/d/concepts/containers/"><?xxe-sn 2ey6qxf8um8 h?>containers</link>
+ approach.</entry>
</row>
<row>
<?xxe-sn 26yv439af40 d3?>
<entry><?xxe-sn 26yv439af40 d4?><code><?xxe-sn 26yv439af40 d5?>*</code></entry>
- <entry><?xxe-sn 26yv439af40 d6?>Unspecified type. Example
- <code><?xxe-sn 26yv439af40 d7?>x = {amount=200,
- currency="USD"}::*.</code></entry>
+ <entry><?xxe-sn 26yv439af40 d6?>An unspecified type. Postpones
+ type checks for this expression. Examples: <code><?xxe-sn 26yv439af40 d7?>x = {amount=200, currency="USD"}::*.</code></entry>
</row>
</tbody>
</tgroup>
</informaltable>
<para><?xxe-sn 26yv439af40 d8?>Compound types:</para>
<informaltable>
<?xxe-sn 26yv439af40 d9?>
<tgroup cols="2">
<?xxe-sn 26yv439af40 da?>
<colspec colwidth="312*"><?xxe-sn 26yv439af40 db?></colspec>
<colspec colwidth="688*"><?xxe-sn 26yv439af40 dc?></colspec>
<tbody>
<?xxe-sn 26yv439af40 dd?>
<row>
<?xxe-sn 26yv439af40 de?>
- <entry><?xxe-sn 26yv439af40 df?><code><?xxe-sn 26yv439af40 dg?>[
- <emphasis><?xxe-sn 26yv439af40 dh?>element-type</emphasis>
- ]</code></entry>
+ <entry><?xxe-sn 26yv439af40 df?>[ <emphasis><?xxe-sn 2ey6qxf8um8 j?>element-type</emphasis> ]</entry>
<entry><?xxe-sn 26yv439af40 di?>List of elements of the same type
<emphasis><?xxe-sn 26yv439af40 dj?>element-type</emphasis>.
- Example: <code><?xxe-sn 26yv439af40 dk?>[int]</code> - list of
- <code><?xxe-sn 26yv439af40 dl?>int</code>'s</entry>
+ Examples: <code><?xxe-sn 26yv439af40 dk?>x = {1, 2, 3}:: [int]</code>
+ - list of <code><?xxe-sn 26yv439af40 dl?>int</code>'s. Lists can
+ have different internal implementations.</entry>
</row>
<row>
<?xxe-sn 26yv439af40 dm?>
- <entry><?xxe-sn 26yv439af40 dn?><code><?xxe-sn 26yv439af40 do?>{<emphasis><?xxe-sn 26yv439af40 dp?>key</emphasis>::
- <emphasis><?xxe-sn 26yv439af40 dq?>type</emphasis>,
- ...}</code></entry>
+ <entry><?xxe-sn 26yv439af40 dn?>{<emphasis><?xxe-sn 2ey6qxf8um8 k?> key</emphasis>:: <emphasis><?xxe-sn 2ey6qxf8um8 l?>type</emphasis>, ... }</entry>
- <entry><?xxe-sn 26yv439af40 dr?>List of elements of different type
- possibly with named keys. Examples: <code><?xxe-sn 26yv439af40 ds?>{int,
- string}</code>, <code><?xxe-sn 26yv439af40 dt?>{name::string,
- age::int}</code></entry>
+ <entry><?xxe-sn 26yv439af40 dr?>Record: a list of elements of
+ different types possibly with named keys. Examples:
+ <code><?xxe-sn 2ey6qxf8um8 15?>{int, string}</code>,
+ <code><?xxe-sn 2ey6qxf8um8 16?>{name::string, age::int}</code>.</entry>
</row>
<row>
<?xxe-sn 26yv439af40 du?>
- <entry><?xxe-sn 26yv439af40 dv?><code><?xxe-sn 26yv439af40 dw?>variant
- {<emphasis><?xxe-sn 26yv439af40 dx?>option</emphasis> ::
- (<emphasis><?xxe-sn 26yv439af40 dy?>type</emphasis>, ...},
- ...}</code></entry>
+ <entry><?xxe-sn 26yv439af40 dv?>variant {<emphasis><?xxe-sn 2ey6qxf8um8 m?>option</emphasis> :: {<emphasis><?xxe-sn 2ey6qxf8um8 n?>type</emphasis>, ...}, ...}</entry>
- <entry><?xxe-sn 26yv439af40 dz?>Holds a single element of type of
- one out of number of options. Examples: <code><?xxe-sn 26yv439af40 e0?>variant
- {FullAddress:: {string, string, string}, ShortAddress::
- {string}}</code></entry>
+ <entry><?xxe-sn 26yv439af40 dz?>ADT type. Variables of this type
+ can hold value of any type out of a list of permitted ones.
+ Examples: <code><?xxe-sn 26yv439af40 e0?>variant {FullAddress:: {string, string, string}, ShortAddress:: {string}}</code>.</entry>
</row>
<row>
<?xxe-sn 26yv439af40 e1?>
- <entry><?xxe-sn 26yv439af40 e2?><code><?xxe-sn 26yv439af40 e3?>slave
- <emphasis><?xxe-sn 26yv439af40 e4?>identifier</emphasis></code></entry>
+ <entry><?xxe-sn 26yv439af40 e2?>slave <emphasis><?xxe-sn 2ey6qxf8um8 o?>identifier</emphasis></entry>
+
+ <entry><?xxe-sn 26yv439af40 e5?>Denotes a type constructed by
+ Transcend. See <link xlink:href="#slave-types"><?xxe-sn 2ezs03nkiyo 17?>slave
+ types</link>. An example: <code><?xxe-sn 26yv439af40 e6?>slave unit_test</code>.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para><?xxe-sn 2ey6qxf8um8 p?>Type operations:</para>
+
+ <informaltable>
+ <?xxe-sn 2ey6qxf8um8 q?>
+
+ <tgroup cols="2">
+ <?xxe-sn 2ey6qxf8um8 r?>
+
+ <colspec colwidth="115*"><?xxe-sn 2ey6qxf8um8 17?></colspec>
+
+ <colspec colwidth="885*"><?xxe-sn 2ey6qxf8um8 18?></colspec>
+
+ <tbody>
+ <?xxe-sn 2ey6qxf8um8 s?>
+
+ <row>
+ <?xxe-sn 2ey6qxf8um8 t?>
+
+ <entry><?xxe-sn 2ey6qxf8um8 u?><emphasis><?xxe-sn 2ey6qxf8um8 v?>type</emphasis> [ <emphasis><?xxe-sn 2ey6qxf8um8 w?>key</emphasis> ]</entry>
- <entry><?xxe-sn 26yv439af40 e5?>Type determined by Transcend.
- Example: <code><?xxe-sn 26yv439af40 e6?>slave
- unit_test</code></entry>
+ <entry><?xxe-sn 2ey6qxf8um8 x?>Index operation: accessing elements
+ of a compound type. Examples: <code><?xxe-sn 2ey6qxf8um8 y?>Bio = type {birth_year:: int, name:: string}. YearBirth = type Bio[birth_year].</code></entry>
</row>
<row>
- <?xxe-sn 26yv439af40 e7?>
+ <?xxe-sn 2ey6qxf8um8 z?>
- <entry><?xxe-sn 26yv439af40 e8?><code><?xxe-sn 26yv439af40 e9?><emphasis><?xxe-sn 26yv439af40 ea?>compound-type</emphasis>
- [ <emphasis><?xxe-sn 26yv439af40 eb?>key</emphasis>
- ]</code></entry>
+ <entry><?xxe-sn 2ey6qxf8um8 10?><emphasis><?xxe-sn 2ey6qxf8um8 12?>type</emphasis> ( <emphasis><?xxe-sn 2ey6qxf8um8 13?>parameters</emphasis>... )</entry>
- <entry><?xxe-sn 26yv439af40 ec?>Accessing elements of compound
- type. Example: <code><?xxe-sn 26yv439af40 ed?>Bio = type
- {birth_year:: int, name:: string}. Year = type
- Bio[birth_year].</code></entry>
+ <entry><?xxe-sn 2ey6qxf8um8 11?>Constructs a concrete type with
+ the given parameters. Examples: <code><?xxe-sn 2ey6qxf8um8 14?>MyTree = type Tree(int)</code>.</entry>
</row>
</tbody>
</tgroup>
</informaltable>
- <para><?xxe-sn 26yv439af40 ee?>New types defined as:</para>
+ <para><?xxe-sn 26yv439af40 ee?>New types are defined as follows:</para>
<synopsis><?xxe-sn 26yv439af40 ef?>SYNTAX:
//type-name// = **type** (//parameters//...) //type-definition// .</synopsis>
- <para><?xxe-sn 26yv439af40 eg?>Example:</para>
+ <para><?xxe-sn 26yv439af40 eg?>Examples:</para>
<programlisting xml:id="Types1"><?xxe-sn 26yv439af40 eh?>name="tests/ast.cpp: AST.Doc_Types"
Tuple = type {string, int}.
-Int = type Tuple[1]. //accessing by index</programlisting>
+Int = type Tuple[1]. //accessing by index
+
+List = type(X) [X]. // List of elements of type X.
+IntList = type List(int). // type function to construct List of ints.</programlisting>
+
+ <section>
+ <?xxe-sn 2f0cduzin5j -wunr7fl0rw8v?>
+
+ <title><?xxe-sn 2f0cduzin5j -wunr7fl0rw8u?>Slave Types</title>
+
+ <synopsis><?xxe-sn 2f0cduzin5j -wunr7fl0rw8t?>SYNTAX:
+**slave** //predicate//
+</synopsis>
+
+ <itemizedlist>
+ <?xxe-sn 2f0cduzin5j -wunr7fl0rw8s?>
+
+ <listitem>
+ <?xxe-sn 2f0cduzin5j -wunr7fl0rw8r?>
+
+ <para><?xxe-sn 2f0cduzin5j -wunr7fl0rw8q?><emphasis><?xxe-sn 2f0cduzin5j -wunr7fl0rw8p?>predicate</emphasis>
+ Name of a logic predicate</para>
+ </listitem>
+ </itemizedlist>
+
+ <para><?xxe-sn 2f0cduzin5j -wunr7fl0rw8o?>Slave type is a reference to a
+ type defined on the Transcend side. This gives Transcend a full control
+ over program types marked as <code><?xxe-sn 2f0cduzin5j -wunr7fl0rw8n?>slave</code>
+ ones. The type is constructed in such a way that variables of this type
+ are able to hold <emphasis><?xxe-sn 2f0cduzin5j -wunr7fl0rw8m?>predicate</emphasis>'s
+ arguments. Type inference works as follows:</para>
+
+ <itemizedlist>
+ <?xxe-sn 2f0cduzin5j -wunr7fl0rw8l?>
+
+ <listitem>
+ <?xxe-sn 2f0cduzin5j -wunr7fl0rw8k?>
+
+ <para><?xxe-sn 2f0cduzin5j -wunr7fl0rw8j?>If a predicate has only
+ one argument then a constructed type is a type of this argument:
+ <code><?xxe-sn 2f0cduzin5j -wunr7fl0rw8i?>int</code>,
+ <code><?xxe-sn 2f0cduzin5j -wunr7fl0rw8h?>string</code>, variant or
+ tuple.</para>
+ </listitem>
+
+ <listitem>
+ <?xxe-sn 2f0cduzin5j -wunr7fl0rw8g?>
+
+ <para><?xxe-sn 2f0cduzin5j -wunr7fl0rw8f?>A constructed type is a
+ record in case of several arguments.</para>
+ </listitem>
+
+ <listitem>
+ <?xxe-sn 2f0cduzin5j -wunr7fl0rw8e?>
+
+ <para><?xxe-sn 2f0cduzin5j -wunr7fl0rw8d?>Predicates correspond to
+ variants in a constructed type.</para>
+ </listitem>
+ </itemizedlist>
+
+ <para><?xxe-sn 2f0cduzin5j -wunr7fl0rw8c?>An example; Transcend
+ facts:</para>
+
+ <programlisting><?xxe-sn 2f0cduzin5j -wunr7fl0rw8b?>person("John", 1962).
+person("Bill", 1961).</programlisting>
+
+ <para><?xxe-sn 2f0cduzin5j -wunr7fl0rw8a?>The Brute side:</para>
+
+ <programlisting xml:id="SlaveTypes1"><?xxe-sn 2f0cduzin5j -wunr7fl0rw89?>name="tests/transcend.cpp: Transcend.Doc_SlaveTypes1", lines=15
+PersonNative = type {string, int}.
+Person = type slave person.</programlisting>
+
+ <para><?xxe-sn 2f0cduzin5j -wunr7fl0rw88?>In the example above the types
+ <code><?xxe-sn 2f0cduzin5j -wunr7fl0rw87?>PersonNative</code> and
+ <code><?xxe-sn 2f0cduzin5j -wunr7fl0rw86?>Person</code> are
+ equivalent.</para>
+ </section>
+ </section>
+
+ <section>
+ <?xxe-sn 2ey6qxf8um8 19?>
+
+ <title><?xxe-sn 2ey6qxf8um8 1a?>Variants</title>
+
+ <para><?xxe-sn 2ey6qxf8um8 1b?>Sometimes it is useful for a variable to
+ have an ability to hold values of different types depending on some
+ conditions, in other words to have a <emphasis><?xxe-sn 2ey6qxf8um8 1c?>variant
+ type</emphasis>. An example:</para>
+
+ <programlisting xml:id="Variants1"><?xxe-sn 2ey6qxf8um8 1d?>name="tests/ast.cpp: AST.Doc_Variants1"
+Color = type variant {
+ White, Black, Magenta,
+ CustomColor:: {r:: int, g:: int, b:: int}
+}.
+
+draw = function:: int
+{
+ clrBorder = Black():: Color.
+ clrBackground = CustomColor(50, 50, 50):: Color.
+
+ drawRectangle({0, 0, 100, 100}, clrBorder, clrBackground)
+}</programlisting>
</section>
<section>
<?xxe-sn 26yv439af40 ei?>
- <title><?xxe-sn 26yv439af40 ej?>Variants and SWITCH VARIANT
- Instruction</title>
+ <title><?xxe-sn 26yv439af40 ej?>SWITCH VARIANT Statement</title>
<synopsis><?xxe-sn 26yv439af40 ek?>SYNTAX:
-**switch variant** ( //condition// [-&gt; //alias// ] [:: //type// [; //annotations//... ] ] ) :: type [; annotations... ]
+**switch variant** ( //condition// [**-&gt;** //alias// ] [:: //type// [; //annotations//... ] ] ) :: type [; annotations... ]
[ **case** ( //guard// ) //case-branch// ]...</synopsis>
<itemizedlist>
<?xxe-sn 26yv439af40 el?>
<listitem>
<?xxe-sn 26yv439af40 em?>
<para><?xxe-sn 26yv439af40 en?><emphasis><?xxe-sn 26yv439af40 eo?>condition</emphasis>
- expression of variant type</para>
+ Expression of a variant type.</para>
</listitem>
<listitem>
<?xxe-sn 26yv439af40 ep?>
<para><?xxe-sn 26yv439af40 eq?><emphasis><?xxe-sn 26yv439af40 er?>alias</emphasis>
- identifier to denote unwrapped content of condition withing case
- branches.</para>
+ Identifier to denote unwrapped content of the <emphasis><?xxe-sn 2ey6qxf8um8 1e?>condition</emphasis>
+ expression withing case branches.</para>
</listitem>
<listitem>
<?xxe-sn 26yv439af40 es?>
<para><?xxe-sn 26yv439af40 et?><emphasis><?xxe-sn 26yv439af40 eu?>guard</emphasis>
- name of variant to match against actual condition's variant</para>
+ Name of a variant to match against actual condition's variant.</para>
</listitem>
<listitem>
<?xxe-sn 26yv439af40 ev?>
<para><?xxe-sn 26yv439af40 ew?><emphasis><?xxe-sn 26yv439af40 ex?>case-branch</emphasis>
- block of code to execute in case of matched variant. Content is
- accessible by using alias Within the branch .</para>
+ Code block to execute in case of the matched variant. The
+ <emphasis><?xxe-sn 2ey6qxf8um8 1f?>condition</emphasis> expression's
+ content is referred to by <emphasis><?xxe-sn 2fadpf0i3zr -wunr7fl0rw8t?>alias</emphasis>
+ within the branch.</para>
</listitem>
</itemizedlist>
- <para><?xxe-sn 26yv439af40 ey?>Sometimes it is useful for a variable to
- have value of different types depending on some conditions, in other words
- it has <emphasis><?xxe-sn 26yv439af40 ez?>variant type</emphasis>.</para>
+ <para><?xxe-sn 26yv439af40 ey?>Variant variables require special means to
+ test which exactly variant they contain at any given moment as well as to
+ access it. Usually, languages that support variant types(ADT) solve this
+ problem be means of <emphasis><?xxe-sn 2ey6qxf8um8 1g?>pattern
+ matching</emphasis>. Xreate intentionally does not support pattern
+ matching since it is depends on parameters order, which is plainly
+ unacceptable; besides, it's hardly usable in case of a large amount of
+ parameters. Instead, Xreate supports special syntax to <emphasis><?xxe-sn 2ey6qxf8um8 1h?>unwrap</emphasis>
+ a variable's content using <code><?xxe-sn 2ey6qxf8um8 1i?>switch variant</code>
+ statement.</para>
- <para><?xxe-sn 26yv439af40 f0?>Let's consider example with variable
- <code><?xxe-sn 26yv439af40 fi?>month</code> of variant type
- <code><?xxe-sn 26yv439af40 fj?>Month</code>:</para>
+ <para><?xxe-sn 26yv439af40 f0?>An example:</para>
- <programlisting xml:id="Variants1"><?xxe-sn 26yv439af40 f3?>name="tests/ast.cpp: AST.Doc_Variants"
+ <programlisting xml:id="VariantsSwitch1"><?xxe-sn 26yv439af40 f3?>name="tests/ast.cpp: AST.Doc_VariantsSwitch1",lines=15
Month = type variant {
- MonName :: {string},
- MonNumber:: {int}
+ MonByName :: {name:: string},
+ MonById :: {id:: int}
+}.
+
+nextMonth = function(month:: Month):: Month
+{
+ switch variant(month):: Month
+ case (MonByName)
+ {
+ monthName = month["name"]:: string. //here month has {name:: string} type
+
+ MonByName(nextMonthByName(monthName))
+ }
+
+ case (MonById)
+ {
+ monthId = month["id"]:: int. //here month has {id:: int} type
+
+ if(monthId == 11):: Month
+ { MonById(0) }
+ else
+ {MonById(monthId + 1)}
+ }
+}</programlisting>
+
+ <para><?xxe-sn 26yv439af40 f4?>The function <code><?xxe-sn 2ey6qxf8um8 1j?>nextMonth</code>
+ computes the next month after a given one. The parameter <code><?xxe-sn 2ey6qxf8um8 1k?>month</code>
+ can't be directly accessed due to being of a variant type; hence, It
+ should be <emphasis><?xxe-sn 26yv439af40 f8?>unwrapped</emphasis> before
+ using. As seen in this example, Xreate silently defines a new variable
+ with the same name <code><?xxe-sn 2ey6qxf8um8 1l?>month</code> which holds
+ an unwrapped content for each <code><?xxe-sn 2ey6qxf8um8 1m?>switch variant</code>'s
+ branch independently.</para>
+ </section>
+
+ <section>
+ <?xxe-sn 2ey6qxf8um8 1t?>
+
+ <title><?xxe-sn 2ey6qxf8um8 1u?>Records</title>
+
+ <para><?xxe-sn 2ey6qxf8um8 1v?>Record's elements(fields) are denoted by
+ strings in order to access the field's value. This gives a possibility to
+ use variables to reference fields. Such references are statically resolved
+ during <link xlink:href="/d/concepts/interpretation/"><?xxe-sn 2ey6qxf8um8 1w?>Interpretation</link>.
+ An example:</para>
+
+ <programlisting xml:id="RecField1"><?xxe-sn 2ey6qxf8um8 1x?>name="tests/ast.cpp: AST.Doc_RecField1"
+Employee = type {
+ name :: string,
+ surname :: string,
+ signature:: string
}.
-test = function:: Month
+test = function:: string; entry
{
- month = MonName("April"):: Month.
- month
+ employee = getAnyEmployee():: Employee.
+ primaryKey = "surname":: string.
+
+ employee[primaryKey]
}</programlisting>
- <para><?xxe-sn 26yv439af40 f4?>Variable <code><?xxe-sn 26yv439af40 f5?>month</code>
- holds value of either <code><?xxe-sn 26yv439af40 f6?>string</code> or
- <code><?xxe-sn 26yv439af40 f7?>int</code> type. Value is not accessible
- directly. It should be <emphasis><?xxe-sn 26yv439af40 f8?>unwrapped</emphasis>
- before using. Xreate supports <code><?xxe-sn 26yv439af40 f9?>switch variant</code>
- instruction for this operation.</para>
+ <para><?xxe-sn 2ey6qxf8um8 1y?>In Xreate the left side of any assignment
+ is always an identifier, hence there is special syntax to update one(or
+ more) record's fields. An example:</para>
- <para><?xxe-sn 26yv439af40 fa?>As an example below is function
- <code><?xxe-sn 26yv439af40 fb?>nextMonth</code>'s definition:</para>
+ <programlisting xml:id="RecUpdate1"><?xxe-sn 2ey6qxf8um8 1z?>name="tests/ast.cpp: AST.Doc_RecUpdate1"
+Day = type {
+ year:: int,
+ month:: string,
+ day:: int
+}.
- <programlisting><?xxe-sn 26yv439af40 fc?>nextMonth = function(month:: Month):: Month
+test = function:: Day
{
- switch variant(month):: Month
- case (MonName)
- {
- //
- }
- case (MonNumber)
+ tomorrow
+
+ today = {year = 1936, month = "July", day = 21}:: Day.
+ tomorrow = today + {day = 22}:: Day.
}</programlisting>
</section>
</chapter>
<?xxe-revisions
+#11 2019-05-16T15:13:16Z pgess
+#10 2019-05-14T16:34:55Z pgess
+1sPEAAABgqphAIIggqpoAAaBG3dBQUFBQWJzv1AjBCMEE4RkgwQTCmOBOgEBE2xTiFwBATMHQwdj
+CmMMQwkzNlOhIiMFY4FBAQFDB0OMaRMEYw1jgSeTDlObCxMEM4Eokw5jBlODUoMEQwtDgTYjGzOO
+fHMEU4EoczczgVoBAVMKEwkTY1O5bmMOU5h0gwUzgSmTDlOCDIMOMwczgUEBARMHEwUTBGOBADMH
+/FMEYwQzBTOaMwDNRoGSNL9Ua7sthG6Nd4IllD7zLaMjhFm1Io50iz6BhXChJLgGgUe6Y65QjHdj
+gTK3apsNY4lggTlrjBWDXYUrgU7qjn5ogVyTGbBmjgCCT4GjFLl4RJh2Y4E0MYJCgh3EPLFuiV2B
+TYGnTJAbgZsahG2bCYkd
+
+#9 2019-05-11T15:02:16Z pgess
+1sPEAAABgqpoAD+CqnAAAB8Zc4H2HhMEE4IfQwRTgUFDCWMFgwSDEBMWQxBTEDOwEgCB/lCB9iCe
+IoIhjnGFA1BBhiuDdtNXghU=
+#8 2019-05-11T12:29:03Z pgess
+1sPEAAABgqpwACuCmDkAABQQc4HfExMNQ44+Ex9DCxMVIwwzqhAAqyWBs26pSIGWIoNAIb8Z
+#7 2019-05-10T16:50:38Z pgess
+1sPEAAABgpg5ABaCl1YAAAkGc4HefRMlQ7g0AKcLgbh6
+#6 2019-05-09T19:09:59Z pgess
+1sPEAAABgpdXAItQgfpzAGWGFYRNIGNjY2NtcHFjdGN1Y3gsIGljeS5QbW9VZz8+W2hvZHA6OnFy
+ZHNkdCB3IGR4KGR5ej8+SGYgLCBlM2VlZWJjPz5laW8uIGFuZCBDV2l6TGVmaWo/PiJOID0oIkE1
+ZmY3VjlmYmZzq2sTBkOmGVMEU95tAQFjjjETLUOBXGMMUyABARMEQxATCwEBQwZjCFMmAQFDBJMQ
+gwsBAUMEMwozBjMOEw1TRTNwQwsjJxMEkxBjDAEBU00zDTMsEwUjHBMEkxBTDAEBUzYBAWMogywT
+BCMdExSDC75TJYMLAQIzCmMEgyxDBIMdEwSTEIMLAQJjBAEDQwRDJoMLAQJjEQEBQyCDgSi7YwYT
+BDMEYyVjBUMNvhMEMwdjBkMGYyxDdwEBQxETCEMdUwRDBEMLEwdjgzFzHQEEQyIBAUMaEwSTB2Ml
+M2tDE4MLMwRDBXMJYzeTUHMdAQFjGIMLAQJDEQECgyIBAVMUMwQjLwEBEwRTEjMOUzaDCwECYyqD
+CwECQxABAWMRM1BzHQEBQwkBAVMWgwsBAmMUUwQBAVMgAQJzFIMFIzTGQwhDB1MFUwXfUwgTCmMG
+UzQBAUMOUwpzBhMJAQJTDnMIUwozUCMcAQJDB2MhoxMJUw6TB3MpYwRTDDMMIwlzE2MMYwhTBDMO
+kywTIAEBEwSTEGMMEwRTIFMFUwYzBTMNIyIBApMRcwSTB3MmAQNDBVMRMxZzE4MLAQFTBAECQwkz
+DCMEMwZTCgECUwRzCFMpEyQzKRMIAQFDC2MfU4EBYwpTgSJDPDMlQwUTBQEDUw9DBGMEUwUTCJMf
+YzFTBWOCMVMLEwRDCzM1M1lTKkMJY4ElEwQjDRMQEwdTE5OBFGMkQwUzDAEBUyQBAWMQQwQTBxMM
+YxCDG0MEQy4zBCMFgxBjLdUjIQEBYxsjCYMbUwS+EwUjBGMIYwQjBlMEIxwBAjMQgwRzCyMewiMI
+EwozLYMLQykBAWMdUwUzBTMPpCMEMwkzEoMFYwUTBbIzBAEDUwVDBIMFUwSDBWM0gwiTHgEBgxBj
+BEMHEwUzBpMcAQFzBEMNEwWTEIMLAQIjDYMHsGMGQwwzCBMFQ1IzECMdAQFTCDMSUwSDBBMIQwUT
+BFMPgxsBAUMEMw1jBlMEEwcjHgEBQxNjDZMKUxETFNMzWpMFMwZDBCMEEwcTBDMFUwQjBkMhYwsA
+qnuBBoGAJqYbhGSPKY5fiimCFY0Qi1eDNFP0Q8xS3kGVtMxa0xi5M4MZ2TpNVI0bgjbOS5U7Dfh0
+gjTPD4FIuQWV+XYNN/O6QIFNnRG0kQKBlAK0l0WZQvOPBPCEfpW0gaYngSFZtDIS84GMU64hhByp
+f5EljRgIrxy4NrxllBfZO4cq2DZ7gatJJGPHIwqBniwT9YQ9g1WMOZWKIkOFa7SBCoGbZdgnAPVO
+tIxhCb5yhn2DYYpykQOJd4HDM7RDtDcSEvVOiFu0Lbc2oQgmhoNkkH+6JL1PwgKleo1AoV2EHqxI
+HzaOal6B2GUttRcLkyROrQP/cIVw7XCVK8sfjSm/F5ACJJEzgUjGTg2ap2+PV5WeFINAgdo/zif4
+W7ooiA+NYK85lSuHZ4VXEyS0tE6xV4GdaptuwVahaSbsFKkkg0KFfYG2fIVgaIVWgQziCYg+7V/B
+ESWOJItgjnuDRN2MS/IwOqJUiUqCRYN2QVyBd3KB2CuCevMi3VaiJmWBFpVOLVgl9mjdeIY1g2z4
+gZ9+gZACr1SDL2lbmQCRGFmBfPiUCLVAjnOuQPsahzaHbuVekkKBjgbKbz6OTZIQi1OB5Au0lC46
+9WRGMIQfl3mB7HuvRbwclSwSgT4MtlG8nGisgwfFtA2ScYR2lFmBsxdzo4J0gYM8lbSxWlaGIYGD
+Ca4zjR2tZjyEU4E5yDiBGq8OpdQtmA6ILK1M+LhZvlAOzQKoFIEfzkKcTtOBqAiDK6d8mDZ6gQiJ
+YQHpAeE6gZAGjG+GVoGREZFW
+#5 2019-05-09T12:03:54Z pgess
+1sPEAAABgfpzACWB+mcAABMLc9olIwUTI1OOcWOBRTNEQ4GPIADkTdoqJY51gUlG
+#4 2019-05-07T18:27:55Z pgess
+1sPEAAABgfptAIxXgeQoAEuGeYUKYXBwYW9uYnVpbHQtaW5yZWN1cnN2dGFraXIuIEFsc3IrR3Mu
+IFBkYWwvL0lGUyAvL1JXaGlsaXVuZG9ub2hpYXh5aW5wdWMyM2M0c4ohExRDC0MEExBzCyMEIwRT
+BEMIQwQTBWMGAQQTBRMEvfxDBFMNAQhDB2MOAQYzBFMMMwpjBgEBYwgTFlOQFGMMY40pM5BEIwRj
+CGMEUzNTBFOBcGMEQwUTBzM1Y1wTBEMMY4FtkwSTDDMUIwZjgRdDL4OBFBMqYxWTEGM2YwtjKyMF
+AQMzBEMMUwUTBmMFAQIzBAEFMwRjBxMKQwsTZjMFEwgBAUOBJDMlYwpTClMhUwljgQ8BAVOBOGMH
+gwpjgU7fQwhTBoMKEzVjYkMEMxBTGnMVkxCDG2MEYzYzBTMGM19jTFMMMx9TQxMGAQRjNEMPU2Yj
+BxMGAQFjBgECYwdDSmMHQxxTE2MbMwgTBlMHcwRjBTMEQ0djCYMbYwRTKJMIMw6DGkM5Y1ozEUMg
+U4E3YydzCpMHQyozgUdjBkMJ8DOBGwECM4UagxMjBUMmUxEzgWdTDRMFMxBTFnM1U1kzREOBJyMH
+Ux5zFZMQgxszBFMHMwozH2NLM2KTKEOBPwEBYwgBAVMKIwYTBUMhg1JjNGMEQ2mDBzMKAQIzBzMQ
+gwQzgV1jHlM1U19DOXMVkxBTdjMGEwZDT1MHMxEBAWMFQwhTIVMvU1oTBGNbEwVDF2MVMwRTBzMK
+Yz0zBkMWEwozgQAzHmMFQ4FNAQQTBBMFYwQzCmNWMwQzBwEB+xMEkwZDB1MJu1MQAQITBUMHkwZj
+JFMIQw0TBGMgQzhTBlMdMwkBAiMHMzJDDxMKcwTTQx8jJTMEIxNTMDMhEwdDOmMLMxwTC0NVUwUj
+DlMFUwczBjM9EwSTBEOBHXMEMw2TBnMHMxATB0OBEVMJYxIzBXMWQwYBASMIEwYTBhMEMwRTJlMK
+Qx9TgTeTBhMEYw9DB2MNUxQzKoMEM4FZUwtDB3OBEEMhUxFjD3M1Y4EVkwtTNTOBE0MoEwRTgRQz
+CzM4YxUTEIMbUwRTByMGY01DE1MhU2wzShMEcwkTBBMHIwtjBTMFMxhDBIMVQwUTBCMFQwczQTMc
+AQFDFFMEUxljOYMhQ4MfIyJjBGOBfnMLgwdTgRBzIYMRcw+TNTOBFVMFcwRzCTM4QyBTBGMcEwQz
+IAEBMxdzFZMQIxwBAWMQAQRTIkMdgwQjIFM6IwdDIGMeExYzgRqTBWMGMwVTMYMbAQIjCUMXUx0B
+AUNREwsBAmMVcwtTCkO8UQCFAo01hU6DdDe5Z/QEmjzLAIMXuW2XHJRuhg+8KIMExR+BLaEiL8NA
+qXgqhxYRhiuDdpd2khyKItFglReDYJBcjmQ7rFTKYqgUhxCXeIVkYA3kbIF/600dgRtgjXiudSGB
+ZpRuQ8hasSxCjzXCTp8smBa8c7ZO0nmDGcgHuGiJQ3mBJYsmo0mdeZMqkmKBEs5D7YFJgTTJZY1g
+7cRgi0FKZhHVIfRbesRjgwlAYYEDgTIjsFZbSCLWfYtIkQ2BPMxPgkkJNRcoiUSoVQ+pAYJygTni
+VPSBMo11E6UAlJFRQ4JnD4IOgUDVK4ZNeekOhg35gWKBHYiKcYU2dDuGWLEIpGSCCdVMW0X0CYEu
+1SH0X+QPj3JMI0/6gQ2BRYFI7w2VLAoi0WKpU4JWiKRKjAyBB/kYmGeeTII2YtUhX55OhCSBCK1x
+V6RMn12ZTkAxx11hqmtrI+gIjB8kDpBN2WeLU2SBA/IkJbVOo0flaMg0jHfPFVmGGrdy7YYqgmKe
+EIFqtVcVbxGmZzKJYBc+rCZYgnqpVTiZWrlkD4F81WSpblOIERsy4ygqQw2uIS/hCYN+rDsVg18K
+t3FVXcyBI+0XgVPseIlemXCBIYl5aNdGjXmBi1P7MIV61h+MIN9ltgBQsIRi+RChQbg+P5xK+TKB
+ZcBwY4ETI5V+Y1chgSA2gReWKS3IcYEn3SyKIfR5gTWcEwxRjkM4b+BKv7llhBeZXudFy0gtpHpa
+jCTpeMc3nFaZBEMfLxYEYlqSTqxjg0VTaYIa9hkXUEWmCQ9Wh3GBgg+bfYF7hH6BiAPaMdUhkBod
+6HjFMYGBUkavC0Uksm2COvePA4h8gS30u36kWotSRIM0aSvgeIIf
#3 2019-02-23T12:37:01Z pgess
+1sPEAAABgeQqAIgmgeMrAHyEMoJvNTM1NTVnLCwgaGlzaWNzOiBxdWU1NWssIGx0ZXJmYWNFeHRl
+cm4tQzVvNXBxPz5POiwgVnN0T2lpbmZsdS4gc3c2Zz8+NSwgNnA/PissIC0sICosIDZ0LCAhPSwg
+NnU2dywgIDcxID03Mi4gID0gIC0gICBoLmFzc29jZHOEEBMEEyQBAUMEIw0BARMZQwRTHNNjGgEB
+MwVDGwECEwoBATMM5FMMIwiTHQEBUwQTCSMnAQFTBEMEAQljBEMpAQETBXMbAQJDDQECYw0jCHMd
+AQEzFXMIcx1jBQEGEwQBCCMsYwVzGwECYzEBAkMGIyjEAQEjCquDC0MiMwRTHQEBIwmDCIMdAQEj
+CiMnIwQjEBMlUwcTJVMEUxUzDkOBCFNIIwljTwEBQwUBAVMIIwpTBhMIQwkBBVMEMw1TBUMbYwlT
+HlMLAQIjJUMEEwUBAUMaAQEzBFMEUwgzBkMMcwlzDGNgYwtThysTCwEHMxxTLFNcMwYTBkMqYwRj
+JUMEQwQjCWMSIwUTBUM1gwQzJEMEUxITDIMEM4FsgwsBDWMJgyxDaIML4gEGQwgjBoMGIwQzBhMk
+gwu+gwpjbYMLAQJjCQECQwYjCQEBUw+DWSMGEwtjJxMEM2pTCCMJQxODCwECQwgjBIMHIwhjDGMG
+AQJzBmMGIwdTCpMGMwpjB4MTgwsBAlMGcwQjHQECQwQBA1MMIwhzK1OBBAEDQ4E7UwRTB3MJIzYz
+CjN3MwUTDoMMUw1DSEMRUwtTBFMEgwsTCyMKEx9DKwEBUxcBAWM9Iw0jIaUjC2MNMwxjMhMEcwu9
+Yw9jGgEFMwQBASMQkw4zNxMHM4EHUwZTIVMRM0pTCmMIEwRTL0MRUw9zBDMLM2VjUiMEM4IaIwlz
+K1MkMwpDBkMTMwUzB2MEUxITBTOBq2MAkmGRICyvPYMnizOEFiQhICCMYA6HDr9DSdKdMo4XNc0J
+r3S3I68FlX+xkEeDQjq5r3G5uasAoHKBYap2sYcRoSKBRo59pmsKK0m3RibGX5qan1wy5WyEXqkW
+i0qDdIRuKhkRgRuCJVKBN8cZnm+nPYV9g0qCDqZHgW5LyA2BBGuBGt9nh3MIrSfJEhuvPQ8bNYNq
+MWuDNIdjjQxJf4QYGK8eLJo9K6IWEL9dhBlL2zfSICqWSNsxtIJ46Ta0dFgKRBcHnzW0mhpEZbR6
+M4FpEummAJEAgliGYY8qgXXRD40xtJAJ8QrZgmQeu08IHcgiDiUbnlsStCr1iiqTVjqpIYlAgQm4
+QIFBZJ1YsSlYSI9gVhpiTOI0qSWoWjivb5sHjUueVSsX7XmKAKsignuXR3KCW5JxiJcbUxa5AUpQ
+N64nZKZngSSBECGGd7k7jTdeoBl1cYF0JmnfSViqNTWCT6ATyU8ysFQZo3QPqkEe
#2 2018-12-18T15:50:51Z pgess
1sPEAAABgeMqAFCB4lUAASggLXObCwEBE4EIIx9DFRMsY4GNb0MjQyITB1MEY4FhcyNTBBMFIzdD
tF4Amw6BCYEpmU2BCIGXHoGOHowjjkUmXYgkgatoghiCZA==
-
#1 2018-12-18T15:11:23Z pgess
1sPEAAABgeJVADCB4lkAABkQc+xgE5kzQ5JQgwhTshozg19DkFhTCmODEwDsX5kyEZJXshmDXoYP
ilQ=
-?>
+?>
\ No newline at end of file
diff --git a/documentation/Transcend/transcend.xml b/documentation/Transcend/transcend.xml
index 9ca00af..26d6895 100644
--- a/documentation/Transcend/transcend.xml
+++ b/documentation/Transcend/transcend.xml
@@ -1,443 +1,578 @@
<?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 2ajela3ur5s 7q?>
<title><?xxe-sn 2ajela3ur5s 7r?>Transcend</title>
- <para><?xxe-sn 2ajela3ur5s 7s?>Transcend is a compilation phase and process
- of reasoning about program in order to influence compilation.</para>
+ <para><?xxe-sn 2ajela3ur5s 7s?>Transcend is a compilation phase and a
+ process of reasoning about a program in order to influence final compilation
+ results.</para>
+
+ <para><?xxe-sn 2ajela3ur5s 7t?>First, the compiler extracts
+ <emphasis><?xxe-sn 2ajela3ur5s 7u?>annotations</emphasis> from a source code
+ as well as other <emphasis><?xxe-sn 2ezs03nkiyo 4?>logic facts</emphasis>
+ from a number of different sources. Second, logic facts are coupled with
+ <emphasis><?xxe-sn 2ezs03nkiyo 5?>logic rules</emphasis>, that describe how
+ to process input data, to form a complete <emphasis><?xxe-sn 2ezs03nkiyo 6?>logic
+ program</emphasis>. Finally, a solver processes the logic program and
+ produces decisions that affect and control compilation in a number of ways.
+ Crucial difference of annotations from language keywords is that they do not
+ have any predefined meaning and semantic; only custom developer provided
+ rules make them matter.</para>
+
+ <para><?xxe-sn 2ezs03nkiyo 7?><phrase condition="clasp"><?xxe-sn 2ezs03nkiyo 8?>Currently,
+ an external logic solver Clasp is used to perform Transcend tasks. Hence,
+ logic rules are written(and annotations are converted to) in the ASP format:
+ one of standard first order logic notations.</phrase></para>
- <para><?xxe-sn 2ajela3ur5s 7t?>First, compiler extracts <emphasis><?xxe-sn 2ajela3ur5s 7u?>annotations</emphasis>
- from source code and other facts from number of sources to form a complete
- <emphasis><?xxe-sn 2ajela3ur5s 7v?>logic program</emphasis>. Then, solver
- processes logic program and outputs decisions that affect and control
- compilation process in a number of ways.</para>
+ <section>
+ <?xxe-sn 2f0cduzin5j -wunr7fl0rw85?>
+
+ <title><?xxe-sn 2f0cduzin5j -wunr7fl0rw84?>Reasoning Solutions</title>
+
+ <para><?xxe-sn 2f0cduzin5j -wunr7fl0rw83?>Transcend prepares solutions to
+ verify, control and guide compilation process. For each uncertain
+ situation the compiler consults reasoning solutions to know how to
+ proceed. Thus, many compilation aspects are delegated to Transcend and are
+ ultimately exposed to a software developer. Transcend solution are used in
+ a number of ways as follows:</para>
+
+ <itemizedlist>
+ <?xxe-sn 2f0cduzin5j -wunr7fl0rw82?>
+
+ <listitem>
+ <?xxe-sn 2f0cduzin5j -wunr7fl0rw81?>
+
+ <para><?xxe-sn 2f0cduzin5j -wunr7fl0rw80?><link
+ xlink:href="/d/concepts/interpretation/#transcend-and-interpreta"><?xxe-sn 2fadpf0i3zr -wunr7fl0rw8v?>Direct
+ connection</link> via the <code><?xxe-sn 2fadpf0i3zr -wunr7fl0rw8u?>query</code>
+ built-in function. A program can request and explicitly process
+ received data from Transcend as it sees fit.</para>
+ </listitem>
+
+ <listitem>
+ <?xxe-sn 2f0cduzin5j -wunr7fl0rw7y?>
+
+ <para><?xxe-sn 2f0cduzin5j -wunr7fl0rw7x?><link
+ xlink:href="/d/concepts/polymorphism/"><?xxe-sn 2f0cduzin5j -wunr7fl0rw7w?>Function
+ level polymorphism</link>. This is the principal way for Transcend to
+ interfere in compilation. Polymorphism is based on a possibility for a
+ function to have several specializations. Each time the function is
+ invoked in a client code, Transcend decides which exactly
+ specialization to call. This gives a deep control over final program
+ behaviour.</para>
+ </listitem>
+
+ <listitem>
+ <?xxe-sn 2f0cduzin5j -wunr7fl0rw7v?>
+
+ <para><?xxe-sn 2f0cduzin5j -wunr7fl0rw7u?><link
+ xlink:href="/d/syntax/modules/"><?xxe-sn 2f0cduzin5j -wunr7fl0rw7t?>Module
+ level polymorphism</link>. Transcend decides which modules to choose
+ that satisfy a client code's requirements.</para>
+ </listitem>
+
+ <listitem>
+ <?xxe-sn 2f0cduzin5j -wunr7fl0rw7s?>
+
+ <para><?xxe-sn 2f0cduzin5j -wunr7fl0rw7r?>The compiler allows
+ Transcend to add hidden parameters every time specific functions are
+ invoked. This is implemented to support the <link
+ xlink:href="/d/concepts/context/"><?xxe-sn 2f0cduzin5j -wunr7fl0rw7q?>Context</link>
+ concept.</para>
+ </listitem>
+
+ <listitem>
+ <?xxe-sn 2f0cduzin5j -wunr7fl0rw7p?>
+
+ <para><?xxe-sn 2f0cduzin5j -wunr7fl0rw7o?>Diagnostics. Transcend is
+ able to validate different aspects of a program and print diagnostic
+ messages to signal found inconsistencies.</para>
+ </listitem>
+ </itemizedlist>
+
+ <para><?xxe-sn 2f0cduzin5j -wunr7fl0rw7n?>As an example, suppose we want
+ to control functions visibility and want to separate the <code><?xxe-sn 2f60onvmups 2?>visibility(private)</code>
+ functions from the rest of a program:</para>
+
+ <programlisting xml:id="Diagnostics1"><?xxe-sn 2f0cduzin5j -wunr7fl0rw7m?>name="tests/transcend.cpp: Transcend.Doc_Diagnostics1"
+sum = function(a:: int, b:: int) :: int; visibility(private)
+{
+ a + b
+}
+
+calculate = function(a:: int, b:: int):: int; visibility(pub_interface)
+{
+ sum(a, b)
+}
+
+test = function(a:: int, b:: int) :: int; entry
+{
+ sum(a, b) // we may not invoke this directly
+}</programlisting>
+
+ <para><?xxe-sn 2f0cduzin5j -wunr7fl0rw7l?>Transcend converts the code
+ above to logic facts as follows(the relevant part is shown):</para>
+
+ <programlisting><?xxe-sn 2f0cduzin5j -wunr7fl0rw7j?>function(sum)
+function(calculate)
+function(test)
+
+bind_func(sum,visibility(private))
+bind_func(calculate,visibility(pub_interface))
+bind_func(test,entry)
+
+cfa_parent(0,function(sum))
+cfa_parent(1,function(calculate))
+cfa_parent(2,function(test))
+
+cfa_call(1,sum)
+cfa_call(2,calculate)</programlisting>
+
+ <para><?xxe-sn 2f0cduzin5j -wunr7fl0rw7i?>At this point all the
+ annotations are completely unknown to the compiler. Next, we need to write
+ rules to check that the <code><?xxe-sn 2f0cduzin5j -wunr7fl0rw7h?>visibility(private)</code>
+ functions are called either by another <code><?xxe-sn 2f0cduzin5j -wunr7fl0rw7g?>visibility(private)</code>
+ ones or by the <code><?xxe-sn 2f0cduzin5j -wunr7fl0rw7f?>visibility(pub_interface)</code>
+ functions which are intended to act as a contact point, the only allowed
+ gate between the private part and the rest of a program:</para>
+
+ <programlisting xml:id="Diagnostics1_Rules"><?xxe-sn 2f60onvmups 1?>name="tests/transcend.cpp: Transcend.Doc_Diagnostics1"
+% Define which functiones are allowed to invoke private ones
+allowed(
+ visibility(private);
+ visibility(pub_interface)
+).
+
+% Check every invocation for violations:
+warning("Visibility violation", FuncFrom, FuncTo):-
+ cfa_call(ScopeFrom, FuncTo);
+ bind_func(FuncTo, visibility(private));
+ scope_func_dict(ScopeFrom, FuncFrom);
+ { bind_func(FuncFrom, Visibility): allowed(Visibility) } 0.</programlisting>
+
+ <para><?xxe-sn 2f60onvmups 3?>Given the rules Transcend goes through all
+ the invocations to check are there any possible visibility violations. For
+ this example Transcend generates a diagnostic message: <code><?xxe-sn 2f60onvmups 4?>warning("Visibility violation",test,sum)</code>.</para>
+
+ <para><?xxe-sn 2f60onvmups 5?>This way it is possible to validate and
+ guide compilation process by analysing program properties employing
+ provided processing rules.</para>
+ </section>
<section>
<?xxe-sn 2ajela3ur5s 7w?>
<title><?xxe-sn 2ajela3ur5s 7x?>Annotations' Syntax</title>
<para><?xxe-sn 2ajela3ur5s 7y?>Xreate's annotations comprise optional
- supplementary information that is processed by compiler along with a
- source code proper and able to affect compilation process. Annotations
- have form of expressions that consist of following elements:</para>
+ supplementary information to be processed by the compiler along with a
+ source code proper with an end goal being to affect a compilation process.
+ Annotations are special expressions in the following form:</para>
<informaltable>
<?xxe-sn 2ajela3ur5s 7z?>
<tgroup cols="2">
<?xxe-sn 2ajela3ur5s 80?>
<colspec colwidth="183*"><?xxe-sn 2ajela3ur5s 81?></colspec>
<colspec colwidth="817*"><?xxe-sn 2ajela3ur5s 82?></colspec>
<tbody>
<?xxe-sn 2ajela3ur5s 83?>
<row>
<?xxe-sn 2ajela3ur5s 84?>
<entry><?xxe-sn 2ajela3ur5s 85?>Literals</entry>
<entry><?xxe-sn 2ajela3ur5s 86?>Strings, numbers. Example:
<code><?xxe-sn 2ajela3ur5s 87?>5, "success"</code></entry>
</row>
<row>
<?xxe-sn 2ajela3ur5s 88?>
<entry><?xxe-sn 2ajela3ur5s 89?>Predicates</entry>
<entry><?xxe-sn 2ajela3ur5s 8a?>Predicates have zero or more
arguments. Example: <code><?xxe-sn 2ajela3ur5s 8b?>final, status(broken), version("12.0.3", unstable)</code></entry>
</row>
<row>
<?xxe-sn 2ajela3ur5s 8c?>
<entry><?xxe-sn 2ajela3ur5s 8d?>Negation</entry>
<entry><?xxe-sn 2ajela3ur5s 8e?>Example: <code><?xxe-sn 2ajela3ur5s 8f?>-i12n, -access(allowed)</code></entry>
</row>
</tbody>
</tgroup>
</informaltable>
<para><?xxe-sn 2ajela3ur5s 8g?>Various Xreate's entities can be annotated.
At the time following entities are supported:</para>
<informaltable>
<?xxe-sn 2ajela3ur5s 8h?>
<tgroup cols="4">
<?xxe-sn 2ajela3ur5s 8i?>
<tbody>
<?xxe-sn 2ajela3ur5s 8j?>
<row>
<?xxe-sn 2ajela3ur5s 8k?>
<entry><?xxe-sn 2ajela3ur5s 8l?><link
- xlink:href="#expression-and-identifiers"><?xxe-sn 2ajela3ur5s 8m?>Expressions
- and Identifiers</link></entry>
+ xlink:href="#expressions"><?xxe-sn 2ajela3ur5s 8m?>Expressions</link></entry>
<entry><?xxe-sn 2ajela3ur5s 8n?><link
xlink:href="#code-blocks-and-context"><?xxe-sn 2ajela3ur5s 8o?>Code
blocks and context</link></entry>
<entry><?xxe-sn 2ajela3ur5s 8p?><link
xlink:href="/d/syntax/#functions"><?xxe-sn 2ajela3ur5s 8q?>Functions</link>
and <link xlink:href="/d/syntax/#function-guards"><?xxe-sn 2ajela3ur5s 8r?>Function
Guards</link></entry>
<entry><?xxe-sn 2ajela3ur5s 8s?><link
xlink:href="/d/syntax/modules/#module-annotations"><?xxe-sn 2ajela3ur5s 8t?>Modules</link></entry>
</row>
</tbody>
</tgroup>
</informaltable>
<section>
<?xxe-sn 2ajela3ur5s 8u?>
- <title><?xxe-sn 2ajela3ur5s 8v?>Expression and Identifiers</title>
+ <title><?xxe-sn 2ajela3ur5s 8v?>Expressions</title>
<synopsis><?xxe-sn 2ajela3ur5s 8w?>SYNTAX:
//expression// **::** //type//**;** //annotation-list//.</synopsis>
<itemizedlist>
<?xxe-sn 2ajela3ur5s 8x?>
<listitem>
<?xxe-sn 2ajela3ur5s 8y?>
<para><?xxe-sn 2ajela3ur5s 8z?><emphasis><?xxe-sn 2ajela3ur5s 90?>type</emphasis>
- expression's type</para>
+ The expression's type</para>
</listitem>
<listitem>
<?xxe-sn 2ajela3ur5s 91?>
<para><?xxe-sn 2ajela3ur5s 92?><emphasis><?xxe-sn 2ajela3ur5s 93?>annotation-list</emphasis>
- one or more annotation attached to the expression. Annotations are
- delimited by semicolon</para>
+ one or more annotations attached to the expression. Annotations are
+ delimited by semicolon.</para>
</listitem>
</itemizedlist>
- <para><?xxe-sn 2ajela3ur5s 94?>Example:</para>
+ <para><?xxe-sn 2ajela3ur5s 94?>An example:</para>
<programlisting xml:id="Expressions1"><?xxe-sn 2ajela3ur5s 95?>name="tests/transcend.cpp: Transcend.Doc_Expressions1"
-test = function:: int
+test = function:: int; entry
{
- x = 5:: int; arithmetic(fast). //annotation applied to an identifier
- y = (x - 8:: int; arithm_optimization(off)) * 2:: float. //annotation applied to a nested expression
+ x = 5:: int; arithmetic(fast). //an annotation applied to an identifier
+ y = ((x - 8):: int; arithm_optimization(off)) * 2:: int. //an annotation applied to a nested expression
x+y
}</programlisting>
+ <para><?xxe-sn 2ezs03nkiyo 9?>For readability's sake compound
+ statements(e.g. <link xlink:href="/d/syntax/#loops"><?xxe-sn 2ezs03nkiyo a?>loops</link>)
+ have slightly different syntax for annotations. See particular
+ statement's syntax for details.</para>
+
<note>
- <?xxe-sn 2ajela3ur5s 96?>
+ <?xxe-sn 2ezs03nkiyo 2?>
- <para><?xxe-sn 2ajela3ur5s 97?>For readability sake compound
- statements(e.g. <link xlink:href="/d/syntax/#loop-statements"><?xxe-sn 2ajela3ur5s 98?>loops</link>)
- have different syntax for an annotations. See particular statement's
- <link xlink:href="/d/syntax/"><?xxe-sn 2ajela3ur5s 99?>syntax</link>
- for details</para>
+ <para><?xxe-sn 2ezs03nkiyo 3?>A current limitation is that
+ expression's annotations are always preceded by a type, hence to
+ annotate nested expressions it is necessary to duplicate the
+ expression's type.</para>
</note>
</section>
<section>
<?xxe-sn 2ajela3ur5s 9a?>
<title><?xxe-sn 2ajela3ur5s 9b?>Code Blocks and Context</title>
<synopsis><?xxe-sn 2ajela3ur5s 9c?>SYNTAX:
**context** :: //annotations-list//.</synopsis>
<itemizedlist>
<?xxe-sn 2ajela3ur5s 9d?>
<listitem>
<?xxe-sn 2ajela3ur5s 9e?>
<para><?xxe-sn 2ajela3ur5s 9f?><emphasis><?xxe-sn 2ajela3ur5s 9g?>annotations-list</emphasis>
- List of annotation delimited by semicolon</para>
+ A list of annotations delimited by semicolon</para>
</listitem>
</itemizedlist>
- <para><?xxe-sn 2ajela3ur5s 9h?>Code block annotations called
- <emphasis><?xxe-sn 2ajela3ur5s 9i?>context</emphasis>. Keyword
- <code><?xxe-sn 2ajela3ur5s 9j?>context</code> used to declare annotation
- within enclosing code block.</para>
+ <para><?xxe-sn 2ajela3ur5s 9h?>Code block annotations are called
+ <emphasis><?xxe-sn 2ajela3ur5s 9i?>context</emphasis>. The keyword
+ <code><?xxe-sn 2ajela3ur5s 9j?>context</code> is reserved to declare
+ annotations within an enclosing code block.</para>
- <para><?xxe-sn 2ajela3ur5s 9k?>Example:</para>
+ <para><?xxe-sn 2ajela3ur5s 9k?>An example:</para>
<programlisting xml:id="Codeblocks1"><?xxe-sn 2ajela3ur5s 9l?>name="tests/transcend.cpp: Transcend.Doc_Codeblocks1"
test = function:: int
{
context:: arithm_optimization(off).
x = 10 :: int.
2 * x - 16
}</programlisting>
</section>
<section>
<?xxe-sn 2ajela3ur5s 9m?>
<title><?xxe-sn 2ajela3ur5s 9n?>Special Annotations</title>
- <para><?xxe-sn 2ajela3ur5s 9o?>There are some annotations in Xreate that
- have special meaning</para>
+ <para><?xxe-sn 2ajela3ur5s 9o?>Despite of "annotations do not have any
+ predefined meaning" being a rule of thumb, still there are deviations in
+ Xreate; few annotation that have special meaning are:</para>
<informaltable>
<?xxe-sn 2ajela3ur5s 9p?>
<tgroup cols="2">
<?xxe-sn 2ajela3ur5s 9q?>
- <colspec colwidth="201*"><?xxe-sn 2ajela3ur5s 9r?></colspec>
+ <colspec colwidth="91*"><?xxe-sn 2ezs03nkiyo b?></colspec>
- <colspec colwidth="799*"><?xxe-sn 2ajela3ur5s 9s?></colspec>
+ <colspec colwidth="909*"><?xxe-sn 2ezs03nkiyo c?></colspec>
<tbody>
<?xxe-sn 2ajela3ur5s 9t?>
<row>
<?xxe-sn 2ajela3ur5s 9u?>
<entry><?xxe-sn 2ajela3ur5s 9v?><code><?xxe-sn 2ajela3ur5s 9w?>entry</code></entry>
- <entry><?xxe-sn 2ajela3ur5s 9x?>Specifies entry point of a
+ <entry><?xxe-sn 2ajela3ur5s 9x?>Specifies the entry point of a
program. See <link xlink:href="/d/syntax/#functions"><?xxe-sn 2ajela3ur5s 9y?>Function
- Syntax</link></entry>
+ Syntax</link>.</entry>
</row>
<row>
<?xxe-sn 2ajela3ur5s 9z?>
<entry><?xxe-sn 2ajela3ur5s a0?><code><?xxe-sn 2ajela3ur5s a1?>final</code></entry>
- <entry><?xxe-sn 2ajela3ur5s a2?>Specifies fixed point of loop
- statements. See <link
- xlink:href="/d/syntax/#loop-statement"><?xxe-sn 2ajela3ur5s a3?>Loop
- Statement</link></entry>
+ <entry><?xxe-sn 2ajela3ur5s a2?>Specifies the fixed point of
+ loops. See <link xlink:href="/d/syntax/#loops"><?xxe-sn 2ajela3ur5s a3?>Loops</link>.</entry>
</row>
</tbody>
</tgroup>
</informaltable>
</section>
</section>
<section>
<?xxe-sn 2ajela3ur5s a4?>
<title><?xxe-sn 2ajela3ur5s a5?>Annotations and Reasoning</title>
- <para><?xxe-sn 2ajela3ur5s a6?>Annotations is a mechanism to express an
- additional pieces of information and can occur in source code or
+ <para><?xxe-sn 2ajela3ur5s a6?>Annotations is a mechanism to express
+ additional pieces of information and can occur in a source code or
accompanying files. They are of declarative nature in a sense that they
express specific properties of and relations between different entities,
- such as: identifiers, statements, code blocks, functions, modules or even
- a whole program.</para>
-
- <para><?xxe-sn 2ajela3ur5s a7?>Annotations are <emphasis><?xxe-sn 2ajela3ur5s a8?>facts</emphasis>
- about source code provided by developer in explicit form. Beside
- annotations there are other sources of information, e.g. implicit facts
- that are automatically inferred by various analysis phases to express
- useful insights regarding analysed code. Such pieces aren't exposed
- directly to a developer but accessed and used internally at reasoning
- phase along with annotations. All types of input are summed up
- below:</para>
+ such as: identifiers and expressions, statements, code blocks, functions,
+ modules or even a whole program.</para>
+
+ <para><?xxe-sn 2ajela3ur5s a7?>Annotations are <emphasis><?xxe-sn 2ezs03nkiyo d?>explicit
+ facts </emphasis>about a source code provided by a code writer in an
+ explicit form. Beside annotations, there are other sources of information,
+ in other words, <emphasis><?xxe-sn 2ezs03nkiyo f?>implicit
+ facts</emphasis> that are automatically inferred by various analysis
+ phases to express useful insights regarding an analysed code. Such pieces
+ aren't exposed directly to a developer but accessed and used internally at
+ the reasoning phase along with annotations. All types of input are summed
+ up below:</para>
<informaltable>
<?xxe-sn 2ajela3ur5s a9?>
<tgroup cols="2">
<?xxe-sn 2ajela3ur5s aa?>
<colspec colwidth="287*"><?xxe-sn 2ajela3ur5s ab?></colspec>
<colspec colwidth="713*"><?xxe-sn 2ajela3ur5s ac?></colspec>
<tbody>
<?xxe-sn 2ajela3ur5s ad?>
<row>
<?xxe-sn 2ajela3ur5s ae?>
- <entry><?xxe-sn 2ajela3ur5s af?>Explicit annotations in source
- files</entry>
+ <entry><?xxe-sn 2ajela3ur5s af?>Explicit annotations</entry>
- <entry><?xxe-sn 2ajela3ur5s ag?>Annotations provided by developer
- in order to explicitly affect compilation</entry>
+ <entry><?xxe-sn 2ajela3ur5s ag?>Annotations provided by a code
+ writer in order to explicitly affect compilation.</entry>
</row>
<row>
<?xxe-sn 2ajela3ur5s ah?>
- <entry><?xxe-sn 2ajela3ur5s ai?>Code Analysis</entry>
+ <entry><?xxe-sn 2ajela3ur5s ai?>Code analysis</entry>
- <entry><?xxe-sn 2ajela3ur5s aj?>Different code analyses during
- compilation provide information implicitly inferred from source
- code</entry>
+ <entry><?xxe-sn 2ajela3ur5s aj?>Different code analyses provide
+ information implicitly inferred from a source code.</entry>
</row>
<row>
<?xxe-sn 2ajela3ur5s ak?>
<entry><?xxe-sn 2ajela3ur5s al?>Supervision</entry>
- <entry><?xxe-sn 2ajela3ur5s am?>External facts that reflect
- requirements, describe hardware and/or environment where
- compilation takes place or program is supposed to work. There are
- many supervision layers possible, from custom compiler's mode, to
- OS- or computer- or even network-wide level. On other words,
- supervision covers local or client supplied annotations</entry>
+ <entry><?xxe-sn 2ajela3ur5s am?>External facts that reflect a
+ hardware and/or an environment where compilation takes place or
+ where a program is supposed to work. There are many supervision
+ layers possible, from custom compiler's mode, to OS- or computer-
+ or even network-wide levels. In other words, supervision covers
+ local or client supplied annotations, e.g. prohibits web cam
+ usage, or external network resources access.</entry>
</row>
<row>
<?xxe-sn 2ajela3ur5s an?>
<entry><?xxe-sn 2ajela3ur5s ao?>Audit</entry>
<entry><?xxe-sn 2ajela3ur5s ap?>Third party supplied external
- information that reflect additional software properties, e.g.
- results of security audit</entry>
+ information that reflects additional software properties, e.g.
+ results of security audit.</entry>
</row>
<row>
<?xxe-sn 2ajela3ur5s aq?>
<entry><?xxe-sn 2ajela3ur5s ar?>Reasoning rules</entry>
<entry><?xxe-sn 2ajela3ur5s as?>Reasoning infers additional facts
- from pool of previously gathered information. It is done by using
- <emphasis><?xxe-sn 2ajela3ur5s at?>resoning rules</emphasis> that
- govern reasoning process</entry>
+ from a pool of previously gathered information. It is done by
+ using <emphasis><?xxe-sn 2ajela3ur5s at?>resoning rules</emphasis>
+ that govern reasoning process.</entry>
</row>
</tbody>
</tgroup>
</informaltable>
</section>
<section>
<?xxe-sn 2ajela3ur5s au?>
<title><?xxe-sn 2ajela3ur5s av?>Why Annotations Matter</title>
<para><?xxe-sn 2ajela3ur5s aw?>This section goes through differences that
annotations have over traditional statements.</para>
<section>
<?xxe-sn 2ajela3ur5s ax?>
<title><?xxe-sn 2ajela3ur5s ay?>Extensible</title>
<para><?xxe-sn 2ajela3ur5s az?>Annotations are not a part of language
- syntax and there is no predefined set of allowed annotations. Developer
- is free to define and use custom annotations to express desired
- properties without prior changes to compiler.</para>
-
- <note>
- <?xxe-sn 2ajela3ur5s b0?>
-
- <para><?xxe-sn 2ajela3ur5s b1?>Yet there are several reserved
- annotations that have specific meaning in Xreate. See <link
- xlink:href="#special-annotations"><?xxe-sn 2ajela3ur5s b2?>special
- annotations</link> for details.</para>
- </note>
+ syntax and there is no predefined set of allowed annotations. A
+ developer is free to define and use custom annotations to express
+ desired properties without prior changes to the compiler.</para>
</section>
<section>
<?xxe-sn 2ajela3ur5s b3?>
<title><?xxe-sn 2ajela3ur5s b4?>Indicative Nature</title>
<para><?xxe-sn 2ajela3ur5s b5?>Unlike language statements that have well
defined compilation output, annotation do not. They are rather of
suggestive nature and actual impact depends on many factors. Annotations
- comprise an input for a reasoning procedure that ultimately determines
- how exactly influence compilation.</para>
+ comprise only an input for a reasoning procedure that ultimately decides
+ how exactly to influence compilation.</para>
</section>
<section>
<?xxe-sn 2ajela3ur5s b6?>
<title><?xxe-sn 2ajela3ur5s b7?>Cooperation</title>
<para><?xxe-sn 2ajela3ur5s b8?>Annotations are gathered from different
- sources and this enables annotations to complement themselves. Compiler
- blends in annotations originated from various sources seamlessly and
- this allows to improve decisions quality.</para>
+ sources enabling annotations to complement each other. The compiler
+ blends in annotations originated from various sources seamlessly to
+ improve decisions quality.</para>
</section>
<section>
<?xxe-sn 2ajela3ur5s b9?>
<title><?xxe-sn 2ajela3ur5s ba?>External Sources and
Adaptability</title>
- <para><?xxe-sn 2ajela3ur5s bb?>Annotations able to express not only
- properties of program itself but also properties of local
- environment(OS, computer, local network) where program is supposed to
- run. Thus compiler operates information inaccessible during software
- development and can't be reflected in the code otherwise. Compilation
- can be adjusted to a particular environment and functioning mode.</para>
+ <para><?xxe-sn 2ajela3ur5s bb?>Annotations can be used not only to
+ express properties of a program itself but also properties of a local
+ environment(OS, computer, local network) where the program is supposed
+ to run. Thus, in fact, the compiler operates by information that is
+ usually inaccessible during software development and can't be reflected
+ in a program code otherwise. In essence, it is <emphasis><?xxe-sn 2ezs03nkiyo g?>postcompilation</emphasis>
+ - a process of adjustments to a particular environment and functioning
+ mode.</para>
</section>
<section>
<?xxe-sn 2ajela3ur5s bc?>
<title><?xxe-sn 2ajela3ur5s bd?>Feedback</title>
<para><?xxe-sn 2ajela3ur5s be?>Traditionally software has a rigid
- strictly defined hierarchical structure and interaction between
- components. More precisely, let's look at client-service code model.
- Service is done independently in order to work well with as wide as
- possible set of different clients. Thus service is unaware of exact
- characteristics of particular client code it works with. All burden of
- complying with interaction specification lies on a client.</para>
-
- <para><?xxe-sn 2ajela3ur5s bf?>However client may use only small subset
- of service functionality or use it in specific and predictable order.
- Generally speaking, service by having additional information on
- particular client able to serve requests more efficiently in many
- cases.</para>
+ strictly defined hierarchical structure of interaction between
+ components. For example, let us focus on a client-service model. A
+ service works the same regardless of a particular client in order to be
+ compatible with as wide set of different clients as possible. However
+ clients may use only small subset of service functionality or use it in
+ a specific and predictable order. Generally speaking, the service in
+ case of having additional information about a particular client is able
+ to serve requests more efficiently in many situations.</para>
<para><?xxe-sn 2ajela3ur5s bg?>It can be conceptualized as a
<emphasis><?xxe-sn 2ajela3ur5s bh?>feedback</emphasis> from a client.
- Annotations is good candidate to express feedback to improve interaction
- quality.</para>
+ Annotations is a good candidate to express feedback to improve
+ interaction quality.</para>
</section>
<section>
<?xxe-sn 2ajela3ur5s bi?>
<title><?xxe-sn 2ajela3ur5s bj?>Resiliency</title>
- <para><?xxe-sn 2ajela3ur5s bk?>As code grows and goes through multiple
- reworks and rewrites many initial assumptions about the code and
- relation between different parts change accordingly. Some implementation
- details and approaches became outdated and code quality
- deteriorates.</para>
-
- <para><?xxe-sn 2ajela3ur5s bl?>DIfferent picture in case if code uses
- annotations to express important properties. Any changes in underlying
- code lead to a restart of reasoning procedure which adjust
- implementation decisions to be still optimal in changed
- environment.</para>
+ <para><?xxe-sn 2ajela3ur5s bk?>As a program grows and goes through
+ multiple reworks and rewrites many initial assumptions about the code
+ and relation between different parts invalidated. Some implementation
+ details and approaches became outdated and code quality deteriorates. A
+ dIfferent picture is if the code uses annotations to express important
+ properties. Any changes in an underlying code lead to a restarting of a
+ reasoning procedure which adjust implementation decisions to be as
+ optimal in a changed environment as before.</para>
</section>
</section>
</chapter>
diff --git a/documentation/index.xml b/documentation/index.xml
index 1388e4b..7e573d3 100644
--- a/documentation/index.xml
+++ b/documentation/index.xml
@@ -1,249 +1,338 @@
<?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" is all about a developer
oriented side focused on an ability to easily write, read, 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.</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?>dataA = readFromFile("/some/file"):: string. //here a file is accessed for the very first time
dataB = readFromFile("/some/file"):: string. //this is the last time the file is accessed</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 a file, in other
words, infers access order. As a result, using the data it is possible to
automatically initialize / destruct related resources.</para>
<para><?xxe-sn 2dc0uidlnnk 8?><link
xlink:href="/d/virtualization/"><?xxe-sn 2dc0uidlnnk 4?>Virtualization</link>
reasoning enables 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:: float, b:: float):: float
{
a / b
}
}
guard:: iAmVerySafe
{
div = function(a:: float, b:: float):: float
{
if ( b == (0::float)):: float {0::float} else {a / b}
}
}
test = function:: float; 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 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);
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 a decision to guide 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: Intentions</title>
+
+ <para><?xxe-sn 2fchdmt7vgg 3?>Suppose we write a program to prepare 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 intention that all the 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 the 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
+ memory overhead and delays response latency 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>
</chapter>
diff --git a/documentation/manual.json b/documentation/manual.json
index 8c9f315..1ca4a56 100644
--- a/documentation/manual.json
+++ b/documentation/manual.json
@@ -1,36 +1,36 @@
{
"book": "Xreate Manual",
"pages":
[
{"title": "Basics", "pages": [
{"title": "Introduction", "slug": "/", "filename": "index.xml.remarkup", "subtitle": "General information about Xreate"},
{"title": "Build and Run", "slug": "build/", "filename": "build.xml.remarkup", "subtitle": "Getting started"},
{"title": "Syntax", "slug": "syntax/", "filename": "syntax.xml.remarkup", "subtitle": "Xreate syntax in detail"},
{"title": "Modules", "slug": "syntax/modules/", "filename": "modules.xml.remarkup", "subtitle": "How to reuse and combine existing code in Xreate"}
]},
{"title": "Transcend", "pages": [
{"title": "Overview", "slug": "transcend/", "filename": "transcend.xml.remarkup", "subtitle": "Declarative level of Xreate"},
{"title": "Late Transcend", "slug": "transcend/late-transcend/", "filename": "latetranscend.xml.remarkup", "subtitle": "Reasoning is able to work at runtime"}
]},
{"title": "Concepts", "pages": [
{"title": "Polymorphism", "slug": "concepts/polymorphism/", "filename": "polymorphism.xml.remarkup", "subtitle": "Let logic inference choose how program would behave at runtime"},
{"title": "Context", "slug": "concepts/context/", "filename": "context.xml.remarkup", "subtitle": "How to capture and use information about control flow and hierachy within program"},
- {"title": "Interpretation", "slug": "concepts/interpretation/", "filename": "interpretation.xml.remarkup", "subtitle": "Compile time computations and more"}
+ {"title": "Interpretation", "slug": "concepts/interpretation/", "filename": "interpretation.xml.remarkup", "subtitle": "Compile time computations"}
]},
{"title": "Extensions", "pages": [
{"title": "Containers", "slug": "concepts/containers/", "filename": "containers.xml.remarkup", "subtitle": "Automatic inference about the most apporpriate container implementation"},
{"title": "Communication", "slug": "communication/", "filename": "communication.xml.remarkup", "subtitle": "Safe usage of mutable as well as global variables"},
{"title": "Exploitation", "slug": "exploitation/", "filename": "exploitation.xml.remarkup", "subtitle": "Shared usage of the external resources - initialization and finalization"},
{"title": "Virtualization", "slug": "virtualization/", "filename": "virtualization.xml.remarkup", "subtitle": "Controls access to the external resources or different program's components"}
]},
{"title": "Transcend APIs", "pages": [
{"title": "AST API", "slug": "transcend/ast-api/", "filename": "ast-api.xml.remarkup", "subtitle": ""},
{"title": "Latex API", "slug": "transcend/latex-api/", "filename": "latex-api.xml.remarkup", "subtitle": ""},
{"title": "Modules API", "slug": "transcend/modules-api/", "filename": "modules-api.xml.remarkup", "subtitle": ""}
]}
]
}
diff --git a/grammar/xreate.ATG b/grammar/xreate.ATG
index c8660e7..abdb3f0 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}.
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
+{( //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>
+// | 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 .
+// 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>
-).
+// 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))); .)
- .
+// 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; .)
-.
+// 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/scripts/execution-order/execorder.lp b/scripts/execution-order/execorder.lp
new file mode 100644
index 0000000..7c3fbad
--- /dev/null
+++ b/scripts/execution-order/execorder.lp
@@ -0,0 +1,33 @@
+% INPUT:
+% - POS expected execution order
+% eov_expect(Resource, ScopeBefore, ScopeAfter).
+%
+% OUTPUT:
+% - does actual execution order match expected one
+
+%cfa_payload(X, Node, Path).
+
+% ---------------------------------
+% Find root of the Expectation POS:
+
+cfa_payload(eov_payload(Resource, Pprev), scope(Sprev), ()):-
+ eov_expect(Resource, Pprev, _);
+ bind(Symprev, eov_checkpoint(Resource, Pprev));
+ Symprev = s(_, _, Sprev).
+
+eov_results(Resource, fail):-
+ eov_expect(Resource, Pprev, Pnext);
+ not cfa_payload(eov_payload(Resource, Pprev), scope(Snext), ());
+ bind(Symnext, eov_checkpoint(Resource, Pnext));
+ Symnext = s(_, _, Snext).
+
+eov_results(Resource, success):-
+ not eov_results(Resource, fail);
+ eov_expect(Resource, _, _).
+
+dfa_callguard(Sym, Impl):-
+ bind(Sym, eov_checkpoint(Resource, _));
+ eov_results(Resource, Result);
+ eov_analysis(Result, Impl).
+
+
diff --git a/scripts/execution-order/test-1.assembly.lp b/scripts/execution-order/test-1.assembly.lp
new file mode 100644
index 0000000..3515920
--- /dev/null
+++ b/scripts/execution-order/test-1.assembly.lp
@@ -0,0 +1,5 @@
+#include "scripts/cfa/payload.lp".
+#include "scripts/execution-order/execorder.lp".
+
+<insert ExampleEov_1_Expectation>
+<insert ExampleEov_1_Registration>
diff --git a/scripts/execution-order/test-1.xreate b/scripts/execution-order/test-1.xreate
new file mode 100644
index 0000000..239d1a8
--- /dev/null
+++ b/scripts/execution-order/test-1.xreate
@@ -0,0 +1,49 @@
+// UnitTest: tests/exploitation.cpp, Exploitation.Doc_ExampleEov_1
+
+interface(extern-c){
+ externalLibs = library:: pkgconfig("libxml-2.0").
+
+ include {
+ externalLibs = {"scripts/virtualization/defs.h"}
+ }.
+}
+
+<insert ExampleEov_1_Specializations>
+
+print = function(content:: Content):: int
+{
+ switch variant(content):: int
+ case (errcode) {content}
+ case (message) {printf("%s", content)}
+}
+
+sendResponse = function(header:: Content, body:: Content, footer:: Content):: int
+{
+ seq
+ {print(header)}
+ {print(body)}
+ {print(footer)}
+}
+
+main = function:: int; entry
+{
+ seq
+ {
+ header = send("Header"):: Content; eov_checkpoint(webpage, header).
+ header
+ }
+
+ {
+ body = send("Body"):: Content; eov_checkpoint(webpage, body).
+ body
+ }
+
+ {
+ footer = send("Footer"):: Content; eov_checkpoint(webpage, footer).
+ footer
+ }
+
+ {
+ sendResponse(header, body, footer)
+ }
+}

Event Timeline