diff --git a/core/control-context.lp b/core/control-context.lp index f815057..27a27e4 100644 --- a/core/control-context.lp +++ b/core/control-context.lp @@ -1,23 +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, _). -bind_scope_demand(Scope, FnCallee):- bind_scope_demand(ScopeChild, FnCallee), cfa_parent(ScopeChild, scope(Scope)). -bind_scope_demand(Scope, FnCallee):- cfa_call(Scope, FnChild), bind_function_demand(FnChild, FnCallee), not bind_scope_decision(Scope, FnCallee, _). -bind_function_demand(Fn, Demand):- bind_scope_demand(Scope, Demand), cfa_parent(Scope, function(Fn)). +%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). \ No newline at end of file +%scope_function(Scope, Fn) :- cfa_parent(Scope, scope(ScopeParent)), scope_function(ScopeParent, Fn). diff --git a/documentation-tools/remarkup/php/index.php b/documentation-tools/remarkup/php/index.php new file mode 100644 index 0000000..2cd89b7 --- /dev/null +++ b/documentation-tools/remarkup/php/index.php @@ -0,0 +1,347 @@ +buildNewTestEngine(); +// $actual_output = $engine->markupText("**duck quack**"); +// echo $actual_output; +// +// +//// foreach (Filesystem::listDirectory($root, $hidden = false) as $file) { +//// echo $root.$file; +//// $contents = Filesystem::readFile($root.$file); +//// +//// $result = "\n" . $this->markupText($root.$file); +//// echo $result; +//// } +// +// $result =""; +// return $result; +// } +// +// private function markupText($markup_file) { +// $contents = Filesystem::readFile($markup_file); +// $file = basename($markup_file); +// +// $parts = explode("\n~~~~~~~~~~\n", $contents); +//// $this->assertEqual(3, count($parts), $markup_file); +// +// list($input_remarkup, $expected_output, $expected_text) = $parts; +// +// $engine = $this->buildNewTestEngine(); +// +// switch ($file) { +// case 'raw-escape.txt': +// +// // NOTE: Here, we want to test PhutilRemarkupEscapeRemarkupRule and +// // PhutilRemarkupBlockStorage, which are triggered by "\1". In the +// // test, "~" is used as a placeholder for "\1" since it's hard to type +// // "\1". +// +// $input_remarkup = str_replace('~', "\1", $input_remarkup); +// $expected_output = str_replace('~', "\1", $expected_output); +// $expected_text = str_replace('~', "\1", $expected_text); +// break; +// case 'toc.txt': +// $engine->setConfig('header.generate-toc', true); +// break; +// } +// +// $actual_output = (string)$engine->markupText($input_remarkup); +// +// switch ($file) { +// case 'toc.txt': +// $table_of_contents = +// PhutilRemarkupHeaderBlockRule::renderTableOfContents($engine); +// $actual_output = $table_of_contents."\n\n".$actual_output; +// break; +// } +// +//// $this->assertEqual( +//// $expected_output, +//// $actual_output, +//// pht("Failed to markup HTML in file '%s'.", $file)); +// +// $engine->setMode(PhutilRemarkupEngine::MODE_TEXT); +// $actual_output = (string)$engine->markupText($input_remarkup); +// +// return $actual_output; +//// $this->assertEqual( +//// $expected_text, +//// $actual_output, +//// pht("Failed to markup text in file '%s'.", $file)); +// } +// +// private function buildNewTestEngine() { +// echo "preprocess0"; +// $engine = new PhutilRemarkupEngine(); +// $engine->setConfig('uri.prefix', 'http://www.example.com/'); +// +// $engine->setConfig( +// 'uri.allowed-protocols', +// array( +// 'http' => true, +// 'mailto' => true, +// 'tel' => true, +// )); +// +// echo "preprocess01"; +// $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(); +// +// echo "preprocess02"; +// $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(); +// +// echo "preprocess03"; +// foreach ($blocks as $block) { +// if (!($block instanceof PhutilRemarkupCodeBlockRule)) { +// $block->setMarkupRules($rules); +// } +// } +// +// echo "preprocess04"; +// $engine->setBlockRules($blocks); +// +// return $engine; +// } +// +//} +// +//echo "aaaa"; +//$test = new PhutilRemarkupEngineTestCase(); +//$output = $test->testEngine(); + +namespace tutorial\php; + +error_reporting(E_ALL); + +require_once '/opt/thrift/lib/php/lib/Thrift/ClassLoader/ThriftClassLoader.php'; + +use Thrift\ClassLoader\ThriftClassLoader; + +$GEN_DIR = '/private/prg/code/tests/php-cpp-integration-test/thrift/gen-php'; + +$loader = new ThriftClassLoader(); +$loader->registerNamespace('Thrift', '/opt/thrift/lib/php/lib'); +$loader->registerDefinition('shared', $GEN_DIR); +$loader->registerDefinition('tutorial', $GEN_DIR); +$loader->register(); + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +/* + * This is not a stand-alone server. It should be run as a normal + * php web script (like through Apache's mod_php) or as a cgi script + * (like with the included runserver.py). You can connect to it with + * THttpClient in any language that supports it. The PHP tutorial client + * will work if you pass it the argument "--http". + */ + +if (php_sapi_name() == 'cli') { + ini_set("display_errors", "stderr"); +} + +use Thrift\Protocol\TBinaryProtocol; +use Thrift\Transport\TPhpStream; +use Thrift\Transport\TBufferedTransport; + +class CalculatorHandler implements \tutorial\CalculatorIf { + protected $log = array(); + + public function ping() { + error_log("ping()"); + } + + public function add($num1, $num2) { + error_log("add({$num1}, {$num2})"); + return $num1 + $num2; + } + + public function calculate($logid, \tutorial\Work $w) { + error_log("calculate({$logid}, {{$w->op}, {$w->num1}, {$w->num2}})"); + switch ($w->op) { + case \tutorial\Operation::ADD: + $val = $w->num1 + $w->num2; + break; + case \tutorial\Operation::SUBTRACT: + $val = $w->num1 - $w->num2; + break; + case \tutorial\Operation::MULTIPLY: + $val = $w->num1 * $w->num2; + break; + case \tutorial\Operation::DIVIDE: + if ($w->num2 == 0) { + $io = new \tutorial\InvalidOperation(); + $io->whatOp = $w->op; + $io->why = "Cannot divide by 0"; + throw $io; + } + $val = $w->num1 / $w->num2; + break; + default: + $io = new \tutorial\InvalidOperation(); + $io->whatOp = $w->op; + $io->why = "Invalid Operation"; + throw $io; + } + + $log = new \shared\SharedStruct(); + $log->key = $logid; + $log->value = (string)$val; + $this->log[$logid] = $log; + + return $val; + } + + public function getStruct($key) { + error_log("getStruct({$key})"); + // This actually doesn't work because the PHP interpreter is + // restarted for every request. + //return $this->log[$key]; + return new \shared\SharedStruct(array("key" => $key, "value" => "PHP is stateless!")); + } + + public function zip() { + error_log("zip()"); + } + +}; + +header('Content-Type', 'application/x-thrift'); +if (php_sapi_name() == 'cli') { + echo "\r\n"; +} + +$handler = new CalculatorHandler(); +$processor = new \tutorial\CalculatorProcessor($handler); + +//boost::shared_ptr socket(new TSocket("localhost", 9090)); +// boost::shared_ptr transport(new TBufferedTransport()); +$transport = new TBufferedTransport(new \Thrift\Transport\TSocketServer('unix:///tmp/mysock3')); +$protocol = new TBinaryProtocol($transport, true, true); + +$transport->open(); +for (;;) { + $processor->process($protocol, $protocol); +} +$transport->close(); \ No newline at end of file diff --git a/documentation-tools/remarkup/php/thrift-example.php b/documentation-tools/remarkup/php/thrift-example.php new file mode 100644 index 0000000..0cb8701 --- /dev/null +++ b/documentation-tools/remarkup/php/thrift-example.php @@ -0,0 +1,347 @@ +buildNewTestEngine(); +// $actual_output = $engine->markupText("**duck quack**"); +// echo $actual_output; +// +// +//// foreach (Filesystem::listDirectory($root, $hidden = false) as $file) { +//// echo $root.$file; +//// $contents = Filesystem::readFile($root.$file); +//// +//// $result = "\n" . $this->markupText($root.$file); +//// echo $result; +//// } +// +// $result =""; +// return $result; +// } +// +// private function markupText($markup_file) { +// $contents = Filesystem::readFile($markup_file); +// $file = basename($markup_file); +// +// $parts = explode("\n~~~~~~~~~~\n", $contents); +//// $this->assertEqual(3, count($parts), $markup_file); +// +// list($input_remarkup, $expected_output, $expected_text) = $parts; +// +// $engine = $this->buildNewTestEngine(); +// +// switch ($file) { +// case 'raw-escape.txt': +// +// // NOTE: Here, we want to test PhutilRemarkupEscapeRemarkupRule and +// // PhutilRemarkupBlockStorage, which are triggered by "\1". In the +// // test, "~" is used as a placeholder for "\1" since it's hard to type +// // "\1". +// +// $input_remarkup = str_replace('~', "\1", $input_remarkup); +// $expected_output = str_replace('~', "\1", $expected_output); +// $expected_text = str_replace('~', "\1", $expected_text); +// break; +// case 'toc.txt': +// $engine->setConfig('header.generate-toc', true); +// break; +// } +// +// $actual_output = (string)$engine->markupText($input_remarkup); +// +// switch ($file) { +// case 'toc.txt': +// $table_of_contents = +// PhutilRemarkupHeaderBlockRule::renderTableOfContents($engine); +// $actual_output = $table_of_contents."\n\n".$actual_output; +// break; +// } +// +//// $this->assertEqual( +//// $expected_output, +//// $actual_output, +//// pht("Failed to markup HTML in file '%s'.", $file)); +// +// $engine->setMode(PhutilRemarkupEngine::MODE_TEXT); +// $actual_output = (string)$engine->markupText($input_remarkup); +// +// return $actual_output; +//// $this->assertEqual( +//// $expected_text, +//// $actual_output, +//// pht("Failed to markup text in file '%s'.", $file)); +// } +// +// private function buildNewTestEngine() { +// echo "preprocess0"; +// $engine = new PhutilRemarkupEngine(); +// $engine->setConfig('uri.prefix', 'http://www.example.com/'); +// +// $engine->setConfig( +// 'uri.allowed-protocols', +// array( +// 'http' => true, +// 'mailto' => true, +// 'tel' => true, +// )); +// +// echo "preprocess01"; +// $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(); +// +// echo "preprocess02"; +// $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(); +// +// echo "preprocess03"; +// foreach ($blocks as $block) { +// if (!($block instanceof PhutilRemarkupCodeBlockRule)) { +// $block->setMarkupRules($rules); +// } +// } +// +// echo "preprocess04"; +// $engine->setBlockRules($blocks); +// +// return $engine; +// } +// +//} +// +//echo "aaaa"; +//$test = new PhutilRemarkupEngineTestCase(); +//$output = $test->testEngine(); + +namespace tutorial\php; + +error_reporting(E_ALL); + +require_once '/opt/thrift/lib/php/lib/Thrift/ClassLoader/ThriftClassLoader.php'; + +use Thrift\ClassLoader\ThriftClassLoader; + +$GEN_DIR = '/private/prg/code/tests/php-cpp-integration-test/thrift/gen-php'; + +$loader = new ThriftClassLoader(); +$loader->registerNamespace('Thrift', '/opt/thrift/lib/php/lib'); +$loader->registerDefinition('shared', $GEN_DIR); +$loader->registerDefinition('tutorial', $GEN_DIR); +$loader->register(); + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +/* + * This is not a stand-alone server. It should be run as a normal + * php web script (like through Apache's mod_php) or as a cgi script + * (like with the included runserver.py). You can connect to it with + * THttpClient in any language that supports it. The PHP tutorial client + * will work if you pass it the argument "--http". + */ + +if (php_sapi_name() == 'cli') { + ini_set("display_errors", "stderr"); +} + +use Thrift\Protocol\TBinaryProtocol; +use Thrift\Transport\TPhpStream; +use Thrift\Transport\TBufferedTransport; + +class CalculatorHandler implements \tutorial\CalculatorIf { + protected $log = array(); + + public function ping() { + error_log("ping()"); + } + + public function add($num1, $num2) { + error_log("add({$num1}, {$num2})"); + return $num1 + $num2; + } + + public function calculate($logid, \tutorial\Work $w) { + error_log("calculate({$logid}, {{$w->op}, {$w->num1}, {$w->num2}})"); + switch ($w->op) { + case \tutorial\Operation::ADD: + $val = $w->num1 + $w->num2; + break; + case \tutorial\Operation::SUBTRACT: + $val = $w->num1 - $w->num2; + break; + case \tutorial\Operation::MULTIPLY: + $val = $w->num1 * $w->num2; + break; + case \tutorial\Operation::DIVIDE: + if ($w->num2 == 0) { + $io = new \tutorial\InvalidOperation(); + $io->whatOp = $w->op; + $io->why = "Cannot divide by 0"; + throw $io; + } + $val = $w->num1 / $w->num2; + break; + default: + $io = new \tutorial\InvalidOperation(); + $io->whatOp = $w->op; + $io->why = "Invalid Operation"; + throw $io; + } + + $log = new \shared\SharedStruct(); + $log->key = $logid; + $log->value = (string)$val; + $this->log[$logid] = $log; + + return $val; + } + + public function getStruct($key) { + error_log("getStruct({$key})"); + // This actually doesn't work because the PHP interpreter is + // restarted for every request. + //return $this->log[$key]; + return new \shared\SharedStruct(array("key" => $key, "value" => "PHP is stateless!")); + } + + public function zip() { + error_log("zip()"); + } + +}; + +header('Content-Type', 'application/x-thrift'); +if (php_sapi_name() == 'cli') { + echo "\r\n"; +} + +$handler = new CalculatorHandler(); +$processor = new \tutorial\CalculatorProcessor($handler); + +//boost::shared_ptr socket(new TSocket("localhost", 9090)); +// boost::shared_ptr transport(new TBufferedTransport()); +$transport = new TBufferedTransport(new \Thrift\Transport\TSocketServer('unix:///tmp/mysock3')); +$protocol = new TBinaryProtocol($transport, true, true); + +$transport->open(); +for (;;) { + $processor->process($protocol, $protocol); +} +$transport->close(); diff --git a/documentation-tools/remarkup/shared.thrift b/documentation-tools/remarkup/shared.thrift new file mode 100644 index 0000000..386000b --- /dev/null +++ b/documentation-tools/remarkup/shared.thrift @@ -0,0 +1,40 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +/** + * This Thrift file can be included by other Thrift files that want to share + * these definitions. + */ + +namespace cpp shared +namespace d share // "shared" would collide with the eponymous D keyword. +namespace dart shared +namespace java shared +namespace perl shared +namespace php shared +namespace haxe shared + +struct SharedStruct { + 1: i32 key + 2: string value +} + +service SharedService { + SharedStruct getStruct(1: i32 key) +} diff --git a/documentation-tools/remarkup/tutorial.thrift b/documentation-tools/remarkup/tutorial.thrift new file mode 100644 index 0000000..c4a96f0 --- /dev/null +++ b/documentation-tools/remarkup/tutorial.thrift @@ -0,0 +1,154 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +# Thrift Tutorial +# Mark Slee (mcslee@facebook.com) +# +# This file aims to teach you how to use Thrift, in a .thrift file. Neato. The +# first thing to notice is that .thrift files support standard shell comments. +# This lets you make your thrift file executable and include your Thrift build +# step on the top line. And you can place comments like this anywhere you like. +# +# Before running this file, you will need to have installed the thrift compiler +# into /usr/local/bin. + +/** + * The first thing to know about are types. The available types in Thrift are: + * + * bool Boolean, one byte + * i8 (byte) Signed 8-bit integer + * i16 Signed 16-bit integer + * i32 Signed 32-bit integer + * i64 Signed 64-bit integer + * double 64-bit floating point value + * string String + * binary Blob (byte array) + * map Map from one type to another + * list Ordered list of one type + * set Set of unique elements of one type + * + * Did you also notice that Thrift supports C style comments? + */ + +// Just in case you were wondering... yes. We support simple C comments too. + +/** + * Thrift files can reference other Thrift files to include common struct + * and service definitions. These are found using the current path, or by + * searching relative to any paths specified with the -I compiler flag. + * + * Included objects are accessed using the name of the .thrift file as a + * prefix. i.e. shared.SharedObject + */ +include "shared.thrift" + +/** + * Thrift files can namespace, package, or prefix their output in various + * target languages. + */ +namespace cpp tutorial +namespace d tutorial +namespace dart tutorial +namespace java tutorial +namespace php tutorial +namespace perl tutorial +namespace haxe tutorial + +/** + * Thrift lets you do typedefs to get pretty names for your types. Standard + * C style here. + */ +typedef i32 MyInteger + +/** + * Thrift also lets you define constants for use across languages. Complex + * types and structs are specified using JSON notation. + */ +const i32 INT32CONSTANT = 9853 +const map MAPCONSTANT = {'hello':'world', 'goodnight':'moon'} + +/** + * You can define enums, which are just 32 bit integers. Values are optional + * and start at 1 if not supplied, C style again. + */ +enum Operation { + ADD = 1, + SUBTRACT = 2, + MULTIPLY = 3, + DIVIDE = 4 +} + +/** + * Structs are the basic complex data structures. They are comprised of fields + * which each have an integer identifier, a type, a symbolic name, and an + * optional default value. + * + * Fields can be declared "optional", which ensures they will not be included + * in the serialized output if they aren't set. Note that this requires some + * manual management in some languages. + */ +struct Work { + 1: i32 num1 = 0, + 2: i32 num2, + 3: Operation op, + 4: optional string comment, +} + +/** + * Structs can also be exceptions, if they are nasty. + */ +exception InvalidOperation { + 1: i32 whatOp, + 2: string why +} + +/** + * Ahh, now onto the cool part, defining a service. Services just need a name + * and can optionally inherit from another service using the extends keyword. + */ +service Calculator extends shared.SharedService { + + /** + * A method definition looks like C code. It has a return type, arguments, + * and optionally a list of exceptions that it may throw. Note that argument + * lists and exception lists are specified using the exact same syntax as + * field lists in struct or exception definitions. + */ + + void ping(), + + i32 add(1:i32 num1, 2:i32 num2), + + i32 calculate(1:i32 logid, 2:Work w) throws (1:InvalidOperation ouch), + + /** + * This method has a oneway modifier. That means the client only makes + * a request and does not listen for any response at all. Oneway methods + * must be void. + */ + oneway void zip() + +} + +/** + * That just about covers the basics. Take a look in the test/ folder for more + * detailed examples. After you run this file, your generated code shows up + * in folders with names gen-. The generated code isn't too scary + * to look at. It even has pretty indentation. + */ diff --git a/documentation-tools/thrift/php/TSocketServer.php b/documentation-tools/thrift/php/TSocketServer.php new file mode 100644 index 0000000..715b52d --- /dev/null +++ b/documentation-tools/thrift/php/TSocketServer.php @@ -0,0 +1,66 @@ +address = $address; + } + + public function open() + { + $server = stream_socket_server($this->address, $errno, $errorMessage); + if ($server === false) { + throw new TException("Could not bind to socket: $errorMessage"); + } + + $this->client = @stream_socket_accept($server, 3600); + if (!$this->client){ + throw new TException("Could not accept connection"); + } + } + + public function close() + { + fclose($this->client); + } + + public function isOpen() + { + return !is_null($client); + } + + public function read($len) + { + $data = @fread($this->client, $len); + if ($data === FALSE || $data === '') { + throw new TException('TPhpStream: Could not read '.$len.' bytes'); + } + + return $data; + } + + public function write($buf) + { + while (TStringFuncFactory::create()->strlen($buf) > 0) { + $got = @fwrite($this->client, $buf); + if ($got === 0 || $got === FALSE) { + throw new TException('TPhpStream: Could not write '.TStringFuncFactory::create()->strlen($buf).' bytes'); + } + $buf = TStringFuncFactory::create()->substr($buf, $got); + } + } + + public function flush() + { + @fflush($this->client); + } +} diff --git a/scripts/metatests/context-latecontext-ContextLoopResolution-direct.lp b/scripts/metatests/context-latecontext-ContextLoopResolution-direct.lp index 8d1c8b6..a60cfbd 100644 --- a/scripts/metatests/context-latecontext-ContextLoopResolution-direct.lp +++ b/scripts/metatests/context-latecontext-ContextLoopResolution-direct.lp @@ -1 +1,68 @@ +%#include "control-context.lp". + +function(a;b;c). +scope(0..2). + + %general +cfa_parent(0, function(a)). +cfa_parent(1, function(b)). +cfa_parent(2, function(c)). + +cfa_call(0, c). +cfa_call(1, c). + + %additional +keys(key0; key1). +data(key0, x). +data(key0, y). +data(key1, m). +data(key1, n). + +bind_scope(0, keys(key0), strong). +bind_scope(1, keys(key1), strong). + +%bind_scope(0, a, strong). +%bind_scope(0, b, strong). +%bind_scope(1, a, strong). +%bind_scope(1, c, strong). + +bind_scope(2, set(X), Options):- bind_scope(2, keys(Key), Options), data(Key, X). + + %nested scope propagation: +bind_scope(Scope, Context, Info) :- bind_scope(ScopeParent, Context, Info), cfa_parent(Scope, scope(ScopeParent)). + + %strong inter-function propagation: +bind_scope(Scope, Context,strong) :- bind_scope(ScopeParent, Context, strong): cfa_call(ScopeParent, FnCur +rent); cfa_parent(Scope, function(FnCurrent)); cfa_call(_, FnCurrent); bind_scope(_, Context, strong); scope(Scope). + + %weak inter-function propagation +bind_scope(Scope, Context, weak(ScopeParent)):- not bind_scope(Scope, Context, strong), bind_scope(ScopeParent, Context, strong), cfa_call(ScopeParent, FnCurrent), cfa_parent(Scope, function(FnCurrent)). +bind_scope(Scope, Context, weak(Id)):- not bind_scope(Scope, Context, strong), bind_scope(ScopeParent, Context, weak(Id)), cfa_call(ScopeParent, FnCurrent), cfa_parent(Scope, function(FnCurrent)). + %make decisions +bind_scope_decision(Scope,z loop(Subject), Scope):- cfa_contextloop(Scope, Subject), demand_dependency(loop(Subject), X), bind_scope(Scope, X, strong). +bind_scope_decision(Scope, loop(Subject), Scope):- cfa_call(Scope, FnChild), bind_function_demand(FnChild, loop(Subject)), demand_dependency(loop(Subject), X), bind_scope(Scope, X, strong). + + %demand +% bind_scope_demand(Scope, loop(Subject)):- cfa_contextloop(Sccghjcope, Subject), not bind_scope_decision(Scope, loop(Subject), _). + + %nested scope demand propagation +bind_scope_demand(Scope, Subject):- bind_scope_demand(ScopeChild, Subject), cfa_parent(ScopeChild, scope(Scope)). +bind_function_demand(Fn, Subject):- bind_scope_demand(Scope, Subject), cfa_parent(Scope, function(Fn)). + + %inter-function propagation demand +bind_scope_demand(Scope, Subject):- cfa_call(Scope, FnChild), bind_function_demand(FnChild, Subject), not bind_scope_decision(Scope, Subject, _). + + + +% GENERATED DECLARATIONS FOR DECISION DEPENDENCIES +% -- cfa_contextloop(Scope, $set) => demand_dependency(loop(set), X) :- bind_scope($ScopeId, X = $set(_), weak(_)). +demand_dependency(loop(set), X) :- bind_scope(2, X, weak(_)), X = set(_). + +% -- rule($Conditon, %Result) => demand_dependency(loop(X), $Condition) :- demand_dependency(loop(X), $Result) +demand_dependency(loop(X), keys(Key)) :- demand_dependency(loop(X), set(Y)), bind_scope(_, keys(Key), _). + + +cfa_contextloop(2, set). + +#show bind_scope/3. diff --git a/scripts/metatests/control-context-demandContext.lp b/scripts/metatests/control-context-demandContext.lp deleted file mode 100644 index 494ab0f..0000000 --- a/scripts/metatests/control-context-demandContext.lp +++ /dev/null @@ -1,20 +0,0 @@ - % context propagation - -bind_scope_demand(Scope, FnCallee):- cfa_call(Scope, FnCallee), cfa_function_specializations(FnCallee, Context), not bind_scope(Scope, Context). -bind_scope_demand(Scope, Context):- bind_scope_demand(ScopeChild, Context), cfa_parent(ScopeChild, scope(Scope)). -bind_scope_demand(Scope, Context):- bind_function_demand(FnChild, Context), cfa_call(Scope, FnChild), not bind_scope(Scope, Context). - -bind_function_demand(Fn, Context):- bind_scope_demand(Scope, Context), 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). \ No newline at end of file diff --git a/scripts/metatests/tests-context-late_context.lp b/scripts/metatests/tests-context-late_context.lp deleted file mode 100644 index 536cdd3..0000000 --- a/scripts/metatests/tests-context-late_context.lp +++ /dev/null @@ -1,26 +0,0 @@ -#include "control-context.lp". - -%body -function(a;b;c;d). -scope(0..4). -cfa_parent(0, function(a)). -cfa_parent(1, function(b)). -cfa_parent(2, function(c)). -cfa_parent(3, function(d)). -cfa_parent(4, function(d)). - -cfa_call(0, c). -cfa_call(1, c). -cfa_call(2, d). - -bind_scope(0, a). -bind_scope(1, b). - -cfa_function_specializations(d, a). -cfa_function_specializations(d, b). - -#show bind_scope_decision/3. -%#show bind_scope_demand/2. -#show bind_function_demand/2. -%#show cfa_call/2. -%#show bind_function_demand/2. \ No newline at end of file