diff --git a/.gitignore b/.gitignore index 04f629e..b3fe7b7 100644 --- a/.gitignore +++ b/.gitignore @@ -1,67 +1,68 @@ # Compiled Object files *.slo *.lo *.o *.obj # Compiled Dynamic libraries *.so *.so.* *.dylib *.dll # Compiled Static libraries *.lai *.la *.a *.lib # Executables *.exe *.out *.app *.class # Mobile Tools for Java (J2ME) .mtj.tmp/ # Package Files # *.jar *.war *.ear # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml hs_err_pid* # Qt-es /.qmake.cache /.qmake.stash *.pro.user *.pro.user.* *.moc moc_*.cpp qrc_*.cpp ui_*.h Makefile* *-build-* # QtCreator *.autosave coco/*.old coco/*~ *~ cpp/build-*/* cpp/xreate-debug/* cpp/xreate-release/* cpp/.idea cpp/CMakeLists.txt.user* hs/* project/* nb*.xml .* target/* +/tools/phabricator/xreate-frontend/nbproject/private/ \ No newline at end of file diff --git a/coco/gen-grammar b/coco/gen-grammar index 132dff9..814c770 100755 --- a/coco/gen-grammar +++ b/coco/gen-grammar @@ -1 +1 @@ -cococpp -frames /usr/share/coco-cpp/ ./xreate.ATG +cococpp -frames ./generator-frames ./xreate.ATG diff --git a/coco/xreate.ATG b/coco/xreate.ATG index 3bfb0e9..242d665 100644 --- a/coco/xreate.ATG +++ b/coco/xreate.ATG @@ -1,518 +1,518 @@ //TODO add ListLiteral //TODO ExprTyped: assign default(none) type #include "ast.h" #include "ExternLayer.h" #include #include #define wprintf(format, ...) \ char __buffer[100]; \ wcstombs(__buffer, format, 100); \ fprintf(stderr, __buffer, __VA_ARGS__) using namespace xreate; using namespace std; COMPILER Xreate xreate::AST root; // current program unit struct { std::stack scopesOld; xreate::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 skipIdent() { int kind = 0; scanner->ResetPeek(); while ((kind = scanner->Peek()->kind) == _colon) if (scanner->Peek()->kind != _ident) return 0; return kind; } bool checkParametersList() { return la->kind == _ident && skipIdent() == _lparen; } bool checkInfix() { return la->kind == _ident && skipIdent() == _ident; } bool checkIndex() { return la->kind == _ident && skipIdent() == _lbrack; } bool checkFuncDecl() { if (la->kind != _ident) return false; int xkind = skipIdent(); Token* y = scanner->Peek(); return xkind == _assign && (y->kind == _function || y->kind == _pre); } bool checkAssignment() { scanner->ResetPeek(); Token* x = scanner->Peek(); return la->kind == _ident && x->kind == _assign; } CHARACTERS letter = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz". any = ANY - '"'. digit = "0123456789". cr = '\r'. lf = '\n'. tab = '\t'. TOKENS ident = (letter | '_') {letter | digit | '_'}. number = digit {digit}. string = '"' { any } '"'. function = "function". pre = "pre". lparen = '('. rparen = ')'. lbrack = '['. rbrack = ']'. lcurbrack = '{'. rcurbrack = '}'. equal = "==". assign = '='. implic = '-' '>'. colon = ':'. context = "context". tagcolon = "::". COMMENTS FROM "/*" TO "*/" NESTED COMMENTS FROM "//" TO lf IGNORE cr + lf + tab PRODUCTIONS Xreate = (. Function* function; .) { ( RuleDecl | InterfaceData | Imprt | ContextSection | IF(checkFuncDecl()) FDecl (. root.add(function); .) | TDecl ) }. Ident = ident {':' ident} (. name = t->val; .). FDecl = (. std::wstring fname; std::wstring varname; TypeAnnotation typIn; TypeAnnotation typOut; bool flagIsPrefunct = false; .) Ident assign [pre (. flagIsPrefunct = true; .)] function (. f = new Function(fname); f->isPrefunction = flagIsPrefunct; CodeScope* entry = f->getEntryScope(); .) ['(' Ident tagcolon Type (. f->addArg(std::move(varname), move(typIn)); .) {',' Ident tagcolon Type (. f->addArg(std::move(varname), move(typIn));.) } ')'] [ tagcolon ( IF(flagIsPrefunct) FnTag | Type (. f->setReturnType(typOut); .) ) {';' FnTag }] BDecl (. entry->__body.bindType(move(typOut));.) . ContextSection<>= (. Expression context; Function* f; .) "case" "context" tagcolon MetaSimpExpr lcurbrack { FDecl (. f->guardContext = context; root.add(f); .) } rcurbrack. /** * TYPES * */ TypeTerm = (. std::wstring tid; .) ("string" | "int" | "num" | "float" | "bool") (. typ = Atom(t->val); .) . Type = (. TypeAnnotation typ2; TypeAtom typ3; std::wstring tid, field; .) ( TList | TStruct | TypeTerm (. typ = TypeAnnotation(typ3); .) |IF (checkIndex()) Ident lbrack Ident (. typ = TypeAnnotation(TypeOperator::ACCESS, {}); typ.__valueCustom = Atom(tid).get(); typ.fields.push_back(Atom(field).get()); .) {',' Ident (. typ.fields.push_back(Atom(field).get()); .) } rbrack | Ident (. typ = TypeAnnotation(TypeOperator::CUSTOM, {}); typ.__valueCustom = Atom(tid).get(); .) ['(' Type (. typ.__operator = TypeOperator::CALL; typ.__operands.push_back(typ2); .) {',' Type (. typ.__operands.push_back(typ2); .) } ')'] ) . TList = (. TypeAnnotation ty; .) '[' Type (. typ = TypeAnnotation(TypeOperator::ARRAY, {ty}); .) {',' Type (. typ.__operator = TypeOperator::TUPLE; typ.__operands.push_back(ty); .) }']' . TStruct = (. TypeAnnotation t; std::wstring field; .) '{' Ident tagcolon Type (. typ = TypeAnnotation(TypeOperator::STRUCT, {t}); typ.fields.push_back(Atom(field).get()); .) {',' Ident tagcolon Type} (. typ.__operands.push_back(t); typ.fields.push_back(Atom(field).get()); .) '}'. TDecl = (. std::wstring ttag; TypeAnnotation t, t1; std::wstring tname, arg; std::vector> args; .) Ident assign "type" ( "alias" Type (. root.add(move(t), Atom(tname)); .) | "variant" lparen Ident (. t = TypeAnnotation(TypeOperator::VARIANT, {}); args.push_back(Atom(arg)); .) {',' Ident (. args.push_back(Atom(arg)); .) } rparen (. t.addFields(move(args)); root.add(move(t), Atom(tname)); .) | Ident ['(' Ident (. args.push_back(Atom(arg)); .) {',' Ident (. args.push_back(Atom(arg)); .) } ')'] Type (. t.addBindings(move(args)); root.add(move(t), Atom(tname)); .) ) '.' . VDecl = (. std::wstring vname; Expression e; TypeAnnotation typ;.) Ident assign ExprTyped (. f->addDeclaration(move(vname), move(typ), move(e)); .) . ContextDecl = (. Expression tag; .) context tagcolon MetaSimpExpr (. scope->tags.push_back(move(tag)); .) {';' MetaSimpExpr (. scope->tags.push_back(move(tag)); .) }. //TODO forbid multiple body declaration (ExprTyped) BDecl = (. Expression body; TypeAnnotation typ; pushContextScope(scope); .) '{' { (RuleContextDecl | ContextDecl '.' | IF(checkAssignment()) VDecl '.' | ExprTyped (. scope->setBody(body); popContextScope();.) )} '}'. IfDecl = (. Expression cond; ManagedScpPtr blockTrue = root.add(new xreate::CodeScope(context.scope)); ManagedScpPtr blockFalse = root.add(new xreate::CodeScope(context.scope)); TypeAnnotation typIf; .) "if" '(' Expr ')' tagcolon Type BDecl<&*blockTrue> "else" BDecl<&*blockFalse> (. e = Expression(Operator::IF, {cond}); e.addBlock(blockTrue); e.addBlock(blockFalse); e.bindType(move(typIf)); .) . LoopDecl = (. Expression eIn, eAcc, eFilters; std::wstring varEl, varAcc, contextClass; TypeAnnotation typEl, typAcc; ManagedScpPtr block = root.add(new xreate::CodeScope(context.scope)); .) "loop" ("map" '(' Expr implic Ident tagcolon Type ')' tagcolon Type BDecl<&*block> (. e = Expression(Operator::MAP, {eIn}); e.addBindings({Atom(varEl)}); block->addArg(Atom(varEl), move(typEl)); e.addBlock(block); .) - |"fold" '(' Expr implic Ident tagcolon Type ['|' Expr ] ',' Expr implic Ident tagcolon Type ')' tagcolon Type BDecl<&*block> + |"fold" '(' Expr implic Ident tagcolon Type ['|' Expr ] ',' Expr implic Ident')' tagcolon Type BDecl<&*block> (. e = Expression(Operator::FOLD, {eIn, eAcc}); e.addBindings({Atom(varEl), Atom(varAcc)}); block->addArg(Atom(varEl), move(typEl)); - block->addArg(Atom(varAcc), move(typAcc)); + block->addArg(Atom(varAcc), move(typOut)); e.addBlock(block); .) | "context" '(' string (. contextClass = t->val; .) ')' BDecl<&*block> (. e = Expression(Operator::LOOP_CONTEXT, {Expression(Atom(std::move(contextClass)))}); e.addBlock(block); .) ). SwitchDecl = (. TypeAnnotation typ; eSwitch = Expression(Operator::SWITCH, {}); Expression eCondition; Expression tag;.) ["switch" ("ad" "hoc" lparen Expr tagcolon MetaSimpExpr rparen (. eSwitch.op = Operator::SWITCH_ADHOC; eSwitch.operands.push_back(eCondition); eSwitch.tags.emplace(tag.getValueString(), move(tag)); .) | lparen Expr rparen tagcolon Type (. eSwitch.operands.push_back(eCondition); eSwitch.type = typ; .) ) ] CaseDecl {CaseDecl} . CaseDecl = (. ManagedScpPtr scope = root.add(new xreate::CodeScope(context.scope)); .) "case" ( "default" BDecl<&*scope> (. Expression exprCase(Operator::CASE_DEFAULT, {}); exprCase.addBlock(scope); outer.operands.insert(++outer.operands.begin(), exprCase); .) | CaseParams<&*scope> (. ManagedScpPtr scopeBody = root.add(new xreate::CodeScope(&*scope)); .) BDecl<&*scopeBody> (. Expression exprCase(Operator::CASE, {}); exprCase.addBlock(scope); exprCase.addBlock(scopeBody); outer.addArg(move(exprCase)); .) ). CaseParams = (. Expression e; Expression guard(Operator::LOGIC_AND, {}); pushContextScope(scope); .) CaseParam {',' CaseParam } (. scope->setBody(guard); popContextScope(); .). CaseParam = (. TypeAnnotation argtyp; Expression condition; .) ( IF(checkAssignment()) VDecl | ExprTyped (. guard.addArg(move(condition)); .) ). SequenceDecl = "sequence" ListLiteral (. sequence.setOp(Operator::SEQUENCE); .). /*============================ INTERFACES ===============================*/ Imprt<> = "import" "raw" lparen string (. root.__rawImports.push_back(Atom(t->val).get()); .) rparen . InterfaceData<> = "interface" '(' ( "dfa" ')' InterfaceDFA | "extern-c" ')' InterfaceExternC | "cfa" ')' InterfaceCFA | "adhoc" ')' InterfaceAdhoc ). InterfaceAdhoc<> = '{' [ PrefunctionSchemeDecl ] '}'. PrefunctionSchemeDecl<> = (. TypeAnnotation typReturn; std::wstring prefName; Expression exprCases; .) pre function Ident tagcolon Type '{' SwitchDecl '}' (. Expression prefData(Operator::CALL, {Atom(prefName), exprCases}); prefData.type = typReturn; root.addInterfaceData(Adhoc, move(prefData)); .). InterfaceExternC<> = (.xreate::ExternData data; .) '{' {IncludeExternDecl | LibExternDecl } '}' (. root.addExternData(move(data)); .) . LibExternDecl = (. std::wstring pkgname, libname; .) Ident assign "library" tagcolon "pkgconfig" '(' string (. pkgname = t->val; .) ')' '.' (. data.addLibrary(Atom(libname), Atom(pkgname)); .) . IncludeExternDecl = (. Expression inc; .) "include" StructLiteral '.' (. data.addIncludeDecl(move(inc)); .) . InterfaceDFA<> = '{' { InstructDecl } '}' . InstructDecl = (.Operator op; Expression tag; Expression scheme; std::vector& tags = scheme.operands; tags.push_back(Expression()); /* return value */ .) "operator" InstructAlias tagcolon '(' (.scheme.setOp(op); .) [ MetaSimpExpr (. tags.push_back(tag); .) { ',' MetaSimpExpr (. tags.push_back(tag); .) } ] ')' [ implic MetaSimpExpr (. tags[0] = tag; .) ] (. root.addDFAData(move(scheme)); .) '.'. InstructAlias = ( "map" (. op = Operator::MAP; .) | "list_range" (. op = Operator::LIST_RANGE; .) | "list" (. op = Operator::LIST; .) | "fold" (. op = Operator::FOLD; .) | "index" (. op = Operator::INDEX; .) ). InterfaceCFA<> = '{' { InstructCFADecl } '}' . InstructCFADecl<> = (.Operator op; Expression tag; Expression scheme; std::vector& tags = scheme.operands; .) "operator" InstructAlias tagcolon (. scheme.setOp(op); .) [ MetaSimpExpr (. tags.push_back(tag); .) { ',' MetaSimpExpr (. tags.push_back(tag); .) } ] '.' (. root.addInterfaceData(CFA, move(scheme)); .). /*============================ METAPROGRAMMING ===============================*/ // TagsDecl = (. Expression tag; TagModifier mod = TagModifier::NONE; .) // ':' { MetaSimpExpr (. /*f.addTag(std::move(tag), mod); */ .) // }. FnTag = (. Expression tag; TagModifier mod = TagModifier::NONE; .) MetaSimpExpr ['-' TagMod] (. f->addTag(std::move(tag), mod); .). TagMod = ( "assert" (. mod = TagModifier::ASSERT; .) | "require" (. mod = TagModifier::REQUIRE; .) ). RuleDecl<> = "rule" tagcolon (. RuleArguments args; RuleGuards guards; DomainAnnotation typ; std::wstring arg; .) '(' Ident tagcolon Domain (. args.add(arg, typ); .) {',' Ident tagcolon Domain (. args.add(arg, typ); .) } ')' ["case" RGuard {',' RGuard}] '{' RBody '}' . /* - TODO use RGuard for guards-*/ RuleContextDecl = (.Expression eHead, eGuards, eBody; .) "rule" "context" tagcolon MetaSimpExpr "case" MetaSimpExpr '{' MetaSimpExpr '}' (.scope->contextRules.push_back(Expression(Operator::CONTEXT_RULE, {eHead, eGuards, eBody})); .). Domain = ( "function" (. dom = DomainAnnotation::FUNCTION; .) | "variable" (. dom = DomainAnnotation::VARIABLE; .) ). RGuard= (. Expression e; .) MetaExpr (. guards.add(std::move(e)); .). MetaExpr= (.Operator op; Expression e2; .) MetaExpr2 [MetaOp MetaExpr2 (. e = Expression(op, {e, e2}); .) ]. MetaExpr2= ( '(' MetaExpr ')' | MetaSimpExpr ). MetaSimpExpr= (. std::wstring i1, infix; Expression e2; .) ( '-' MetaSimpExpr (. e = Expression(Operator::NEG, {e2}); .) | IF(checkParametersList()) Ident (. e = Expression(Operator::CALL, {Expression(Atom(i1))}); .) '(' [ CalleeParams ] ')' | IF(checkInfix()) Ident Ident MetaSimpExpr (. e = Expression(Operator::CALL, {Expression(Atom(infix))}); e.addArg(Expression(Atom(i1))); e.addArg(std::move(e2)); .) | Ident (. e = Expression(Atom(i1)); .) ). RBody = (. Expression e; std::wstring msg; .) "warning" MetaExpr ["message" string (. msg = t->val; .) ] (. root.add(new RuleWarning(RuleArguments(args), RuleGuards(guards), std::move(e), Atom(msg))); .) . MetaOp< Operator& op> = implic (. op = Operator::IMPL; .) . /*============================ Expressions ===============================*/ ExprTyped = (. Expression tag; .) Expr [tagcolon Type (. e.bindType(move(typ)); .) {';' MetaSimpExpr (. e.tags.emplace(tag.getValueString(), move(tag)); .) }] . Expr< Expression& e> (. Operator op; Expression e2; .) = SimExpr< e> [ RelOp< op> SimExpr< e2> (. e = Expression(op, {e, e2}); .) ]. SimExpr< Expression& e> (. Operator op; Expression e2; .) = Term< e> { AddOp< op> Term< e2> (. e = Expression(op, {e, e2});.) }. Term< Expression& e> (. Operator op; Expression e2; .) = Factor< e> { MulOp< op> Factor< e2> (. e = Expression(op, {e, e2}); .) }. Factor< Expression& e> (. std::wstring name; TypeAnnotation typ; .) = (IF (checkParametersList()) Ident< name> (. e = Expression(Operator::CALL, {Atom(name)}); .) '(' [CalleeParams] ')' |IF (checkIndex()) Ident lbrack CalleeParams rbrack (. e.setOp(Operator::INDEX); e.setValue({Atom(name)}); .) | Ident< name> (. e = Expression(Atom(name)); root.recognizeVariantIdentifier(e); .) | ListLiteral (. /* tuple */.) | StructLiteral (. /* struct */.) | SequenceDecl | LoopDecl | IfDecl | SwitchDecl | AdhocDecl | number (. e = Expression(Atom(t->val)); .) | string (. e = Expression(Atom(t->val)); .) | '-' Factor< e> (. e = Expression(Operator::NEG, {e}); .) | '(' Expr ')' ). StructLiteral = (. std::wstring key; Expression val; std::list> keys; .) '{' Ident '=' Expr (. keys.push_back(Atom(key)); e = Expression(Operator::LIST_NAMED, {val}); .) {',' Ident '=' Expr (.e.addArg(move(val)); keys.push_back(Atom(key)); .) } '}' (. e.addBindings(keys.begin(), keys.end()); .) . ListLiteral = (. Expression eFrom, eTo; .) '[' [ Expr (. e.addArg(std::move(eFrom)); .) (".." Expr (. e.addArg(std::move(eTo)); e.setOp(Operator::LIST_RANGE); .) |{',' Expr (. e.addArg(std::move(eFrom)); .) } (. e.setOp(Operator::LIST); .) ) ] ']'. AdhocDecl = (. Expression command; .) "ad" "hoc" Expr (. e.setOp(Operator::ADHOC); e.addArg(std::move(command)); .). CalleeParams = (. Expression e2; TypeAnnotation typ; .) ExprTyped (. e.addArg(std::move(e2)); .) {',' ExprTyped (. e.addArg(std::move(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 | '<' (. op = Operator::LSS; .) | '>' (. op = Operator::GTR; .) ). END Xreate. diff --git a/config/default.json b/config/default.json index 80e5eb5..08e9bd6 100644 --- a/config/default.json +++ b/config/default.json @@ -1,58 +1,59 @@ { "containers": { "id": { "implementations": "impl_fulfill_cluster", "clusters": "var_cluster", "prototypes": "proto_cluster", "linkedlist": "linkedlist" }, "impl": { "solid": "solid", "onthefly": "on_the_fly" } }, "logging": { "id": "logging" }, "function-entry": "entry", "clasp": { "bindings" : { "variable": "bind", "function": "bind_func", "scope": "bind_scope", "function_demand" : "bind_function_demand", "scope_decision": "bind_scope_decision" }, "nonevalue": "nonevalue", "ret": { "symbol": "retv", "tag": "ret" } }, "tests": { - "template": "installation", + "template": "context", "templates": { "basic": "EntryFunction*", "default": "*-", "types": "Types*-", "containers": "Containers*-", "ast": "AST*", "non-containers": "*-Containers*", "log": "Logging*", "clang": "ClangAPI*", "cfg": "CFG.*", "skip": "SkipDetection*", "raw-xml": "libxml2*", "xml": "Xml.*", "adhocs": "ExpressionSerializer.*:Adhoc.*:Context.*", + "context": "ExpressionSerializer.*:Context.*", "installation": "Compilation.*:Sprint1.*" } } } diff --git a/core/control-context.lp b/core/control-context.lp index 27a27e4..62237fe 100644 --- a/core/control-context.lp +++ b/core/control-context.lp @@ -1,24 +1,24 @@ % context propagation bind_scope_decision(Scope, Fn, Resolution):- cfa_call(Scope, Fn), cfa_function_specializations(Fn, Resolution), bind_scope(Scope, Resolution). bind_scope_decision(Scope, Fn, Resolution):- cfa_call(Scope, FnChild), bind_function_demand(FnChild, Fn), cfa_function_specializations(Fn, Resolution), bind_scope(Scope, Resolution). bind_scope_demand(Scope, FnCallee):- cfa_call(Scope, FnCallee), cfa_function_specializations(FnCallee, _), not bind_scope_decision(Scope, FnCallee, _). -%demand propagation + %demand propagation bind_scope_demand(Scope, Subject):- bind_scope_demand(ScopeChild, Subject), cfa_parent(ScopeChild, scope(Scope)). bind_scope_demand(Scope, Subject):- cfa_call(Scope, FnChild), bind_function_demand(FnChild, Subject), not bind_scope_decision(Scope, Subject, _). bind_function_demand(Fn, Subject):- bind_scope_demand(Scope, Subject), cfa_parent(Scope, function(Fn)). bind_scope(Scope, Context) :- bind_scope(ScopeParent, Context), cfa_parent(Scope, scope(ScopeParent)). bind_scope(Scope, Context) :- bind_scope(ScopeParent, Context): cfa_call(ScopeParent, FnCurrent); cfa_call(_, FnCurrent) , cfa_parent(Scope, function(FnCurrent)), bind_scope(_, Context), scope(Scope). % adhoc classes(unfinished): %bind_func(Fn, adhoc_class(Context)) :- bind_func(Fn, adhoc(Context)), bind_scope(Scope, Context), cfa_parent(Scope, function(Fn)). %scope_parent(Scope, ScopeParent) :- cfa_parent(Scope, scope(ScopeParent)). %scope_parent(Scope, ScopeParent2) :- cfa_parent(Scope, scope(ScopeParent)), scope_parent(ScopeParent, ScopeParent2). %scope_function(Scope, Fn) :- cfa_parent(Scope, function(Fn)). %scope_function(Scope, Fn) :- cfa_parent(Scope, scope(ScopeParent)), scope_function(ScopeParent, Fn). diff --git a/cpp/CMakeLists.txt b/cpp/CMakeLists.txt index 909759a..1c12f2e 100644 --- a/cpp/CMakeLists.txt +++ b/cpp/CMakeLists.txt @@ -1,183 +1,16 @@ cmake_minimum_required(VERSION 2.8.11) -project(xreate) -find_package(LLVM REQUIRED CONFIG) - -# MACRO (ADD_PCH_RULE _header_filename _src_list) -# SET(_gch_filename "${_header_filename}.gch") -# LIST(APPEND ${_src_list} ${_gch_filename}) -# SET (_args ${CMAKE_CXX_FLAGS}) -# LIST(APPEND _args -c ${_header_filename} -o ${_gch_filename}) -# GET_DIRECTORY_PROPERTY(DIRINC INCLUDE_DIRECTORIES) -# foreach (_inc ${DIRINC}) -# LIST(APPEND _args "-I" ${_inc}) -# endforeach(_inc ${DIRINC}) -# SEPARATE_ARGUMENTS(_args) -# add_custom_command(OUTPUT ${_gch_filename} -# COMMAND rm -f ${_gch_filename} -# COMMAND ${CMAKE_CXX_COMPILER} ${CMAKE_CXX_COMPILER_ARG1} ${_args} -# DEPENDS ${_header_filename}) -# ENDMACRO(ADD_PCH_RULE _header_filename _src_list) - -set (CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake-tools") -include(PCH_GCC4_v2) - -set(LLVM_VERSION ${LLVM_VERSION_MAJOR}.${LLVM_VERSION_MINOR}) - -link_directories(${LLVM_LIBRARY_DIRS}) - -set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR}) -message ("MPATH:" ${CMAKE_MODULE_PATH}) - -message(STATUS "Found LLVM ${LLVM_PACKAGE_VERSION}") -message(STATUS "Using LLVMConfig.cmake in: ${LLVM_DIR}") -#find_package(Clang REQUIRED clangTooling libClang) +set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -g -Wall -fprofile-arcs -ftest-coverage -O0") set(CMAKE_BUILD_TYPE Debug) -set(POTASSCO_PATH "/opt/potassco/gringo" CACHE PATH "Path to gringo sources") -set (LIBCLASP_PATH ${POTASSCO_PATH}/build/debug) -link_directories(${LIBCLASP_PATH}) - -FILE (GLOB TEST_FILES ./tests/*.cpp) -message("TEST: " ${TEST_FILES}) -set(SOURCE_FILES - ./src/pass/compilepass.cpp - ./src/compilation/latecontextcompiler2.cpp - - ${TEST_FILES} - - #./src/compilation/latecontextcompiler.cpp - - ./src/serialization/expressionserializer.cpp - ./src/serialization/expressionserializer2.cpp - ./src/query/context.cpp - - ./src/ast.cpp - ./src/llvmlayer.cpp ./src/clasplayer.cpp - - ./src/utils.cpp - ./src/passmanager.cpp - - ./src/pass/abstractpass.cpp ./src/pass/dfgpass.cpp - ./src/pass/cfgpass.cpp - ./src/pass/loggerpass.cpp - ./src/pass/adhocpass.cpp - #./src/pass/rulespass.cpp # - - ./src/compilation/instr-containers.cpp - - ./src/query/containers.cpp - ./src/query/ptrvalid.cpp - - - ./src/attachments.cpp - ./src/contextrule.cpp - - #${POTASSCO_PATH}/app/shared/src/clingocontrol.cc - #${POTASSCO_PATH}/app/pyclingo/src/clingo_lib.cc -) - -set(COCO_PATH ${CMAKE_HOME_DIRECTORY}/../coco/) -set(COCO_SOURCE_FILES - ${COCO_PATH}/Parser.h - ${COCO_PATH}/Scanner.h - ${COCO_PATH}/Parser.cpp - ${COCO_PATH}/Scanner.cpp -) - -INCLUDE_DIRECTORIES(${LLVM_INCLUDE_DIRS}) -INCLUDE_DIRECTORIES("/usr/include/libxml2") -INCLUDE_DIRECTORIES(${COCO_PATH} ./src) -INCLUDE_DIRECTORIES(${POTASSCO_PATH}/libgringo -${POTASSCO_PATH}/libclasp -${POTASSCO_PATH}/libclingo -${POTASSCO_PATH}/libprogram_opts -) - -include_directories(${CMAKE_HOME_DIRECTORY}/../vendors/jeayeson/include/) - -#execute_process(COMMAND ${COCO_PATH}/gen-xreate WORKING_DIRECTORY OUTPUT_VARIABLE COCO_OUTPUT) - - -message(STATUS "COCO GRAMMAR BUILD STATUS:" ${COCO_OUTPUT}) - -include_directories(${LLVM_INCLUDE_DIRS}) -add_definitions(${LLVM_DEFINITIONS}) -#add_definitions() -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Winvalid-pch -std=c++14 -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS") -set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -g -Wall -fprofile-arcs -ftest-coverage -O0 -DWITH_THREADS=1") - -set(RESOURCES_DBUS_INTERFACES - resources/hamster.xml -) -# ADD_PCH_RULE (${CMAKE_HOME_DIRECTORY}/src/ast.h SOURCE_FILES) -# ADD_PCH_RULE (${CMAKE_HOME_DIRECTORY}/src/llvmlayer.h SOURCE_FILES) -# ADD_PCH_RULE (${CMAKE_HOME_DIRECTORY}/src/clasplayer.h SOURCE_FILES) -# ADD_PCH_RULE (${CMAKE_HOME_DIRECTORY}/src/pass/abstractpass.h SOURCE_FILES) - -add_custom_command(OUTPUT ${COCO_PATH}/Parser.cpp - COMMAND ${COCO_PATH}/gen-grammar - WORKING_DIRECTORY ${COCO_PATH} - DEPENDS ${COCO_PATH}/xreate.ATG -) - -add_executable(xreate ${SOURCE_FILES} ${COCO_SOURCE_FILES} src/ExternLayer.cpp src/ExternLayer.h) - -add_custom_target (coverage - COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/src/code-coverage.sh - WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) - -message(STATUS "BINARY DIR" ${CMAKE_BINARY_DIR}) - -#add_dependencies(${PROJECT_NAME} coverageTarget) - -llvm_map_components_to_libnames(llvm_libs support core irreader all native nativecodegen) -message(STATUS "LLVM LIBS: " ${llvm_libs}) - -set(LIBCLASP_LIBS - clingo - clasp - gringo - program_opts - reify -) - -message(STATUS "CLANG LIBS: " ${CLANG_LIBS}) -message(STATUS "CLASP LIBS: " ${LIBCLASP_LIBS}) - - - - - -FUNCTION(PREPEND var prefix) - SET(listVar "") - FOREACH(f ${ARGN}) - LIST(APPEND listVar "${prefix}/${f}") - ENDFOREACH(f) - SET(${var} "${listVar}" PARENT_SCOPE) -ENDFUNCTION(PREPEND) - - -find_package(GTest REQUIRED) -INCLUDE_DIRECTORIES(${GTEST_INCLUDE_DIRS}) +add_subdirectory(src) -set(CLANG_LIBS - clangCodeGen - clangASTMatchers - clangQuery - clangTooling - clangFrontend - clangSerialization - clangDriver - clangParse - clangSema - clangAnalysis - clangAST - clangEdit - clangLex - clangBasic - ) +if (BUILD_XREATE_TESTS) + message ("Building xreate tests") + add_subdirectory(tests) +endif () -target_link_libraries(xreate ${GTEST_LIBRARIES} LLVM-${LLVM_VERSION} ${LIBCLASP_LIBS} ${CLANG_LIBS} pthread xml2 gcov tbb) -#set(COTIRE_UNITY_SOURCE_MAXIMUM_NUMBER_OF_INCLUDES "-j4") -#cotire(xreate) +if (BUILD_XREATE_SERVER) + message ("Building xreate server") + add_subdirectory(../tools/execution-server execution-server) +endif () diff --git a/cpp/src/CMakeLists.txt b/cpp/src/CMakeLists.txt new file mode 100644 index 0000000..3a28174 --- /dev/null +++ b/cpp/src/CMakeLists.txt @@ -0,0 +1,221 @@ +cmake_minimum_required(VERSION 2.8.11) +project(xreate) +cmake_policy(SET CMP0022 NEW) + +# BUILD OPTIONS +#====================== +set(XREATE_DEFINITIONS + -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -DWITH_THREADS=1 +) + +add_definitions(${XREATE_DEFINITIONS}) +add_compile_options(-Winvalid-pch -std=c++14 -fPIC) + + + +# LLVM +#====================== +find_package(LLVM REQUIRED CONFIG) +set (CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake-tools") +include(PCH_GCC4_v2) + +set(LLVM_VERSION ${LLVM_VERSION_MAJOR}.${LLVM_VERSION_MINOR}) + +link_directories(${LLVM_LIBRARY_DIRS}) + +set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR}) +message ("MPATH:" ${CMAKE_MODULE_PATH}) + +message(STATUS "Found LLVM ${LLVM_PACKAGE_VERSION}") +message(STATUS "Using LLVMConfig.cmake in: ${LLVM_DIR}") +INCLUDE_DIRECTORIES(${LLVM_INCLUDE_DIRS}) +message("LLVM defs: " ${LLVM_DEFINITIONS}) +add_definitions(${LLVM_DEFINITIONS}) +#llvm_map_components_to_libnames(llvm_libs support core irreader all native nativecodegen) + + + +# CLANG +#====================== +set(CLANG_LIBS + clangCodeGen + clangASTMatchers + clangQuery + clangTooling + clangFrontend + clangSerialization + clangDriver + clangParse + clangSema + clangAnalysis + clangAST + clangEdit + clangLex + clangBasic +) +#find_package(Clang REQUIRED clangTooling libClang) +message(STATUS "CLANG LIBS: " ${CLANG_LIBS}) + + + +# POTASSCO +#====================== +set(POTASSCO_PATH "/opt/potassco/gringo" CACHE PATH "Path to gringo sources") +set(POTASSCO_INCLUDE_PATH + ${POTASSCO_PATH}/libgringo + ${POTASSCO_PATH}/libclasp + ${POTASSCO_PATH}/libclingo + ${POTASSCO_PATH}/libprogram_opts +) + +INCLUDE_DIRECTORIES(${POTASSCO_INCLUDE_PATH}) + +set (LIBCLASP_PATH ${POTASSCO_PATH}/build/debug) + +set(LIBCLASP_LIBS + clingo + clasp + gringo + program_opts + reify +) +message(STATUS "CLASP LIBS: " ${LIBCLASP_LIBS}) +link_directories(${LIBCLASP_PATH}) + + + +# OTHER DEPENDENCIES +#=========================== +set(JEAYESON_INCLUDE_PATH + ${CMAKE_HOME_DIRECTORY}/../vendors/jeayeson/include/ +) +INCLUDE_DIRECTORIES(${JEAYESON_INCLUDE_PATH}) + + + +# COCO +#=========================== +set(COCO_PATH ${CMAKE_HOME_DIRECTORY}/../coco/) +set(COCO_SOURCE_FILES + ${COCO_PATH}/Parser.cpp + ${COCO_PATH}/Scanner.cpp +) + +INCLUDE_DIRECTORIES(${COCO_PATH} ./src) +add_custom_command(OUTPUT COCO_OUTPUT + COMMAND ${COCO_PATH}/gen-grammar + WORKING_DIRECTORY ${COCO_PATH} + DEPENDS ${COCO_PATH}/xreate.ATG +) +message(STATUS "COCO GRAMMAR BUILD STATUS:" ${COCO_OUTPUT}) + + + +# XREATE +#====================== +set(SOURCE_FILES + pass/compilepass.cpp + compilation/latecontextcompiler2.cpp + #compilation/latecontextcompiler.cpp + serialization/expressionserializer.cpp + serialization/expressionserializer2.cpp + query/context.cpp + + ast.cpp + llvmlayer.cpp clasplayer.cpp + + utils.cpp + passmanager.cpp + + pass/abstractpass.cpp pass/dfgpass.cpp + pass/cfgpass.cpp + pass/loggerpass.cpp + pass/adhocpass.cpp + #pass/rulespass.cpp # + + compilation/instr-containers.cpp + + query/containers.cpp + query/ptrvalid.cpp + + + attachments.cpp + contextrule.cpp + ExternLayer.cpp + + #${POTASSCO_PATH}/app/shared/src/clingocontrol.cc + #${POTASSCO_PATH}/app/pyclingo/src/clingo_lib.cc +) + +set(XREATE_INCLUDE_DIRS + ${CMAKE_CURRENT_SOURCE_DIR}/ +) + +INCLUDE_DIRECTORIES(${XREATE_INCLUDE_DIRS}) + +set(XREATE_PRIVATE_INCLUDE_DIRS + ${XREATE_INCLUDE_DIRS} + ${COCO_PATH} + ${JEAYESON_INCLUDE_PATH} + ${LLVM_INCLUDE_DIRS} + ${POTASSCO_INCLUDE_PATH} +) + +add_library(${PROJECT_NAME} SHARED ${SOURCE_FILES} ${COCO_SOURCE_FILES} ) +target_link_libraries(${PROJECT_NAME} ${LIBCLASP_LIBS} ${CLANG_LIBS} tbb) + + +target_include_directories(${PROJECT_NAME} INTERFACE + ${XREATE_INCLUDE_DIRS} + ${COCO_PATH} + ${JEAYESON_INCLUDE_PATH} + ${LLVM_INCLUDE_DIRS} + ${POTASSCO_INCLUDE_PATH} +) + +get_directory_property(DEFINITIONS_ALL DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} COMPILE_DEFINITIONS) +message("definitions all: " ${DEFINITIONS_ALL}) +target_compile_definitions(${PROJECT_NAME} INTERFACE ${DEFINITIONS_ALL}) + +get_directory_property(COMPILATION_OPTIONS_ALL DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} COMPILE_OPTIONS) +message("compilations all: " ${COMPILATION_OPTIONS_ALL}) +target_compile_options(${PROJECT_NAME} INTERFACE ${COMPILATION_OPTIONS_ALL}) + +SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES INTERFACE_LINK_LIBRARIES + LLVM-${LLVM_VERSION} +) + +#set (LINK_INTERFACE_LIBRARIES "") + +# FUNCTION(PREPEND var prefix) +# SET(listVar "") +# FOREACH(f ${ARGN}) +# LIST(APPEND listVar "${prefix}/${f}") +# ENDFOREACH(f) +# SET(${var} "${listVar}" PARENT_SCOPE) +# ENDFUNCTION(PREPEND) + +#set(COTIRE_UNITY_SOURCE_MAXIMUM_NUMBER_OF_INCLUDES "-j4") +#cotire(xreate) + + +# MACRO (ADD_PCH_RULE _header_filename _src_list) +# SET(_gch_filename "${_header_filename}.gch") +# LIST(APPEND ${_src_list} ${_gch_filename}) +# SET (_args ${CMAKE_CXX_FLAGS}) +# LIST(APPEND _args -c ${_header_filename} -o ${_gch_filename}) +# GET_DIRECTORY_PROPERTY(DIRINC INCLUDE_DIRECTORIES) +# foreach (_inc ${DIRINC}) +# LIST(APPEND _args "-I" ${_inc}) +# endforeach(_inc ${DIRINC}) +# SEPARATE_ARGUMENTS(_args) +# add_custom_command(OUTPUT ${_gch_filename} +# COMMAND rm -f ${_gch_filename} +# COMMAND ${CMAKE_CXX_COMPILER} ${CMAKE_CXX_COMPILER_ARG1} ${_args} +# DEPENDS ${_header_filename}) +# ENDMACRO(ADD_PCH_RULE _header_filename _src_list) + +# ADD_PCH_RULE (${CMAKE_HOME_DIRECTORY}/src/ast.h SOURCE_FILES) +# ADD_PCH_RULE (${CMAKE_HOME_DIRECTORY}/src/llvmlayer.h SOURCE_FILES) +# ADD_PCH_RULE (${CMAKE_HOME_DIRECTORY}/src/clasplayer.h SOURCE_FILES) +# ADD_PCH_RULE (${CMAKE_HOME_DIRECTORY}/src/pass/abstractpass.h SOURCE_FILES) diff --git a/cpp/tests/CMakeLists.txt b/cpp/tests/CMakeLists.txt new file mode 100644 index 0000000..c729026 --- /dev/null +++ b/cpp/tests/CMakeLists.txt @@ -0,0 +1,19 @@ +cmake_minimum_required(VERSION 2.8.11) +project(xreate-tests) + +find_package(GTest REQUIRED) +INCLUDE_DIRECTORIES(${GTEST_INCLUDE_DIRS}) +INCLUDE_DIRECTORIES("/usr/include/libxml2") +INCLUDE_DIRECTORIES($) + + + +# TESTS +#========================= +aux_source_directory(. TEST_FILES) +add_executable(${PROJECT_NAME} ${TEST_FILES}) +target_link_libraries(${PROJECT_NAME} xreate ${GTEST_LIBRARIES} pthread xml2 gcov) + +add_custom_target (coverage + COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/src/code-coverage.sh + WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) diff --git a/cpp/tests/context.cpp b/cpp/tests/context.cpp index 77f2d8a..56655b3 100644 --- a/cpp/tests/context.cpp +++ b/cpp/tests/context.cpp @@ -1,267 +1,325 @@ /* * frame-context.cpp * * Created on: Dec 3, 2015 * Author: pgess */ #include "passmanager.h" #include "query/context.h" #include "gtest/gtest.h" #include +#include using namespace xreate; -TEST(Context, frame_Context1){ - PassManager* man = PassManager::prepareForCode( - " import raw (\"core/control-context.lp\")\n" - " testC = function::int {\n" - " context:: testC.\n" - - " 0\n" - " }\n" - - " testA = function:: int {\n" - " context:: testA; test.\n" - - " testC()\n" - " }\n" - - " testB = function:: int {\n" - " context:: testB; test.\n" - - " testC()\n" - " }\n" - ); - - ContextQuery* query = (ContextQuery*) man->clasp->registerQuery(new ContextQuery(), QueryId::ContextQuery); - man->runWithoutCompilation(); - - CodeScope* scopeTestC = man->root->findFunction("testC")->getEntryScope(); - const ContextDomain& context = query->getContext(man->clasp->pack(scopeTestC)); - - int contextSize = context.size(); - EXPECT_EQ(2, contextSize); +//TEST(Context, frame_Context1){ +// PassManager* man = PassManager::prepareForCode( +// " import raw (\"core/control-context.lp\")\n" +// " testC = function::int {\n" +// " context:: testC.\n" +// +// " 0\n" +// " }\n" +// +// " testA = function:: int {\n" +// " context:: testA; test.\n" +// +// " testC()\n" +// " }\n" +// +// " testB = function:: int {\n" +// " context:: testB; test.\n" +// +// " testC()\n" +// " }\n" +// ); +// +// ContextQuery* query = (ContextQuery*) man->clasp->registerQuery(new ContextQuery(), QueryId::ContextQuery); +// man->runWithoutCompilation(); +// +// CodeScope* scopeTestC = man->root->findFunction("testC")->getEntryScope(); +// const ContextDomain& context = query->getContext(man->clasp->pack(scopeTestC)); +// +// int contextSize = context.size(); +// EXPECT_EQ(2, contextSize); +//} +// +//TEST(Context, full_ContextBasedFunctionSpecialization){ +// +// PassManager* man = PassManager::prepareForCode( +// " case context::toMillimeters {\n" +// " convert = function(source:: num)::num {\n" +// " 10 * source \n" +// " }\n" +// " }\n" +// +// " case context::toInches {\n" +// " convert = function(source:: num)::num {\n" +// " 2 * source \n" +// " }\n" +// " }\n" +// +// "test = function(vrnt:: int)::int; entry {\n" +// " switch(vrnt):: int\n" +// " case 0 {\n" +// " context:: toMillimeters.\n" +// " convert(1)\n" +// " }\n" +// "\n" +// " case 1 {\n" +// " context:: toInches.\n" +// " convert(1)\n" +// " }\n" +// " case default {0}\n" +// " }" ); +// +// int (*main)(int) = (int (*)(int)) man->run(); +// ASSERT_EQ(10, main(0)); +// ASSERT_EQ(2, main(1)); +//} +// +//TEST(Context, full_LoopContext){ +// +// PassManager* man = PassManager::prepareForCode("case context:: a {\n" +// " print = function:: string {\n" +// " \"a\"\n" +// " }}\n" +// "\n" +// " case context:: b {\n" +// " print = function:: string {\n" +// " \"b\"\n" +// " }}\n" +// "\n" +// " case context:: c {\n" +// " print = function:: string {\n" +// " \"c\"\n" +// " }}\n" +// "\n" +// " case context:: d {\n" +// " print = function:: string {\n" +// " \"d\"\n" +// " }}\n" +// "\n" +// " start = function(command::int)::string; entry {\n" +// " switch (command) :: string \n" +// " case 0 {\n" +// " context:: print(a); print(b); print(d).\n" +// "\n" +// " loop context (\"print\") {\n" +// " print()\n" +// " }\n" +// " }\n" +// "\n" +// " case default {\n" +// " context:: print(c).\n" +// " loop context (\"print\") {\n" +// " print()\n" +// " }\n" +// " }\n" +// " }"); +// +// +// char* (*main)(int) =(char* (*)(int)) man->run(); +// ASSERT_STREQ("c", main(1)); +// ASSERT_STREQ("a", main(0)); +//} +// +//TEST(Context, full_RuleContext){ +// /* +// "rule context:: childs(Child)\n" +// " case artefact(Item)\n" +// " {\n" +// " artefact_depends(Item, Child)\n" +// " }"; +// */ +// +// PassManager* man = PassManager::prepareForCode( +// " case context:: toMilli {\n" +// " convert = function(length::int)::int{\n" +// " 10 * length\n" +// " }\n" +// " }\n" +// "\n" +// " case context:: toCenti {\n" +// " convert = function(length::int)::int{\n" +// " length\n" +// " }\n" +// " }\n" +// "\n" +// " main=function::int; entry {\n" +// " context:: output(milli).\n" +// "\n" +// " rule context::toMilli\n" +// " case output(milli) {true}\n" +// "\n" +// " convert(1)\n" +// " }" ); +// man->clasp->addRawScript("true."); +// +// int (*entry)() = (int (*)()) man->run(); +// ASSERT_EQ(10, entry()); +//} +// +//TEST(Context, full_InheritedRuleContext){ +// PassManager* man = PassManager::prepareForCode( +// " import raw (\"core/control-context.lp\") \n" +// +// " case context:: toMilli {\n" +// " convert = function(length::int)::int{\n" +// " 10 * length\n" +// " }\n" +// " }\n" +// +// " case context:: toCenti {\n" +// " convert = function(length::int)::int{\ n" +// " length\n" +// " }\n" +// " }\n" +// "\n" +// +// "main = function(comm:: num)::num; entry{\n" +// " rule context::X case output(X) {true}\n" +// "\n" +// " switch (comm)::num \n" +// " case 0 {\n" +// " context:: output(toMilli).\n" +// " convert(1)\n" +// " }\n" +// " case default {\n" +// " context:: output(toCenti).\n" +// " convert(1)\n" +// " }\n" +// " }"); +// +// man->clasp->addRawScript("true."); +// int (*entry)(int) = (int (*)(int)) man->run(); +// ASSERT_EQ(10, entry(0)); +// ASSERT_EQ(1, entry(1)); +//} +// +// +// +//TEST(Context, full_LateContext){ +// PassManager* man = PassManager::prepareForCode( +// "import raw (\"core/control-context.lp\")\n" +// +// " convert = function(length:: num)::num{\n" +// " 0\n" +// " }\n" +// +// "case context:: milli {\n" +// " convert = function(length:: num)::num{\n" +// " 1000 * length\n" +// " }\n" +// "}\n" +// "\n" +// "case context:: centi {\n" +// " convert = function(length:: num)::num{\n" +// " 100 * length\n" +// " }\n" +// "}\n" +// "\n" +// "calculate = function(length:: num)::num {\n" +// " convert(length)\n" +// "}\n" +// "\n" +// "main = function(com:: num):: num; entry {\n" +// " switch (com):: num \n" +// " case 0 {\n" +// " context:: milli.\n" +// " calculate(1)\n" +// " }\n" +// "\n" +// " case default{\n" +// " context:: centi. \n" +// " calculate(1)\n" +// " }\n" +// "}"); +// +// man->runWithoutCompilation(); +// ContextQuery* queryContext = reinterpret_cast(man->clasp->getQuery(QueryId::ContextQuery)); +// Expression exprSwitch = man->root->findFunction("main")->__entry->__body; +// CodeScope* blockDefault = man->root->findFunction("main")->__entry->__body.operands[1].blocks.front(); +// ScopePacked blockDefaultId = man->clasp->pack(blockDefault); +// const ContextDomain& domDefault = queryContext->getContext(blockDefaultId); +// ASSERT_EQ(1, domDefault.count(Expression(Atom("centi")))); +// +// std::list variants = man->root->getFunctionVariants("convert"); +// for (ManagedFnPtr f: variants){ +// const Expression guard = f->guardContext; +// bool result = (guard.getValueString() == "centi" || guard.getValueString() == "milli" || !guard.isValid()); +// ASSERT_TRUE(result); +// } +// +// const FunctionContextDemand& demMain = queryContext->getFunctionDemand("main"); +// ASSERT_EQ(0, demMain.size()); +// +// const FunctionContextDemand& demCalculate = queryContext->getFunctionDemand("calculate"); +// ASSERT_EQ(1, demCalculate.size()); +// ASSERT_EQ(1, demCalculate.right.count("convert")); +// +// int (*entry)(int) = (int (*)(int)) man->run(); +// ASSERT_EQ(1000, entry(0)); +// ASSERT_EQ(100, entry(1)); +//} + +TEST(Context, pathDependent_context){ + std::string program = +R"CODE(case context:: convert(milli, meters) { + convert = function(length:: num) :: num { + 1000 * length + } } -TEST(Context, full_ContextBasedFunctionSpecialization){ - - PassManager* man = PassManager::prepareForCode( - " case context::toMillimeters {\n" - " convert = function(source:: num)::num {\n" - " 10 * source \n" - " }\n" - " }\n" - - " case context::toInches {\n" - " convert = function(source:: num)::num {\n" - " 2 * source \n" - " }\n" - " }\n" - - "test = function(vrnt:: int)::int; entry {\n" - " switch(vrnt):: int\n" - " case 0 {\n" - " context:: toMillimeters.\n" - " convert(1)\n" - " }\n" - "\n" - " case 1 {\n" - " context:: toInches.\n" - " convert(1)\n" - " }\n" - " case default {0}\n" - " }" ); - - int (*main)(int) = (int (*)(int)) man->run(); - ASSERT_EQ(10, main(0)); - ASSERT_EQ(2, main(1)); +case context:: convert(centi, meters) { + convert = function(length:: num) :: num { + 100 * length + } } -TEST(Context, full_LoopContext){ - - PassManager* man = PassManager::prepareForCode("case context:: a {\n" - " print = function:: string {\n" - " \"a\"\n" - " }}\n" - "\n" - " case context:: b {\n" - " print = function:: string {\n" - " \"b\"\n" - " }}\n" - "\n" - " case context:: c {\n" - " print = function:: string {\n" - " \"c\"\n" - " }}\n" - "\n" - " case context:: d {\n" - " print = function:: string {\n" - " \"d\"\n" - " }}\n" - "\n" - " start = function(command::int)::string; entry {\n" - " switch (command) :: string \n" - " case 0 {\n" - " context:: print(a); print(b); print(d).\n" - "\n" - " loop context (\"print\") {\n" - " print()\n" - " }\n" - " }\n" - "\n" - " case default {\n" - " context:: print(c).\n" - " loop context (\"print\") {\n" - " print()\n" - " }\n" - " }\n" - " }"); - - - char* (*main)(int) =(char* (*)(int)) man->run(); - ASSERT_STREQ("c", main(1)); - ASSERT_STREQ("a", main(0)); +case context:: convert(centi, kilo) { + convert = function(length:: num) :: num { + 100000 * length + } } -TEST(Context, full_RuleContext){ - /* - "rule context:: childs(Child)\n" - " case artefact(Item)\n" - " {\n" - " artefact_depends(Item, Child)\n" - " }"; - */ - - PassManager* man = PassManager::prepareForCode( - " case context:: toMilli {\n" - " convert = function(length::int)::int{\n" - " 10 * length\n" - " }\n" - " }\n" - "\n" - " case context:: toCenti {\n" - " convert = function(length::int)::int{\n" - " length\n" - " }\n" - " }\n" - "\n" - " main=function::int; entry {\n" - " context:: output(milli).\n" - "\n" - " rule context::toMilli\n" - " case output(milli) {true}\n" - "\n" - " convert(1)\n" - " }" ); - man->clasp->addRawScript("true."); - - int (*entry)() = (int (*)()) man->run(); - ASSERT_EQ(10, entry()); +case context:: convert(milli, kilo) { + convert = function(length:: num) :: num { + 1000000 * length + } } -TEST(Context, full_InheritedRuleContext){ - PassManager* man = PassManager::prepareForCode( - " import raw (\"core/control-context.lp\") \n" - - " case context:: toMilli {\n" - " convert = function(length::int)::int{\n" - " 10 * length\n" - " }\n" - " }\n" +test1_fromCentiToKilo = function(a::num)::num { + context:: input(centi). - " case context:: toCenti {\n" - " convert = function(length::int)::int{\n" - " length\n" - " }\n" - " }\n" - "\n" - - "main = function(comm:: num)::num; entry{\n" - " rule context::X case output(X) {true}\n" - "\n" - " switch (comm)::num \n" - " case 0 {\n" - " context:: output(toMilli).\n" - " convert(1)\n" - " }\n" - " case default {\n" - " context:: output(toCenti).\n" - " convert(1)\n" - " }\n" - " }"); - - man->clasp->addRawScript("true."); - int (*entry)(int) = (int (*)(int)) man->run(); - ASSERT_EQ(10, entry(0)); - ASSERT_EQ(1, entry(1)); + toKilo(a) } -TEST(Context, full_LateContext){ - PassManager* man = PassManager::prepareForCode( - "import raw (\"core/control-context.lp\")\n" - - " convert = function(length:: num)::num{\n" - " 0\n" - " }\n" +test2_fromMilliToMeters = function(a::num)::num{ + context:: input(milli). - "case context:: milli {\n" - " convert = function(length:: num)::num{\n" - " 1000 * length\n" - " }\n" - "}\n" - "\n" - "case context:: centi {\n" - " convert = function(length:: num)::num{\n" - " 100 * length\n" - " }\n" - "}\n" - "\n" - "calculate = function(length:: num)::num {\n" - " convert(length)\n" - "}\n" - "\n" - "main = function(com:: num):: num; entry {\n" - " switch (com):: num \n" - " case 0 {\n" - " context:: milli.\n" - " calculate(1)\n" - " }\n" - "\n" - " case default{\n" - " context:: centi. \n" - " calculate(1)\n" - " }\n" - "}"); - - man->runWithoutCompilation(); - ContextQuery* queryContext = reinterpret_cast(man->clasp->getQuery(QueryId::ContextQuery)); - Expression exprSwitch = man->root->findFunction("main")->__entry->__body; - CodeScope* blockDefault = man->root->findFunction("main")->__entry->__body.operands[1].blocks.front(); - ScopePacked blockDefaultId = man->clasp->pack(blockDefault); - const ContextDomain& domDefault = queryContext->getContext(blockDefaultId); - ASSERT_EQ(1, domDefault.count(Expression(Atom("centi")))); - - std::list variants = man->root->getFunctionVariants("convert"); - for (ManagedFnPtr f: variants){ - const Expression guard = f->guardContext; - bool result = (guard.getValueString() == "centi" || guard.getValueString() == "milli" || !guard.isValid()); - ASSERT_TRUE(result); - } - - const FunctionContextDemand& demMain = queryContext->getFunctionDemand("main"); - ASSERT_EQ(0, demMain.size()); - - const FunctionContextDemand& demCalculate = queryContext->getFunctionDemand("calculate"); - ASSERT_EQ(1, demCalculate.size()); - ASSERT_EQ(1, demCalculate.right.count("convert")); + toMeters(a) +} - int (*entry)(int) = (int (*)(int)) man->run(); - ASSERT_EQ(1000, entry(0)); - ASSERT_EQ(100, entry(1)); +toMeters = function(a::num)::num { + rule context :: convert(X, meters) case input(X) {true} + + convert(a) } +toKilo = function(a::num)::num { + rule context :: convert(X, kilo) case input(X) {true} + + convert(a) +})CODE"; + + + + boost::scoped_ptr man(PassManager::prepareForCode(move(program))); + man->runWithoutCompilation(); +} diff --git a/documentation-tools/RemarkupParser/CMakeLists.txt b/documentation-tools/RemarkupParser/CMakeLists.txt new file mode 100644 index 0000000..d2f6ef6 --- /dev/null +++ b/documentation-tools/RemarkupParser/CMakeLists.txt @@ -0,0 +1,23 @@ +project(RemarkupParser) +aux_source_directory(cpp/ SRC_LIST) + +set(SRC_LIST ${SRC_LIST} + gen-cpp/PhabricatorParserPrivate.cpp + gen-cpp/remarkup_constants.cpp + gen-cpp/remarkup_types.cpp +) + +include_directories(cpp/ gen-cpp/) +set(REMARKUP_PARSER_INCLUDE_DIRS + ${CMAKE_CURRENT_SOURCE_DIR}/cpp/ + ${CMAKE_CURRENT_SOURCE_DIR}/gen-cpp/ + +CACHE INTERNAL "REMARKUP_PARSER: Include Directories" FORCE +) + + + +add_library(${PROJECT_NAME} SHARED ${SRC_LIST}) +target_link_libraries(${PROJECT_NAME} thrift-1.0.0-dev Qt5::Core) + +set(CMAKE_BUILD_TYPE Debug) diff --git a/documentation-tools/RemarkupParser/cpp/remarkupparser.cpp b/documentation-tools/RemarkupParser/cpp/remarkupparser.cpp new file mode 100644 index 0000000..5926147 --- /dev/null +++ b/documentation-tools/RemarkupParser/cpp/remarkupparser.cpp @@ -0,0 +1,96 @@ +#include "remarkupparser.h" +#include "PhabricatorParserPrivate.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace std; +using namespace std; +using namespace apache::thrift; +using namespace apache::thrift::protocol; +using namespace apache::thrift::transport; + +const char* SOCKET_NAME = tempnam(0,0); +const string SERVER_INDEX = "/private/prg/code/xreate/documentation-tools/RemarkupParser/php/index.php"; +const string LOCK_FILENAME = "/var/lock/phabricator-parser"; + +void +RemarkupParser::startPhabricatorParserServer(){ + //acquire lock: +// if (-1 == open( LOCK_FILENAME.c_str(), O_RDWR | O_CREAT | O_EXCL, 0666 )){ +// qDebug()<<"Lock acquiring failure"; +// return; +// } + + phpServerId = fork(); + if(phpServerId < 0 ) + { + qDebug()<<"fork failure"; + return; + } + + //child + if(phpServerId == 0) + { + execl("/usr/bin/php", "php", SERVER_INDEX.c_str(), SOCKET_NAME, NULL); + _exit(0); + } + + qDebug()<<"successfully forked"; +} + +RemarkupParser::RemarkupParser(){ + startPhabricatorParserServer(); +} + +bool +RemarkupParser::connect(){ + qDebug()<<"RemarkupParser::connect"; + if (!QFile::exists(QString::fromLatin1(SOCKET_NAME))) return false; + + boost::shared_ptr socket(new TSocket(SOCKET_NAME)); + boost::shared_ptr transport(new TBufferedTransport(socket)); + boost::shared_ptr protocol(new TBinaryProtocol(transport)); + + client = new PhabricatorParserPrivateClient (protocol); + transport->open(); + + return true; +} + +Blocks +RemarkupParser::parse(const QString& text) +{ + qDebug()<<"RemarkupParser:: parsing"; + std::vector output; + + if (!client){ + qDebug() << "Parser does not connected"; + return output; + } + + try { + client->parse(output, text.toStdString()); + } catch (TException& tx) { + qDebug() << "RemarkupParser exception: " << tx.what(); + } + + return output; +} + +RemarkupParser::~RemarkupParser(){ + delete client; + // remove(LOCK_FILENAME.c_str()); + + qDebug()<<"RemarkupParser::kill PHP"; + kill(phpServerId, SIGKILL); + remove(SOCKET_NAME); +} diff --git a/documentation-tools/RemarkupParser/cpp/remarkupparser.h b/documentation-tools/RemarkupParser/cpp/remarkupparser.h new file mode 100644 index 0000000..87b15f8 --- /dev/null +++ b/documentation-tools/RemarkupParser/cpp/remarkupparser.h @@ -0,0 +1,26 @@ +#ifndef PHABRICATORPARSER_H +#define PHABRICATORPARSER_H + +#include "remarkup_types.h" +#include + +class PhabricatorParserPrivateClient; + +class RemarkupParser +{ +public: + RemarkupParser(); + ~RemarkupParser(); + + bool connect(); + bool isConnected() const {return client != NULL;} + Blocks parse(const QString& text); + +private: + __pid_t phpServerId; + + PhabricatorParserPrivateClient* client = NULL; + void startPhabricatorParserServer(); +}; + +#endif // PHABRICATORPARSER_H diff --git a/documentation-tools/RemarkupParser/php/RemarkupBlocksParser.php b/documentation-tools/RemarkupParser/php/RemarkupBlocksParser.php new file mode 100644 index 0000000..9315b80 --- /dev/null +++ b/documentation-tools/RemarkupParser/php/RemarkupBlocksParser.php @@ -0,0 +1,71 @@ +engine->splitTextIntoBlocks($text); + + $output = array(); + foreach($blocks as $block) { + $block['rule'] = get_class($block['rule']); + $output[] = new Block($block); + } + return $output; + } + + + public function __construct() { + $this->engine = $this->initialize(); + $this->engine->setMode(PhutilRemarkupEngine::MODE_TEXT); + } + + private function initialize() { + $engine = new PhutilRemarkupEngine(); + $engine->setConfig('uri.prefix', 'http://www.example.com/'); + + $engine->setConfig( + 'uri.allowed-protocols', + array( + 'http' => true, + 'mailto' => true, + 'tel' => true, + )); + + $rules = array(); + $rules[] = new PhutilRemarkupEscapeRemarkupRule(); + $rules[] = new PhutilRemarkupMonospaceRule(); + $rules[] = new PhutilRemarkupDocumentLinkRule(); + $rules[] = new PhutilRemarkupHyperlinkRule(); + $rules[] = new PhutilRemarkupBoldRule(); + $rules[] = new PhutilRemarkupItalicRule(); + $rules[] = new PhutilRemarkupDelRule(); + $rules[] = new PhutilRemarkupUnderlineRule(); + $rules[] = new PhutilRemarkupHighlightRule(); + + $blocks = array(); + $blocks[] = new PhutilRemarkupQuotesBlockRule(); + $blocks[] = new PhutilRemarkupReplyBlockRule(); + $blocks[] = new PhutilRemarkupHeaderBlockRule(); + $blocks[] = new PhutilRemarkupHorizontalRuleBlockRule(); + $blocks[] = new PhutilRemarkupCodeBlockRule(); + $blocks[] = new PhutilRemarkupLiteralBlockRule(); + $blocks[] = new PhutilRemarkupNoteBlockRule(); + $blocks[] = new PhutilRemarkupTableBlockRule(); + $blocks[] = new PhutilRemarkupSimpleTableBlockRule(); + $blocks[] = new PhutilRemarkupDefaultBlockRule(); + $blocks[] = new PhutilRemarkupListBlockRule(); + $blocks[] = new PhutilRemarkupInterpreterBlockRule(); + + foreach ($blocks as $block) { + if (!($block instanceof PhutilRemarkupCodeBlockRule)) { + $block->setMarkupRules($rules); + } + } + + $engine->setBlockRules($blocks); + + return $engine; + } + +} diff --git a/documentation-tools/RemarkupParser/php/index.php b/documentation-tools/RemarkupParser/php/index.php new file mode 100644 index 0000000..05f26b3 --- /dev/null +++ b/documentation-tools/RemarkupParser/php/index.php @@ -0,0 +1,193 @@ +registerNamespace('Thrift', '/opt/thrift/lib/php/lib'); +$loader->register(); + +$GEN_DIR = dirname ( __FILE__ ).'/../gen-php'; +set_include_path(get_include_path() . PATH_SEPARATOR . $GEN_DIR); +require_once 'Types.php'; +require_once 'PhabricatorParserPrivate.php'; +//require_once 'RemarkupBlocksParser.php'; + +class RemarkupBlocksParser implements PhabricatorParserPrivateIf{ + + private $engine = null; + + public function parse($text) { + echo "[PHP] RemarkupBlocksParser:: parsing text \n"; + + $blocks = $this->engine->splitTextIntoBlocks($text); + + $output = array(); + foreach($blocks as $block) { + $additionalData = ""; + + if ($block['rule'] instanceof PhutilRemarkupNoteBlockRule){ + $additionalData = $block['rule']->additionalData; + } + + $block['rule'] = get_class($block['rule']) . $additionalData; + $output[] = new Block($block); + } + + return $output; + } + + + public function __construct() { + $this->engine = $this->initialize(); + $this->engine->setMode(PhutilRemarkupEngine::MODE_TEXT); + } + + private function initialize() { + $engine = new PhutilRemarkupEngine(); + $engine->setConfig('uri.prefix', 'http://www.example.com/'); + + $engine->setConfig( + 'uri.allowed-protocols', + array( + 'http' => true, + 'mailto' => true, + 'tel' => true, + )); + + $rules = array(); + $rules[] = new PhutilRemarkupEscapeRemarkupRule(); + $rules[] = new PhutilRemarkupMonospaceRule(); + $rules[] = new PhutilRemarkupDocumentLinkRule(); + $rules[] = new PhutilRemarkupHyperlinkRule(); + $rules[] = new PhutilRemarkupBoldRule(); + $rules[] = new PhutilRemarkupItalicRule(); + $rules[] = new PhutilRemarkupDelRule(); + $rules[] = new PhutilRemarkupUnderlineRule(); + $rules[] = new PhutilRemarkupHighlightRule(); + + $blocks = array(); + $blocks[] = new PhutilRemarkupQuotesBlockRule(); + $blocks[] = new PhutilRemarkupReplyBlockRule(); + $blocks[] = new PhutilRemarkupHeaderBlockRule(); + $blocks[] = new PhutilRemarkupHorizontalRuleBlockRule(); + $blocks[] = new PhutilRemarkupCodeBlockRule(); + $blocks[] = new PhutilRemarkupLiteralBlockRule(); + $blocks[] = new PhutilRemarkupNoteBlockRule(); + $blocks[] = new PhutilRemarkupTableBlockRule(); + $blocks[] = new PhutilRemarkupSimpleTableBlockRule(); + $blocks[] = new PhutilRemarkupDefaultBlockRule(); + $blocks[] = new PhutilRemarkupListBlockRule(); + $blocks[] = new PhutilRemarkupInterpreterBlockRule(); + + foreach ($blocks as $block) { + if (!($block instanceof PhutilRemarkupCodeBlockRule)) { + $block->setMarkupRules($rules); + } + } + + $engine->setBlockRules($blocks); + + return $engine; + } + +} + +$handler = new RemarkupBlocksParser(); +$processor = new PhabricatorParserPrivateProcessor($handler); + +$socketName = $argv[1]; +echo "[PHP] socketName: ". $socketName . "\n"; +//$transport = new TBufferedTransport(new \Thrift\Transport\TSocketServer("unix://".$socketName)); +$transport = new \Thrift\Transport\TSocketServer("unix://".$socketName); +$protocol = new TBinaryProtocol($transport, true, true); + +echo "[PHP] RemarkupBlocksParser:: loading.. \n"; + +$transport->open(); + + for (;;) { + $processor->process($protocol, $protocol); + } + +$transport->close(); + + + diff --git a/documentation-tools/remarkup/php/thrift-example.php b/documentation-tools/RemarkupParser/php/thrift-example.php similarity index 100% rename from documentation-tools/remarkup/php/thrift-example.php rename to documentation-tools/RemarkupParser/php/thrift-example.php diff --git a/documentation-tools/RemarkupParser/remarkup.thrift b/documentation-tools/RemarkupParser/remarkup.thrift new file mode 100644 index 0000000..22ea2c2 --- /dev/null +++ b/documentation-tools/RemarkupParser/remarkup.thrift @@ -0,0 +1,11 @@ +struct Block { + 1: i32 start, + 2: i32 num_lines, + 3: string rule +} + +typedef list Blocks + +service PhabricatorParserPrivate { + Blocks parse(1: string text) +} diff --git a/documentation-tools/remarkup/shared.thrift b/documentation-tools/RemarkupParser/shared.thrift similarity index 100% rename from documentation-tools/remarkup/shared.thrift rename to documentation-tools/RemarkupParser/shared.thrift diff --git a/documentation-tools/RemarkupParser/test/main.cpp b/documentation-tools/RemarkupParser/test/main.cpp new file mode 100644 index 0000000..5361187 --- /dev/null +++ b/documentation-tools/RemarkupParser/test/main.cpp @@ -0,0 +1,46 @@ +#include + +#include +#include +#include + +#include "gen-cpp/PhabricatorParserPrivate.h" + +using namespace std; +using namespace apache::thrift; +using namespace apache::thrift::protocol; +using namespace apache::thrift::transport; + +int main() { + boost::shared_ptr socket(new TSocket("/tmp/phabricator-parser")); + boost::shared_ptr transport(new TBufferedTransport(socket)); + boost::shared_ptr protocol(new TBinaryProtocol(transport)); + PhabricatorParserPrivateClient client(protocol); + + string text = +"= Large Header = \n \ + \n\ +== Smaller Header == \n\ + \n\ +## This is a Header As Well\n\ + \n\ +Also a Large Header \n\ +=================== \n\ + \n\ +Also a Smaller Header \n\ +---------------------"; + try { + transport->open(); + + + for (int i=0; i +#include "phrictionclient.h" +#include + +using namespace std; + +int main(int argc, char** argv) +{ + QCoreApplication a(argc, argv); + + PhrictionClient c("http://192.168.11.130:80/api", "user", "api-ko4x6j4hujleutuxlntdqj37wfjj", "bydxwfn7pey6ack274dilywrgakkhjpmwrgieedqxlnxpocwovisz3ysgndzagtmft33e2tx3xyatwklzbrrzhyyonibim7nwbnpqo36fmer7hjvv5mmmammxf3fybqn52dgsmczrj44e4l4r774ajyiydmcxughsttgonydjsgf3b2rmvtunjtez4zbtcqmwrhjl3aijv22jefvymu2oz3tzu3zlv4lk226riq5utudndd6ae4ixzqmzyo6pqr"); + c.create(); + + return a.exec(); +} + diff --git a/documentation-tools/conduit-client/CMakeLists.txt b/documentation-tools/conduit-client/CMakeLists.txt new file mode 100644 index 0000000..ac9fd1d --- /dev/null +++ b/documentation-tools/conduit-client/CMakeLists.txt @@ -0,0 +1,16 @@ +project(conduitclient) +cmake_minimum_required(VERSION 2.8) + +aux_source_directory(. SRC_LIST) +set(CMAKE_BUILD_TYPE Debug) + +add_library(${PROJECT_NAME} SHARED ${SRC_LIST}) +target_link_libraries(${PROJECT_NAME} Qt5::Core Qt5::Network) + +set(CONDUIT_CLIENT_INCLUDE_PATH + ${CMAKE_CURRENT_SOURCE_DIR}/ + + CACHE INTERNAL "Conduit client: Include Directories" FORCE +) + +message("CONDUIT_CLIENT_INCLUDE_PATH:" ${CONDUIT_CLIENT_INCLUDE_PATH}) diff --git a/documentation-tools/conduit-client/conduitclient.cpp b/documentation-tools/conduit-client/conduitclient.cpp new file mode 100644 index 0000000..0b88e83 --- /dev/null +++ b/documentation-tools/conduit-client/conduitclient.cpp @@ -0,0 +1,104 @@ +#include "conduitclient.h" +#include "QtNetwork/QNetworkAccessManager" +#include +#include +#include +#include +#include +#include +#include + +QEventLoopLocker* lockerWaitingResponce = 0; + +ConduitClient::~ConduitClient(){} + +ConduitClient::ConduitClient(const QString& uri, const QString& user, const QString& token, const QString& sertificate) + : QObject(nullptr), m_URI(uri), m_user(user), m_conduitToken(token), m_Sertificate(sertificate), m_manager(new QNetworkAccessManager()), m_loopWaitingResponce(new QEventLoop()) +{ + connect(m_manager, SIGNAL(finished(QNetworkReply*)), + this, SLOT(replyReceived(QNetworkReply*))); +} + +bool +ConduitClient::createSession() +{ + const QString token = QString("%1").arg(time(0)); + const QString signatureRaw = token + m_Sertificate; + QByteArray signatureHash = QCryptographicHash::hash(signatureRaw.toLatin1(), QCryptographicHash::Sha1); + QString signatureHashLatin = QString::fromLatin1(signatureHash.toHex()); + QJsonObject query; + query["authToken"] = token; + query["authSignature"] =signatureHashLatin; + query["client"] = "juffed-client"; + query["clientVersion"] = "1"; + query["user"] = m_user; + + QJsonObject reply = requestRaw("conduit.connect", query); + + //Example: "result\":{\"connectionID\":17,\"sessionKey\":\"l6jih3u7kxz3i624tewq2fvvmvmjiwzzp5ddicnk\" + if (reply.contains("result")){ + QJsonObject sessionData = reply.find("result").value().toObject(); + + if (sessionData.empty()) return false; + m_SessionKey = sessionData["sessionKey"].toString(); + m_ConnectionID = sessionData["connectionID"].toInt();; + return true; + } + + return false; +} + +QJsonObject +ConduitClient::request(const QString& method, const QJsonObject& json){ + if (m_SessionKey.isNull()) { + if (!createSession()){ + return QJsonObject(); + } + } + + QJsonObject metaQuery; + metaQuery["sessionKey"] = m_SessionKey; + metaQuery["connectionID"] = m_ConnectionID; + metaQuery["token"] = m_conduitToken; + + QJsonObject query(json); + query["__conduit__"] = metaQuery; + + return requestRaw(method, query); +} + +void +ConduitClient::replyReceived(QNetworkReply* reply){ + m_serverReply = reply; + + delete lockerWaitingResponce; + lockerWaitingResponce = 0; +} + +QJsonObject +ConduitClient::requestRaw(const QString& method, const QJsonObject& json) +{ + QUrl server(m_URI + "/" + method); + QUrlQuery query; + + query.addQueryItem("output", "json"); + query.addQueryItem("__conduit__", "true"); + query.addQueryItem("params", QJsonDocument(json).toJson(QJsonDocument::Compact)); + + server.setQuery(query); + + qDebug()<get(request); + lockerWaitingResponce = new QEventLoopLocker(m_loopWaitingResponce); + m_loopWaitingResponce->exec(); + + QString replyJson(m_serverReply->readAll()); + qDebug() << replyJson; + delete m_serverReply; + + return QJsonDocument::fromJson(replyJson.toUtf8()).object(); +} + +//void +//ConduitClient::req diff --git a/documentation-tools/conduit-client/conduitclient.h b/documentation-tools/conduit-client/conduitclient.h new file mode 100644 index 0000000..bbdc1dc --- /dev/null +++ b/documentation-tools/conduit-client/conduitclient.h @@ -0,0 +1,48 @@ +#ifndef CONDUITCLIENT_H +#define CONDUITCLIENT_H + +#include +#include +#include + +class QNetworkAccessManager; +class QNetworkReply; +class QEventLoop; + +class ConduitClient: public QObject { + Q_OBJECT + +public: + ConduitClient(const QString& uri, const QString& user, const QString& token, const QString& sertificate); + ~ConduitClient(); + QJsonObject request(const QString& method, const QJsonObject& json); + bool createSession(); + +public slots: + void replyReceived(QNetworkReply*); + +private: + QString m_URI; + QString m_user; + QString m_conduitToken; + QString m_SessionKey; + int m_ConnectionID; + QString m_Sertificate; + + QNetworkAccessManager* m_manager; + QNetworkReply* m_serverReply; + QEventLoop* m_loopWaitingResponce; + + QJsonObject requestRaw(const QString& method, const QJsonObject& json); + + +// private int? ; +// ClientName +// ClientVersion +// User +// Certificate + + +}; + +#endif // CONDUITCLIENT_H diff --git a/documentation-tools/conduit-client/phrictionclient.cpp b/documentation-tools/conduit-client/phrictionclient.cpp new file mode 100644 index 0000000..635228a --- /dev/null +++ b/documentation-tools/conduit-client/phrictionclient.cpp @@ -0,0 +1,85 @@ +#include "phrictionclient.h" +#include "conduitclient.h" + +PhrictionClient::PhrictionClient(const QString& uri, const QString& user, const QString& token, const QString& sertificate) + : transport (new ConduitClient(uri, user, token, sertificate)) +{ +} + +bool +PhrictionClient::createDocument(QString slug, QString title, QString content, QString description){ + //try to create + QJsonObject request{ + {"slug", slug} + ,{"title", title} + ,{"content", content} + ,{"description", description} + }; + + QJsonObject answer= transport->request("phriction.create", request); + QJsonValue error = answer.value("error_code"); + if (!error.isUndefined() && error.isNull()){ + return true; + } + + return false; +} + +bool +PhrictionClient::updateDocument(QString slug, QString title, QString content, QString description){ + //try to create + QJsonObject request{ + {"slug", slug} + ,{"title", title} + ,{"content", content} + ,{"description", description} + }; + + QJsonObject answer= transport->request("phriction.edit", request); + QJsonValue error = answer.value("error_code"); + if (!error.isUndefined() && error.isNull()){ + return true; + } + + return false; +} + +bool PhrictionClient::existsDocument(const QString& slug){ + QJsonObject request{ + {"slug", slug} + }; + + QJsonObject answer= transport->request("phriction.info", request); + QJsonValue status = answer.value("result").toObject().value("status"); + + if (status.toString() == "exists"){ + return true; + } + + return false; +} + +bool +PhrictionClient::publishDocument(QString slug, QString title, QString content, QString description){ + if (existsDocument(slug)){ + return updateDocument(slug, title, content, description); + } + + QStringList slugParts = slug.split('/'); + slugParts.removeLast(); + + QString slugParent; + for (QString part: slugParts){ + slugParent += part + "/"; + if (! existsDocument(slugParent)){ + createDocument(slugParent, part, " ", ""); + } + } + + return createDocument(slug, title, content, description); +} + + +PhrictionClient::~PhrictionClient(){ + delete transport; +} diff --git a/documentation-tools/conduit-client/phrictionclient.h b/documentation-tools/conduit-client/phrictionclient.h new file mode 100644 index 0000000..3c6c24e --- /dev/null +++ b/documentation-tools/conduit-client/phrictionclient.h @@ -0,0 +1,23 @@ +#ifndef PHRICTIONCLIENT_H +#define PHRICTIONCLIENT_H +#include + +class ConduitClient; + +class PhrictionClient +{ +public: + PhrictionClient(const QString& uri, const QString& user, const QString& token, const QString& sertificate); + ~PhrictionClient(); + + + bool publishDocument(QString slug, QString title, QString content, QString description); +private: + ConduitClient* transport; + + bool createDocument(QString slug, QString title, QString content, QString description); + bool updateDocument(QString slug, QString title, QString content, QString description); + bool existsDocument(const QString& slug); +}; + +#endif // PHRICTIONCLIENT_H diff --git a/documentation-tools/juffed-lexers/qscilexerremarkup.cpp b/documentation-tools/juffed-lexers/qscilexerremarkup.cpp new file mode 100644 index 0000000..1e3c3b5 --- /dev/null +++ b/documentation-tools/juffed-lexers/qscilexerremarkup.cpp @@ -0,0 +1,171 @@ +#include "qscilexerremarkup.h" +#include +#include + +enum + { + Default = 0, + Hidden, + Bold, + Italic, + Del, + DocumentLink, + EscapeRemarkup, + Hightlight, + HyperLink, + + Monospace, + Underline + }; + +QRegularExpression patternBold("\\*\\*(.+?)\\*\\*"); +QRegularExpression patternItalic("(?SendScintilla(QsciScintilla::SCI_GETTEXTRANGE, start, end, chars); + QString source = QString::fromUtf8(chars); + delete [] chars; + + runPhutilRemarkupBoldRule(source,start); + runPhutilRemarkupItalicRule(source,start); +} + +void +QsciLexerRemarkup::runPhutilRemarkupBoldRule(const QString& source, int index){ + int pos =0; + while(true) { + QRegularExpressionMatch result = patternBold.match(source, pos); + if (!result.hasMatch()){break;} + + //hide: + startStyling(index + result.capturedStart(0)); + setStyling(result.capturedLength(0), Hidden); + + QString r = result.captured(1); + startStyling(index + result.capturedStart(1)); + setStyling(result.capturedLength(1), Bold); + pos = result.capturedEnd(1) + 1; + } +} + +void +QsciLexerRemarkup::runPhutilRemarkupItalicRule(const QString& source, int index){ + int pos =0; + while(true) { + QRegularExpressionMatch result = patternItalic.match(source, pos); + if (!result.hasMatch()){break;} + + //hide: + startStyling(index + result.capturedStart(0)); + setStyling(result.capturedLength(0), Hidden); + + startStyling(index + result.capturedStart(1)); + setStyling(result.capturedLength(1), Italic); + pos = result.capturedEnd(1) + 1; + } +} + +//"PhutilRemarkupBoldRule.php: **bold** +//PhutilRemarkupItalicRule.php: //italic// + +/* +"PhutilRemarkupDelRule.php" +"PhutilRemarkupDocumentLinkRule.php" +"PhutilRemarkupEscapeRemarkupRule.php" +"PhutilRemarkupHighlightRule.php" +"PhutilRemarkupHyperlinkRule.php" + +"PhutilRemarkupLinebreaksRule.php" +"PhutilRemarkupMonospaceRule.php" +"PhutilRemarkupRule.php" +"PhutilRemarkupUnderlineRule.php" +*/ + diff --git a/documentation-tools/juffed-lexers/qscilexerremarkup.h b/documentation-tools/juffed-lexers/qscilexerremarkup.h new file mode 100644 index 0000000..597319d --- /dev/null +++ b/documentation-tools/juffed-lexers/qscilexerremarkup.h @@ -0,0 +1,29 @@ +#ifndef QSCILEXERREMARKUP_H +#define QSCILEXERREMARKUP_H + +#include +#include + +class QsciLexerRemarkup : public QsciLexerCustom +{ + Q_OBJECT + +public: + virtual QColor defaultColor(int style) const; + virtual QFont defaultFont(int style) const; + virtual QColor defaultPaper(int style) const; + QsciStyle getStyle(int style); + + QsciLexerRemarkup(QObject * parent = 0); + ~QsciLexerRemarkup(); + + void styleText(int start, int end); + QString description(int style) const; + const char* language() const; + +private: + void runPhutilRemarkupBoldRule(const QString& source, int index); + void runPhutilRemarkupItalicRule(const QString& source, int index); +}; + +#endif // QSCILEXERREMARKUP_H diff --git a/documentation-tools/juffed-lexers/remarkup.xml b/documentation-tools/juffed-lexers/remarkup.xml new file mode 100644 index 0000000..b47b7ab --- /dev/null +++ b/documentation-tools/juffed-lexers/remarkup.xml @@ -0,0 +1,19 @@ + + + + +