├── .gitignore ├── CMakeLists.txt ├── LICENSE ├── README.md ├── _config.yml ├── demos ├── main.cpp ├── piranha │ ├── demo.mr │ ├── hello_world.mr │ ├── member_function_demo.mr │ ├── number_adder.mr │ ├── performance_test.mr │ ├── standard-library │ │ ├── console.mr │ │ ├── conversions.mr │ │ ├── literals.mr │ │ ├── operators.mr │ │ ├── probes.mr │ │ └── standard_library.mr │ ├── test.mr │ └── vector_test.mr ├── reference_language_rules.cpp ├── reference_language_rules.h ├── utilities.cpp └── utilities.h ├── dependencies └── libraries │ └── flex │ └── include │ └── FlexLexer.h ├── docs ├── handbook │ └── handbook.md ├── public │ ├── banner_v1.png │ ├── banner_v2.png │ ├── banner_v3.png │ ├── example_1.png │ ├── example_2.png │ └── example_3.png └── v2_design │ └── new_design.md ├── flex-bison ├── scanner.l └── specification.y ├── include ├── add_operation_output.h ├── assembly.h ├── bool_negate_operation.h ├── build_settings.h ├── channel_node.h ├── channel_type.h ├── compilation_error.h ├── compiler.h ├── console_input_node.h ├── console_output_node.h ├── default_literal_node.h ├── divide_operation_output.h ├── error_list.h ├── exceptions.h ├── float_conversions.h ├── fundamental_output.h ├── fundamental_types.h ├── int_conversions.h ├── int_probe.h ├── ir_attribute.h ├── ir_attribute_definition.h ├── ir_attribute_definition_list.h ├── ir_attribute_list.h ├── ir_binary_operator.h ├── ir_compilation_unit.h ├── ir_context_tree.h ├── ir_import_statement.h ├── ir_literal_node.h ├── ir_node.h ├── ir_node_definition.h ├── ir_parser_structure.h ├── ir_structure_list.h ├── ir_token_info.h ├── ir_unary_operator.h ├── ir_value.h ├── ir_value_constant.h ├── ir_visibility.h ├── key_value_lookup.h ├── language_rules.h ├── literal_node.h ├── literal_node_output.h ├── memory_management.h ├── memory_tracker.h ├── multiply_operation_output.h ├── no_op_node.h ├── node.h ├── node_allocator.h ├── node_container.h ├── node_graph.h ├── node_output.h ├── node_program.h ├── num_negate_operation.h ├── operation_node.h ├── path.h ├── pipe_node.h ├── piranha.h ├── pkey_value_lookup.h ├── rule.h ├── scanner.h ├── standard_allocator.h ├── string_conversions.h ├── subtract_operation_output.h ├── throw_runtime_error_node.h ├── vector_constructor.h ├── vector_output.h ├── vector_split.h ├── vector_split_node.h └── version.h ├── src ├── assembly.cpp ├── channel_node.cpp ├── channel_type.cpp ├── compilation_error.cpp ├── compiler.cpp ├── error_list.cpp ├── float_conversions.cpp ├── fundamental_types.cpp ├── int_conversions.cpp ├── ir_attribute.cpp ├── ir_attribute_definition.cpp ├── ir_attribute_definition_list.cpp ├── ir_attribute_list.cpp ├── ir_binary_operator.cpp ├── ir_compilation_unit.cpp ├── ir_context_tree.cpp ├── ir_import_statement.cpp ├── ir_node.cpp ├── ir_node_definition.cpp ├── ir_parser_structure.cpp ├── ir_unary_operator.cpp ├── ir_value.cpp ├── language_rules.cpp ├── memory_tracker.cpp ├── no_op_node.cpp ├── node.cpp ├── node_allocator.cpp ├── node_container.cpp ├── node_graph.cpp ├── node_output.cpp ├── node_program.cpp ├── path.cpp ├── standard_allocator.cpp ├── string_conversions.cpp └── vector_constructor.cpp ├── test ├── compilation_tests.cpp ├── general_tests.cpp ├── operator_tests.cpp ├── optimization_tests.cpp ├── runtime_tests.cpp ├── sdl │ ├── attribute_definition_test.mr │ ├── bad_type_enforcement.mr │ ├── construction-tests │ │ ├── demo.mr │ │ ├── nested_conversions.1.mr │ │ ├── nested_conversions.mr │ │ ├── simple_float.mr │ │ └── test.mr │ ├── dependency_test.mr │ ├── dependency_tree.mr │ ├── duplicate_node_definition.mr │ ├── full-error-testing │ │ ├── test_case_1.mr │ │ ├── test_case_2.mr │ │ └── test_case_3.mr │ ├── general-tests │ │ ├── general_syntax_test_1.mr │ │ ├── general_syntax_test_10.mr │ │ ├── general_syntax_test_11.mr │ │ ├── general_syntax_test_12.mr │ │ ├── general_syntax_test_13.mr │ │ ├── general_syntax_test_13_min.mr │ │ ├── general_syntax_test_14.mr │ │ ├── general_syntax_test_15.mr │ │ ├── general_syntax_test_16.mr │ │ ├── general_syntax_test_17.mr │ │ ├── general_syntax_test_18.mr │ │ ├── general_syntax_test_19.mr │ │ ├── general_syntax_test_2.mr │ │ ├── general_syntax_test_20.mr │ │ ├── general_syntax_test_21.mr │ │ ├── general_syntax_test_21a.mr │ │ ├── general_syntax_test_21b.mr │ │ ├── general_syntax_test_22.mr │ │ ├── general_syntax_test_23.mr │ │ ├── general_syntax_test_24a.mr │ │ ├── general_syntax_test_24b.mr │ │ ├── general_syntax_test_25.mr │ │ ├── general_syntax_test_26.mr │ │ ├── general_syntax_test_27.mr │ │ ├── general_syntax_test_28.mr │ │ ├── general_syntax_test_29.mr │ │ ├── general_syntax_test_3.mr │ │ ├── general_syntax_test_30.mr │ │ ├── general_syntax_test_31.mr │ │ ├── general_syntax_test_32.mr │ │ ├── general_syntax_test_33.mr │ │ ├── general_syntax_test_34.mr │ │ ├── general_syntax_test_35.mr │ │ ├── general_syntax_test_36.mr │ │ ├── general_syntax_test_37.mr │ │ ├── general_syntax_test_4.mr │ │ ├── general_syntax_test_6.mr │ │ ├── general_syntax_test_7.mr │ │ ├── general_syntax_test_8.mr │ │ └── general_syntax_test_9.mr │ ├── global_reference_test.mr │ ├── infinite_loop_test_1.mr │ ├── infinite_loop_test_2.mr │ ├── infinite_loop_test_3.mr │ ├── infinite_loop_test_4.mr │ ├── input_connection_test.mr │ ├── missing_dependency.mr │ ├── node_body.mr │ ├── operation_definition.mr │ ├── operator-tests │ │ ├── operator_sanity_check.mr │ │ ├── operator_test_1.mr │ │ ├── operator_test_2.mr │ │ ├── operator_test_3.mr │ │ ├── operator_test_4.mr │ │ ├── operator_test_5.mr │ │ ├── operator_test_6.mr │ │ ├── operator_test_7.mr │ │ ├── operator_test_8.mr │ │ ├── operator_test_9.mr │ │ └── operators.mr │ ├── optimization-tests │ │ ├── optimization_test_1.mr │ │ ├── optimization_test_2.mr │ │ ├── optimization_test_3.mr │ │ ├── optimization_test_4.mr │ │ ├── optimization_test_5.mr │ │ ├── optimization_test_6.mr │ │ └── optimization_test_7.mr │ ├── position_attribute_test.mr │ ├── reference_resolution.mr │ ├── resolution-tests │ │ ├── resolution_errors_1.mr │ │ └── resolution_errors_2.mr │ ├── runtime-tests │ │ └── runtime_error_test.mr │ ├── sample_lib │ │ ├── dependency_tree.mr │ │ ├── example_dependency.mr │ │ └── test_lib.mr │ ├── single_empty_node.mr │ ├── single_node_bool.mr │ ├── single_node_builtin.mr │ ├── single_node_data_access.mr │ ├── single_node_definition.mr │ ├── single_node_import_statement.mr │ ├── single_node_inline_node.mr │ ├── single_node_simple_eq.mr │ ├── single_node_single_attrib.mr │ ├── single_node_single_int.mr │ ├── single_node_string_attrib.mr │ ├── single_node_two_attribs.mr │ ├── single_node_vector_float.mr │ ├── single_node_vector_int.mr │ ├── stress-testing │ │ ├── deep_error.mr │ │ ├── deep_error_isolated.mr │ │ ├── node_argument_stress_test_1.mr │ │ ├── stress_test_1.mr │ │ └── stress_test_1_isolated.mr │ ├── syntax_error.mr │ ├── two_nodes.mr │ └── visibility-tests │ │ ├── color.mr │ │ ├── some_library.mr │ │ ├── visibility_test_1.mr │ │ └── visibility_test_2.mr ├── sdl_stress_tests.cpp ├── sdl_tests.cpp ├── test_rules.cpp ├── test_rules.h ├── utilities.cpp └── utilities.h └── utilities └── src └── main.cpp /.gitignore: -------------------------------------------------------------------------------- 1 | # Ignore user's workspace 2 | workspace/ 3 | 4 | # Ignore the final build location 5 | build/ 6 | 7 | # Ignore autogenerated files 8 | autogen/ 9 | 10 | # Ignore compile commands used for code completion in vim 11 | compile_commands.json 12 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 Ange Yaghi 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![Alt text](docs/public/banner_v3.png?raw=true) 2 | 3 | 4 | **Piranha** is an open-source scripting framework currently under development. It is a reusable framework which allows developers to quickly write scripting interfaces to native C++ libraries. 5 | 6 | Piranha is currently used as an SDL (scene description language) for the [MantaRay](https://github.com/ange-yaghi/manta-ray) ray-tracer. 7 | 8 | For syntax highlighting in Visual Studio Code check out the [Piranha Visual Studio Code Extension](https://github.com/ange-yaghi/piranha-vscode-extension). 9 | 10 | For syntax highlighting in Sublime Text check out the [Piranha Sublime Text Package](https://github.com/Kostasn2/piranha-syntax-highlighting-package). 11 | 12 | To get started, check out the introductory handbook: [Piranha Handbook](docs/handbook/handbook.md) 13 | 14 | Example Piranha compiler implementation: [Hello World Piranha Compiler](https://github.com/ange-yaghi/piranha-hello-world-compiler) 15 | 16 | ## Design Scripting Interfaces For Your Native Libraries 17 | 18 | Write interfaces to your native code with full type-checking, syntax checking and error reporting, syntax highlighting, support for importing libraries and more! 19 | 20 | ![Alt text](docs/public/example_1.png?raw=true) 21 | 22 | ## Design Robust Configuration Languages 23 | 24 | Skip writing your own parser and implement your own custom configuration language using Piranha. Piranha supports advanced features like binary and unary operations, custom functions and variables which can simplify tasks like writing configuration files. 25 | 26 | ![Alt text](docs/public/example_2.png?raw=true) 27 | 28 | ## Design Complex Node-Based Systems 29 | 30 | Piranha was designed for the unique demands of a ray-tracer SDL (scene description language) where a user may want to write shaders, specify multiple render jobs in a particular sequence, perform image post processing and a number of other operations. Custom logic written in Piranha has a comparable runtime to native code! 31 | 32 | ![Alt text](docs/public/example_3.png?raw=true) 33 | 34 | ## Setup Instructions For Developers 35 | 36 | Only a few steps are required to begin contributing to Piranha. 37 | 38 | ### Install Dependencies 39 | I have tried to rely on as few dependencies as possible and at some point may eliminate these dependencies as well, but for now you'll have to live with the pain. Install the following: 40 | 41 | 1. CMake 42 | 2. Boost (make sure to build the optional dependencies as well) 43 | 3. Flex 44 | 4. Bison 45 | 46 | ### Build with CMake 47 | After cloning the Piranha repository, `cd` into the repository and run the following commands: 48 | 49 | ``` 50 | mkdir build 51 | cd build 52 | cmake .. 53 | cmake --build . 54 | ``` 55 | 56 | If using MSVC, to set whether it is a Release or Debug build, run the last step like this: 57 | ``` 58 | cmake --build . --config Release 59 | ``` 60 | 61 | If using MSVC, CMake will output a Visual Studio solution which you can use for development and debugging. You can also try running the reference compiler directly `piranha_reference_compiler`. 62 | 63 | **You are now ready to begin development!** 64 | -------------------------------------------------------------------------------- /_config.yml: -------------------------------------------------------------------------------- 1 | theme: jekyll-theme-slate -------------------------------------------------------------------------------- /demos/main.cpp: -------------------------------------------------------------------------------- 1 | #include "reference_language_rules.h" 2 | #include "utilities.h" 3 | 4 | #include "../include/compiler.h" 5 | #include "../include/node_program.h" 6 | #include "../include/ir_compilation_unit.h" 7 | #include "../include/compilation_error.h" 8 | #include "../include/memory_tracker.h" 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | int main() { 16 | std::string filename; 17 | std::cout << "Enter .mr file: "; 18 | std::cin >> filename; 19 | 20 | while (true) { 21 | auto startCompile = std::chrono::high_resolution_clock::now(); 22 | 23 | { 24 | std::cout << "--- Compiling --------------" << std::endl; 25 | piranha::NodeProgram nodeProgram; 26 | piranha_demo::ReferenceLanguageRules languageRules; 27 | languageRules.initialize(); 28 | 29 | piranha::Compiler compiler(&languageRules); 30 | piranha::IrCompilationUnit *unit = compiler.compile(filename); 31 | 32 | piranha_demo::printErrorTrace(compiler.getErrorList()); 33 | 34 | if (unit == nullptr) { 35 | std::cout << "Could not find file: " << filename << std::endl; 36 | } 37 | else if (compiler.getErrorList()->getErrorCount() == 0) { 38 | unit->build(&nodeProgram); 39 | 40 | std::cout << "--- Running ----------------" << std::endl; 41 | auto endCompile = std::chrono::high_resolution_clock::now(); 42 | 43 | nodeProgram.initialize(); 44 | //nodeProgram.optimize(); 45 | nodeProgram.execute(); 46 | 47 | auto endExecute = std::chrono::high_resolution_clock::now(); 48 | 49 | nodeProgram.writeAssembly("../workspace/asm/" + unit->getPath().getStem() + ".pasm"); 50 | 51 | std::cout << std::endl; 52 | std::cout << "----------------------------" << std::endl; 53 | std::cout << " Compile time: " << 54 | (endCompile - startCompile).count() * 1.0e-6 << " ms" << std::endl; 55 | std::cout << " Execution time: " << 56 | (endExecute - endCompile).count() * 1.0e-6 << " ms" << std::endl; 57 | 58 | nodeProgram.free(); 59 | } 60 | 61 | compiler.free(); 62 | } 63 | 64 | std::cout << "Memory leaks: " << piranha::MemoryTracker::get()->countLeaks() << std::endl; 65 | piranha::MemoryTracker::get()->reset(); 66 | 67 | std::cout << std::endl; 68 | std::cout << "Run again (y/n)? "; 69 | 70 | char cmd; 71 | std::cin >> cmd; 72 | 73 | if (cmd != 'y') break; 74 | 75 | std::cout << std::endl; 76 | } 77 | 78 | return 0; 79 | } 80 | -------------------------------------------------------------------------------- /demos/piranha/demo.mr: -------------------------------------------------------------------------------- 1 | private import "standard-library/standard_library.mr" as std 2 | 3 | node age_calculator { 4 | input prompt; 5 | output age: float(current_year) - birth_year; 6 | 7 | console_in birth_year(prompt) 8 | console_in current_year("Enter the current year: ") 9 | } 10 | 11 | node box { 12 | input prompt; 13 | 14 | age_calculator(10) 15 | } 16 | 17 | console_out("Your age is " + string(age_calculator("Enter birth year: ").age)) 18 | console_out("Your age is " + string(age_calculator(10).age)) 19 | 20 | box("Enter birth year: ") 21 | -------------------------------------------------------------------------------- /demos/piranha/hello_world.mr: -------------------------------------------------------------------------------- 1 | private import "standard-library/standard_library.mr" as std 2 | 3 | std::console_out("Hello world!") 4 | -------------------------------------------------------------------------------- /demos/piranha/member_function_demo.mr: -------------------------------------------------------------------------------- 1 | private import "standard-library/standard_library.mr" as std 2 | 3 | node some_class { 4 | output out: "Hello world!"; 5 | } 6 | 7 | node some_member { 8 | input this [some_class]; 9 | output out: this.out; 10 | } 11 | 12 | std::console_out(some_class().some_member().out) 13 | -------------------------------------------------------------------------------- /demos/piranha/number_adder.mr: -------------------------------------------------------------------------------- 1 | private import "standard-library/standard_library.mr" as std 2 | 3 | private node print_header { 4 | std::console_out("---------------------------------------\n") 5 | std::console_out(" Piranha Number Adder\n") 6 | std::console_out(" Ange Yaghi (c) 2019\n") 7 | std::console_out("---------------------------------------\n") 8 | } 9 | 10 | private node get_input { 11 | output number1: std::console_in("Enter a number: "); 12 | output number2: std::console_in("Enter another number: "); 13 | } 14 | 15 | private node add_and_print { 16 | input inputs; 17 | 18 | string formatted(float(inputs.number1) + float(inputs.number2) + fake) 19 | std::console_out("---------------------------------------\n") 20 | std::console_out(inputs.number1 + " + " + inputs.number2 + " = " + formatted + "\n") 21 | } 22 | 23 | // Execute 24 | print_header() 25 | add_and_print( 26 | get_input() 27 | ) 28 | -------------------------------------------------------------------------------- /demos/piranha/performance_test.mr: -------------------------------------------------------------------------------- 1 | private import "standard-library/standard_library.mr" as std 2 | 3 | float(2.0 / 4.0) 4 | -------------------------------------------------------------------------------- /demos/piranha/standard-library/console.mr: -------------------------------------------------------------------------------- 1 | private import "conversions.mr" 2 | private import "literals.mr" 3 | 4 | public inline node console_in => __piranha__console_in { 5 | input prompt [string]: ""; 6 | alias output raw_input [string]; 7 | } 8 | 9 | public inline node console_out => __piranha__console_out { 10 | input data [string]: ""; 11 | } 12 | -------------------------------------------------------------------------------- /demos/piranha/standard-library/conversions.mr: -------------------------------------------------------------------------------- 1 | public inline node int_channel => __piranha__int { /* void */ } 2 | public inline node float_channel => __piranha__float { /* void */ } 3 | public inline node string_channel => __piranha__string { /* void */ } 4 | public inline node bool_channel => __piranha__bool { /* void */ } 5 | public inline node vector_channel => __piranha__vector { 6 | output x [float]; 7 | output y [float]; 8 | output z [float]; 9 | output w [float]; 10 | } 11 | 12 | public inline node int { 13 | input __in [int_channel]; 14 | alias output __out [int_channel]: __in; 15 | } 16 | 17 | public inline node float { 18 | input __in [float_channel]; 19 | alias output __out [float_channel]: __in; 20 | } 21 | 22 | public inline node string { 23 | input __in [string_channel]; 24 | alias output __out [string_channel]: __in; 25 | } 26 | 27 | public inline node bool { 28 | input __in [bool_channel]; 29 | alias output __out [bool_channel]: __in; 30 | } 31 | 32 | public inline node vector => __piranha__vector_constructor { 33 | input __in0 [float]; 34 | input __in1 [float]; 35 | input __in2 [float]; 36 | input __in3 [float]; 37 | 38 | alias output __out [vector_channel]; 39 | } 40 | 41 | public inline node string_to_float => __piranha__string_to_float { 42 | input __in [string]; 43 | alias output __out [float]; 44 | } 45 | 46 | public inline node float_to_string => __piranha__float_to_string { 47 | input __in [float]; 48 | alias output __out [string]; 49 | } 50 | 51 | public inline node int_to_float => __piranha__int_to_float { 52 | input __in [int]; 53 | alias output __out [float]; 54 | } 55 | -------------------------------------------------------------------------------- /demos/piranha/standard-library/literals.mr: -------------------------------------------------------------------------------- 1 | private import "conversions.mr" 2 | 3 | public node literal_string => __piranha__literal_string { 4 | alias output __out [string]; 5 | } 6 | 7 | public node literal_int => __piranha__literal_int { 8 | alias output __out [int]; 9 | } 10 | 11 | public node literal_float => __piranha__literal_float { 12 | alias output __out [float]; 13 | } 14 | 15 | public node literal_bool => __piranha__literal_bool { 16 | alias output __out [bool]; 17 | } 18 | -------------------------------------------------------------------------------- /demos/piranha/standard-library/operators.mr: -------------------------------------------------------------------------------- 1 | private import "conversions.mr" 2 | 3 | // ADD NODES 4 | public inline node int_add => __piranha__int_add { 5 | input __in0 [int]; 6 | input __in1 [int]; 7 | alias output __out [int]; 8 | } 9 | 10 | public inline node float_add => __piranha__float_add { 11 | input __in0 [float]; 12 | input __in1 [float]; 13 | alias output __out [float]; 14 | } 15 | 16 | public inline node string_add => __piranha__string_add { 17 | input __in0 [string]; 18 | input __in1 [string]; 19 | alias output __out [string]; 20 | } 21 | 22 | public inline node vector_add => __piranha__vector_add { 23 | input __in0 [vector]; 24 | input __in1 [vector]; 25 | alias output __out [vector]; 26 | } 27 | 28 | // SUBTRACT NODES 29 | public inline node int_subtract => __piranha__int_subtract { 30 | input __in0 [int]; 31 | input __in1 [int]; 32 | alias output __out [int]; 33 | } 34 | 35 | public inline node float_subtract => __piranha__float_subtract { 36 | input __in0 [float]; 37 | input __in1 [float]; 38 | alias output __out [float]; 39 | } 40 | 41 | public inline node vector_subtract => __piranha__vector_subtract { 42 | input __in0 [vector]; 43 | input __in1 [vector]; 44 | alias output __out [vector]; 45 | } 46 | 47 | // MULTIPLY NODES 48 | public inline node int_multiply => __piranha__int_multiply { 49 | input __in0 [int]; 50 | input __in1 [int]; 51 | alias output __out [int]; 52 | } 53 | 54 | public inline node float_multiply => __piranha__float_multiply { 55 | input __in0 [float]; 56 | input __in1 [float]; 57 | alias output __out [float]; 58 | } 59 | 60 | public inline node vector_multiply => __piranha__vector_multiply { 61 | input __in0 [vector]; 62 | input __in1 [vector]; 63 | alias output __out [vector]; 64 | } 65 | 66 | // DIVIDE NODES 67 | public inline node int_divide => __piranha__int_divide { 68 | input __in0 [int]; 69 | input __in1 [int]; 70 | alias output __out [int]; 71 | } 72 | 73 | public inline node float_divide => __piranha__float_divide { 74 | input __in0 [float]; 75 | input __in1 [float]; 76 | alias output __out [float]; 77 | } 78 | 79 | public inline node vector_divide => __piranha__vector_divide { 80 | input __in0 [vector]; 81 | input __in1 [vector]; 82 | alias output __out [vector]; 83 | } 84 | 85 | // UNARY OPERATORS 86 | 87 | // Numerical negate 88 | public inline node float_negate => __piranha__float_negate { 89 | input __in [float]; 90 | alias output __out [float]; 91 | } 92 | 93 | public inline node int_negate => __piranha__int_negate { 94 | input __in [int]; 95 | alias output __out [int]; 96 | } 97 | 98 | public inline node vector_negate => __piranha__vector_negate { 99 | input __in [vector]; 100 | alias output __out [vector]; 101 | } 102 | 103 | public inline node float_positive => __piranha__float_positive { 104 | input __in [float]; 105 | alias output __out [float]; 106 | } 107 | 108 | public inline node int_positive => __piranha__int_positive { 109 | input __in [int]; 110 | alias output __out [int]; 111 | } 112 | 113 | public inline node vector_positive => __piranha__vector_positive { 114 | input __in [vector]; 115 | alias output __out [vector]; 116 | } 117 | 118 | public inline node bool_negate => __piranha__bool_negate { 119 | input __in [bool]; 120 | alias output __out [bool]; 121 | } 122 | -------------------------------------------------------------------------------- /demos/piranha/standard-library/probes.mr: -------------------------------------------------------------------------------- 1 | private import "literals.mr" 2 | private import "conversions.mr" 3 | 4 | public node throw_runtime_error => __piranha__throw_runtime_error { 5 | input throw [bool]: false; 6 | } 7 | 8 | public node int_probe => __piranha__int_probe { 9 | input __in [int]; 10 | } 11 | -------------------------------------------------------------------------------- /demos/piranha/standard-library/standard_library.mr: -------------------------------------------------------------------------------- 1 | public import "literals.mr" 2 | public import "conversions.mr" 3 | public import "operators.mr" 4 | public import "console.mr" 5 | public import "probes.mr" 6 | -------------------------------------------------------------------------------- /demos/piranha/test.mr: -------------------------------------------------------------------------------- 1 | private import "standard-library/standard_library.mr" as std 2 | 3 | std::vector vec1(1, 2, 3, 4) 4 | std::vector vec2(4, 3, 2, 1) 5 | 6 | node format_vector { 7 | input a [std::vector]; 8 | alias output __out: 9 | string(a.x) + ", " + string(a.y) + ", " + string(a.z) + ", " + string(a.w); 10 | } 11 | 12 | std::console_out(format_vector((vec1 + vec2 * vec1)) + "\n") 13 | 14 | std::console_out(format_vector(-(+vec1 + (-vec1) + vec1))) 15 | -------------------------------------------------------------------------------- /demos/piranha/vector_test.mr: -------------------------------------------------------------------------------- 1 | private import "standard-library/standard_library.mr" as std 2 | 3 | std::vector v1(1.0, 2.0, 3.0, 4.0) 4 | std::vector v2(4.0, 3.0, 2.0, 1.0) 5 | 6 | std::console_out((v1 + v2).x) 7 | -------------------------------------------------------------------------------- /demos/reference_language_rules.h: -------------------------------------------------------------------------------- 1 | #ifndef PIRANHA_REFERENCE_COMPILER_REFERENCE_LANGUAGE_RULES_H 2 | #define PIRANHA_REFERENCE_COMPILER_REFERENCE_LANGUAGE_RULES_H 3 | 4 | #include "../include/language_rules.h" 5 | 6 | namespace piranha_demo { 7 | 8 | class ReferenceLanguageRules : public piranha::LanguageRules { 9 | public: 10 | ReferenceLanguageRules(); 11 | ~ReferenceLanguageRules(); 12 | 13 | protected: 14 | virtual void registerBuiltinNodeTypes(); 15 | }; 16 | 17 | } /* namespace piranha_demo */ 18 | 19 | #endif /* PIRANHA_REFERENCE_COMPILER_REFERENCE_LANGUAGE_RULES_H */ 20 | -------------------------------------------------------------------------------- /demos/utilities.cpp: -------------------------------------------------------------------------------- 1 | #include "utilities.h" 2 | 3 | #include "../include/ir_compilation_unit.h" 4 | #include "../include/path.h" 5 | #include "../include/ir_context_tree.h" 6 | #include "../include/ir_node.h" 7 | #include "../include/ir_node_definition.h" 8 | 9 | #include 10 | 11 | void piranha_demo::printError(const piranha::CompilationError *err) { 12 | const piranha::ErrorCode_struct &errorCode = err->getErrorCode(); 13 | std::cout << err->getCompilationUnit()->getPath().getStem() << "(" << err->getErrorLocation()->lineStart << "): error " << errorCode.stage << errorCode.code << ": " << errorCode.info << std::endl; 14 | 15 | piranha::IrContextTree *context = err->getInstantiation(); 16 | while (context != nullptr) { 17 | piranha::IrNode *instance = context->getContext(); 18 | if (instance != nullptr) { 19 | std::string instanceName = instance->getName(); 20 | std::string definitionName = (instance->getDefinition() != nullptr) ? instance->getDefinition()->getName() : std::string(""); 21 | std::string formattedName; 22 | if (instanceName.empty()) formattedName = " " + definitionName; 23 | else formattedName = instanceName + " " + definitionName; 24 | 25 | std::cout << 26 | " While instantiating: " << 27 | instance->getParentUnit()->getPath().getStem() << "(" << instance->getSummaryToken()->lineStart << "): " << formattedName << std::endl; 28 | } 29 | 30 | context = context->getParent(); 31 | } 32 | } 33 | 34 | void piranha_demo::printErrorTrace(const piranha::ErrorList *errList) { 35 | int errorCount = errList->getErrorCount(); 36 | for (int i = 0; i < errorCount; i++) { 37 | printError(errList->getCompilationError(i)); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /demos/utilities.h: -------------------------------------------------------------------------------- 1 | #ifndef PIRANHA_REFERENCE_COMPILER_UTILITIES_H 2 | #define PIRANHA_REFERENCE_COMPILER_UTILITIES_H 3 | 4 | #include "../include/compilation_error.h" 5 | #include "../include/error_list.h" 6 | 7 | namespace piranha_demo { 8 | 9 | void printError(const piranha::CompilationError *err); 10 | void printErrorTrace(const piranha::ErrorList *errList); 11 | 12 | } /* namespace piranha_demo */ 13 | 14 | #endif /* PIRANHA_REFERENCE_COMPILER_UTILITIES_H */ 15 | -------------------------------------------------------------------------------- /docs/public/banner_v1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ange-yaghi/piranha/ff2955daddb2a7e0bae93f8e444a9601bf5bf111/docs/public/banner_v1.png -------------------------------------------------------------------------------- /docs/public/banner_v2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ange-yaghi/piranha/ff2955daddb2a7e0bae93f8e444a9601bf5bf111/docs/public/banner_v2.png -------------------------------------------------------------------------------- /docs/public/banner_v3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ange-yaghi/piranha/ff2955daddb2a7e0bae93f8e444a9601bf5bf111/docs/public/banner_v3.png -------------------------------------------------------------------------------- /docs/public/example_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ange-yaghi/piranha/ff2955daddb2a7e0bae93f8e444a9601bf5bf111/docs/public/example_1.png -------------------------------------------------------------------------------- /docs/public/example_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ange-yaghi/piranha/ff2955daddb2a7e0bae93f8e444a9601bf5bf111/docs/public/example_2.png -------------------------------------------------------------------------------- /docs/public/example_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ange-yaghi/piranha/ff2955daddb2a7e0bae93f8e444a9601bf5bf111/docs/public/example_3.png -------------------------------------------------------------------------------- /docs/v2_design/new_design.md: -------------------------------------------------------------------------------- 1 | # Piranha V2 Design 2 | 3 | ## Types 4 | 5 | Name | WireDefinition 6 | ---- | -------------- 7 | TypeId | String 8 | AdaptorDefinition | NodeDefinition \| NULL 9 | 10 | --- 11 | 12 | Name | Wire 13 | ---- | ------------ 14 | Definition | WireDefinition 15 | Adaptor | Node \| NULL 16 | 17 | --- 18 | 19 | Name | Conduit 20 | ---- | ------- 21 | Node | Node \| NULL 22 | Wire | Wire \| NULL 23 | 24 | --- 25 | 26 | Name | Port 27 | ---- | ---- 28 | Type | INPUT \| OUTPUT 29 | Default | Conduit 30 | 31 | --- 32 | 33 | Name | NodeDefinition 34 | ---- | -------------- 35 | InputPorts | Port[] 36 | OutputPorts | Port[] 37 | AliasPort | Port \| NULL 38 | Nodes | NodeInstance[] 39 | 40 | --- 41 | 42 | Name | Context 43 | ---- | ------- 44 | ConnectionMap | Port -> (Conduit \| NULL \| UNKNOWN) 45 | Node | Node | NULL 46 | 47 | --- 48 | 49 | Name | Node 50 | ---- | ------------ 51 | Context | Context 52 | NodeDefinition | NodeDefinition 53 | 54 | ## Stages 55 | 56 | 1. Parsing 57 | 2. Name Resolution 58 | 3. Operator Expansion 59 | 4. Access Resolution 60 | 5. Type Resolution 61 | 6. Optimization 62 | -------------------------------------------------------------------------------- /include/add_operation_output.h: -------------------------------------------------------------------------------- 1 | #ifndef PIRANHA_ADD_OPERATION_OUTPUT_H 2 | #define PIRANHA_ADD_OPERATION_OUTPUT_H 3 | 4 | #include "fundamental_output.h" 5 | 6 | #include "pipe_node.h" 7 | #include "default_literal_node.h" 8 | 9 | namespace piranha { 10 | 11 | template 12 | class AddOperationNodeOutput : public FundamentalOutput { 13 | public: 14 | AddOperationNodeOutput() { 15 | /* void */ 16 | } 17 | 18 | virtual ~AddOperationNodeOutput() { 19 | /* void */ 20 | } 21 | 22 | virtual void fullCompute(void *_target) const { 23 | Type *target = reinterpret_cast(_target); 24 | 25 | Type left; 26 | Type right; 27 | 28 | m_left->fullCompute((void *)&left); 29 | m_right->fullCompute((void *)&right); 30 | *target = left + right; 31 | } 32 | 33 | pNodeInput *getLeftConnection() { return &m_left; } 34 | pNodeInput *getRightConnection() { return &m_right; } 35 | 36 | protected: 37 | virtual void registerInputs() { 38 | this->registerInput(&m_left); 39 | this->registerInput(&m_right); 40 | } 41 | 42 | protected: 43 | pNodeInput m_left; 44 | pNodeInput m_right; 45 | }; 46 | 47 | } /* namespace piranha */ 48 | 49 | #endif /* PIRANHA_ADD_OPERATION_OUTPUT_H */ 50 | -------------------------------------------------------------------------------- /include/assembly.h: -------------------------------------------------------------------------------- 1 | #ifndef PIRANHA_ASSEMBLY_H 2 | #define PIRANHA_ASSEMBLY_H 3 | 4 | #include "key_value_lookup.h" 5 | 6 | namespace piranha { 7 | 8 | class NodeOutput; 9 | 10 | class Assembly { 11 | public: 12 | Assembly(); 13 | ~Assembly(); 14 | 15 | int getOutputLabel(NodeOutput *output); 16 | 17 | protected: 18 | KeyValueLookup m_outputLookup; 19 | int m_currentIndex; 20 | }; 21 | 22 | } /* namespace piranha */ 23 | 24 | #endif /* PIRANHA_ASSEMBLY_H */ 25 | -------------------------------------------------------------------------------- /include/bool_negate_operation.h: -------------------------------------------------------------------------------- 1 | #ifndef PIRANHA_BOOL_NEGATE_OPERATION_H 2 | #define PIRANHA_BOOL_NEGATE_OPERATION_H 3 | 4 | #include "fundamental_output.h" 5 | 6 | #include "pipe_node.h" 7 | 8 | namespace piranha { 9 | 10 | template 11 | class BoolNegateOperationNodeOutput : public FundamentalOutput { 12 | public: 13 | BoolNegateOperationNodeOutput() { 14 | /* void */ 15 | } 16 | 17 | virtual ~BoolNegateOperationNodeOutput() { 18 | /* void */ 19 | } 20 | 21 | virtual void fullCompute(void *_target) const { 22 | Type *target = reinterpret_cast(_target); 23 | 24 | Type in; 25 | m_input->fullCompute(&in); 26 | 27 | *target = !in; 28 | } 29 | 30 | pNodeInput *getConnection() { return &m_input; } 31 | 32 | protected: 33 | virtual void registerInputs() { 34 | this->registerInput(&m_input); 35 | } 36 | 37 | protected: 38 | pNodeInput m_input; 39 | }; 40 | 41 | template 42 | using BoolNegateOperationNode = PipeNode>; 43 | 44 | } /* namespace piranha */ 45 | 46 | #endif /* PIRANHA_BOOL_NEGATE_OPERATION_H */ 47 | -------------------------------------------------------------------------------- /include/build_settings.h: -------------------------------------------------------------------------------- 1 | #ifndef PIRANHA_BUILD_SETTINGS_H 2 | #define PIRANHA_BUILD_SETTINGS_H 3 | 4 | #define ENABLE_MEMORY_TRACKER 0 5 | #define STD_ALLOC_ENABLE_LEDGER 0 6 | 7 | #endif /* PIRANHA_BUILD_SETTINGS_H */ 8 | -------------------------------------------------------------------------------- /include/channel_node.h: -------------------------------------------------------------------------------- 1 | #ifndef PIRANHA_CHANNEL_NODE_H 2 | #define PIRANHA_CHANNEL_NODE_H 3 | 4 | #include "node.h" 5 | 6 | namespace piranha { 7 | 8 | class ChannelNode : public Node { 9 | public: 10 | ChannelNode(); 11 | ~ChannelNode(); 12 | }; 13 | 14 | } /* namespace piranha */ 15 | 16 | #endif /* PIRANHA_CHANNEL_NODE_H */ 17 | -------------------------------------------------------------------------------- /include/channel_type.h: -------------------------------------------------------------------------------- 1 | #ifndef PIRANHA_CHANNEL_TYPE_H 2 | #define PIRANHA_CHANNEL_TYPE_H 3 | 4 | #include 5 | 6 | namespace piranha { 7 | 8 | class ChannelType { 9 | public: 10 | ChannelType(); 11 | ChannelType(const char *type, const ChannelType *parent = nullptr); 12 | ~ChannelType(); 13 | 14 | void initialize(const char *type, const ChannelType *parent); 15 | 16 | public: 17 | const char *getType() const { return m_typeString; } 18 | bool isCompatibleWith(const ChannelType &t) const; 19 | bool isEqual(const ChannelType &t) const; 20 | 21 | private: 22 | static int generateHash(const char *string); 23 | int getHash() const { return m_hash; } 24 | 25 | private: 26 | const ChannelType *m_parent; 27 | int m_hash; 28 | const char *m_typeString; 29 | }; 30 | 31 | } /* namespace piranha */ 32 | 33 | #endif /* PIRANHA_CHANNEL_TYPE_H */ 34 | -------------------------------------------------------------------------------- /include/compiler.h: -------------------------------------------------------------------------------- 1 | #ifndef PIRANHA_COMPILER_H 2 | #define PIRANHA_COMPILER_H 3 | 4 | #include "path.h" 5 | #include "error_list.h" 6 | 7 | #include 8 | #include 9 | 10 | namespace piranha { 11 | 12 | class IrCompilationUnit; 13 | class LanguageRules; 14 | 15 | typedef Path IrPath; 16 | 17 | class Compiler { 18 | public: 19 | Compiler(const LanguageRules *rules = nullptr); 20 | ~Compiler(); 21 | 22 | IrCompilationUnit *compile(const IrPath &scriptPath); 23 | void free(); 24 | IrCompilationUnit *getUnit(const IrPath &scriptPath) const; 25 | 26 | int getUnitCount() const { return (int)m_units.size(); } 27 | 28 | const ErrorList *getErrorList() const { return &m_errorList; } 29 | 30 | void setFileExtension(const std::string &extension) { m_extension = extension; } 31 | std::string getFileExtension() const { return m_extension; } 32 | 33 | void addSearchPath(const IrPath &path); 34 | int getSearchPathCount() const { return (int)m_searchPaths.size(); } 35 | 36 | bool resolvePath(const IrPath &path, IrPath *target) const; 37 | 38 | protected: 39 | IrCompilationUnit *analyze(const IrPath &scriptPath); 40 | bool isPathEquivalent(const IrPath &a, const IrPath &b) const; 41 | 42 | static bool hasEnding(std::string const &fullString, std::string const &ending); 43 | 44 | protected: 45 | // Build steps 46 | void resolve(); 47 | void validate(); 48 | 49 | protected: 50 | const LanguageRules *m_rules; 51 | 52 | ErrorList m_errorList; 53 | std::vector m_units; 54 | 55 | std::vector m_searchPaths; 56 | std::string m_extension; 57 | }; 58 | 59 | } /* namespace piranha */ 60 | 61 | #endif /* PIRANHA_COMPILER_H */ 62 | -------------------------------------------------------------------------------- /include/console_input_node.h: -------------------------------------------------------------------------------- 1 | #ifndef PIRANHA_CONSOLE_INPUT_NODE_H 2 | #define PIRANHA_CONSOLE_INPUT_NODE_H 3 | 4 | #include "node.h" 5 | 6 | #include "literal_node_output.h" 7 | #include "fundamental_types.h" 8 | 9 | #include 10 | #include 11 | 12 | namespace piranha { 13 | 14 | class ConsoleInputNode : public Node { 15 | public: 16 | ConsoleInputNode() { 17 | /* void */ 18 | } 19 | 20 | ~ConsoleInputNode() { 21 | /* void */ 22 | } 23 | 24 | protected: 25 | virtual void _initialize() { 26 | m_promptInput = nullptr; 27 | } 28 | 29 | virtual void _evaluate() { 30 | std::string prompt; 31 | m_promptInput->fullCompute(&prompt); 32 | 33 | std::cout << prompt; 34 | std::cin >> m_inputData; 35 | 36 | m_output.setData(m_inputData); 37 | } 38 | 39 | virtual void registerInputs() { 40 | registerInput(&m_promptInput, "prompt"); 41 | } 42 | 43 | virtual void registerOutputs() { 44 | setPrimaryOutput("raw_input"); 45 | registerOutput(&m_output, "raw_input"); 46 | } 47 | 48 | protected: 49 | pNodeInput m_promptInput; 50 | LiteralNodeOutput m_output; 51 | std::string m_inputData; 52 | }; 53 | 54 | } /* namespace piranha */ 55 | 56 | #endif /* PIRANHA_CONSOLE_OUTPUT_NODE_H */ 57 | -------------------------------------------------------------------------------- /include/console_output_node.h: -------------------------------------------------------------------------------- 1 | #ifndef PIRANHA_CONSOLE_OUTPUT_NODE_H 2 | #define PIRANHA_CONSOLE_OUTPUT_NODE_H 3 | 4 | #include "node.h" 5 | 6 | #include "fundamental_types.h" 7 | 8 | #include 9 | #include 10 | 11 | namespace piranha { 12 | 13 | class ConsoleOutputNode : public Node { 14 | public: 15 | ConsoleOutputNode() { 16 | /* void */ 17 | } 18 | 19 | ~ConsoleOutputNode() { 20 | /* void */ 21 | } 22 | 23 | protected: 24 | virtual void _initialize() { 25 | m_dataOut = nullptr; 26 | } 27 | 28 | virtual void _evaluate() { 29 | std::string data; 30 | m_dataOut->fullCompute(&data); 31 | 32 | std::cout << data; 33 | } 34 | 35 | virtual void registerInputs() { 36 | registerInput(&m_dataOut, "data"); 37 | } 38 | 39 | virtual void registerOutputs() { 40 | /* void */ 41 | } 42 | 43 | protected: 44 | pNodeInput m_dataOut; 45 | }; 46 | 47 | } /* namespace piranha */ 48 | 49 | #endif /* PIRANHA_CONSOLE_OUTPUT_NODE_H */ 50 | -------------------------------------------------------------------------------- /include/default_literal_node.h: -------------------------------------------------------------------------------- 1 | #ifndef PIRANHA_DEFAULT_LITERAL_NODE_H 2 | #define PIRANHA_DEFAULT_LITERAL_NODE_H 3 | 4 | #include "literal_node.h" 5 | 6 | namespace piranha { 7 | 8 | template 9 | class DefaultLiteralNode : public LiteralNode { 10 | public: 11 | DefaultLiteralNode() { 12 | /* void */ 13 | } 14 | 15 | ~DefaultLiteralNode() { 16 | /* void */ 17 | } 18 | 19 | virtual void setData(LiteralType data) { m_literalData = data; } 20 | 21 | protected: 22 | virtual void _initialize() { 23 | /* void */ 24 | } 25 | 26 | virtual Node *_optimize(NodeAllocator *nodeAllocator) { 27 | Node::addFlag(Node::META_CONSTANT); 28 | Node::addFlag(Node::META_ACTIONLESS); 29 | 30 | return this; 31 | } 32 | 33 | virtual void _evaluate() { 34 | m_output.setData(m_literalData); 35 | } 36 | 37 | virtual void registerOutputs() { 38 | Node::setPrimaryOutput("__out"); 39 | Node::registerOutput(&m_output, "__out"); 40 | } 41 | 42 | protected: 43 | LiteralNodeOutput m_output; 44 | LiteralType m_literalData; 45 | }; 46 | 47 | typedef DefaultLiteralNode DefaultLiteralStringNode; 48 | typedef DefaultLiteralNode DefaultLiteralIntNode; 49 | typedef DefaultLiteralNode DefaultLiteralFloatNode; 50 | typedef DefaultLiteralNode DefaultLiteralBoolNode; 51 | 52 | } /* namespace piranha */ 53 | 54 | #endif /* PIRANHA_DEFAULT_LITERAL_NODE_H */ 55 | -------------------------------------------------------------------------------- /include/divide_operation_output.h: -------------------------------------------------------------------------------- 1 | #ifndef PIRANHA_DIVIDE_OPERATION_OUTPUT_H 2 | #define PIRANHA_DIVIDE_OPERATION_OUTPUT_H 3 | 4 | #include "fundamental_output.h" 5 | 6 | #include "pipe_node.h" 7 | 8 | namespace piranha { 9 | 10 | template 11 | class DivideOperationNodeOutput : public FundamentalOutput { 12 | public: 13 | DivideOperationNodeOutput() { 14 | /* void */ 15 | } 16 | 17 | virtual ~DivideOperationNodeOutput() { 18 | /* void */ 19 | } 20 | 21 | virtual void fullCompute(void *_target) const { 22 | Type *target = reinterpret_cast(_target); 23 | 24 | Type left; 25 | Type right; 26 | 27 | m_left->fullCompute(&left); 28 | m_right->fullCompute(&right); 29 | *target = left / right; 30 | } 31 | 32 | pNodeInput *getLeftConnection() { return &m_left; } 33 | pNodeInput *getRightConnection() { return &m_right; } 34 | 35 | protected: 36 | virtual void registerInputs() { 37 | this->registerInput(&m_left); 38 | this->registerInput(&m_right); 39 | } 40 | 41 | protected: 42 | pNodeInput m_left; 43 | pNodeInput m_right; 44 | }; 45 | 46 | } /* namespace piranha */ 47 | 48 | #endif /* PIRANHA_DIVIDE_OPERATION_OUTPUT_H */ 49 | -------------------------------------------------------------------------------- /include/error_list.h: -------------------------------------------------------------------------------- 1 | #ifndef PIRANHA_IR_ERROR_LIST_H 2 | #define PIRANHA_IR_ERROR_LIST_H 3 | 4 | #include 5 | 6 | namespace piranha { 7 | 8 | class CompilationError; 9 | 10 | class ErrorList { 11 | public: 12 | ErrorList(); 13 | ~ErrorList(); 14 | 15 | void addCompilationError(CompilationError *err); 16 | CompilationError *getCompilationError(int index) const { return m_compilationErrors[index]; } 17 | int getErrorCount() const { return (int)m_compilationErrors.size(); } 18 | 19 | void free(); 20 | 21 | protected: 22 | std::vector m_compilationErrors; 23 | }; 24 | 25 | } /* namespace piranha */ 26 | 27 | #endif /* PIRANHA_IR_ERROR_LIST_H */ 28 | -------------------------------------------------------------------------------- /include/exceptions.h: -------------------------------------------------------------------------------- 1 | #ifndef PIRANHA_EXCEPTIONS_H 2 | #define PIRANHA_EXCEPTIONS_H 3 | 4 | #include 5 | 6 | namespace piranha { 7 | 8 | struct MissingConversion : public std::exception { 9 | virtual const char *what() const throw() { 10 | return "A required conversion is missing from the language specification"; 11 | } 12 | }; 13 | 14 | struct EmptyPort : public std::exception { 15 | virtual const char *what() const throw() { 16 | return "Could not find a node or output to populate a port"; 17 | } 18 | }; 19 | 20 | struct InvalidLiteralType : public std::exception { 21 | virtual const char *what() const throw() { 22 | return "Invalid type used for a literal. All node types used for literals must derive from " 23 | "LiteralNode<>"; 24 | } 25 | }; 26 | 27 | } /* namespace piranha */ 28 | 29 | #endif /* PIRANHA_EXCEPTIONS_H */ 30 | -------------------------------------------------------------------------------- /include/float_conversions.h: -------------------------------------------------------------------------------- 1 | #ifndef PIRANHA_FLOAT_CONVERSIONS_H 2 | #define PIRANHA_FLOAT_CONVERSIONS_H 3 | 4 | #include "fundamental_output.h" 5 | 6 | #include "pipe_node.h" 7 | #include "default_literal_node.h" 8 | 9 | namespace piranha { 10 | 11 | class StringToFloatConversionOutput : public FloatValueOutput { 12 | public: 13 | StringToFloatConversionOutput(); 14 | ~StringToFloatConversionOutput(); 15 | 16 | virtual void fullCompute(void *target) const; 17 | virtual void registerInputs(); 18 | 19 | pNodeInput *getInputConnection() { return &m_input; } 20 | 21 | protected: 22 | pNodeInput m_input; 23 | }; 24 | 25 | 26 | class IntToFloatConversionOutput : public FloatValueOutput { 27 | public: 28 | IntToFloatConversionOutput(); 29 | ~IntToFloatConversionOutput(); 30 | 31 | virtual void fullCompute(void *target) const; 32 | virtual void registerInputs(); 33 | 34 | pNodeInput *getInputConnection() { return &m_input; } 35 | 36 | protected: 37 | pNodeInput m_input; 38 | }; 39 | 40 | template 41 | class FloatConversion : public Node { 42 | public: 43 | FloatConversion() { 44 | /* void */ 45 | } 46 | 47 | ~FloatConversion() { 48 | /* void */ 49 | } 50 | 51 | virtual void _initialize() { 52 | m_output.initialize(); 53 | } 54 | 55 | virtual void _evaluate() { 56 | /* void */ 57 | } 58 | 59 | virtual void _destroy() { 60 | /* void */ 61 | } 62 | 63 | virtual void registerInputs() { 64 | registerInput(m_output.getInputConnection(), "__in"); 65 | } 66 | 67 | virtual void registerOutputs() { 68 | setPrimaryOutput("__out"); 69 | registerOutput(&m_output, "__out"); 70 | } 71 | 72 | protected: 73 | virtual Node *_optimize(NodeAllocator *nodeAllocator) { 74 | addFlag(Node::META_ACTIONLESS); 75 | 76 | bool isConstant = true; 77 | pNodeInput input = *m_output.getInputConnection(); 78 | if (!input->getParentNode()->hasFlag(META_CONSTANT)) { 79 | isConstant = false; 80 | } 81 | 82 | if (isConstant) { 83 | addFlag(Node::META_CONSTANT); 84 | 85 | const bool result = evaluate(); 86 | if (!result) return nullptr; 87 | 88 | DefaultLiteralNode *newLiteral = 89 | nodeAllocator->allocate>(); 90 | 91 | piranha::native_float computedValue; 92 | m_output.fullCompute((void *)&computedValue); 93 | 94 | mapOptimizedPort(newLiteral, "__out", "__out"); 95 | newLiteral->setData(computedValue); 96 | return newLiteral; 97 | } 98 | 99 | return this; 100 | } 101 | 102 | T_ConversionOutput m_output; 103 | }; 104 | 105 | typedef FloatConversion IntToFloatConversionNode; 106 | typedef FloatConversion StringToFloatConversionNode; 107 | 108 | } /* namespace piranha */ 109 | 110 | #endif /* PIRANHA_FLOAT_CONVERSIONS_H */ 111 | -------------------------------------------------------------------------------- /include/fundamental_output.h: -------------------------------------------------------------------------------- 1 | #ifndef PIRANHA_FUNDAMENTAL_OUTPUT_H 2 | #define PIRANHA_FUNDAMENTAL_OUTPUT_H 3 | 4 | #include "node_output.h" 5 | 6 | #include "fundamental_types.h" 7 | 8 | #include 9 | 10 | namespace piranha { 11 | 12 | template 13 | class FundamentalOutput : public NodeOutput {}; 14 | 15 | template <> 16 | class FundamentalOutput : public NodeOutput { 17 | public: 18 | FundamentalOutput() : NodeOutput(&FundamentalType::FloatType) {}; 19 | ~FundamentalOutput() { /* void */ } 20 | }; 21 | 22 | template <> 23 | class FundamentalOutput : public NodeOutput { 24 | public: 25 | FundamentalOutput() : NodeOutput(&FundamentalType::IntType) {}; 26 | ~FundamentalOutput() { /* void */ } 27 | }; 28 | 29 | template <> 30 | class FundamentalOutput : public NodeOutput { 31 | public: 32 | FundamentalOutput() : NodeOutput(&FundamentalType::BoolType) {}; 33 | ~FundamentalOutput() { /* void */ } 34 | }; 35 | 36 | template <> 37 | class FundamentalOutput : public NodeOutput { 38 | public: 39 | FundamentalOutput() : NodeOutput(&FundamentalType::StringType) {}; 40 | ~FundamentalOutput() { /* void */ } 41 | }; 42 | 43 | typedef FundamentalOutput FloatValueOutput; 44 | typedef FundamentalOutput IntValueOutput; 45 | typedef FundamentalOutput BoolValueOutput; 46 | typedef FundamentalOutput StringValueOutput; 47 | 48 | } /* namespace piranha */ 49 | 50 | #endif /* PIRANHA_FUNDAMENTAL_OUTPUT_H */ 51 | -------------------------------------------------------------------------------- /include/fundamental_types.h: -------------------------------------------------------------------------------- 1 | #ifndef PIRANHA_FUNDAMENTAL_TYPES_H 2 | #define PIRANHA_FUNDAMENTAL_TYPES_H 3 | 4 | #include "channel_type.h" 5 | 6 | #include 7 | 8 | namespace piranha { 9 | 10 | struct FundamentalType { 11 | static const ChannelType FloatType; 12 | static const ChannelType IntType; 13 | static const ChannelType StringType; 14 | static const ChannelType BoolType; 15 | static const ChannelType VectorType; 16 | }; 17 | 18 | struct vector { 19 | double x; 20 | double y; 21 | double z; 22 | double w; 23 | 24 | vector operator+(const vector &v) const { 25 | return { x + v.x, y + v.y, z + v.z, w + v.w }; 26 | } 27 | 28 | vector operator-(const vector &v) const { 29 | return { x - v.x, y - v.y, z - v.z, w - v.w }; 30 | } 31 | 32 | vector operator/(const vector &v) const { 33 | return { x / v.x, y / v.y, z / v.z, w / v.w }; 34 | } 35 | 36 | vector operator*(const vector &v) const { 37 | return { x * v.x, y * v.y, z * v.z, w * v.w }; 38 | } 39 | 40 | vector operator-() const { 41 | return { -x, -y, -z, -w }; 42 | } 43 | }; 44 | 45 | // Native types 46 | typedef double native_float; 47 | typedef bool native_bool; 48 | typedef std::string native_string; 49 | typedef int native_int; 50 | typedef vector native_vector; 51 | 52 | enum class LiteralType { 53 | Float, 54 | Boolean, 55 | String, 56 | Integer, 57 | Undefined 58 | }; 59 | 60 | template 61 | bool dependantFalse() { 62 | // This stops clang/gcc from seeing the static_assert is always false 63 | return false; 64 | } 65 | 66 | template 67 | inline LiteralType LiteralTypeLookup() { static_assert(dependantFalse, "Looking up a type that does not exist"); return LiteralType::Undefined; }; 68 | 69 | template <> inline LiteralType LiteralTypeLookup() { return LiteralType::Float; } 70 | template <> inline LiteralType LiteralTypeLookup() { return LiteralType::Boolean; } 71 | template <> inline LiteralType LiteralTypeLookup() { return LiteralType::Integer; } 72 | template <> inline LiteralType LiteralTypeLookup() { return LiteralType::String; } 73 | 74 | template 75 | inline const ChannelType *NativeTypeLookup() { static_assert(dependantFalse, "Looking up a type that does not exist"); return nullptr; } 76 | 77 | template <> inline const ChannelType *NativeTypeLookup() { return &FundamentalType::FloatType; } 78 | template <> inline const ChannelType *NativeTypeLookup() { return &FundamentalType::BoolType; } 79 | template <> inline const ChannelType *NativeTypeLookup() { return &FundamentalType::IntType; } 80 | template <> inline const ChannelType *NativeTypeLookup() { return &FundamentalType::StringType; } 81 | template <> inline const ChannelType *NativeTypeLookup() { return &FundamentalType::VectorType; } 82 | 83 | } /* namespace piranha */ 84 | 85 | #endif /* PIRANHA_FUNDAMENTAL_TYPES_H */ 86 | -------------------------------------------------------------------------------- /include/int_conversions.h: -------------------------------------------------------------------------------- 1 | #ifndef PIRANHA_INT_CONVERSIONS_H 2 | #define PIRANHA_INT_CONVERSIONS_H 3 | 4 | #include "fundamental_output.h" 5 | 6 | #include "pipe_node.h" 7 | 8 | namespace piranha { 9 | 10 | class StringToIntConversion : public StringValueOutput { 11 | public: 12 | StringToIntConversion(); 13 | ~StringToIntConversion(); 14 | 15 | virtual void fullCompute(void *target) const; 16 | virtual void registerInputs(); 17 | 18 | pNodeInput *getInputConnection() { return &m_input; } 19 | 20 | protected: 21 | pNodeInput m_input; 22 | }; 23 | typedef PipeNode StringToIntConversionNode; 24 | 25 | } /* namespace piranha */ 26 | 27 | #endif /* PIRANHA_INT_CONVERSIONS_H */ 28 | -------------------------------------------------------------------------------- /include/int_probe.h: -------------------------------------------------------------------------------- 1 | #ifndef PIRANHA_INT_PROBE_NODE_H 2 | #define PIRANHA_INT_PROBE_NODE_H 3 | 4 | #include "node.h" 5 | 6 | #include "fundamental_types.h" 7 | 8 | #include 9 | #include 10 | 11 | namespace piranha { 12 | 13 | class IntProbeNode : public Node { 14 | public: 15 | IntProbeNode() { 16 | m_input = nullptr; 17 | } 18 | 19 | ~IntProbeNode() { 20 | /* void */ 21 | } 22 | 23 | protected: 24 | virtual void _evaluate() { 25 | piranha::native_int data; 26 | m_input->fullCompute(&data); 27 | } 28 | 29 | virtual void registerInputs() { 30 | registerInput(&m_input, "__in"); 31 | } 32 | 33 | virtual void registerOutputs() { 34 | /* void */ 35 | } 36 | 37 | protected: 38 | pNodeInput m_input; 39 | }; 40 | 41 | } /* namespace piranha */ 42 | 43 | #endif /* PIRANHA_INT_PROBE_NODE_H */ 44 | -------------------------------------------------------------------------------- /include/ir_attribute.h: -------------------------------------------------------------------------------- 1 | #ifndef PIRANHA_IR_ATTRIBUTE_H 2 | #define PIRANHA_IR_ATTRIBUTE_H 3 | 4 | #include "ir_parser_structure.h" 5 | 6 | #include "ir_token_info.h" 7 | 8 | namespace piranha { 9 | 10 | class IrValue; 11 | class IrAttributeDefinition; 12 | 13 | class IrAttribute : public IrParserStructure { 14 | public: 15 | IrAttribute(); 16 | IrAttribute(const IrTokenInfo_string &name, IrValue *value); 17 | IrAttribute(IrValue *value); 18 | ~IrAttribute(); 19 | 20 | std::string getName() const { return m_name.data; } 21 | 22 | void setValue(IrValue *value); 23 | IrValue *getValue() const { return m_value; } 24 | 25 | void setPosition(int position) { m_position = position; } 26 | int getPosition() const { return m_position; } 27 | 28 | // If no name is specified positional notation is assumed 29 | bool isPositional() const { return getName() == ""; } 30 | 31 | virtual bool isExternalInput() const { return true; } 32 | 33 | virtual void free(); 34 | 35 | protected: 36 | IrTokenInfo_string m_name; 37 | IrValue *m_value; 38 | 39 | int m_position; 40 | 41 | // Resolution stage 42 | public: 43 | void setAttributeDefinition(IrAttributeDefinition *definition) { 44 | m_definition = definition; 45 | } 46 | IrAttributeDefinition *getAttributeDefinition() const { return m_definition; } 47 | 48 | virtual IrParserStructure *getImmediateReference( 49 | const IrReferenceQuery &query, IrReferenceInfo *output); 50 | virtual void _checkTypes(IrContextTree *context); 51 | 52 | protected: 53 | IrAttributeDefinition *m_definition; 54 | }; 55 | 56 | } /* namespace piranha */ 57 | 58 | #endif /* PIRANHA_IR_ATTRIBUTE_H */ 59 | -------------------------------------------------------------------------------- /include/ir_attribute_definition.h: -------------------------------------------------------------------------------- 1 | #ifndef PIRANHA_IR_ATTRIBUTE_DEFINITION_H 2 | #define PIRANHA_IR_ATTRIBUTE_DEFINITION_H 3 | 4 | #include "ir_parser_structure.h" 5 | 6 | #include "ir_token_info.h" 7 | 8 | namespace piranha { 9 | 10 | class IrValue; 11 | class IrInputConnection; 12 | class CompilationError; 13 | class IrNodeDefinition; 14 | 15 | class IrAttributeDefinition : public IrParserStructure { 16 | public: 17 | enum class Direction { 18 | Input, 19 | Output, 20 | Modify, 21 | Toggle 22 | }; 23 | 24 | public: 25 | IrAttributeDefinition(const IrTokenInfo_string &directionToken, 26 | const IrTokenInfo_string &name, Direction dir); 27 | IrAttributeDefinition(const IrTokenInfo_string &name); 28 | virtual ~IrAttributeDefinition(); 29 | 30 | const IrTokenInfo *getNameToken() const { return &m_name; } 31 | std::string getName() const { return m_name.data; } 32 | 33 | void setDefaultValue(IrValue *value); 34 | IrValue *getDefaultValue() const { return m_defaultValue; } 35 | 36 | void setAliasToken(const IrTokenInfo_string &name); 37 | const IrTokenInfo *getAliasToken() const { return (m_isAlias) ? &m_aliasToken : nullptr; } 38 | void setAlias(bool isAlias) { m_isAlias = isAlias; } 39 | bool isAlias() const { return m_isAlias; } 40 | 41 | const IrTokenInfo *getDirectionToken() const { return &m_directionToken; } 42 | void setDirection(Direction direction) { m_direction = direction; } 43 | Direction getDirection() const { return m_direction; } 44 | 45 | virtual IrParserStructure *getImmediateReference(const IrReferenceQuery &query, IrReferenceInfo *output); 46 | 47 | void setTypeInfo(const IrTokenInfoSet &typeInfo) { m_typeInfo = typeInfo; } 48 | bool typeInfoSpecified() const { return m_typeInfo.data[0].specified; } 49 | 50 | IrNodeDefinition *getTypeDefinition() const; 51 | IrNodeDefinition *getImmediateTypeDefinition() const { return m_typeDefinition; } 52 | virtual const ChannelType *getImmediateChannelType(); 53 | 54 | virtual void _expand(IrContextTree *context); 55 | virtual void _checkTypes(IrContextTree *context); 56 | 57 | bool isInput() const; 58 | bool isThis() const; 59 | 60 | protected: 61 | IrTokenInfo_string m_directionToken; 62 | IrTokenInfo_string m_aliasToken; 63 | IrTokenInfo_string m_name; 64 | IrTokenInfoSet m_typeInfo; 65 | 66 | IrValue *m_defaultValue; 67 | 68 | Direction m_direction; 69 | bool m_isAlias; 70 | 71 | std::vector m_impliedMembers; 72 | 73 | // Resolution stage 74 | protected: 75 | virtual void _resolveDefinitions(); 76 | 77 | IrNodeDefinition *m_typeDefinition; 78 | 79 | protected: 80 | virtual Node *_generateNode(IrContextTree *context, NodeProgram *program, NodeContainer *container); 81 | virtual NodeOutput *_generateNodeOutput(IrContextTree *context, NodeProgram *program, NodeContainer *container); 82 | }; 83 | 84 | } /* namespace piranha */ 85 | 86 | #endif /* PIRANHA_IR_ATTRIBUTE_DEFINITION_H */ 87 | -------------------------------------------------------------------------------- /include/ir_attribute_definition_list.h: -------------------------------------------------------------------------------- 1 | #ifndef PIRANHA_IR_ATTRIBUTE_DEFINITION_LIST_H 2 | #define PIRANHA_IR_ATTRIBUTE_DEFINITION_LIST_H 3 | 4 | #include "ir_parser_structure.h" 5 | 6 | #include "ir_attribute_definition.h" 7 | 8 | #include 9 | #include 10 | 11 | namespace piranha { 12 | 13 | class IrAttributeDefinitionList : public IrParserStructure { 14 | public: 15 | IrAttributeDefinitionList(); 16 | ~IrAttributeDefinitionList(); 17 | 18 | void addDefinition(IrAttributeDefinition *definition); 19 | IrAttributeDefinition *getDefinition(int index) const { return m_definitions[index]; } 20 | int getDefinitionCount() const { return (int)m_definitions.size(); } 21 | 22 | IrAttributeDefinition *getDefinition(int index, bool isInput) const; 23 | IrAttributeDefinition *getInputDefinition(int index) const; 24 | 25 | IrAttributeDefinition *getOutputDefinition(int index) const; 26 | IrAttributeDefinition *getOutputDefinition(const std::string &name) const; 27 | IrAttributeDefinition *getAliasOutput() const; 28 | 29 | int getCount(IrAttributeDefinition::Direction direction) const; 30 | int getInputCount() const; 31 | int getOutputCount() const; 32 | 33 | protected: 34 | std::vector m_definitions; 35 | }; 36 | 37 | } /* namespace piranha */ 38 | 39 | #endif /* PIRANHA_IR_ATTRIBUTE_DEFINITION_LIST_H */ 40 | -------------------------------------------------------------------------------- /include/ir_attribute_list.h: -------------------------------------------------------------------------------- 1 | #ifndef PIRANHA_IR_ATTRIBUTE_LIST_H 2 | #define PIRANHA_IR_ATTRIBUTE_LIST_H 3 | 4 | #include "ir_parser_structure.h" 5 | 6 | #include 7 | 8 | namespace piranha { 9 | 10 | class IrAttribute; 11 | class IrAttributeDefinition; 12 | 13 | class IrAttributeList : public IrParserStructure { 14 | public: 15 | IrAttributeList(); 16 | ~IrAttributeList(); 17 | 18 | void addAttribute(IrAttribute *attribute); 19 | IrAttribute *getAttribute(int index) const { return m_attributes[index]; } 20 | IrAttribute *getAttribute(IrAttributeDefinition *definition) const; 21 | int getAttributeCount() const { return (int)m_attributes.size(); } 22 | 23 | virtual void free(); 24 | 25 | protected: 26 | std::vector m_attributes; 27 | }; 28 | 29 | } /* namespace piranha */ 30 | 31 | #endif /* PIRANHA_IR_ATTRIBUTE_LIST_H */ 32 | -------------------------------------------------------------------------------- /include/ir_binary_operator.h: -------------------------------------------------------------------------------- 1 | #ifndef PIRANHA_IR_BINARY_OPERATOR_H 2 | #define PIRANHA_IR_BINARY_OPERATOR_H 3 | 4 | #include "ir_value.h" 5 | 6 | #include "pkey_value_lookup.h" 7 | 8 | namespace piranha { 9 | 10 | class CompilationError; 11 | class IrNodeDefinition; 12 | 13 | class IrBinaryOperator : public IrValue { 14 | public: 15 | enum class Operator { 16 | Dot, 17 | Add, 18 | Sub, 19 | Mul, 20 | Div 21 | }; 22 | 23 | public: 24 | IrBinaryOperator(Operator op, IrValue *leftOperand, IrValue *rightOperand); 25 | ~IrBinaryOperator(); 26 | 27 | Operator getOperator() const { return m_operator; } 28 | IrValue *getLeft() const { return m_leftOperand; } 29 | IrValue *getRight() const { return m_rightOperand; } 30 | 31 | virtual IrParserStructure *resolveLocalName(const std::string &name) const; 32 | virtual IrParserStructure *getImmediateReference(const IrReferenceQuery &query, IrReferenceInfo *output); 33 | 34 | protected: 35 | void _expand(IrContextTree *tree); 36 | 37 | protected: 38 | Operator m_operator; 39 | IrValue *m_leftOperand; 40 | IrValue *m_rightOperand; 41 | 42 | protected: 43 | virtual Node *_generateNode(IrContextTree *context, NodeProgram *program, NodeContainer *container); 44 | virtual NodeOutput *_generateNodeOutput(IrContextTree *context, NodeProgram *program, NodeContainer *container); 45 | }; 46 | 47 | } /* namespace piranha */ 48 | 49 | #endif /* PIRANHA_IR_BINARY_OPERATOR_H */ 50 | -------------------------------------------------------------------------------- /include/ir_context_tree.h: -------------------------------------------------------------------------------- 1 | #ifndef PIRANHA_IR_CONTEXT_TREE_H 2 | #define PIRANHA_IR_CONTEXT_TREE_H 3 | 4 | #include 5 | 6 | namespace piranha { 7 | 8 | class IrNode; 9 | class IrAttributeDefinition; 10 | class IrParserStructure; 11 | class Node; 12 | class NodeOutput; 13 | 14 | class IrContextTree { 15 | public: 16 | IrContextTree(); 17 | IrContextTree(IrNode *context, bool mainContext = false); 18 | ~IrContextTree(); 19 | 20 | void setParent(IrContextTree *parent) { m_parent = parent; } 21 | IrContextTree *getParent() const { return m_parent; } 22 | IrContextTree *getRoot(); 23 | IrContextTree *getMain(); 24 | 25 | IrContextTree *newChild(IrNode *context, bool mainContext = false); 26 | 27 | IrNode *getContext() const { return m_context; } 28 | bool hasParent(const IrContextTree *context) const; 29 | IrContextTree *findContext(IrNode *context); 30 | 31 | IrParserStructure *resolveDefinition(IrAttributeDefinition *definition); 32 | 33 | bool isMainContext() const { return m_mainContext; } 34 | 35 | bool operator==(const IrContextTree &ref) const { return isEqual(&ref); } 36 | bool isEqual(const IrContextTree *ref) const; 37 | bool isOutside(const IrContextTree *ref) const; 38 | 39 | int getChildCount() const { return (int)m_children.size(); } 40 | 41 | bool isEmpty() const { return m_context == nullptr; } 42 | 43 | virtual void free(); 44 | 45 | protected: 46 | IrContextTree *_getMain(); 47 | 48 | IrNode *m_context; 49 | bool m_mainContext; 50 | 51 | IrContextTree *m_parent; 52 | std::vector m_children; 53 | }; 54 | 55 | } /* namespace piranha */ 56 | 57 | #endif /* PIRANHA_IR_CONTEXT_TREE_H */ 58 | -------------------------------------------------------------------------------- /include/ir_import_statement.h: -------------------------------------------------------------------------------- 1 | #ifndef PIRANHA_IR_IMPORT_STATEMENT_H 2 | #define PIRANHA_IR_IMPORT_STATEMENT_H 3 | 4 | #include 5 | 6 | #include "ir_parser_structure.h" 7 | #include "ir_token_info.h" 8 | #include "ir_visibility.h" 9 | 10 | namespace piranha { 11 | 12 | class IrCompilationUnit; 13 | 14 | class IrImportStatement : public IrParserStructure { 15 | public: 16 | IrImportStatement(const IrTokenInfo_string &libName); 17 | ~IrImportStatement(); 18 | 19 | std::string getLibName() const { return m_libName.data; } 20 | 21 | void setUnit(IrCompilationUnit *unit) { m_unit = unit; } 22 | IrCompilationUnit *getUnit() const { return m_unit; } 23 | 24 | void setShortName(const IrTokenInfo_string &shortName) { m_shortName = shortName; } 25 | bool hasShortName() const { return m_shortName.specified; } 26 | std::string getShortName() const { return m_shortName.data; } 27 | 28 | protected: 29 | IrTokenInfo_string m_shortName; 30 | IrTokenInfo_string m_libName; 31 | IrCompilationUnit *m_unit; 32 | }; 33 | 34 | } /* namespace piranha */ 35 | 36 | #endif /* PIRANHA_IR_IMPORT_STATEMENT */ 37 | -------------------------------------------------------------------------------- /include/ir_literal_node.h: -------------------------------------------------------------------------------- 1 | #ifndef PIRANHA_IR_LITERAL_NODE_H 2 | #define PIRANHA_IR_LITERAL_NODE_H 3 | 4 | #include "ir_node.h" 5 | 6 | #include "node.h" 7 | #include "literal_node.h" 8 | #include "fundamental_types.h" 9 | #include "exceptions.h" 10 | 11 | namespace piranha { 12 | 13 | template 14 | class IrLiteralNode : public IrNode { 15 | public: 16 | IrLiteralNode() { 17 | reset(m_literalData); 18 | } 19 | 20 | ~IrLiteralNode() { 21 | /* void */ 22 | } 23 | 24 | void setLiteralData(const NativeType &type) { m_literalData = type; } 25 | 26 | public: 27 | virtual Node *_generateNode(IrContextTree *context, NodeProgram *program, NodeContainer *container) { 28 | Node *newNode = IrNode::_generateNode(context, program, container); 29 | 30 | if (!newNode->isLiteral()) { 31 | throw InvalidLiteralType(); 32 | } 33 | else { 34 | LiteralNode *literalNode = 35 | static_cast *>(newNode); 36 | 37 | // Inject the literal data 38 | literalNode->setData(m_literalData); 39 | } 40 | 41 | return newNode; 42 | } 43 | 44 | protected: 45 | NativeType m_literalData; 46 | 47 | protected: 48 | static void reset(piranha::native_bool &s) { s = false; } 49 | static void reset(piranha::native_float &s) { s = (piranha::native_float)0.0; } 50 | static void reset(piranha::native_int &s) { s = (piranha::native_int)0; } 51 | static void reset(piranha::native_string &s) { s = ""; } 52 | static void reset(piranha::native_vector &s) { s = { 0.0, 0.0, 0.0, 0.0 }; } 53 | }; 54 | 55 | } /* namespace piranha */ 56 | 57 | #endif /* PIRANHA_IR_LITERAL_NODE_H */ 58 | -------------------------------------------------------------------------------- /include/ir_node_definition.h: -------------------------------------------------------------------------------- 1 | #ifndef PIRANHA_IR_NODE_DEFINITION_H 2 | #define PIRANHA_IR_NODE_DEFINITION_H 3 | 4 | #include "ir_parser_structure.h" 5 | 6 | #include "ir_token_info.h" 7 | #include "ir_structure_list.h" 8 | #include "fundamental_types.h" 9 | 10 | namespace piranha { 11 | 12 | class IrAttributeDefinitionList; 13 | class IrAttributeDefinition; 14 | class IrCompilationUnit; 15 | 16 | class IrNodeDefinition : public IrParserStructure { 17 | public: 18 | IrNodeDefinition(const IrTokenInfo_string &name); 19 | virtual ~IrNodeDefinition(); 20 | 21 | const IrTokenInfo *getBuiltinNameToken() const { return m_definesBuiltin ? &m_builtinName : nullptr; } 22 | std::string getBuiltinName() const { return m_builtinName.data; } 23 | void setBuiltinName(const IrTokenInfo_string &builtin); 24 | 25 | void setDefinesBuiltin(bool defines) { m_definesBuiltin = defines; } 26 | bool isBuiltin() const { return m_definesBuiltin; } 27 | 28 | void setIsInline(bool isInline) { m_isInline = isInline; } 29 | bool isInline() const { return m_isInline; } 30 | 31 | const IrTokenInfo_string *getNameToken() const { return &m_name; } 32 | std::string getName() const { return m_name.data; } 33 | 34 | void setAttributeDefinitionList(IrAttributeDefinitionList *definitions); 35 | const IrAttributeDefinitionList *getAttributeDefinitionList() const { return m_attributes; } 36 | 37 | void setScopeToken(const IrTokenInfo_string &token); 38 | const IrTokenInfo *getScopeToken() const { return &m_scopeToken; } 39 | 40 | IrAttributeDefinition *getAttributeDefinition(const std::string &attributeName) const; 41 | 42 | void setBody(IrNodeList *body) { m_body = body; registerComponent(body); } 43 | IrNodeList *getBody() const { return m_body; } 44 | 45 | virtual IrParserStructure *resolveName(const std::string &name) const; 46 | 47 | const ChannelType *getChannelType(); 48 | IrNodeDefinition *getAliasType(); 49 | 50 | virtual void free(); 51 | 52 | protected: 53 | IrTokenInfo_string m_name; 54 | 55 | bool m_definesBuiltin; 56 | IrTokenInfo_string m_builtinName; 57 | 58 | bool m_isInline; 59 | 60 | IrAttributeDefinitionList *m_attributes; 61 | IrNodeList *m_body; 62 | 63 | IrTokenInfo_string m_scopeToken; 64 | 65 | // Resolution stage 66 | public: 67 | virtual void checkCircularDefinitions(); 68 | 69 | int countSymbolIncidence(const std::string &name) const; 70 | IrParserStructure *resolveLocalName(const std::string &name) const; 71 | 72 | protected: 73 | virtual void _validate(); 74 | void validateBuiltinMappings(); 75 | }; 76 | 77 | } /* namespace piranha */ 78 | 79 | #endif /* PIRANHA_IR_NODE_DEFINITION_H */ 80 | -------------------------------------------------------------------------------- /include/ir_structure_list.h: -------------------------------------------------------------------------------- 1 | #ifndef PIRANHA_IR_STRUCTURE_LIST_H 2 | #define PIRANHA_IR_STRUCTURE_LIST_H 3 | 4 | #include "ir_parser_structure.h" 5 | 6 | #include 7 | 8 | namespace piranha { 9 | 10 | template 11 | class IrStructureList : public IrParserStructure { 12 | public: 13 | IrStructureList() { /* void */ } 14 | ~IrStructureList() { /* void */ } 15 | 16 | void add(T *item) { m_items.push_back(item); registerComponent(item); } 17 | T *getItem(int index) const { return m_items[index]; } 18 | int getItemCount() const { return (int)m_items.size(); } 19 | 20 | protected: 21 | std::vector m_items; 22 | }; 23 | 24 | class IrNode; 25 | 26 | typedef IrStructureList IrNodeList; 27 | 28 | } /* namespace piranha */ 29 | 30 | #endif /* PIRANHA_IR_STRUCTURE_LIST_H */ 31 | -------------------------------------------------------------------------------- /include/ir_token_info.h: -------------------------------------------------------------------------------- 1 | #ifndef PIRANHA_IR_TOKEN_INFO_H 2 | #define PIRANHA_IR_TOKEN_INFO_H 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | namespace piranha { 9 | 10 | struct IrTokenInfo { 11 | IrTokenInfo(int lineStart, int lineEnd, int colStart, int colEnd) : 12 | lineStart(lineStart), lineEnd(lineEnd), colStart(colStart), colEnd(colEnd) { 13 | valid = true; 14 | specified = true; 15 | empty = false; 16 | } 17 | 18 | IrTokenInfo() : 19 | lineStart(INT_MAX), lineEnd(-1), colStart(INT_MAX), colEnd(-1) { 20 | valid = true; 21 | specified = false; 22 | empty = true; 23 | } 24 | 25 | ~IrTokenInfo() { 26 | /* void */ 27 | } 28 | 29 | int lineStart; 30 | int lineEnd; 31 | int colStart; 32 | int colEnd; 33 | bool valid; 34 | bool empty; 35 | bool specified; 36 | 37 | void combine(const IrTokenInfo *info) { 38 | valid = valid && info->valid; 39 | 40 | if (info->lineStart < lineStart) { 41 | lineStart = info->lineStart; 42 | colStart = info->colStart; 43 | } 44 | else if (info->lineStart == lineStart) { 45 | if (info->colStart < colStart) { 46 | colStart = info->colStart; 47 | } 48 | } 49 | 50 | if (info->lineEnd > lineEnd) { 51 | lineEnd = info->lineEnd; 52 | colEnd = info->colEnd; 53 | } 54 | else if (info->lineEnd == lineEnd) { 55 | if (info->colEnd > colEnd) { 56 | colEnd = info->colEnd; 57 | } 58 | } 59 | } 60 | 61 | friend std::ostream& operator<<(std::ostream& os, const IrTokenInfo& dt) { 62 | os << dt.colStart << " (L" << dt.lineStart << ")" 63 | << " - " << dt.colEnd << " (L" << dt.lineEnd << ")" << std::endl; 64 | return os; 65 | } 66 | }; 67 | 68 | template 69 | struct T_IrTokenInfo : public IrTokenInfo { 70 | T_IrTokenInfo() { 71 | /* void */ 72 | } 73 | 74 | T_IrTokenInfo(const T &data) : data(data) { 75 | /* void */ 76 | } 77 | 78 | T_IrTokenInfo(const T &data, int lineStart, int lineEnd, int colStart, int colEnd) 79 | : data(data), IrTokenInfo(lineStart, lineEnd, colStart, colEnd) { 80 | /* void */ 81 | } 82 | 83 | ~T_IrTokenInfo() { 84 | /* void */ 85 | } 86 | 87 | T data; 88 | }; 89 | 90 | template 91 | struct IrTokenInfoSet { 92 | IrTokenInfoSet() { 93 | /* void */ 94 | } 95 | 96 | ~IrTokenInfoSet() { 97 | /* void */ 98 | } 99 | 100 | T_IrTokenInfo data[size]; 101 | }; 102 | 103 | typedef T_IrTokenInfo IrTokenInfo_int; 104 | typedef T_IrTokenInfo IrTokenInfo_string; 105 | typedef T_IrTokenInfo IrTokenInfo_float; 106 | typedef T_IrTokenInfo IrTokenInfo_bool; 107 | 108 | } /* namespace piranha */ 109 | 110 | #endif /* PIRANHA_IR_TOKEN_INFO_H */ 111 | -------------------------------------------------------------------------------- /include/ir_unary_operator.h: -------------------------------------------------------------------------------- 1 | #ifndef PIRANHA_IR_UNARY_OPERATOR_H 2 | #define PIRANHA_IR_UNARY_OPERATOR_H 3 | 4 | #include "ir_value.h" 5 | 6 | namespace piranha { 7 | 8 | class CompilationError; 9 | 10 | class IrUnaryOperator : public IrValue { 11 | public: 12 | enum class Operator { 13 | Default, 14 | NumericNegate, 15 | BoolNegate, 16 | Positive 17 | }; 18 | 19 | public: 20 | IrUnaryOperator(Operator op, IrValue *operand); 21 | ~IrUnaryOperator(); 22 | 23 | Operator getOperator() const { return m_operator; } 24 | IrValue *getOperand() const { return m_operand; } 25 | 26 | virtual IrParserStructure *getImmediateReference(const IrReferenceQuery &query, IrReferenceInfo *output); 27 | 28 | protected: 29 | void _expand(IrContextTree *context); 30 | 31 | protected: 32 | Operator m_operator; 33 | IrValue *m_operand; 34 | }; 35 | 36 | } /* namespace piranha */ 37 | 38 | #endif /* PIRANHA_IR_UNARY_OPERATOR_H */ 39 | -------------------------------------------------------------------------------- /include/ir_value.h: -------------------------------------------------------------------------------- 1 | #ifndef PIRANHA_IR_VALUE_H 2 | #define PIRANHA_IR_VALUE_H 3 | 4 | #include "ir_parser_structure.h" 5 | 6 | #include 7 | 8 | namespace piranha { 9 | 10 | class IrAttribute; 11 | class NodeOutput; 12 | class Node; 13 | class NodeProgram; 14 | class IrContextTree; 15 | 16 | class IrValue : public IrParserStructure { 17 | public: 18 | enum class ValueType { 19 | ConstantFloat, 20 | ConstantInt, 21 | ConstantString, 22 | ConstantLabel, 23 | ConstantBool, 24 | 25 | BinaryOperation, 26 | UnaryOperation, 27 | 28 | NodeReference, 29 | InternalReference 30 | }; 31 | 32 | public: 33 | IrValue(ValueType type); 34 | virtual ~IrValue(); 35 | 36 | ValueType getType() const { return m_type; } 37 | 38 | private: 39 | ValueType m_type; 40 | }; 41 | 42 | } /* namespace piranha */ 43 | 44 | #endif /* PIRANHA_IR_VALUE_H */ 45 | -------------------------------------------------------------------------------- /include/ir_visibility.h: -------------------------------------------------------------------------------- 1 | #ifndef PIRANHA_IR_VISIBILITY_H 2 | #define PIRANHA_IR_VISIBILITY_H 3 | 4 | namespace piranha { 5 | 6 | enum class IrVisibility { 7 | Private, 8 | Public, 9 | Default 10 | }; 11 | 12 | } /* namespace piranha */ 13 | 14 | #endif /* PIRANHA_IR_VISIBILITY_H */ 15 | -------------------------------------------------------------------------------- /include/key_value_lookup.h: -------------------------------------------------------------------------------- 1 | #ifndef PIRANHA_KEY_VALUE_LOOKUP_H 2 | #define PIRANHA_KEY_VALUE_LOOKUP_H 3 | 4 | #include "memory_tracker.h" 5 | 6 | #include 7 | 8 | namespace piranha { 9 | 10 | template 11 | class KeyValueLookup { 12 | private: 13 | struct KeyValuePair { 14 | KeyType key; 15 | ValueType *value; 16 | }; 17 | 18 | public: 19 | KeyValueLookup() { 20 | /* void */ 21 | } 22 | 23 | ~KeyValueLookup() { 24 | for (const KeyValuePair kvp : m_lookupTable) { 25 | delete FTRACK(kvp.value); 26 | } 27 | } 28 | 29 | int getEntryCount() const { 30 | return (int)m_lookupTable.size(); 31 | } 32 | 33 | ValueType *lookup(const KeyType &key) const { 34 | int entryCount = getEntryCount(); 35 | for (int i = 0; i < entryCount; i++) { 36 | if (m_lookupTable[i].key == key) { 37 | return m_lookupTable[i].value; 38 | } 39 | } 40 | 41 | return nullptr; 42 | } 43 | 44 | const KeyType &getKey(int index) const { 45 | return m_lookupTable[index].key; 46 | } 47 | 48 | ValueType *get(int index) const { 49 | return m_lookupTable[index].value; 50 | } 51 | 52 | template 53 | ValueType *newValue(const KeyType &key) { 54 | KeyValuePair kvp; 55 | kvp.key = key; 56 | kvp.value = TRACK(new T_Value()); 57 | 58 | m_lookupTable.push_back(kvp); 59 | 60 | return kvp.value; 61 | } 62 | 63 | ValueType *newValue(const KeyType &key) { 64 | KeyValuePair kvp; 65 | kvp.key = key; 66 | kvp.value = TRACK(new ValueType()); 67 | 68 | m_lookupTable.push_back(kvp); 69 | 70 | return kvp.value; 71 | } 72 | 73 | protected: 74 | std::vector m_lookupTable; 75 | }; 76 | 77 | } /* namespace piranha */ 78 | 79 | #endif /* PIRANHA_KEY_VALUE_LOOKUP_H */ 80 | -------------------------------------------------------------------------------- /include/literal_node.h: -------------------------------------------------------------------------------- 1 | #ifndef PIRANHA_LITERAL_NODE_H 2 | #define PIRANHA_LITERAL_NODE_H 3 | 4 | #include "node.h" 5 | 6 | #include "literal_node_output.h" 7 | 8 | namespace piranha { 9 | 10 | template 11 | class LiteralNode : public Node { 12 | public: 13 | LiteralNode() { /* void */ } 14 | ~LiteralNode() { /* void */ } 15 | 16 | virtual void setData(NativeType data) = 0; 17 | virtual bool isLiteral() const { return true; } 18 | }; 19 | 20 | typedef LiteralNode StringLiteralNode; 21 | typedef LiteralNode IntLiteralNode; 22 | typedef LiteralNode FloatLiteralNode; 23 | typedef LiteralNode BoolLiteralNode; 24 | 25 | } /* namespace piranha */ 26 | 27 | #endif /* PIRANHA_LITERAL_NODE_H */ 28 | -------------------------------------------------------------------------------- /include/literal_node_output.h: -------------------------------------------------------------------------------- 1 | #ifndef PIRANHA_LITERAL_NODE_OUTPUT_H 2 | #define PIRANHA_LITERAL_NODE_OUTPUT_H 3 | 4 | #include "fundamental_output.h" 5 | 6 | #include "fundamental_types.h" 7 | 8 | #include 9 | 10 | namespace piranha { 11 | 12 | template 13 | class LiteralNodeOutput : public FundamentalOutput { 14 | public: 15 | LiteralNodeOutput() { 16 | /* void */ 17 | } 18 | 19 | virtual ~LiteralNodeOutput() { 20 | /* void */ 21 | } 22 | 23 | void setData(const LiteralType &data) { 24 | m_data = data; 25 | } 26 | 27 | LiteralType getData() const { 28 | return m_data; 29 | } 30 | 31 | virtual void fullCompute(void *_target) const { 32 | LiteralType *target = reinterpret_cast(_target); 33 | *target = m_data; 34 | } 35 | 36 | protected: 37 | LiteralType m_data; 38 | }; 39 | 40 | typedef LiteralNodeOutput LiteralFloatOutput; 41 | typedef LiteralNodeOutput LiteralIntOutput; 42 | typedef LiteralNodeOutput LiteralStringOutput; 43 | typedef LiteralNodeOutput LiteralBoolOutput; 44 | 45 | } /* namespace piranha */ 46 | 47 | #endif /* PIRANHA_LITERAL_NODE_OUTPUT_H */ 48 | -------------------------------------------------------------------------------- /include/memory_management.h: -------------------------------------------------------------------------------- 1 | #ifndef PIRANHA_MEMORY_MANAGEMENT_H 2 | #define PIRANHA_MEMORY_MANAGEMENT_H 3 | 4 | #include 5 | 6 | #if __APPLE__ 7 | #define __int64 long long 8 | #endif 9 | 10 | namespace piranha { 11 | 12 | typedef unsigned __int64 mem_size; 13 | 14 | constexpr mem_size KB = 1000; 15 | constexpr mem_size MB = 1000 * KB; 16 | constexpr mem_size GB = 1000 * MB; 17 | 18 | #define CHECK_ALIGNMENT(pointer, required) assert((((unsigned __int64)((char *)(pointer))) % (required)) == 0) 19 | 20 | } /* namespace piranha */ 21 | 22 | #endif /* PIRANHA_MEMORY_MANAGEMENT_H */ 23 | -------------------------------------------------------------------------------- /include/memory_tracker.h: -------------------------------------------------------------------------------- 1 | #ifndef PIRANHA_MEMORY_TRACKER_H 2 | #define PIRANHA_MEMORY_TRACKER_H 3 | 4 | #include "build_settings.h" 5 | 6 | #include 7 | #include 8 | 9 | namespace piranha { 10 | 11 | class MemoryTracker { 12 | public: 13 | struct Allocation { 14 | std::string filename; 15 | int line; 16 | int index; 17 | 18 | void *address = nullptr; 19 | bool freed = false; 20 | }; 21 | 22 | protected: 23 | static MemoryTracker *s_instance; 24 | 25 | public: 26 | MemoryTracker(); 27 | ~MemoryTracker(); 28 | 29 | static MemoryTracker *get(); 30 | void reset(); 31 | 32 | bool find(void *address, Allocation *allocation); 33 | 34 | void recordAllocation(void *address, const std::string &filename, int line); 35 | void recordFree(void *address); 36 | 37 | int countLeaks() const; 38 | 39 | private: 40 | std::vector m_allocations; 41 | }; 42 | 43 | #if ENABLE_MEMORY_TRACKER 44 | 45 | #define TRACK(address) \ 46 | (trackedAllocation(address, __FILE__, __LINE__)) 47 | 48 | #define FTRACK(address) \ 49 | (trackedFree(address)) 50 | 51 | #else 52 | 53 | #define TRACK(address) (address) 54 | #define FTRACK(address) (address) 55 | 56 | #endif /* ENABLE_MEMORY_TRACKER */ 57 | 58 | template 59 | T *trackedAllocation(T *address, const char *_filename, int line) { 60 | const std::string filename = _filename; 61 | MemoryTracker::get()->recordAllocation(address, filename, line); 62 | 63 | return address; 64 | } 65 | 66 | template 67 | T *trackedFree(T *address) { 68 | MemoryTracker::get()->recordFree(address); 69 | 70 | return address; 71 | } 72 | 73 | } /* namespace piranha */ 74 | 75 | #endif /* PIRANHA_MEMORY_TRACKER_H */ 76 | -------------------------------------------------------------------------------- /include/multiply_operation_output.h: -------------------------------------------------------------------------------- 1 | #ifndef PIRANHA_MULTIPLY_OPERATION_OUTPUT_H 2 | #define PIRANHA_MULTIPLY_OPERATION_OUTPUT_H 3 | 4 | #include "fundamental_output.h" 5 | 6 | #include "pipe_node.h" 7 | 8 | namespace piranha { 9 | 10 | template 11 | class MultiplyOperationNodeOutput : public FundamentalOutput { 12 | public: 13 | MultiplyOperationNodeOutput() { 14 | /* void */ 15 | } 16 | 17 | virtual ~MultiplyOperationNodeOutput() { 18 | /* void */ 19 | } 20 | 21 | virtual void fullCompute(void *_target) const { 22 | Type *target = reinterpret_cast(_target); 23 | 24 | Type left; 25 | Type right; 26 | 27 | m_left->fullCompute(&left); 28 | m_right->fullCompute(&right); 29 | *target = left * right; 30 | } 31 | 32 | pNodeInput *getLeftConnection() { return &m_left; } 33 | pNodeInput *getRightConnection() { return &m_right; } 34 | 35 | protected: 36 | virtual void registerInputs() { 37 | this->registerInput(&m_left); 38 | this->registerInput(&m_right); 39 | } 40 | 41 | protected: 42 | pNodeInput m_left; 43 | pNodeInput m_right; 44 | }; 45 | 46 | } /* namespace piranha */ 47 | 48 | #endif /* PIRANHA_MULTIPLY_OPERATION_OUTPUT_H */ 49 | -------------------------------------------------------------------------------- /include/no_op_node.h: -------------------------------------------------------------------------------- 1 | #ifndef PIRANHA_NO_OP_NODE_H 2 | #define PIRANHA_NO_OP_NODE_H 3 | 4 | #include "node.h" 5 | 6 | namespace piranha { 7 | 8 | class NoOpNode : public Node { 9 | public: 10 | NoOpNode(); 11 | ~NoOpNode(); 12 | 13 | virtual void _initialize(); 14 | virtual void _evaluate(); 15 | virtual void _destroy(); 16 | 17 | virtual void registerInputs(); 18 | virtual void registerOutputs(); 19 | 20 | protected: 21 | pNodeInput m_input; 22 | }; 23 | 24 | } /* namespace piranha */ 25 | 26 | #endif /* PIRANHA_NO_OP_NODE_H */ 27 | -------------------------------------------------------------------------------- /include/node_allocator.h: -------------------------------------------------------------------------------- 1 | #ifndef PIRANHA_NODE_ALLOCATOR_H 2 | #define PIRANHA_NODE_ALLOCATOR_H 3 | 4 | #include "memory_tracker.h" 5 | 6 | namespace piranha { 7 | 8 | class NodeAllocator { 9 | public: 10 | NodeAllocator(); 11 | virtual ~NodeAllocator(); 12 | 13 | template 14 | T_NodeType *allocate() { 15 | void *memory = allocate(sizeof(T_NodeType)); 16 | return TRACK(new(memory) T_NodeType); 17 | } 18 | 19 | template 20 | void free(T_NodeType *target) { 21 | target = FTRACK(target); 22 | 23 | target->~T_NodeType(); 24 | free((void *)target); 25 | } 26 | 27 | protected: 28 | virtual void *allocate(int size); 29 | virtual void free(void *memory); 30 | }; 31 | 32 | } /* namespace piranha */ 33 | 34 | #endif /* PIRANHA_NODE_ALLOCATOR_H */ 35 | -------------------------------------------------------------------------------- /include/node_container.h: -------------------------------------------------------------------------------- 1 | #ifndef PIRANHA_NODE_CONTAINER_H 2 | #define PIRANHA_NODE_CONTAINER_H 3 | 4 | #include "node.h" 5 | 6 | #include 7 | #include 8 | 9 | namespace piranha { 10 | 11 | class NodeContainer : public Node { 12 | public: 13 | NodeContainer(); 14 | virtual ~NodeContainer(); 15 | 16 | void addNode(Node *node); 17 | Node *getNode(int index) const { return m_nodes[index]; } 18 | bool findNode(Node *node) const; 19 | bool findContainer(Node *node) const; 20 | int getNodeCount() const { return (int)m_nodes.size(); } 21 | 22 | void addChild(NodeContainer *container); 23 | NodeContainer *getChild(int index) const { return m_children[index]; } 24 | int getChildCount() const { return (int)m_children.size(); } 25 | 26 | NodeContainer *getTopLevel(); 27 | 28 | void addContainerInput(const std::string &name, bool modifiesInput, bool enableInput); 29 | void addContainerOutput(pNodeInput output, Node *node, const std::string &name, bool primary); 30 | 31 | virtual void writeAssembly(std::fstream &file, Assembly *assembly, int indent) const; 32 | 33 | void prune(); 34 | 35 | protected: 36 | virtual void _initialize(); 37 | virtual void _evaluate(); 38 | virtual void _destroy(); 39 | 40 | virtual Node *_optimize(NodeAllocator *nodeAllocator); 41 | 42 | protected: 43 | std::vector m_children; 44 | std::vector m_nodes; 45 | 46 | std::vector m_connections; 47 | }; 48 | 49 | } /* namspace piranha */ 50 | 51 | #endif /* PIRANHA_NODE_CONTAINER_H */ 52 | -------------------------------------------------------------------------------- /include/node_graph.h: -------------------------------------------------------------------------------- 1 | #ifndef PIRANHA_NODE_GRAPH_H 2 | #define PIRANHA_NODE_GRAPH_H 3 | 4 | #include 5 | 6 | namespace piranha { 7 | 8 | class Node; 9 | class NodeProgram; 10 | class NodeContainer; 11 | 12 | class NodeGraph { 13 | public: 14 | struct GraphNode { 15 | Node *node; 16 | std::vector outConnections; 17 | std::vector inConnections; 18 | 19 | bool hasOutConnection(GraphNode *node); 20 | bool hasInConnection(GraphNode *node); 21 | 22 | int liveOutputConnections; 23 | }; 24 | 25 | public: 26 | NodeGraph(); 27 | ~NodeGraph(); 28 | 29 | void generateNodeGraph(NodeProgram *program); 30 | 31 | void markDeadTree(GraphNode *node); 32 | void markDeadNodes(); 33 | 34 | int getNodeCount() const { return (int)m_nodes.size(); } 35 | 36 | protected: 37 | GraphNode *findNode(Node *node); 38 | void createNode(Node *node); 39 | 40 | void generateNodes(NodeContainer *container); 41 | void generateConnections(); 42 | 43 | std::vector m_nodes; 44 | }; 45 | 46 | } /* namespace piranha */ 47 | 48 | #endif /* PIRANHA_NODE_GRAPH_H */ 49 | -------------------------------------------------------------------------------- /include/node_output.h: -------------------------------------------------------------------------------- 1 | #ifndef PIRANHA_NODE_OUTPUT_H 2 | #define PIRANHA_NODE_OUTPUT_H 3 | 4 | #include "channel_type.h" 5 | 6 | #include 7 | #include 8 | 9 | namespace piranha { 10 | 11 | struct IntersectionPoint; 12 | class Node; 13 | class NodeAllocator; 14 | 15 | class NodeOutput { 16 | public: 17 | NodeOutput(const ChannelType *singleType); 18 | virtual ~NodeOutput(); 19 | 20 | virtual void fullCompute(void *target) const { /* void */ } 21 | virtual void registerInputs() { /* void */ } 22 | 23 | int getInputCount() const { return (int)m_inputs.size(); } 24 | NodeOutput **getInputConnection(int index) { return m_inputs[index]; } 25 | 26 | int getModifyConnectionCount() const; 27 | void addModifyConnection(Node *output); 28 | Node *getModifyConnection(int index) const; 29 | 30 | bool isType(const ChannelType &type) const { return m_singleType == &type; } 31 | const ChannelType *getType() const { return m_singleType; } 32 | 33 | void initialize(); 34 | bool evaluate(); 35 | bool checkEnabled(); 36 | 37 | bool isEnabled() const { return m_enabled; } 38 | 39 | void setName(const std::string &name) { m_name = name; } 40 | const std::string &getName() const { return m_name; } 41 | 42 | void setParentNode(Node *parentNode) { m_parentNode = parentNode; } 43 | Node *getParentNode() const { return m_parentNode; } 44 | 45 | Node *generateInterface(NodeAllocator *nodeAllocator); 46 | Node *getInterface() const; 47 | 48 | void overrideType(const ChannelType *type) { m_singleType = type; } 49 | 50 | void addDependency(Node *node) { m_dependencyChain.push_back(node); } 51 | 52 | protected: 53 | virtual Node *newInterface(NodeAllocator *nodeAllocator) { return nullptr; } 54 | 55 | private: 56 | const ChannelType *m_singleType; 57 | 58 | std::string m_name; 59 | 60 | Node *m_parentNode; 61 | Node *m_interface; 62 | 63 | bool m_evaluated; 64 | bool m_evaluating; 65 | bool m_checkedEnabled; 66 | 67 | bool m_enabled; 68 | 69 | protected: 70 | virtual void _evaluate(); 71 | virtual void registerInput(NodeOutput **nodeInput) { m_inputs.push_back(nodeInput); } 72 | 73 | std::vector m_inputs; 74 | std::vector m_modifyConnections; 75 | std::vector m_dependencyChain; 76 | }; 77 | 78 | // Type to reduce confusion 79 | typedef NodeOutput * pNodeInput; 80 | 81 | } /* namespace piranha */ 82 | 83 | #endif /* PIRANHA_NODE_OUTPUT_H */ 84 | -------------------------------------------------------------------------------- /include/node_program.h: -------------------------------------------------------------------------------- 1 | #ifndef PIRANHA_NODE_PROGRAM_H 2 | #define PIRANHA_NODE_PROGRAM_H 3 | 4 | #include "node_container.h" 5 | #include "pkey_value_lookup.h" 6 | #include "ir_compilation_unit.h" 7 | #include "language_rules.h" 8 | 9 | #include 10 | #include 11 | 12 | namespace piranha { 13 | 14 | class Node; 15 | class NodeAllocator; 16 | class IrParserStructure; 17 | class IrContextTree; 18 | 19 | class NodeProgram { 20 | public: 21 | static const bool CheckDuplicates = true; 22 | 23 | public: 24 | NodeProgram(); 25 | ~NodeProgram(); 26 | 27 | void initialize(); 28 | void optimize(); 29 | bool execute(); 30 | void free(); 31 | 32 | void writeAssembly(const std::string &fname) const; 33 | 34 | NodeContainer *getTopLevelContainer() { return &m_topLevelContainer; } 35 | 36 | int getNodeCount() const { return (int)m_nodeCache.size(); } 37 | 38 | void addNode(Node *node); 39 | Node *getCachedInstance(IrParserStructure *ir, IrContextTree *context); 40 | Node *getCachedInstance(Node *node); 41 | 42 | void addContainer(IrContextTree *context, NodeContainer *container); 43 | NodeContainer *getContainer(IrContextTree *context); 44 | 45 | std::string getRuntimeError() const { return m_errorMessage; } 46 | void throwRuntimeError(const std::string &msg, Node *node); 47 | 48 | void setRootUnit(IrCompilationUnit *unit) { m_rootUnit = unit; } 49 | IrCompilationUnit *getRootUnit() const { return m_rootUnit; } 50 | 51 | void setRootContext(IrContextTree *context) { m_rootContext = context; } 52 | IrContextTree *getRootContext() const { return m_rootContext; } 53 | 54 | NodeAllocator *getNodeAllocator() { return m_rootUnit->getRules()->getNodeAllocator(); } 55 | 56 | void kill() { m_kill = true; } 57 | bool isKilled() const { return m_kill; } 58 | 59 | protected: 60 | bool m_initialized; 61 | 62 | IrContextTree *m_rootContext; 63 | IrCompilationUnit *m_rootUnit; 64 | 65 | NodeContainer m_topLevelContainer; 66 | PKeyValueLookup m_containers; 67 | 68 | std::vector m_nodeCache; 69 | 70 | bool m_runtimeError; 71 | std::string m_errorMessage; 72 | Node *m_errorNode; 73 | 74 | std::atomic m_kill = false; 75 | }; 76 | 77 | } /* namespace piranha */ 78 | 79 | #endif /* PIRANHA_NODE_PROGRAM_H */ 80 | -------------------------------------------------------------------------------- /include/num_negate_operation.h: -------------------------------------------------------------------------------- 1 | #ifndef PIRANHA_NUM_NEGATE_OPERATION_H 2 | #define PIRANHA_NUM_NEGATE_OPERATION_H 3 | 4 | #include "fundamental_output.h" 5 | 6 | #include "pipe_node.h" 7 | 8 | namespace piranha { 9 | 10 | template 11 | class NumNegateOperationNodeOutput : public FundamentalOutput { 12 | public: 13 | NumNegateOperationNodeOutput() { 14 | /* void */ 15 | } 16 | 17 | virtual ~NumNegateOperationNodeOutput() { 18 | /* void */ 19 | } 20 | 21 | virtual void fullCompute(void *_target) const { 22 | Type *target = reinterpret_cast(_target); 23 | 24 | Type in; 25 | m_input->fullCompute(&in); 26 | 27 | *target = -in; 28 | } 29 | 30 | pNodeInput *getConnection() { return &m_input; } 31 | 32 | protected: 33 | virtual void registerInputs() { 34 | this->registerInput(&m_input); 35 | } 36 | 37 | protected: 38 | pNodeInput m_input; 39 | }; 40 | 41 | template 42 | using NumNegateOperationNode = PipeNode>; 43 | 44 | } /* namespace piranha */ 45 | 46 | #endif /* PIRANHA_NUM_NEGATE_OPERATION_H */ 47 | -------------------------------------------------------------------------------- /include/operation_node.h: -------------------------------------------------------------------------------- 1 | #ifndef PIRANHA_OPERATION_NODE_H 2 | #define PIRANHA_OPERATION_NODE_H 3 | 4 | #include "node.h" 5 | 6 | #include "add_operation_output.h" 7 | #include "fundamental_output.h" 8 | 9 | namespace piranha { 10 | 11 | class OperationNode : public Node { 12 | public: 13 | OperationNode() {} 14 | ~OperationNode() {} 15 | 16 | virtual void connectLeft(pNodeInput input) { 17 | (*m_inputs[0].input) = input; 18 | } 19 | 20 | virtual void connectRight(pNodeInput input) { 21 | (*m_inputs[1].input) = input; 22 | } 23 | }; 24 | 25 | template class OperationNodeType> 26 | class OperationNodeSpecialized : public OperationNode { 27 | public: 28 | OperationNodeSpecialized() { 29 | /* void */ 30 | } 31 | 32 | ~OperationNodeSpecialized() { 33 | /* void */ 34 | } 35 | 36 | virtual void _initialize() { 37 | m_output.initialize(); 38 | } 39 | 40 | virtual void _evaluate() { 41 | /* void */ 42 | } 43 | 44 | virtual void _destroy() { 45 | /* void */ 46 | } 47 | 48 | virtual void registerOutputs() { 49 | setPrimaryOutput("__out"); 50 | registerOutput(&m_output, "__out"); 51 | } 52 | 53 | virtual void registerInputs() { 54 | registerInput( 55 | m_output.getLeftConnection(), "__in0"); 56 | registerInput( 57 | m_output.getRightConnection(), "__in1"); 58 | } 59 | 60 | protected: 61 | OperationNodeType m_output; 62 | 63 | protected: 64 | virtual Node *_optimize(NodeAllocator *nodeAllocator) { 65 | addFlag(Node::META_ACTIONLESS); 66 | 67 | const bool leftConstant = (*m_output.getLeftConnection()) 68 | ->getParentNode() 69 | ->hasFlag(Node::META_CONSTANT); 70 | const bool rightConstant = (*m_output.getRightConnection()) 71 | ->getParentNode() 72 | ->hasFlag(Node::META_CONSTANT); 73 | 74 | if (leftConstant && rightConstant) { 75 | addFlag(Node::META_CONSTANT); 76 | 77 | const bool result = evaluate(); 78 | if (!result) return nullptr; 79 | 80 | DefaultLiteralNode *newLiteral = 81 | nodeAllocator->allocate>(); 82 | 83 | FundamentalType computedValue; 84 | m_output.fullCompute((void *)&computedValue); 85 | 86 | mapOptimizedPort(newLiteral, "__out", "__out"); 87 | newLiteral->setData(computedValue); 88 | return newLiteral; 89 | } 90 | else return this; 91 | } 92 | }; 93 | 94 | } /* namespace piranha */ 95 | 96 | #endif /* PIRANHA_OPERATION_NODE_H */ 97 | -------------------------------------------------------------------------------- /include/path.h: -------------------------------------------------------------------------------- 1 | #ifndef PIRANHA_PATH_H 2 | #define PIRANHA_PATH_H 3 | 4 | #include 5 | #include 6 | 7 | namespace piranha { 8 | 9 | class Path { 10 | protected: Path(const std::filesystem::path &path); 11 | public: 12 | Path(const std::string &path); 13 | Path(const char *path); 14 | Path(const Path &path); 15 | Path(); 16 | ~Path(); 17 | 18 | std::string toString() const; 19 | 20 | void setPath(const std::string &path); 21 | bool operator==(const Path &path) const; 22 | Path append(const Path &path) const; 23 | 24 | void getParentPath(Path *path) const; 25 | 26 | const Path &operator =(const Path &b); 27 | 28 | std::string getExtension() const; 29 | std::string getStem() const; 30 | 31 | bool isAbsolute() const; 32 | bool exists() const; 33 | 34 | protected: 35 | std::filesystem::path *m_path; 36 | 37 | protected: 38 | const std::filesystem::path &getBoostPath() const { return *m_path; } 39 | }; 40 | 41 | } /* namespace piranha */ 42 | 43 | #endif /* PIRANHA_PATH_H */ 44 | -------------------------------------------------------------------------------- /include/pipe_node.h: -------------------------------------------------------------------------------- 1 | #ifndef PIRANHA_PIPE_NODE_H 2 | #define PIRANHA_PIPE_NODE_H 3 | 4 | #include "node.h" 5 | 6 | #include 7 | 8 | namespace piranha { 9 | 10 | template 11 | class PipeNode : public Node { 12 | public: 13 | PipeNode() { 14 | /* void */ 15 | } 16 | 17 | ~PipeNode() { 18 | /* void */ 19 | } 20 | 21 | virtual void _initialize() { 22 | m_output.initialize(); 23 | } 24 | 25 | virtual void _evaluate() { 26 | /* void */ 27 | } 28 | 29 | virtual void _destroy() { 30 | /* void */ 31 | } 32 | 33 | virtual void registerOutputs() { 34 | setPrimaryOutput("__out"); 35 | registerOutput(&m_output, "__out"); 36 | } 37 | 38 | virtual void registerInputs() { 39 | int inputCount = m_output.getInputCount(); 40 | for (int i = 0; i < inputCount; i++) { 41 | // Generate a standard name 42 | std::stringstream ss; 43 | if (inputCount > 1) ss << "__in" << i; 44 | else ss << "__in"; 45 | 46 | // Register all inputs of the one node output 47 | registerInput(m_output.NodeOutput::getInputConnection(i), ss.str()); 48 | } 49 | } 50 | 51 | protected: 52 | OutputType m_output; 53 | }; 54 | 55 | } /* namespace piranha */ 56 | 57 | #endif /* PIRANHA_PIPE_NODE_H */ 58 | -------------------------------------------------------------------------------- /include/piranha.h: -------------------------------------------------------------------------------- 1 | #ifndef PIRANHA_PIRANHA_H 2 | #define PIRANHA_PIRANHA_H 3 | 4 | #define PIRANHA_DIST 5 | 6 | #include "add_operation_output.h" 7 | #include "assembly.h" 8 | #include "bool_negate_operation.h" 9 | #include "build_settings.h" 10 | #include "channel_node.h" 11 | #include "channel_type.h" 12 | #include "compilation_error.h" 13 | #include "compiler.h" 14 | #include "console_input_node.h" 15 | #include "console_output_node.h" 16 | #include "default_literal_node.h" 17 | #include "divide_operation_output.h" 18 | #include "error_list.h" 19 | #include "exceptions.h" 20 | #include "float_conversions.h" 21 | #include "fundamental_output.h" 22 | #include "fundamental_types.h" 23 | #include "int_conversions.h" 24 | #include "int_probe.h" 25 | #include "ir_attribute.h" 26 | #include "ir_attribute_definition.h" 27 | #include "ir_attribute_definition_list.h" 28 | #include "ir_attribute_list.h" 29 | #include "ir_binary_operator.h" 30 | #include "ir_compilation_unit.h" 31 | #include "ir_context_tree.h" 32 | #include "ir_import_statement.h" 33 | #include "ir_literal_node.h" 34 | #include "ir_node.h" 35 | #include "ir_node_definition.h" 36 | #include "ir_parser_structure.h" 37 | #include "ir_structure_list.h" 38 | #include "ir_token_info.h" 39 | #include "ir_unary_operator.h" 40 | #include "ir_value.h" 41 | #include "ir_value_constant.h" 42 | #include "ir_visibility.h" 43 | #include "key_value_lookup.h" 44 | #include "language_rules.h" 45 | #include "literal_node.h" 46 | #include "literal_node_output.h" 47 | #include "memory_management.h" 48 | #include "memory_tracker.h" 49 | #include "multiply_operation_output.h" 50 | #include "node.h" 51 | #include "node_allocator.h" 52 | #include "node_container.h" 53 | #include "node_graph.h" 54 | #include "node_output.h" 55 | #include "node_program.h" 56 | #include "no_op_node.h" 57 | #include "num_negate_operation.h" 58 | #include "operation_node.h" 59 | #include "path.h" 60 | #include "pipe_node.h" 61 | #include "pkey_value_lookup.h" 62 | #include "rule.h" 63 | #include "standard_allocator.h" 64 | #include "string_conversions.h" 65 | #include "subtract_operation_output.h" 66 | #include "throw_runtime_error_node.h" 67 | #include "vector_constructor.h" 68 | #include "vector_output.h" 69 | #include "vector_split.h" 70 | #include "vector_split_node.h" 71 | #include "version.h" 72 | 73 | #endif /* PIRANHA_PIRANHA_H */ 74 | -------------------------------------------------------------------------------- /include/pkey_value_lookup.h: -------------------------------------------------------------------------------- 1 | #ifndef PIRANHA_PKEY_VALUE_LOOKUP_H 2 | #define PIRANHA_PKEY_VALUE_LOOKUP_H 3 | 4 | #include "memory_tracker.h" 5 | 6 | #include 7 | 8 | namespace piranha { 9 | 10 | template 11 | class PKeyValueLookup { 12 | private: 13 | struct KeyValuePair { 14 | const KeyType *key; 15 | ValueType *value; 16 | }; 17 | 18 | public: 19 | PKeyValueLookup() { 20 | /* void */ 21 | } 22 | 23 | ~PKeyValueLookup() { 24 | /* void */ 25 | } 26 | 27 | int getEntryCount() const { 28 | return (int)m_lookupTable.size(); 29 | } 30 | 31 | ValueType *lookup(const KeyType *key) const { 32 | int entryCount = getEntryCount(); 33 | for (int i = 0; i < entryCount; i++) { 34 | if (key == nullptr || m_lookupTable[i].key == nullptr) { 35 | if (key == m_lookupTable[i].key) { 36 | return m_lookupTable[i].value; 37 | } 38 | } 39 | else if (*m_lookupTable[i].key == *key) { 40 | return m_lookupTable[i].value; 41 | } 42 | } 43 | 44 | return nullptr; 45 | } 46 | 47 | ValueType *get(int index) const { 48 | return m_lookupTable[index].value; 49 | } 50 | 51 | template 52 | ValueType *newValue(const KeyType *key) { 53 | ValueType *current = lookup(key); 54 | if (current != nullptr) return current; 55 | 56 | KeyValuePair kvp; 57 | kvp.key = key; 58 | kvp.value = TRACK(new T()); 59 | 60 | m_lookupTable.push_back(kvp); 61 | 62 | return kvp.value; 63 | } 64 | 65 | ValueType *newValue(const KeyType *key) { 66 | return newValue(key); 67 | } 68 | 69 | void destroy() { 70 | for (KeyValuePair &kvp : m_lookupTable) { 71 | delete FTRACK(kvp.value); 72 | } 73 | } 74 | 75 | protected: 76 | std::vector m_lookupTable; 77 | }; 78 | 79 | } /* namespace piranha */ 80 | 81 | #endif /* PIRANHA_PKEY_VALUE_LOOKUP_H */ 82 | -------------------------------------------------------------------------------- /include/rule.h: -------------------------------------------------------------------------------- 1 | #ifndef PIRANHA_RULE_H 2 | #define PIRANHA_RULE_H 3 | 4 | #include "memory_tracker.h" 5 | 6 | #include 7 | 8 | namespace piranha { 9 | 10 | class Node; 11 | 12 | template 13 | class Rule { 14 | public: 15 | Rule(const ValueType &value) { 16 | m_value = value; 17 | m_reference = nullptr; 18 | } 19 | 20 | Rule() { m_reference = nullptr; } 21 | 22 | virtual ~Rule() { /* void */ } 23 | 24 | virtual NodeBase *buildNode(NodeAllocator *nodeAllocator) const = 0; 25 | void destroy(NodeAllocator *nodeAllocator) { 26 | nodeAllocator->free(m_reference); 27 | } 28 | 29 | void setValue(const ValueType &value) { m_value = value; } 30 | const ValueType &getValue() const { return m_value; } 31 | 32 | void setReference(NodeBase *reference) { m_reference = reference; } 33 | 34 | const NodeBase *getReference() const { return m_reference; } 35 | 36 | void generateReference(NodeAllocator *nodeAllocator) { 37 | NodeBase *reference = buildNode(nodeAllocator); 38 | reference->initialize(); 39 | 40 | Rule::setReference(reference); 41 | } 42 | 43 | protected: 44 | ValueType m_value; 45 | NodeBase *m_reference; 46 | }; 47 | 48 | template 49 | class SpecializedRule : public Rule { 50 | public: 51 | SpecializedRule(const ValueType &value) : Rule(value) { 52 | /* void */ 53 | } 54 | 55 | SpecializedRule() : Rule() { /* void */ } 56 | 57 | virtual ~SpecializedRule() { /* void */ } 58 | 59 | virtual NodeBase *buildNode(NodeAllocator *nodeAllocator) const { 60 | return nodeAllocator->allocate(); 61 | } 62 | }; 63 | 64 | } /* namespace piranha */ 65 | 66 | #endif /* PIRANHA_RULE_H */ 67 | -------------------------------------------------------------------------------- /include/scanner.h: -------------------------------------------------------------------------------- 1 | #ifndef PIRANHA_SCANNER_H 2 | #define PIRANHA_SCANNER_H 3 | 4 | #if !defined(yyFlexLexerOnce) 5 | #ifdef PIRANHA_DIST 6 | #include "../lib/FlexLexer.h" 7 | #else 8 | #include 9 | #endif /* PIRANHA_DIST */ 10 | #endif 11 | 12 | #include 13 | #include "ir_token_info.h" 14 | #include "ir_token_info.h" 15 | #include "memory_tracker.h" 16 | 17 | namespace piranha { 18 | 19 | class Scanner : public yyFlexLexer { 20 | public: 21 | Scanner(std::istream *in) : yyFlexLexer(in) { 22 | m_loc = TRACK(new piranha::Parser::location_type()); 23 | m_loc->colStart = m_loc->colEnd = 1; 24 | m_loc->lineStart = m_loc->lineEnd = 1; 25 | } 26 | 27 | virtual ~Scanner() { 28 | delete FTRACK(m_loc); 29 | } 30 | 31 | using FlexLexer::yylex; 32 | 33 | virtual int yylex( 34 | piranha::Parser::semantic_type *lval, piranha::Parser::location_type *location); 35 | 36 | private: 37 | void comment(); 38 | void count(); 39 | void countChar(char c); 40 | void step(); 41 | 42 | template 43 | void buildValue(const T &data, piranha::Parser::location_type *location, bool valid = true) { 44 | typedef T_IrTokenInfo _TokenInfo; 45 | 46 | _TokenInfo info(data, m_loc->lineStart, m_loc->lineEnd, 47 | m_loc->colStart, m_loc->colEnd); 48 | info.valid = valid; 49 | m_yylval->build<_TokenInfo>(info); 50 | *location = info; 51 | } 52 | 53 | piranha::Parser::semantic_type *m_yylval = nullptr; 54 | piranha::Parser::location_type *m_loc = nullptr; 55 | }; 56 | 57 | } /* namespace piranha */ 58 | 59 | #endif /* PIRANHA_SCANNER_H */ 60 | -------------------------------------------------------------------------------- /include/string_conversions.h: -------------------------------------------------------------------------------- 1 | #ifndef PIRANHA_STRING_CONVERSIONS_H 2 | #define PIRANHA_STRING_CONVERSIONS_H 3 | 4 | #include "fundamental_output.h" 5 | 6 | #include "pipe_node.h" 7 | 8 | namespace piranha { 9 | 10 | class FloatToStringConversionOutput : public StringValueOutput { 11 | public: 12 | FloatToStringConversionOutput(); 13 | ~FloatToStringConversionOutput(); 14 | 15 | virtual void fullCompute(void *target) const; 16 | virtual void registerInputs(); 17 | 18 | pNodeInput *getInputConnection() { return &m_input; } 19 | 20 | protected: 21 | pNodeInput m_input; 22 | }; 23 | typedef PipeNode FloatToStringConversionNode; 24 | 25 | class IntToStringConversionOutput : public StringValueOutput { 26 | public: 27 | IntToStringConversionOutput(); 28 | ~IntToStringConversionOutput(); 29 | 30 | virtual void fullCompute(void *target) const; 31 | virtual void registerInputs(); 32 | 33 | pNodeInput *getInputConnection() { return &m_input; } 34 | 35 | protected: 36 | pNodeInput m_input; 37 | }; 38 | typedef PipeNode IntToStringConversionNode; 39 | 40 | } /* namespace piranha */ 41 | 42 | #endif /* PIRANHA_STRING_CONVERSIONS_H */ 43 | -------------------------------------------------------------------------------- /include/subtract_operation_output.h: -------------------------------------------------------------------------------- 1 | #ifndef PIRANHA_SUBTRACT_OPERATION_OUTPUT_H 2 | #define PIRANHA_SUBTRACT_OPERATION_OUTPUT_H 3 | 4 | #include "fundamental_output.h" 5 | 6 | #include "pipe_node.h" 7 | 8 | namespace piranha { 9 | 10 | template 11 | class SubtractOperationNodeOutput : public FundamentalOutput { 12 | public: 13 | SubtractOperationNodeOutput() { 14 | /* void */ 15 | } 16 | 17 | virtual ~SubtractOperationNodeOutput() { 18 | /* void */ 19 | } 20 | 21 | virtual void fullCompute(void *_target) const { 22 | Type *target = reinterpret_cast(_target); 23 | 24 | Type left; 25 | Type right; 26 | 27 | m_left->fullCompute(&left); 28 | m_right->fullCompute(&right); 29 | *target = left - right; 30 | } 31 | 32 | pNodeInput *getLeftConnection() { return &m_left; } 33 | pNodeInput *getRightConnection() { return &m_right; } 34 | 35 | protected: 36 | virtual void registerInputs() { 37 | this->registerInput(&m_left); 38 | this->registerInput(&m_right); 39 | } 40 | 41 | protected: 42 | pNodeInput m_left; 43 | pNodeInput m_right; 44 | }; 45 | 46 | } /* namespace piranha */ 47 | 48 | #endif /* PIRANHA_SUBTRACT_OPERATION_OUTPUT_H */ 49 | -------------------------------------------------------------------------------- /include/throw_runtime_error_node.h: -------------------------------------------------------------------------------- 1 | #ifndef PIRANHA_THROW_RUNTIME_ERROR_NODE_H 2 | #define PIRANHA_THROW_RUNTIME_ERROR_NODE_H 3 | 4 | #include "node.h" 5 | 6 | #include "fundamental_types.h" 7 | 8 | #include 9 | #include 10 | 11 | namespace piranha { 12 | 13 | class ThrowRuntimeErrorNode : public Node { 14 | public: 15 | ThrowRuntimeErrorNode() { 16 | /* void */ 17 | } 18 | 19 | ~ThrowRuntimeErrorNode() { 20 | /* void */ 21 | } 22 | 23 | protected: 24 | virtual void _evaluate() { 25 | piranha::native_bool data; 26 | m_input->fullCompute(&data); 27 | 28 | if (data) { 29 | throwError("Planned error"); 30 | } 31 | else { 32 | // Do nothing 33 | } 34 | } 35 | 36 | virtual void registerInputs() { 37 | registerInput(&m_input, "throw"); 38 | } 39 | 40 | virtual void registerOutputs() { 41 | /* void */ 42 | } 43 | 44 | protected: 45 | pNodeInput m_input; 46 | }; 47 | 48 | } /* namespace piranha */ 49 | 50 | #endif /* PIRANHA_THROW_RUNTIME_ERROR_NODE_H */ 51 | -------------------------------------------------------------------------------- /include/vector_constructor.h: -------------------------------------------------------------------------------- 1 | #ifndef PIRANHA_VECTOR_CONSTRUCTOR_H 2 | #define PIRANHA_VECTOR_CONSTRUCTOR_H 3 | 4 | #include "pipe_node.h" 5 | #include "vector_output.h" 6 | 7 | namespace piranha { 8 | 9 | class VectorConstructorOutput : public VectorValueOutput { 10 | public: 11 | VectorConstructorOutput(); 12 | ~VectorConstructorOutput(); 13 | 14 | virtual void fullCompute(void *target) const; 15 | virtual void registerInputs(); 16 | 17 | pNodeInput *getXInputConnection() { return &m_inputX; } 18 | pNodeInput *getYInputConnection() { return &m_inputY; } 19 | pNodeInput *getZInputConnection() { return &m_inputZ; } 20 | pNodeInput *getWInputConnection() { return &m_inputW; } 21 | 22 | protected: 23 | pNodeInput m_inputX; 24 | pNodeInput m_inputY; 25 | pNodeInput m_inputZ; 26 | pNodeInput m_inputW; 27 | }; 28 | 29 | class VectorConstructorNode : public Node { 30 | public: 31 | VectorConstructorNode() { 32 | /* void */ 33 | } 34 | 35 | ~VectorConstructorNode() { 36 | /* void */ 37 | } 38 | 39 | virtual void _initialize() { 40 | m_output.initialize(); 41 | } 42 | 43 | virtual void _evaluate() { 44 | /* void */ 45 | } 46 | 47 | virtual void _destroy() { 48 | /* void */ 49 | } 50 | 51 | virtual void registerOutputs() { 52 | setPrimaryOutput("__out"); 53 | registerOutput(&m_output, "__out"); 54 | } 55 | 56 | virtual void registerInputs() { 57 | int inputCount = m_output.getInputCount(); 58 | for (int i = 0; i < inputCount; i++) { 59 | // Generate a standard name 60 | std::stringstream ss; 61 | if (inputCount > 1) ss << "__in" << i; 62 | else ss << "__in"; 63 | 64 | // Register all inputs of the one node output 65 | registerInput(m_output.NodeOutput::getInputConnection(i), ss.str()); 66 | } 67 | } 68 | 69 | protected: 70 | VectorConstructorOutput m_output; 71 | }; 72 | 73 | } /* namespace piranha */ 74 | 75 | #endif /* PIRANHA_VECTOR_CONSTRUCTOR_H */ 76 | -------------------------------------------------------------------------------- /include/vector_output.h: -------------------------------------------------------------------------------- 1 | #ifndef PIRANHA_VECTOR_OUTPUT_H 2 | #define PIRANHA_VECTOR_OUTPUT_H 3 | 4 | #include "fundamental_output.h" 5 | 6 | #include "memory_tracker.h" 7 | #include "vector_split_node.h" 8 | 9 | namespace piranha { 10 | 11 | template <> 12 | class FundamentalOutput : public NodeOutput { 13 | public: 14 | FundamentalOutput() : NodeOutput(&FundamentalType::VectorType) { /* void */ }; 15 | ~FundamentalOutput() { /* void */ } 16 | 17 | protected: 18 | virtual Node *newInterface(NodeAllocator *nodeAllocator) { 19 | VectorSplitNode *vectorInterface = nodeAllocator->allocate(); 20 | vectorInterface->initialize(); 21 | vectorInterface->connectInput(this, "__in", nullptr); 22 | 23 | return vectorInterface; 24 | } 25 | }; 26 | 27 | typedef FundamentalOutput VectorValueOutput; 28 | 29 | } /* namespace piranha */ 30 | 31 | #endif /* PIRANHA_VECTOR_OUTPUT_H */ 32 | -------------------------------------------------------------------------------- /include/vector_split.h: -------------------------------------------------------------------------------- 1 | #ifndef PIRANHA_VECTOR_SPLIT_H 2 | #define PIRANHA_VECTOR_SPLIT_H 3 | 4 | #include "fundamental_output.h" 5 | 6 | namespace piranha { 7 | 8 | template 9 | class VectorSplitOutput : public FloatValueOutput { 10 | public: 11 | VectorSplitOutput() { m_input = nullptr; } 12 | ~VectorSplitOutput() { /* void */ } 13 | 14 | virtual void fullCompute(void *_target) const { 15 | piranha::native_float *target = reinterpret_cast(_target); 16 | 17 | piranha::native_vector data; 18 | m_input->fullCompute((void *)&data); 19 | 20 | switch (index) { 21 | case 0: *target = data.x; return; 22 | case 1: *target = data.y; return; 23 | case 2: *target = data.z; return; 24 | case 3: *target = data.w; return; 25 | default: *target = 0.0; return; 26 | } 27 | } 28 | 29 | virtual void registerInputs() { 30 | registerInput(&m_input); 31 | } 32 | 33 | pNodeInput *getInputConnection() { return &m_input; } 34 | 35 | protected: 36 | pNodeInput m_input; 37 | }; 38 | 39 | } /* namespace piranha */ 40 | 41 | #endif /* PIRANHA_VECTOR_SPLIT_H */ 42 | -------------------------------------------------------------------------------- /include/vector_split_node.h: -------------------------------------------------------------------------------- 1 | #ifndef PIRANHA_VECTOR_SPLIT_NODE_H 2 | #define PIRANHA_VECTOR_SPLIT_NODE_H 3 | 4 | #include "../include/node.h" 5 | 6 | #include "../include/vector_split.h" 7 | #include "../include/fundamental_types.h" 8 | 9 | #include 10 | #include 11 | 12 | namespace piranha { 13 | 14 | class VectorSplitNode : public Node { 15 | public: 16 | VectorSplitNode() { 17 | m_primaryInput = nullptr; 18 | } 19 | 20 | ~VectorSplitNode() { 21 | /* void */ 22 | } 23 | 24 | protected: 25 | virtual void _initialize() { 26 | /* void */ 27 | } 28 | 29 | virtual void _evaluate() { 30 | /* void */ 31 | } 32 | 33 | virtual void registerInputs() { 34 | setInterfaceInput(&m_primaryInput); 35 | registerInput(&m_primaryInput, "__in"); 36 | registerInput(m_outputX.getInputConnection(), "__in"); 37 | registerInput(m_outputY.getInputConnection(), "__in"); 38 | registerInput(m_outputZ.getInputConnection(), "__in"); 39 | registerInput(m_outputW.getInputConnection(), "__in"); 40 | } 41 | 42 | virtual void registerOutputs() { 43 | registerOutput(&m_outputX, "x"); 44 | registerOutput(&m_outputY, "y"); 45 | registerOutput(&m_outputZ, "z"); 46 | registerOutput(&m_outputW, "w"); 47 | } 48 | 49 | protected: 50 | pNodeInput m_primaryInput; 51 | 52 | VectorSplitOutput<0> m_outputX; 53 | VectorSplitOutput<1> m_outputY; 54 | VectorSplitOutput<2> m_outputZ; 55 | VectorSplitOutput<3> m_outputW; 56 | }; 57 | 58 | } /* namespace piranha */ 59 | 60 | #endif /* PIRANHA_VECTOR_SPLIT_NODE_H */ 61 | -------------------------------------------------------------------------------- /include/version.h: -------------------------------------------------------------------------------- 1 | #ifndef PIRANHA_VERSION_H 2 | #define PIRANHA_VERSION_H 3 | 4 | #define PIRANHA_VERSION "v0.0.11a" 5 | 6 | #endif /* PIRANHA_VERSION_H */ 7 | -------------------------------------------------------------------------------- /src/assembly.cpp: -------------------------------------------------------------------------------- 1 | #include "../include/assembly.h" 2 | 3 | piranha::Assembly::Assembly() { 4 | m_currentIndex = 0; 5 | } 6 | 7 | piranha::Assembly::~Assembly() { 8 | /* void */ 9 | } 10 | 11 | int piranha::Assembly::getOutputLabel(NodeOutput *output) { 12 | int *lookup = m_outputLookup.lookup(output); 13 | if (lookup != nullptr) return *lookup; 14 | 15 | int *newValue = m_outputLookup.newValue(output); 16 | *newValue = m_currentIndex++; 17 | 18 | return *newValue; 19 | } 20 | -------------------------------------------------------------------------------- /src/channel_node.cpp: -------------------------------------------------------------------------------- 1 | #include "../include/channel_node.h" 2 | 3 | piranha::ChannelNode::ChannelNode() { 4 | /* void */ 5 | } 6 | 7 | piranha::ChannelNode::~ChannelNode() { 8 | /* void */ 9 | } 10 | -------------------------------------------------------------------------------- /src/channel_type.cpp: -------------------------------------------------------------------------------- 1 | #include "../include/channel_type.h" 2 | 3 | piranha::ChannelType::ChannelType() { 4 | initialize("", nullptr); 5 | } 6 | 7 | piranha::ChannelType::ChannelType(const char *type, const ChannelType *parent) { 8 | initialize(type, parent); 9 | } 10 | 11 | piranha::ChannelType::~ChannelType() { 12 | /* void */ 13 | } 14 | 15 | void piranha::ChannelType::initialize(const char *type, const ChannelType *parent) { 16 | m_typeString = type; 17 | m_hash = generateHash(type); 18 | m_parent = parent; 19 | } 20 | 21 | bool piranha::ChannelType::isCompatibleWith(const ChannelType &t) const { 22 | if (isEqual(t)) return true; 23 | else { 24 | return (m_parent == nullptr) 25 | ? false 26 | : m_parent->isCompatibleWith(t); 27 | } 28 | } 29 | 30 | bool piranha::ChannelType::isEqual(const ChannelType &t) const { 31 | return (m_hash == t.m_hash) 32 | ? strcmp(t.m_typeString, m_typeString) == 0 33 | : false; 34 | } 35 | 36 | int piranha::ChannelType::generateHash(const char *string) { 37 | // Very simple hash for now 38 | int sum = 0, i = 0; 39 | while (string[i] != '\0') sum += (int)string[i++]; 40 | 41 | return sum; 42 | } 43 | -------------------------------------------------------------------------------- /src/error_list.cpp: -------------------------------------------------------------------------------- 1 | #include "../include/error_list.h" 2 | 3 | #include "../include/compilation_error.h" 4 | #include "../include/memory_tracker.h" 5 | 6 | piranha::ErrorList::ErrorList() { 7 | /* void */ 8 | } 9 | 10 | piranha::ErrorList::~ErrorList() { 11 | /* void */ 12 | } 13 | 14 | void piranha::ErrorList::addCompilationError(CompilationError *err) { 15 | m_compilationErrors.push_back(err); 16 | } 17 | 18 | void piranha::ErrorList::free() { 19 | const int errorCount = getErrorCount(); 20 | 21 | for (int i = 0; i < errorCount; i++) { 22 | delete FTRACK(m_compilationErrors[i]); 23 | } 24 | 25 | m_compilationErrors.clear(); 26 | } 27 | -------------------------------------------------------------------------------- /src/float_conversions.cpp: -------------------------------------------------------------------------------- 1 | #include "float_conversions.h" 2 | 3 | #include 4 | 5 | // CONVERSION ============================================= 6 | // string -> float 7 | piranha::StringToFloatConversionOutput::StringToFloatConversionOutput() { 8 | /* void */ 9 | } 10 | 11 | piranha::StringToFloatConversionOutput::~StringToFloatConversionOutput() { 12 | /* void */ 13 | } 14 | 15 | void piranha::StringToFloatConversionOutput::fullCompute(void *_target) const { 16 | std::string value; 17 | m_input->fullCompute((void *)&value); 18 | 19 | piranha::native_float floatValue; 20 | std::stringstream ss(value); 21 | ss >> floatValue; 22 | 23 | piranha::native_float *target = reinterpret_cast(_target); 24 | *target = floatValue; 25 | } 26 | 27 | void piranha::StringToFloatConversionOutput::registerInputs() { 28 | registerInput(&m_input); 29 | } 30 | 31 | // CONVERSION ============================================= 32 | // int -> float 33 | piranha::IntToFloatConversionOutput::IntToFloatConversionOutput() { 34 | /* void */ 35 | } 36 | 37 | piranha::IntToFloatConversionOutput::~IntToFloatConversionOutput() { 38 | /* void */ 39 | } 40 | 41 | void piranha::IntToFloatConversionOutput::fullCompute(void *_target) const { 42 | int value; 43 | m_input->fullCompute((void *)&value); 44 | 45 | piranha::native_float *target = reinterpret_cast(_target); 46 | *target = (piranha::native_float)value; 47 | } 48 | 49 | void piranha::IntToFloatConversionOutput::registerInputs() { 50 | registerInput(&m_input); 51 | } 52 | -------------------------------------------------------------------------------- /src/fundamental_types.cpp: -------------------------------------------------------------------------------- 1 | #include "../include/fundamental_types.h" 2 | 3 | const piranha::ChannelType piranha::FundamentalType::FloatType("FloatNodeType"); 4 | const piranha::ChannelType piranha::FundamentalType::IntType("IntNodeType"); 5 | const piranha::ChannelType piranha::FundamentalType::BoolType("BoolNodeType"); 6 | const piranha::ChannelType piranha::FundamentalType::StringType("StringNodeType"); 7 | const piranha::ChannelType piranha::FundamentalType::VectorType("VectorType"); 8 | -------------------------------------------------------------------------------- /src/int_conversions.cpp: -------------------------------------------------------------------------------- 1 | #include "int_conversions.h" 2 | 3 | // CONVERSION ============================================= 4 | // string -> int 5 | piranha::StringToIntConversion::StringToIntConversion() { 6 | /* void */ 7 | } 8 | 9 | piranha::StringToIntConversion::~StringToIntConversion() { 10 | /* void */ 11 | } 12 | 13 | void piranha::StringToIntConversion::fullCompute(void *_target) const { 14 | std::string value; 15 | m_input->fullCompute((void *)&value); 16 | 17 | piranha::native_int intValue; 18 | std::stringstream ss(value); 19 | ss >> intValue; 20 | 21 | piranha::native_int *target = reinterpret_cast(_target); 22 | *target = intValue; 23 | } 24 | 25 | void piranha::StringToIntConversion::registerInputs() { 26 | registerInput(&m_input); 27 | } 28 | -------------------------------------------------------------------------------- /src/ir_attribute_list.cpp: -------------------------------------------------------------------------------- 1 | #include "../include/ir_attribute_list.h" 2 | 3 | #include "../include/ir_attribute.h" 4 | #include "../include/memory_tracker.h" 5 | 6 | piranha::IrAttributeList::IrAttributeList() { 7 | /* void */ 8 | } 9 | 10 | piranha::IrAttributeList::~IrAttributeList() { 11 | /* void */ 12 | } 13 | 14 | void piranha::IrAttributeList::addAttribute(IrAttribute *attribute) { 15 | if (attribute != nullptr) { 16 | const int index = getAttributeCount(); 17 | 18 | m_attributes.push_back(attribute); 19 | attribute->setPosition(index); 20 | 21 | registerComponent(attribute); 22 | } 23 | } 24 | 25 | piranha::IrAttribute *piranha::IrAttributeList:: 26 | getAttribute(IrAttributeDefinition *definition) const 27 | { 28 | const int attributeCount = getAttributeCount(); 29 | for (int i = 0; i < attributeCount; i++) { 30 | IrAttribute *attribute = getAttribute(i); 31 | if (attribute->getAttributeDefinition() == definition) { 32 | return attribute; 33 | } 34 | } 35 | 36 | return nullptr; 37 | } 38 | 39 | void piranha::IrAttributeList::free() { 40 | IrParserStructure::free(); 41 | } 42 | -------------------------------------------------------------------------------- /src/ir_import_statement.cpp: -------------------------------------------------------------------------------- 1 | #include "../include/ir_import_statement.h" 2 | 3 | piranha::IrImportStatement::IrImportStatement(const IrTokenInfo_string &libName) 4 | : m_libName(libName) 5 | { 6 | registerToken(&libName); 7 | m_unit = nullptr; 8 | } 9 | 10 | piranha::IrImportStatement::~IrImportStatement() { 11 | /* void */ 12 | } 13 | -------------------------------------------------------------------------------- /src/ir_value.cpp: -------------------------------------------------------------------------------- 1 | #include "../include/ir_value.h" 2 | 3 | piranha::IrValue::IrValue(piranha::IrValue::ValueType type) { 4 | m_type = type; 5 | } 6 | 7 | piranha::IrValue::~IrValue() { 8 | /* void */ 9 | } 10 | -------------------------------------------------------------------------------- /src/memory_tracker.cpp: -------------------------------------------------------------------------------- 1 | #include "../include/memory_tracker.h" 2 | 3 | #include 4 | 5 | piranha::MemoryTracker *piranha::MemoryTracker::s_instance = nullptr; 6 | 7 | piranha::MemoryTracker::MemoryTracker() { 8 | /* void */ 9 | } 10 | 11 | piranha::MemoryTracker::~MemoryTracker() { 12 | /* void */ 13 | } 14 | 15 | piranha::MemoryTracker *piranha::MemoryTracker::get() { 16 | if (s_instance == nullptr) s_instance = new MemoryTracker; 17 | return s_instance; 18 | } 19 | 20 | void piranha::MemoryTracker::reset() { 21 | m_allocations = std::vector(); 22 | } 23 | 24 | bool piranha::MemoryTracker::find(void *address, Allocation *target) { 25 | for (Allocation &allocation : m_allocations) { 26 | if (allocation.address == address) { 27 | *target = allocation; 28 | return true; 29 | } 30 | } 31 | 32 | return false; 33 | } 34 | 35 | void piranha::MemoryTracker::recordAllocation( 36 | void *address, const std::string &filename, int line) 37 | { 38 | for (Allocation &allocation : m_allocations) { 39 | if (allocation.address == address) { 40 | allocation.freed = false; 41 | allocation.line = line; 42 | allocation.filename = filename; 43 | return; 44 | } 45 | } 46 | 47 | Allocation allocation; 48 | allocation.address = address; 49 | allocation.filename = filename; 50 | allocation.freed = false; 51 | allocation.line = line; 52 | allocation.index = (int)m_allocations.size(); 53 | 54 | m_allocations.push_back(allocation); 55 | } 56 | 57 | void piranha::MemoryTracker::recordFree(void *address) { 58 | for (Allocation &allocation : m_allocations) { 59 | if (allocation.address == address) { 60 | assert(!allocation.freed); 61 | 62 | allocation.freed = true; 63 | } 64 | } 65 | } 66 | 67 | int piranha::MemoryTracker::countLeaks() const { 68 | std::vector unfreed; 69 | 70 | int count = 0; 71 | for (const Allocation &allocation : m_allocations) { 72 | if (!allocation.freed) { 73 | ++count; 74 | 75 | unfreed.push_back(allocation); 76 | } 77 | } 78 | 79 | return count; 80 | } 81 | -------------------------------------------------------------------------------- /src/no_op_node.cpp: -------------------------------------------------------------------------------- 1 | #include "../include/no_op_node.h" 2 | 3 | piranha::NoOpNode::NoOpNode() { 4 | m_input = nullptr; 5 | } 6 | 7 | piranha::NoOpNode::~NoOpNode() { 8 | /* void */ 9 | } 10 | 11 | void piranha::NoOpNode::_initialize() { 12 | /* void */ 13 | } 14 | 15 | void piranha::NoOpNode::_evaluate() { 16 | /* void */ 17 | } 18 | 19 | void piranha::NoOpNode::_destroy() { 20 | /* void */ 21 | } 22 | 23 | void piranha::NoOpNode::registerOutputs() { 24 | setPrimaryOutput("__out"); 25 | registerOutputReference(&m_input, "__out"); 26 | } 27 | 28 | void piranha::NoOpNode::registerInputs() { 29 | registerInput(&m_input, "__in"); 30 | } 31 | -------------------------------------------------------------------------------- /src/node_allocator.cpp: -------------------------------------------------------------------------------- 1 | #include "../include/node_allocator.h" 2 | 3 | piranha::NodeAllocator::NodeAllocator() { 4 | /* void */ 5 | } 6 | 7 | piranha::NodeAllocator::~NodeAllocator() { 8 | /* void */ 9 | } 10 | 11 | void *piranha::NodeAllocator::allocate(int size) { 12 | return malloc(size); 13 | } 14 | 15 | void piranha::NodeAllocator::free(void *memory) { 16 | ::free(memory); 17 | } 18 | -------------------------------------------------------------------------------- /src/node_output.cpp: -------------------------------------------------------------------------------- 1 | #include "../include/node_output.h" 2 | 3 | #include "../include/node.h" 4 | #include "../include/memory_tracker.h" 5 | 6 | piranha::NodeOutput::NodeOutput(const ChannelType *singleType) { 7 | m_singleType = singleType; 8 | m_evaluated = false; 9 | m_evaluating = false; 10 | m_checkedEnabled = false; 11 | m_interface = nullptr; 12 | m_parentNode = nullptr; 13 | 14 | m_enabled = true; 15 | } 16 | 17 | piranha::NodeOutput::~NodeOutput() { 18 | /* void */ 19 | } 20 | 21 | int piranha::NodeOutput::getModifyConnectionCount() const { 22 | return (int)m_modifyConnections.size(); 23 | } 24 | 25 | void piranha::NodeOutput::addModifyConnection(Node *output) { 26 | m_modifyConnections.push_back(output); 27 | } 28 | 29 | piranha::Node *piranha::NodeOutput::getModifyConnection(int index) const { 30 | return m_modifyConnections[index]; 31 | } 32 | 33 | void piranha::NodeOutput::initialize() { 34 | registerInputs(); 35 | } 36 | 37 | bool piranha::NodeOutput::evaluate() { 38 | if (m_evaluated || m_evaluating) return true; 39 | else m_evaluating = true; 40 | 41 | const int inputCount = getInputCount(); 42 | for (int i = 0; i < inputCount; i++) { 43 | bool result = (*m_inputs[i])->evaluate(); 44 | if (!result) return false; 45 | } 46 | 47 | const int modifyCount = getModifyConnectionCount(); 48 | for (int i = 0; i < modifyCount; i++) { 49 | const bool result = m_modifyConnections[i]->evaluate(); 50 | if (!result) return false; 51 | } 52 | 53 | if (m_parentNode != nullptr) { 54 | const bool result = m_parentNode->evaluate(); 55 | if (!result) return false; 56 | } 57 | 58 | _evaluate(); 59 | 60 | m_evaluated = true; 61 | return true; 62 | } 63 | 64 | bool piranha::NodeOutput::checkEnabled() { 65 | if (m_checkedEnabled) return true; 66 | else m_checkedEnabled = true; 67 | 68 | m_enabled = true; 69 | 70 | const int inputCount = getInputCount(); 71 | for (int i = 0; i < inputCount; i++) { 72 | const bool status = (*m_inputs[i])->checkEnabled(); 73 | if (!status) return false; 74 | if (!(*m_inputs[i])->isEnabled()) m_enabled = false; 75 | } 76 | 77 | const int modifyCount = getModifyConnectionCount(); 78 | for (int i = 0; i < modifyCount; i++) { 79 | const bool status = m_modifyConnections[i]->checkEnabled(); 80 | if (!status) return false; 81 | if (!m_modifyConnections[i]->isEnabled()) m_enabled = false; 82 | } 83 | 84 | if (m_parentNode != nullptr) { 85 | const bool status = m_parentNode->checkEnabled(); 86 | if (!status) return false; 87 | if (!m_parentNode->isEnabled()) m_enabled = false; 88 | } 89 | 90 | return true; 91 | } 92 | 93 | piranha::Node *piranha::NodeOutput::generateInterface(NodeAllocator *nodeAllocator) { 94 | m_interface = newInterface(nodeAllocator); 95 | if (m_interface != nullptr) { 96 | m_interface->setMemorySpace(Node::MemorySpace::ClientExternal); 97 | } 98 | 99 | return m_interface; 100 | } 101 | 102 | piranha::Node *piranha::NodeOutput::getInterface() const { 103 | return m_interface; 104 | } 105 | 106 | void piranha::NodeOutput::_evaluate() { 107 | /* void */ 108 | } 109 | -------------------------------------------------------------------------------- /src/path.cpp: -------------------------------------------------------------------------------- 1 | #include "../include/path.h" 2 | 3 | #include "../include/memory_tracker.h" 4 | 5 | #include 6 | 7 | piranha::Path::Path(const std::string &path) { 8 | m_path = nullptr; 9 | setPath(path); 10 | } 11 | 12 | piranha::Path::Path(const char *path) { 13 | m_path = nullptr; 14 | setPath(std::string(path)); 15 | } 16 | 17 | piranha::Path::Path(const Path &path) { 18 | m_path = TRACK(new std::filesystem::path); 19 | *m_path = path.getBoostPath(); 20 | } 21 | 22 | piranha::Path::Path() { 23 | m_path = nullptr; 24 | } 25 | 26 | piranha::Path::Path(const std::filesystem::path &path) { 27 | m_path = TRACK(new std::filesystem::path); 28 | *m_path = path; 29 | } 30 | 31 | piranha::Path::~Path() { 32 | if (m_path != nullptr) delete FTRACK(m_path); 33 | } 34 | 35 | std::string piranha::Path::toString() const { 36 | return m_path->string(); 37 | } 38 | 39 | void piranha::Path::setPath(const std::string &path) { 40 | if (m_path != nullptr) delete FTRACK(m_path); 41 | 42 | m_path = TRACK(new std::filesystem::path(path)); 43 | } 44 | 45 | bool piranha::Path::operator==(const Path &path) const { 46 | return std::filesystem::equivalent(this->getBoostPath(), path.getBoostPath()); 47 | } 48 | 49 | piranha::Path piranha::Path::append(const Path &path) const { 50 | return Path(getBoostPath() / path.getBoostPath()); 51 | } 52 | 53 | void piranha::Path::getParentPath(Path *path) const { 54 | path->m_path = TRACK(new std::filesystem::path); 55 | *path->m_path = m_path->parent_path(); 56 | } 57 | 58 | const piranha::Path &piranha::Path::operator=(const Path &b) { 59 | if (m_path != nullptr) delete FTRACK(m_path); 60 | 61 | m_path = TRACK(new std::filesystem::path); 62 | *m_path = b.getBoostPath(); 63 | 64 | return *this; 65 | } 66 | 67 | std::string piranha::Path::getExtension() const { 68 | return m_path->extension().string(); 69 | } 70 | 71 | std::string piranha::Path::getStem() const { 72 | return m_path->stem().string(); 73 | } 74 | 75 | bool piranha::Path::isAbsolute() const { 76 | return m_path->is_absolute(); 77 | } 78 | 79 | bool piranha::Path::exists() const { 80 | return std::filesystem::exists(*m_path); 81 | } 82 | -------------------------------------------------------------------------------- /src/standard_allocator.cpp: -------------------------------------------------------------------------------- 1 | #include "../include/standard_allocator.h" 2 | 3 | piranha::StandardAllocator *piranha::StandardAllocator::s_global = nullptr; 4 | 5 | piranha::StandardAllocator *piranha::StandardAllocator::Global() { 6 | if (s_global == nullptr) return s_global = new StandardAllocator; 7 | else return s_global; 8 | } 9 | 10 | piranha::StandardAllocator::StandardAllocator() { 11 | m_allocationLedger = 0; 12 | 13 | m_maxUsage = 0; 14 | m_currentUsage = 0; 15 | } 16 | 17 | piranha::StandardAllocator::~StandardAllocator() { 18 | assert(m_allocationLedger == 0); 19 | assert(m_currentUsage == 0); 20 | } 21 | 22 | void piranha::StandardAllocator::initialize() { 23 | m_allocationLedger = 0; 24 | 25 | m_maxUsage = 0; 26 | m_currentUsage = 0; 27 | } 28 | -------------------------------------------------------------------------------- /src/string_conversions.cpp: -------------------------------------------------------------------------------- 1 | #include "../include/string_conversions.h" 2 | 3 | #include 4 | 5 | // CONVERSION ============================================= 6 | // float -> string 7 | piranha::FloatToStringConversionOutput::FloatToStringConversionOutput() { 8 | /* void */ 9 | } 10 | 11 | piranha::FloatToStringConversionOutput::~FloatToStringConversionOutput() { 12 | /* void */ 13 | } 14 | 15 | void piranha::FloatToStringConversionOutput::fullCompute(void *_target) const { 16 | piranha::native_float value; 17 | m_input->fullCompute((void *)&value); 18 | 19 | std::stringstream ss; 20 | ss << value; 21 | 22 | std::string *target = reinterpret_cast(_target); 23 | *target = ss.str(); 24 | } 25 | 26 | void piranha::FloatToStringConversionOutput::registerInputs() { 27 | registerInput(&m_input); 28 | } 29 | 30 | // CONVERSION ============================================= 31 | // int -> string 32 | piranha::IntToStringConversionOutput::IntToStringConversionOutput() { 33 | /* void */ 34 | } 35 | 36 | piranha::IntToStringConversionOutput::~IntToStringConversionOutput() { 37 | /* void */ 38 | } 39 | 40 | void piranha::IntToStringConversionOutput::fullCompute(void *_target) const { 41 | piranha::native_int value; 42 | m_input->fullCompute((void *)&value); 43 | 44 | std::stringstream ss; 45 | ss << value; 46 | 47 | std::string *target = reinterpret_cast(_target); 48 | *target = ss.str(); 49 | } 50 | 51 | void piranha::IntToStringConversionOutput::registerInputs() { 52 | registerInput(&m_input); 53 | } 54 | -------------------------------------------------------------------------------- /src/vector_constructor.cpp: -------------------------------------------------------------------------------- 1 | #include "../include/vector_constructor.h" 2 | 3 | #include 4 | 5 | piranha::VectorConstructorOutput::VectorConstructorOutput() { 6 | /* void */ 7 | } 8 | 9 | piranha::VectorConstructorOutput::~VectorConstructorOutput() { 10 | /* void */ 11 | } 12 | 13 | void piranha::VectorConstructorOutput::fullCompute(void *_target) const { 14 | piranha::native_float x, y, z, w; 15 | m_inputX->fullCompute((void *)&x); 16 | m_inputY->fullCompute((void *)&y); 17 | m_inputZ->fullCompute((void *)&z); 18 | m_inputW->fullCompute((void *)&w); 19 | 20 | vector *target = reinterpret_cast(_target); 21 | *target = {x, y, z, w}; 22 | } 23 | 24 | void piranha::VectorConstructorOutput::registerInputs() { 25 | registerInput(&m_inputX); 26 | registerInput(&m_inputY); 27 | registerInput(&m_inputZ); 28 | registerInput(&m_inputW); 29 | } 30 | -------------------------------------------------------------------------------- /test/compilation_tests.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "../include/node.h" 4 | #include "../include/ir_compilation_unit.h" 5 | #include "../include/ir_node.h" 6 | #include "../include/ir_attribute_list.h" 7 | #include "../include/ir_attribute.h" 8 | #include "../include/ir_value_constant.h" 9 | #include "../include/ir_binary_operator.h" 10 | #include "../include/ir_import_statement.h" 11 | #include "../include/ir_node_definition.h" 12 | #include "../include/ir_attribute_definition.h" 13 | #include "../include/ir_attribute_definition_list.h" 14 | #include "../include/compilation_error.h" 15 | #include "../include/error_list.h" 16 | #include "../include/compiler.h" 17 | #include "../include/language_rules.h" 18 | #include "../include/node_program.h" 19 | 20 | #include "test_rules.h" 21 | #include "utilities.h" 22 | 23 | using namespace piranha; 24 | 25 | TEST(IrConstructionTests, IrConstructionSanityCheck) { 26 | MemoryTracker::get()->reset(); 27 | 28 | const ErrorList *list; 29 | Compiler *compiler; 30 | LanguageRules *rules; 31 | IrCompilationUnit *unit = compileFile("construction-tests/simple_float.mr", &list, &rules, &compiler); 32 | 33 | EXPECT_EQ(list->getErrorCount(), 0); 34 | 35 | NodeProgram program; 36 | unit->build(&program); 37 | 38 | program.execute(); 39 | 40 | double value; 41 | program.getTopLevelContainer()->getNode(1)->getPrimaryOutput()->fullCompute((void *)&value); 42 | EXPECT_EQ(value, 10.0); 43 | 44 | program.getTopLevelContainer()->getNode(3)->getPrimaryOutput()->fullCompute((void *)&value); 45 | EXPECT_EQ(value, 5.0); 46 | 47 | program.getTopLevelContainer()->getNode(5)->getPrimaryOutput()->fullCompute((void *)&value); 48 | EXPECT_EQ(value, 15.0); 49 | 50 | std::string stringValue; 51 | program.getTopLevelContainer()->getNode(7)->getPrimaryOutput()->fullCompute((void *)&stringValue); 52 | EXPECT_EQ(stringValue, "5"); 53 | 54 | program.getTopLevelContainer()->getNode(9)->getPrimaryOutput()->fullCompute((void *)&stringValue); 55 | EXPECT_EQ(stringValue, "123"); 56 | 57 | program.free(); 58 | compiler->free(); 59 | delete rules; 60 | 61 | EXPECT_EQ(MemoryTracker::get()->countLeaks(), 0); 62 | } 63 | 64 | TEST(IrConstructionTests, IrConstructionNestedTest) { 65 | MemoryTracker::get()->reset(); 66 | 67 | Compiler *compiler; 68 | LanguageRules *rules; 69 | IrCompilationUnit *unit = compileFile("construction-tests/nested_conversions.mr", nullptr, &rules, &compiler); 70 | 71 | NodeProgram program; 72 | unit->build(&program); 73 | 74 | program.execute(); 75 | 76 | Node *topLevel = program.getTopLevelContainer()->getNode(5); 77 | EXPECT_EQ(topLevel->getContext()->getContext()->getName(), "top_level"); 78 | 79 | double value; 80 | topLevel->getPrimaryOutput()->fullCompute((void *)&value); 81 | EXPECT_EQ(value, 10.5); 82 | 83 | program.free(); 84 | compiler->free(); 85 | 86 | delete rules; 87 | 88 | EXPECT_EQ(MemoryTracker::get()->countLeaks(), 0); 89 | } 90 | -------------------------------------------------------------------------------- /test/runtime_tests.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "../include/node.h" 4 | #include "../include/ir_compilation_unit.h" 5 | #include "../include/ir_node.h" 6 | #include "../include/ir_attribute_list.h" 7 | #include "../include/ir_attribute.h" 8 | #include "../include/ir_value_constant.h" 9 | #include "../include/ir_binary_operator.h" 10 | #include "../include/ir_import_statement.h" 11 | #include "../include/ir_node_definition.h" 12 | #include "../include/ir_attribute_definition.h" 13 | #include "../include/ir_attribute_definition_list.h" 14 | #include "../include/compilation_error.h" 15 | #include "../include/error_list.h" 16 | #include "../include/compiler.h" 17 | #include "../include/language_rules.h" 18 | #include "../include/node_program.h" 19 | 20 | #include "test_rules.h" 21 | #include "utilities.h" 22 | 23 | using namespace piranha; 24 | 25 | TEST(RuntimeTests, RuntimeErrorTest) { 26 | MemoryTracker::get()->reset(); 27 | 28 | Compiler *compiler; 29 | const ErrorList *errList; 30 | LanguageRules *rules; 31 | IrCompilationUnit *unit = compileFile("runtime-tests/runtime_error_test.mr", &errList, &rules, &compiler); 32 | 33 | NodeProgram program; 34 | unit->build(&program); 35 | 36 | const bool result = program.execute(); 37 | EXPECT_FALSE(result); 38 | 39 | EXPECT_EQ(program.getRuntimeError(), "Planned error"); 40 | 41 | program.free(); 42 | compiler->free(); 43 | delete rules; 44 | 45 | EXPECT_EQ(MemoryTracker::get()->countLeaks(), 0); 46 | } 47 | -------------------------------------------------------------------------------- /test/sdl/attribute_definition_test.mr: -------------------------------------------------------------------------------- 1 | module { 2 | @author: "Ange Yaghi" 3 | @date: "2019-05-30" 4 | } 5 | 6 | node TestNode { 7 | input A; 8 | input B; 9 | output C: "Random value"; 10 | } 11 | 12 | TestNode nodeInstance ( 13 | A: 5, 14 | B: 6, 15 | C: "kaboom", 16 | D: "undefined" 17 | ) 18 | -------------------------------------------------------------------------------- /test/sdl/bad_type_enforcement.mr: -------------------------------------------------------------------------------- 1 | node test_node { 2 | input test_input [fake_node]; 3 | } 4 | 5 | test_node(5) 6 | test_node(5) 7 | -------------------------------------------------------------------------------- /test/sdl/construction-tests/demo.mr: -------------------------------------------------------------------------------- 1 | public node VideoLoader => __video_loader { 2 | input filename: ""; 3 | output video; 4 | } 5 | 6 | public node VideoAdder => __video_adder { 7 | input video1; 8 | input video2; 9 | output added_video; 10 | } 11 | 12 | public node FrameAdder => __frame_adder { 13 | input frame; 14 | input frame2; 15 | output added_frames; 16 | } 17 | 18 | public node ConvertBW => __convert_bw { 19 | input frame; 20 | output bw_frame; 21 | } 22 | 23 | public node StreamingVideo => ___ { 24 | output frame; 25 | } 26 | 27 | public node VideoOutput => ___ { 28 | input frame; 29 | input filename; 30 | } 31 | 32 | StreamingVideo s1() 33 | StreamingVideo s2() 34 | 35 | VideoOutput vo( 36 | filename: "whatever.mov", 37 | frame: FrameAdder fa( 38 | s1, 39 | ConvertBW(s2) 40 | ) 41 | ) 42 | -------------------------------------------------------------------------------- /test/sdl/construction-tests/nested_conversions.1.mr: -------------------------------------------------------------------------------- 1 | public literal float => __builtin__float 2 | public literal int => __builtin__int 3 | 4 | public float >> int => __builtin__float_to_int 5 | public int >> float => __builtin__int_to_float 6 | public float >> vector => __builtin__float_to_vector 7 | 8 | public node vector => __builtin__float { 9 | input x [float]: 0.0; 10 | input y [float]: 0.0; 11 | 12 | output x [float]; 13 | output y [float]; 14 | } 15 | -------------------------------------------------------------------------------- /test/sdl/construction-tests/nested_conversions.mr: -------------------------------------------------------------------------------- 1 | public inline node float_channel => __piranha__float {} 2 | public inline node string_channel => __piranha__string {} 3 | 4 | public inline node literal_string => __piranha__literal_string { 5 | alias output __out [string]; 6 | } 7 | 8 | public inline node literal_float => __piranha__literal_float { 9 | alias output __out [float]; 10 | } 11 | 12 | public inline node float { 13 | input __in [float_channel]: 10.0; 14 | alias output __out [float_channel]: __in; 15 | } 16 | 17 | public inline node string { 18 | input __in [string_channel]: "DEFAULT"; 19 | alias output __out [string_channel]: __in; 20 | } 21 | 22 | public inline node float_to_string => __piranha__float_to_string { 23 | input __in [float]; 24 | alias output __out [string]; 25 | } 26 | 27 | public inline node string_to_float => __piranha__string_to_float { 28 | input __in [string]; 29 | alias output __out [float]; 30 | } 31 | 32 | float top_level( 33 | string( 34 | float( 35 | string( 36 | string( 37 | float( 38 | float( 39 | float( 40 | string("10.5") 41 | ) 42 | ) 43 | ) 44 | ) 45 | ) 46 | ) 47 | ) 48 | ) 49 | -------------------------------------------------------------------------------- /test/sdl/construction-tests/simple_float.mr: -------------------------------------------------------------------------------- 1 | public node float_channel => __piranha__float {} 2 | public node string_channel => __piranha__string {} 3 | 4 | public inline node literal_string => __piranha__literal_string { 5 | alias output __out [string]; 6 | } 7 | 8 | public inline node literal_float => __piranha__literal_float { 9 | alias output __out [float]; 10 | } 11 | 12 | public inline node float { 13 | input __in [float_channel]: "10.0"; 14 | alias output __out [float_channel]: __in; 15 | } 16 | 17 | public inline node string { 18 | input __in [string_channel]: 123.0; 19 | alias output __out [string_channel]: __in; 20 | } 21 | 22 | public inline node float_to_string => __piranha__float_to_string { 23 | input __in [float]; 24 | alias output __out [string]; 25 | } 26 | 27 | public inline node string_to_float => __piranha__string_to_float { 28 | input __in [string]; 29 | alias output __out [float]; 30 | } 31 | 32 | float() 33 | float("5.0") 34 | float string_to_float("15.0") 35 | string(5.0) 36 | string() 37 | -------------------------------------------------------------------------------- /test/sdl/construction-tests/test.mr: -------------------------------------------------------------------------------- 1 | public node float => __float { 2 | input __in; 3 | } 4 | 5 | public node int => __int { 6 | input __out; 7 | } 8 | 9 | public node float_conversion => __float_conv { 10 | input __in; 11 | output __out [float]; 12 | } 13 | 14 | public node int_conversion => __int_conv { 15 | input __in; 16 | output __out [int]; 17 | } 18 | 19 | // Internally the '+' operator will map to both a C++ type and this builtin name 20 | // The builtin name is used by the compiler for reference checking 21 | public node float_add => __float_add { 22 | input a; 23 | input b; 24 | default output c [float]; 25 | } 26 | 27 | public node int_add => __int_add { 28 | input a; 29 | input b; 30 | default output c [int]; 31 | } 32 | 33 | // Things I need 34 | // 1. Rather than mapping an operator to a whole node type, it needs to also map to a builtin type for type checking 35 | // 2. Operator resolution needs to happen much earlier in the process so that the operator can be linked to a node definition 36 | // 3. A builtin node would also have to indicate whether or not it is an alias for an actual channel type 37 | // a. Ie. the float node for example is essentially an alias for the FloatNodeOutput type 38 | // - This way float_add would basically return a floating point value 39 | -------------------------------------------------------------------------------- /test/sdl/dependency_test.mr: -------------------------------------------------------------------------------- 1 | import "sample_lib/example_dependency.mr" 2 | 3 | FileImage image () 4 | -------------------------------------------------------------------------------- /test/sdl/dependency_tree.mr: -------------------------------------------------------------------------------- 1 | public import "sample_lib/example_dependency" 2 | private import "sample_lib/dependency_tree" 3 | 4 | NewNode1 test( 5 | A: "Input" 6 | ) 7 | 8 | NewNode2 test2( 9 | A: "Input" 10 | ) 11 | -------------------------------------------------------------------------------- /test/sdl/duplicate_node_definition.mr: -------------------------------------------------------------------------------- 1 | private node the_same_node { // DuplicateNodeDefinition 2 | input A; 3 | output B: A; 4 | } 5 | 6 | private node the_same_node { // DuplicateNodeDefinition 7 | input C; // SymbolUsedMultipleTimes 8 | input C; // SymbolUsedMultipleTimes 9 | input D; // SymbolUsedMultipleTimes 10 | output D: C; // SymbolUsedMultipleTimes 11 | output D; // SymbolUsedMultipleTimes, OutputWithNoDefinition 12 | output C; // SymbolUsedMultipleTimes, OutputWithNoDefinition 13 | 14 | interior_node C() // SymbolUsedMultipleTimes 15 | } 16 | 17 | private node interior_node { 18 | input A: 0; 19 | output B: A; 20 | } 21 | -------------------------------------------------------------------------------- /test/sdl/full-error-testing/test_case_1.mr: -------------------------------------------------------------------------------- 1 | private node AddNode { 2 | input p1; 3 | input p2; 4 | alias output out: p1 + p2; 5 | } 6 | 7 | private node AddMulNode { 8 | input p1; 9 | input p2; 10 | input p3; 11 | alias output out: AddNode(p1, p2) * p3; 12 | } 13 | 14 | private node BrokenNodeDef### { 15 | input a; 16 | input b; 17 | alias output out: a - b; 18 | } 19 | 20 | // This node should still be read even though 21 | // the node definition before is messed up 22 | BrokenNodeDef brokenNodeInstance( // UndefinedNodeType 23 | fake_input_1: 5, 24 | fake_input_2: 6 25 | ) 26 | -------------------------------------------------------------------------------- /test/sdl/full-error-testing/test_case_2.mr: -------------------------------------------------------------------------------- 1 | private node AddNode { 2 | input p1; 3 | input p2; 4 | alias output out: p1 + p2; 5 | } 6 | 7 | private node AddMulNode { 8 | input p1; 9 | input p2; 10 | input p3; 11 | alias output out: AddNode(p1, p2) * p3; 12 | } 13 | 14 | private node BrokenNodeDef { 15 | // Broken attribute, the rest should still work 16 | input a###: 5; // UnidentifiedToken 17 | input b; 18 | alias output out: a - b; 19 | } 20 | 21 | // This node should still be read even though 22 | // the node definition before is messed up 23 | BrokenNodeDef brokenNodeInstance( 24 | fake_input_1: 5, // PortNotFound 25 | fake_input_2: 6, // PortNotFound 26 | b: 15, // Good 27 | 28 | a: "Works" 29 | ) 30 | -------------------------------------------------------------------------------- /test/sdl/full-error-testing/test_case_3.mr: -------------------------------------------------------------------------------- 1 | private node AddNode { 2 | input p1; 3 | input p2; 4 | output out: p1 + p2; 5 | output boom: test_label$; // UnidentifiedToken, UnresolvedReference 6 | } 7 | 8 | private node AddMulNode { 9 | input p1; 10 | input p2; 11 | input p3; 12 | // Broken definition 13 | output out: AddNode(p1 $, p2) * p3; // UnidentifiedToken, InputNotConnected 14 | output test: AddNode(p1 $, p2).out * p3; // UnidentifiedToken, InputNotConnected 15 | output boom: AddNode(p1, p2).boom; // UndefinedMember 16 | output bad_access: AddNode(p1, p2)."weird"; // UnexpectedToken 17 | } 18 | 19 | private node BrokenNodeDef { 20 | input a; 21 | input b; 22 | output out: a - b; 23 | } 24 | 25 | // This node should still be read even though 26 | // the node definition before is messed up 27 | AddMulNode brokenNodeInstance( 28 | p1: 5, 29 | p2: 15, 30 | p3: 16 31 | ) 32 | 33 | private node UnusedNode { 34 | input a; 35 | input b; 36 | output out: a + z; // UnresolvedReference 37 | } 38 | -------------------------------------------------------------------------------- /test/sdl/general-tests/general_syntax_test_1.mr: -------------------------------------------------------------------------------- 1 | private import "../../../demos/piranha/standard-library/standard_library.mr" as std 2 | 3 | private node print_header { 4 | std::console_out("---------------------------------------\n") 5 | std::console_out(" Piranha Number Adder\n") 6 | std::console_out(" Ange Yaghi (c) 2019\n") 7 | std::console_out("---------------------------------------\n") 8 | } 9 | 10 | private node get_input { 11 | output number1: std::console_in("Enter a number: "); 12 | output number2: std::console_in("Enter another number: "); 13 | } 14 | 15 | private node add_and_print { 16 | input inputs; 17 | 18 | string formatted(float(inputs.number1) + float(inputs.number2) + fake) 19 | std::console_out("---------------------------------------\n") 20 | std::console_out(inputs.number1 + " + " + inputs.number2 + " = " + formatted + "\n") 21 | } 22 | 23 | // Execute 24 | print_header() 25 | add_and_print( 26 | get_input() 27 | ) 28 | -------------------------------------------------------------------------------- /test/sdl/general-tests/general_syntax_test_10.mr: -------------------------------------------------------------------------------- 1 | private import "../../../demos/piranha/standard-library/standard_library.mr" as std 2 | 3 | node print_stuff { 4 | input a; 5 | std::console_out(a + "\n") 6 | } 7 | 8 | node top_level { 9 | //print_stuff("Good") 10 | print_stuff(2) // InvalidOperands 11 | //print_stuff("Good") 12 | } 13 | 14 | top_level() 15 | top_level() 16 | -------------------------------------------------------------------------------- /test/sdl/general-tests/general_syntax_test_11.mr: -------------------------------------------------------------------------------- 1 | node string_channel => __piranha__string {} 2 | node float_channel => __piranha__float {} 3 | node int_channel => __piranha__int {} 4 | 5 | public node literal_string => __piranha__literal_string { 6 | alias output __out [string]; 7 | } 8 | 9 | public node literal_int => __piranha__literal_int { 10 | alias output __out [int_channel]; 11 | } 12 | 13 | public node literal_float => __piranha__literal_float { 14 | alias output __out [float]; 15 | } 16 | 17 | node float_to_string => __piranha__float_to_string { 18 | input __in [float]; 19 | alias output __out [string]; 20 | } 21 | 22 | node float { 23 | input __in [float_channel]; 24 | alias output __out [float_channel]: __in; 25 | } 26 | 27 | node string { 28 | input __in [string_channel]; 29 | alias output __out [string_channel]: __in; 30 | } 31 | 32 | node test { 33 | input a [string]: 5; 34 | output b [string]: a; 35 | } 36 | 37 | test(5) 38 | test("hello") 39 | test(5.0) 40 | test(10) 41 | -------------------------------------------------------------------------------- /test/sdl/general-tests/general_syntax_test_12.mr: -------------------------------------------------------------------------------- 1 | private import "../../../demos/piranha/standard-library/standard_library.mr" as std 2 | 3 | node fake_type {} 4 | node other_fake_type {} 5 | 6 | node processor { 7 | input in [fake_type]: other_fake_type(); 8 | output out: in; 9 | } 10 | 11 | processor(5) 12 | processor(fake_type()) 13 | processor(other_fake_type()) 14 | -------------------------------------------------------------------------------- /test/sdl/general-tests/general_syntax_test_13.mr: -------------------------------------------------------------------------------- 1 | private import "../../../demos/piranha/standard-library/standard_library.mr" as std 2 | 3 | node output_structure { 4 | input some_input [string]; 5 | 6 | output raw: some_input; 7 | output formatted: "The result was " + some_input /* missing semicolon */ 8 | } 9 | 10 | node test_node { 11 | input my_default: "5.0"; 12 | input other_param [string]: float(my_default); 13 | alias output __out: output_structure(other_param); 14 | } 15 | 16 | test_node test() 17 | 18 | console_out(test.raw) 19 | console_out(test.formatted) 20 | -------------------------------------------------------------------------------- /test/sdl/general-tests/general_syntax_test_13_min.mr: -------------------------------------------------------------------------------- 1 | private import "../../../demos/piranha/standard-library/standard_library.mr" as std 2 | 3 | node output_structure { 4 | input __in; 5 | output out: __in + "end"; 6 | } 7 | 8 | node test_node { 9 | input __in; 10 | alias output __out: output_structure(__in); 11 | } 12 | 13 | test_node test("The ") 14 | 15 | node dummy_node { input a; } 16 | 17 | dummy_node(test.out) 18 | -------------------------------------------------------------------------------- /test/sdl/general-tests/general_syntax_test_14.mr: -------------------------------------------------------------------------------- 1 | private import "../../../demos/piranha/standard-library/standard_library.mr" as std 2 | 3 | node output_structure { 4 | input some_input [string]; 5 | output raw: some_input + "Hello"; 6 | output kaboom: some_input + 5.0; // some_input should have converted to a string, which would cause this to fail 7 | } 8 | 9 | output_structure(5.0) 10 | -------------------------------------------------------------------------------- /test/sdl/general-tests/general_syntax_test_15.mr: -------------------------------------------------------------------------------- 1 | private import "../../../demos/piranha/standard-library/standard_library.mr" as std 2 | 3 | node some_type { 4 | input a; 5 | output b: a + "hello"; 6 | } 7 | 8 | node output_structure { 9 | input some_input [some_type]; 10 | output raw: some_input.fake + "Hello"; 11 | } 12 | 13 | console_out( 14 | output_structure( 15 | some_type("Preface: ") 16 | ).raw 17 | ) -------------------------------------------------------------------------------- /test/sdl/general-tests/general_syntax_test_16.mr: -------------------------------------------------------------------------------- 1 | private import "../../../demos/piranha/standard-library/standard_library.mr" as std 2 | 3 | node some_type { 4 | input a; 5 | input b [float]; 6 | output c: a + "hello from [" + string(b) + "]"; 7 | output d: b; 8 | } 9 | 10 | node output_structure { 11 | input some_input [some_type]; 12 | output raw: some_input.c + "Hello"; 13 | output kaboom: some_input.d + "kaboom"; 14 | } 15 | 16 | console_out( 17 | output_structure( 18 | some_type("Preface: ", "loc") 19 | ).raw 20 | ) -------------------------------------------------------------------------------- /test/sdl/general-tests/general_syntax_test_17.mr: -------------------------------------------------------------------------------- 1 | node float_channel => __piranha__float {} 2 | node string_channel => __piranha__string {} 3 | 4 | public node literal_string => __piranha__literal_string { 5 | alias output __out [string]; 6 | } 7 | 8 | public node literal_float => __piranha__literal_float { 9 | alias output __out [float]; 10 | } 11 | 12 | node float { 13 | input __in [float_channel]; 14 | alias output __out [float_channel]: __in; 15 | } 16 | 17 | node string { 18 | input __in [string_channel]; 19 | alias output __out [string_channel]: __in; 20 | } 21 | 22 | node string_to_float => __piranha__string_to_float { 23 | input __in [string]; 24 | alias output __out [float]; 25 | } 26 | 27 | node float_to_string => __piranha__float_to_string { 28 | input __in [float]; 29 | alias output __out [string]; 30 | } 31 | 32 | node console_out => __piranha__console_out { 33 | input data [string]: ""; 34 | } 35 | 36 | node some_thing { 37 | input in [float]; 38 | output out: in; 39 | } 40 | 41 | console_out this_thing( 42 | float("5.0") 43 | ) 44 | 45 | console_out( 46 | some_thing("10").out 47 | ) 48 | -------------------------------------------------------------------------------- /test/sdl/general-tests/general_syntax_test_18.mr: -------------------------------------------------------------------------------- 1 | node float_channel => __piranha__fake_type {} 2 | -------------------------------------------------------------------------------- /test/sdl/general-tests/general_syntax_test_19.mr: -------------------------------------------------------------------------------- 1 | private import "../../../demos/piranha/standard-library/standard_library.mr" as std 2 | 3 | node prompt_info { 4 | input msg [string]; 5 | input data 6 | 7 | output str_msg: msg; 8 | output some_data: data; 9 | } 10 | 11 | node do_something { 12 | input prompt_info [prompt_info] : 13 | prompt_info("Test message", 10); 14 | output some_data [float]: prompt_info.some_data; 15 | output original_prompt: prompt_info; 16 | 17 | console_out(prompt_info.str_msg + string(": ") + string(prompt_info.some_data)) 18 | } 19 | 20 | node do_something_else { 21 | input some_value [int]; 22 | 23 | console_out("Something else: " + string(float(some_value))) 24 | } 25 | 26 | do_something_else( 27 | do_something().some_data 28 | ) 29 | -------------------------------------------------------------------------------- /test/sdl/general-tests/general_syntax_test_2.mr: -------------------------------------------------------------------------------- 1 | private import "../../../demos/piranha/standard-library/standard_library.mr" as std 2 | 3 | private node print_header { 4 | std::console_out("---------------------------------------\n") 5 | std::console_out(" Piranha Number Adder\n") 6 | std::console_out(" Ange Yaghi (c) 2019\n") 7 | std::console_out("---------------------------------------\n") 8 | } 9 | 10 | private node get_input { 11 | output number1: std::console_in("Enter a number: "); 12 | output number2: std::console_in("Enter another number: "); 13 | } 14 | 15 | private node add_and_print { 16 | input inputs; 17 | 18 | string formatted(float(inputs.number1) + float(inputs.number2)) 19 | std::console_out("---------------------------------------\n") 20 | std::console_out(inputs.number1 + " + " + inputs.number2 + " = " + formatted + "\n") 21 | } 22 | 23 | // Execute 24 | print_header() 25 | add_and_print( 26 | get_input() + 5 27 | ) 28 | -------------------------------------------------------------------------------- /test/sdl/general-tests/general_syntax_test_20.mr: -------------------------------------------------------------------------------- 1 | private import "../../../demos/piranha/standard-library/standard_library.mr" as std 2 | 3 | node prompt_info { 4 | input msg [string]: "Test message"; 5 | input data: 10 6 | 7 | output str_msg: msg; 8 | output some_data: data; 9 | } 10 | 11 | node do_something { 12 | input prompt_info [prompt_info] : 10; // Invalid default value 13 | output some_data [float]: prompt_info.some_data; 14 | output original_prompt: prompt_info; 15 | 16 | console_out(prompt_info.str_msg + string(": ") + string(prompt_info.some_data)) 17 | } 18 | 19 | node do_something_else { 20 | input some_value [int]; 21 | 22 | console_out("Something else: " + string(float(some_value))) 23 | } 24 | 25 | do_something_else( 26 | do_something().some_data 27 | ) 28 | -------------------------------------------------------------------------------- /test/sdl/general-tests/general_syntax_test_21.mr: -------------------------------------------------------------------------------- 1 | private import "../../../demos/piranha/standard-library/standard_library.mr" as std 2 | 3 | node embedded { 4 | input thing [int]; 5 | input empty_input; 6 | 7 | output test_int1 [int]; 8 | output test_int2: thing; 9 | output test_string: ""; 10 | output test_float: 10.0; 11 | output empty: empty_input; 12 | } 13 | 14 | node prompt_info { 15 | input msg [string]: "Test message"; 16 | input data: 10 17 | input empty; 18 | 19 | output str_msg: msg; 20 | output some_data: data; 21 | output embedded: embedded(empty, empty); 22 | } 23 | 24 | node do_something { 25 | input prompt_info [prompt_info] : 10; // Invalid default value 26 | output some_data [float]: prompt_info.some_data; 27 | output original_prompt: prompt_info; 28 | 29 | string(prompt_info.embedded.test_int1 + prompt_info.embedded.test_string) 30 | string(prompt_info.embedded.test_int1) 31 | string(prompt_info.embedded.test_int2 + prompt_info.embedded.test_string) 32 | string(prompt_info.embedded.test_int2) 33 | 34 | string(prompt_info.embedded.test_float + 5.0) 35 | string(prompt_info.embedded.test_string) 36 | string(prompt_info.embedded.empty) // Should not cause an error 37 | } 38 | 39 | node do_something_else { 40 | input some_value [int]; 41 | 42 | console_out("Something else: " + string(float(some_value))) 43 | } 44 | 45 | do_something_else( 46 | do_something().some_data 47 | ) 48 | -------------------------------------------------------------------------------- /test/sdl/general-tests/general_syntax_test_21a.mr: -------------------------------------------------------------------------------- 1 | private import "../../../demos/piranha/standard-library/standard_library.mr" as std 2 | 3 | node embedded { 4 | input thing [int]; 5 | output test_int2: thing; 6 | } 7 | 8 | node fake_type {} 9 | 10 | node checker { 11 | input a [fake_type]; 12 | } 13 | 14 | node test { 15 | input test [embedded] : 5; 16 | 17 | checker(test.test_int2) 18 | } 19 | 20 | test() 21 | -------------------------------------------------------------------------------- /test/sdl/general-tests/general_syntax_test_21b.mr: -------------------------------------------------------------------------------- 1 | private import "../../../demos/piranha/standard-library/standard_library.mr" as std 2 | 3 | node embedded { 4 | input thing [int]; 5 | output test_int2: thing; 6 | } 7 | 8 | node prompt_info { 9 | input empty; 10 | output embedded: embedded(empty); 11 | } 12 | 13 | node do_something { 14 | input prompt_info [prompt_info] : 10; // Invalid default value 15 | 16 | string(prompt_info.embedded.test_int2 + "") 17 | string(prompt_info.embedded.test_int2) 18 | } 19 | 20 | do_something() 21 | -------------------------------------------------------------------------------- /test/sdl/general-tests/general_syntax_test_22.mr: -------------------------------------------------------------------------------- 1 | private import "../../../demos/piranha/standard-library/standard_library.mr" as std 2 | 3 | node embedded { 4 | input thing [int]; 5 | input empty_input; 6 | 7 | output test_int1 [int]; 8 | output test_int2: thing; 9 | output test_string: ""; 10 | output test_float: 10.0; 11 | output empty: empty_input; 12 | } 13 | 14 | node prompt_info { 15 | input msg [string]: "Test message"; 16 | input data: 10 17 | input empty; 18 | 19 | output str_msg: msg; 20 | output some_data: data; 21 | output embedded: embedded(empty, empty); 22 | } 23 | 24 | node tester_positive { 25 | input test [prompt_info]; 26 | } 27 | 28 | node tester_negative { 29 | input test [int]; 30 | } 31 | 32 | node do_something { 33 | input prompt_info [prompt_info] : 10; // Invalid default value 34 | output some_data [float]: prompt_info.some_data; 35 | output original_prompt: prompt_info; 36 | 37 | tester_positive(prompt_info) // Should be okay 38 | tester_negative(prompt_info) // Should cause an error 39 | } 40 | 41 | node do_something_else { 42 | input some_value [int]; 43 | 44 | console_out("Something else: " + string(float(some_value))) 45 | } 46 | 47 | do_something_else( 48 | do_something().some_data 49 | ) 50 | 51 | // This should be totally fine 52 | do_something( 53 | prompt_info( 54 | empty: 10 55 | ) 56 | ) 57 | -------------------------------------------------------------------------------- /test/sdl/general-tests/general_syntax_test_23.mr: -------------------------------------------------------------------------------- 1 | node broken_definition => __piranha__float_add { 2 | input __in_bad_name [float]; 3 | input __in1 [float]; 4 | output __out_bad_name [float]; 5 | } 6 | -------------------------------------------------------------------------------- /test/sdl/general-tests/general_syntax_test_24a.mr: -------------------------------------------------------------------------------- 1 | private import "general_syntax_test_24b.mr" 2 | 3 | node test { 4 | input a; 5 | output b: a; 6 | } 7 | -------------------------------------------------------------------------------- /test/sdl/general-tests/general_syntax_test_24b.mr: -------------------------------------------------------------------------------- 1 | private import "general_syntax_test_24a.mr" 2 | 3 | node test { 4 | input a; 5 | output b: a; 6 | } 7 | -------------------------------------------------------------------------------- /test/sdl/general-tests/general_syntax_test_25.mr: -------------------------------------------------------------------------------- 1 | private import "../../../demos/piranha/standard-library/standard_library.mr" as std 2 | 3 | private node test { 4 | output test: 15; 5 | } 6 | 7 | private node do_stuff { 8 | input test; 9 | alias output t: test.test; 10 | } 11 | 12 | test test() 13 | do_stuff(test) 14 | -------------------------------------------------------------------------------- /test/sdl/general-tests/general_syntax_test_26.mr: -------------------------------------------------------------------------------- 1 | private import "../../../demos/piranha/standard-library/standard_library.mr" as std 2 | 3 | private node test { 4 | toggle enable: true; 5 | output test: 15; 6 | } 7 | 8 | private node do_stuff { 9 | input test; 10 | alias output t: test.test; 11 | } 12 | 13 | private node do_stuff2 { 14 | input test; 15 | alias output t: test; 16 | } 17 | 18 | test test(enable: false) 19 | do_stuff(test) 20 | do_stuff2("Should work") 21 | -------------------------------------------------------------------------------- /test/sdl/general-tests/general_syntax_test_27.mr: -------------------------------------------------------------------------------- 1 | private import "../../../demos/piranha/standard-library/standard_library.mr" as std 2 | 3 | private node test { 4 | toggle enable: true; 5 | alias output a: 5; 6 | 7 | std::console_out("Node 1\n") 8 | } 9 | 10 | private node do_stuff0 { 11 | input test; 12 | alias output t: test; 13 | 14 | std::console_out("Node 2\n") 15 | } 16 | 17 | private node do_stuff1 { 18 | input test; 19 | alias output t: test; 20 | 21 | std::console_out("Node 3\n") 22 | } 23 | 24 | private node do_stuff2 { 25 | input test; 26 | alias output t: test; 27 | 28 | std::console_out("Node 4\n") 29 | } 30 | 31 | test test(enable: false) 32 | do_stuff0 node0(test) 33 | do_stuff1 node1(node0) 34 | -------------------------------------------------------------------------------- /test/sdl/general-tests/general_syntax_test_28.mr: -------------------------------------------------------------------------------- 1 | private import "../../../demos/piranha/standard-library/standard_library.mr" as std 2 | 3 | auto 4 | private node test { 5 | toggle enable: false; 6 | alias output a: 5; 7 | 8 | std::console_out("Node 1\n") 9 | } 10 | 11 | auto 12 | private node do_stuff0 { 13 | input test_in: test; 14 | alias output t: test_in; 15 | 16 | std::console_out("Node 2\n") 17 | } 18 | 19 | auto 20 | private node do_stuff1 { 21 | input test: do_stuff0; 22 | alias output t: test; 23 | 24 | std::console_out("Node 3\n") 25 | } 26 | 27 | auto 28 | private node do_stuff2 { 29 | input test: do_stuff1; 30 | alias output t: test; 31 | 32 | std::console_out("Node 4\n") 33 | } 34 | -------------------------------------------------------------------------------- /test/sdl/general-tests/general_syntax_test_29.mr: -------------------------------------------------------------------------------- 1 | private import "../../../demos/piranha/standard-library/standard_library.mr" as std 2 | 3 | auto 4 | private node test { 5 | input this: test; 6 | output a: 5; 7 | 8 | std::console_out("Node 1\n") 9 | } 10 | -------------------------------------------------------------------------------- /test/sdl/general-tests/general_syntax_test_3.mr: -------------------------------------------------------------------------------- 1 | private import "../../../demos/piranha/standard-library/standard_library.mr" as std 2 | 3 | private node print_header { 4 | std::console_out("---------------------------------------\n") 5 | std::console_out(" Piranha Number Adder\n") 6 | std::console_out(" Ange Yaghi (c) 2019\n") 7 | std::console_out("---------------------------------------\n") 8 | } 9 | 10 | private node get_input { 11 | output number1: std::console_in("Enter a number: "); 12 | output number2: std::console_in("Enter another number: "); 13 | } 14 | 15 | private node add_and_print { 16 | input inputs; 17 | 18 | string formatted(float(inputs.number1) + float(inputs.number2)) 19 | std::console_out("---------------------------------------\n") 20 | std::console_out(inputs.number1 + " + " + inputs.number2 + " = " + formatted + "\n") 21 | } 22 | 23 | // Execute 24 | print_header(), 25 | add_and_print( 26 | get_input() + 0test 27 | ) 28 | -------------------------------------------------------------------------------- /test/sdl/general-tests/general_syntax_test_30.mr: -------------------------------------------------------------------------------- 1 | private import "../../../demos/piranha/standard-library/standard_library.mr" as std 2 | 3 | vector v1(0.0, 0.0, 0.0, 0.0) 4 | 5 | test(true, v1.x) 6 | test(false, v1) 7 | 8 | private node test { 9 | toggle enable; 10 | input test; 11 | } 12 | -------------------------------------------------------------------------------- /test/sdl/general-tests/general_syntax_test_31.mr: -------------------------------------------------------------------------------- 1 | public node int_channel => __piranha__int {} 2 | 3 | public node literal_int => __piranha__literal_int { 4 | alias output __out [int_channel]; 5 | } 6 | 7 | auto private node test { 8 | input value: 5; 9 | output value_out: value; 10 | output out: test.value_out; 11 | } 12 | -------------------------------------------------------------------------------- /test/sdl/general-tests/general_syntax_test_32.mr: -------------------------------------------------------------------------------- 1 | private import "../../../demos/piranha/standard-library/standard_library.mr" as std 2 | 3 | auto private node test { 4 | output pre: test.a; 5 | output a: 5; 6 | } 7 | -------------------------------------------------------------------------------- /test/sdl/general-tests/general_syntax_test_33.mr: -------------------------------------------------------------------------------- 1 | private import "../../../demos/piranha/standard-library/standard_library.mr" as std 2 | 3 | auto private node test { 4 | input pre: test.a; 5 | input a: 5; 6 | } 7 | -------------------------------------------------------------------------------- /test/sdl/general-tests/general_syntax_test_34.mr: -------------------------------------------------------------------------------- 1 | private import "../../../demos/piranha/standard-library/standard_library.mr" as std 2 | 3 | auto private inline node test { 4 | input pre: test.a; 5 | input a: 5; 6 | } 7 | -------------------------------------------------------------------------------- /test/sdl/general-tests/general_syntax_test_35.mr: -------------------------------------------------------------------------------- 1 | private import "../../../demos/piranha/standard-library/standard_library.mr" as std 2 | 3 | node sub { 4 | output c: 5; 5 | } 6 | 7 | node test { 8 | input this; 9 | output out: this.c; 10 | } 11 | 12 | sub().test() 13 | -------------------------------------------------------------------------------- /test/sdl/general-tests/general_syntax_test_36.mr: -------------------------------------------------------------------------------- 1 | private import "../../../demos/piranha/standard-library/standard_library.mr" as std 2 | 3 | node sub { 4 | output c: 5; 5 | } 6 | 7 | node test { 8 | input this; 9 | output out: this.c; 10 | } 11 | 12 | sub().test(this: sub()) 13 | -------------------------------------------------------------------------------- /test/sdl/general-tests/general_syntax_test_37.mr: -------------------------------------------------------------------------------- 1 | private import "../../../demos/piranha/standard-library/standard_library.mr" as std 2 | 3 | node parameter_pattern { 4 | input test: 0.0; 5 | } 6 | 7 | node parameterized { 8 | input parameters: parameter_pattern(); 9 | input test: parameters.test; 10 | output c: test; 11 | } 12 | 13 | parameter_pattern params( 14 | test: float_add(1.0, 1.0) 15 | ) 16 | 17 | parameterized( 18 | params 19 | ) 20 | -------------------------------------------------------------------------------- /test/sdl/general-tests/general_syntax_test_4.mr: -------------------------------------------------------------------------------- 1 | private import "../../../demos/piranha/standard-library/standard_library.mr" as std 2 | 3 | private node print_header { 4 | std::console_out("---------------------------------------\n") 5 | std::console_out(" Piranha Number Adder\n") 6 | std::console_out(" Ange Yaghi (c) 2019\n") 7 | std::console_out("---------------------------------------\n") 8 | } 9 | 10 | private node get_input { 11 | output number1: std::console_in("Enter a number: "); 12 | output number2: std::console_in("Enter another number: "); 13 | } 14 | 15 | private node add_and_print { 16 | input inputs;; 17 | 18 | string formatted(float(inputs.number1) + float(inputs.number2) + 0test) - 5 19 | std::console_out("---------------------------------------\n" + 0test) 20 | std::console_out(inputs.number1 + " + " + inputs.number2 + " = " + formatted + "\n") 21 | } 22 | 23 | // Execute 24 | print_header() 25 | add_and_print( 26 | get_input() 27 | ) 28 | -------------------------------------------------------------------------------- /test/sdl/general-tests/general_syntax_test_6.mr: -------------------------------------------------------------------------------- 1 | private import "../../../demos/piranha/standard-library/standard_library.mr" as std 2 | 3 | private node print_header { 4 | std::console_out("---------------------------------------\n") 5 | std::console_out(" Piranha Number Adder\n") 6 | std::console_out(" Ange Yaghi (c) 2019\n") 7 | std::console_out("---------------------------------------\n") 8 | } 9 | 10 | private node nested_console { 11 | output a: std::console_in("Stuff"); 12 | output fake: std::console_in("fake"); 13 | } 14 | 15 | private node get_input { 16 | output number1: std::console_in("Enter a number: "); 17 | output number2: nested_console().fake; 18 | } 19 | 20 | private node add_and_print { 21 | input inputs; 22 | 23 | string formatted(float(inputs.number1) + float(inputs.number2)) 24 | std::console_out("---------------------------------------\n") 25 | std::console_out(inputs.number1 + " + " + inputs.number2 + " = " + formatted + "\n") 26 | } 27 | 28 | // Execute 29 | print_header() 30 | add_and_print( 31 | get_input() 32 | ) 33 | -------------------------------------------------------------------------------- /test/sdl/general-tests/general_syntax_test_7.mr: -------------------------------------------------------------------------------- 1 | private import "../../../demos/piranha/standard-library/standard_library.mr" as std 2 | 3 | std::vector v1(3.0, 2.0, 3.0, 4.0) 4 | std::vector v2(4.0, 3.0, 2.0, 1.0) 5 | 6 | std::console_out((v1 + v2 + v1).w) 7 | -------------------------------------------------------------------------------- /test/sdl/general-tests/general_syntax_test_8.mr: -------------------------------------------------------------------------------- 1 | private import "../../../demos/piranha/standard-library/standard_library.mr" as std 2 | 3 | private node reverse_vector { 4 | input vector; 5 | alias output reversed: 6 | std::vector(vector.w, vector.z, vector.y, vector.x); 7 | } 8 | 9 | private node print_vector { 10 | input vector; 11 | 12 | std::console_out( 13 | string(vector.x) + ", " + 14 | string(vector.y) + ", " + 15 | string(vector.z) + ", " + 16 | string(vector.w) 17 | ) 18 | } 19 | 20 | std::vector v1(1.0, 2.0, 3.0, 4.0) 21 | std::vector v2(4.0, 3.0, 2.0, 1.0) 22 | 23 | console_out( 24 | reverse_vector(v1 + v2 + v1).x + 5 25 | ) 26 | -------------------------------------------------------------------------------- /test/sdl/general-tests/general_syntax_test_9.mr: -------------------------------------------------------------------------------- 1 | private import "../../../demos/piranha/standard-library/standard_library.mr" as std 2 | 3 | private inline node reverse_vector { 4 | input vector; 5 | alias output reversed: 6 | std::vector(vector.w, vector.z, vector.y, vector.x); 7 | } 8 | 9 | private inline node print_vector { 10 | input vector; 11 | 12 | std::console_out( 13 | string(vector.x) + ", " + 14 | string(vector.y) + ", " + 15 | string(vector.z) + ", " + 16 | string(vector.w) 17 | ) 18 | } 19 | 20 | std::vector v1(0.0, 0.0, 0.0, 0.0) 21 | 22 | print_vector( 23 | reverse_vector(v1 + vector(10, 0, 0, 0)) 24 | ) 25 | -------------------------------------------------------------------------------- /test/sdl/global_reference_test.mr: -------------------------------------------------------------------------------- 1 | auto private node some_node { 2 | output a: 5; 3 | } 4 | 5 | private node other_node { 6 | input t: some_node; 7 | output a: some_node.a; 8 | output b: some_node.b; // Undefined member 9 | } 10 | -------------------------------------------------------------------------------- /test/sdl/infinite_loop_test_1.mr: -------------------------------------------------------------------------------- 1 | node test { 2 | input test: test; 3 | output b: test; 4 | } 5 | 6 | test A(5) 7 | test B(B.b) 8 | -------------------------------------------------------------------------------- /test/sdl/infinite_loop_test_2.mr: -------------------------------------------------------------------------------- 1 | node int => __piranha__int {} 2 | node float => __piranha__float {} 3 | 4 | node int_to_float => __piranha__int_to_float { 5 | input __in [int]; 6 | alias output __out [float]; 7 | } 8 | 9 | node float_add => __piranha__float_add { 10 | input __in0 [float]; 11 | input __in1 [float]; 12 | alias output __out [float]; 13 | } 14 | 15 | node test { 16 | input test [float]: test; 17 | output b: test + 5.0; 18 | } 19 | 20 | test(5) 21 | -------------------------------------------------------------------------------- /test/sdl/infinite_loop_test_3.mr: -------------------------------------------------------------------------------- 1 | node test { 2 | output a: test(); 3 | output b: 5.0; 4 | } 5 | 6 | node test2 { 7 | output a: test().b; 8 | output b: test().a.a.a.b; 9 | output c: test().a.a.a.c; 10 | output d: test().c; 11 | output e: test().a.c; 12 | } 13 | -------------------------------------------------------------------------------- /test/sdl/infinite_loop_test_4.mr: -------------------------------------------------------------------------------- 1 | node nested { 2 | output c: test(); 3 | } 4 | 5 | node test { 6 | output a: nested(); 7 | output b: 5.0; 8 | } 9 | -------------------------------------------------------------------------------- /test/sdl/input_connection_test.mr: -------------------------------------------------------------------------------- 1 | private node CommonComponent { 2 | input in_message; 3 | output out_message: in_message; 4 | } 5 | 6 | private node SomeNode { 7 | output attribute: "Hello world"; 8 | output common: component; 9 | 10 | CommonComponent component("Some node here") 11 | } 12 | 13 | private node SomeOtherNode { 14 | output other_attribute: "Hello other world"; 15 | output common: component; 16 | 17 | CommonComponent component("Some other node here") 18 | } 19 | 20 | private node AttributeExtractor { 21 | input n: SomeNode(); 22 | input in_no_default; 23 | output attribute: n.attribute; 24 | output message: n.common.out_message; 25 | output other_attribute: in_no_default.other_attribute; 26 | } 27 | 28 | ::AttributeExtractor test_extractor ( 29 | n: SomeOtherNode(), // Kaboom 30 | in_no_default: SomeNode() // Kaboom 31 | ) 32 | -------------------------------------------------------------------------------- /test/sdl/missing_dependency.mr: -------------------------------------------------------------------------------- 1 | import "fake_file.mr" 2 | -------------------------------------------------------------------------------- /test/sdl/node_body.mr: -------------------------------------------------------------------------------- 1 | // For SdlNodeBodyTest 2 | 3 | import "sample_lib/test_lib" 4 | 5 | SampleNode test ( 6 | A: 5, 7 | B: 5 8 | ) 9 | -------------------------------------------------------------------------------- /test/sdl/operation_definition.mr: -------------------------------------------------------------------------------- 1 | private node operator+ => __builtin_add { 2 | input __in0; 3 | input __in1; 4 | alias output __out0 [Placeholder]; 5 | } 6 | 7 | operator+ test_node ( 8 | 2, 9 | 2 10 | ) 11 | 12 | private node Placeholder {} 13 | -------------------------------------------------------------------------------- /test/sdl/operator-tests/operator_sanity_check.mr: -------------------------------------------------------------------------------- 1 | private import "operators.mr" as operators 2 | 3 | node test { 4 | alias output __out: 5.0; 5 | } 6 | 7 | test() 8 | -------------------------------------------------------------------------------- /test/sdl/operator-tests/operator_test_1.mr: -------------------------------------------------------------------------------- 1 | private import "operators.mr" as operators 2 | 3 | node test { 4 | alias output __out: 5.0 + 5.0; 5 | } 6 | 7 | test() 8 | -------------------------------------------------------------------------------- /test/sdl/operator-tests/operator_test_2.mr: -------------------------------------------------------------------------------- 1 | private import "operators.mr" as operators 2 | 3 | node test { 4 | output test1: float(5.0) + 5.0; 5 | output test2: 5 + 5.0; 6 | output test3: 5.0 + 5; 7 | } 8 | 9 | test() 10 | -------------------------------------------------------------------------------- /test/sdl/operator-tests/operator_test_3.mr: -------------------------------------------------------------------------------- 1 | private import "operators.mr" as operators 2 | 3 | node test { 4 | input input1: 5; 5 | output test1: input1 + 5; 6 | } 7 | 8 | test test1() 9 | test test2(10) 10 | test test2(10.0) 11 | -------------------------------------------------------------------------------- /test/sdl/operator-tests/operator_test_4.mr: -------------------------------------------------------------------------------- 1 | private import "operators.mr" as operators 2 | 3 | node test { 4 | input input1: 5; 5 | output test1: input1 + 5; 6 | } 7 | 8 | test test1(10.0 + 5) 9 | test test2(10 + 5) 10 | test test3(10.0 + 5.0) 11 | -------------------------------------------------------------------------------- /test/sdl/operator-tests/operator_test_5.mr: -------------------------------------------------------------------------------- 1 | private import "operators.mr" as operators 2 | 3 | node test { 4 | input input1: 5; 5 | output test1: (input1 + 5); 6 | } 7 | 8 | test test1(test2.test1) 9 | test test2(10.0 + float("5.0")) 10 | -------------------------------------------------------------------------------- /test/sdl/operator-tests/operator_test_6.mr: -------------------------------------------------------------------------------- 1 | private import "operators.mr" as operators 2 | 3 | node test { 4 | input input1: 5; 5 | output test1: input1 + 5; // InvalidOperandTypes 6 | } 7 | 8 | test test1(test2.test1) 9 | test test2(10.0 + "5.0") // InvalidOperandTypes 10 | test test3("5.0") 11 | -------------------------------------------------------------------------------- /test/sdl/operator-tests/operator_test_7.mr: -------------------------------------------------------------------------------- 1 | private import "operators.mr" as operators 2 | 3 | node test { 4 | input input1; 5 | output test1: input1 + 5; // InvalidOperandTypes 6 | } 7 | 8 | test test1(test2.test1) 9 | test test2(10.0 + "5.0") // InvalidOperandTypes 10 | test test3("5.0") 11 | -------------------------------------------------------------------------------- /test/sdl/operator-tests/operator_test_8.mr: -------------------------------------------------------------------------------- 1 | private import "operators.mr" as operators 2 | 3 | inline node test { 4 | input input1; 5 | alias output test1: (input1 + " world!"); 6 | } 7 | 8 | test test1("Hello") 9 | test test2("Goodbye") 10 | -------------------------------------------------------------------------------- /test/sdl/operator-tests/operator_test_9.mr: -------------------------------------------------------------------------------- 1 | private import "operators.mr" as operators 2 | 3 | node test { 4 | input __in; 5 | output __out: -__in; // InvalidOperandTypes 6 | } 7 | 8 | test test1(0.5) 9 | -------------------------------------------------------------------------------- /test/sdl/operator-tests/operators.mr: -------------------------------------------------------------------------------- 1 | public node int => __piranha__int {} 2 | public node float => __piranha__float {} 3 | public node string => __piranha__string {} 4 | 5 | public inline node int_add => __piranha__int_add { 6 | input __in0; 7 | input __in1; 8 | alias output __out [int]; 9 | } 10 | 11 | public inline node float_add => __piranha__float_add { 12 | input __in0; 13 | input __in1; 14 | alias output __out [float]; 15 | } 16 | 17 | public inline node float_negate => __piranha__float_negate { 18 | input __in; 19 | alias output __out [float]; 20 | } 21 | 22 | public inline node string_add => __piranha__string_add { 23 | input __in0; 24 | input __in1; 25 | alias output __out [string]; 26 | } 27 | 28 | public inline node literal_string => __piranha__literal_string { 29 | alias output __out [string]; 30 | } 31 | 32 | public inline node literal_int => __piranha__literal_int { 33 | alias output __out [int]; 34 | } 35 | 36 | public inline node literal_float => __piranha__literal_float { 37 | alias output __out [float]; 38 | } 39 | -------------------------------------------------------------------------------- /test/sdl/optimization-tests/optimization_test_1.mr: -------------------------------------------------------------------------------- 1 | private import "../../../demos/piranha/standard-library/standard_library.mr" as std 2 | 3 | node container { 4 | input s; 5 | 6 | int_probe(s) 7 | } 8 | 9 | container( 10 | int_add(5, 4) 11 | ) 12 | -------------------------------------------------------------------------------- /test/sdl/optimization-tests/optimization_test_2.mr: -------------------------------------------------------------------------------- 1 | private import "../../../demos/piranha/standard-library/standard_library.mr" as std 2 | 3 | node container { 4 | input s; 5 | 6 | int_probe probe(s) 7 | } 8 | 9 | container( 10 | int_add(5 + 8, 4 + 4 / 2) 11 | ) 12 | -------------------------------------------------------------------------------- /test/sdl/optimization-tests/optimization_test_3.mr: -------------------------------------------------------------------------------- 1 | private import "../../../demos/piranha/standard-library/standard_library.mr" as std 2 | 3 | inline node test { 4 | input s; 5 | 6 | int_probe probe(s) 7 | } 8 | 9 | test(5) 10 | -------------------------------------------------------------------------------- /test/sdl/optimization-tests/optimization_test_4.mr: -------------------------------------------------------------------------------- 1 | private import "../../../demos/piranha/standard-library/standard_library.mr" as std 2 | 3 | node container { 4 | input s; 5 | 6 | int_probe probe(s) 7 | } 8 | 9 | node calculation { 10 | output d: int_add(5 + 8, 4 + 4 / 2); 11 | } 12 | 13 | container( 14 | calculation().d 15 | ) 16 | -------------------------------------------------------------------------------- /test/sdl/optimization-tests/optimization_test_5.mr: -------------------------------------------------------------------------------- 1 | private import "../../../demos/piranha/standard-library/standard_library.mr" as std 2 | 3 | node container { 4 | input s; 5 | output out: s.d; 6 | } 7 | 8 | node calculation { 9 | output d: int_add(5 + 8, 4 + 4 / 2); 10 | } 11 | 12 | container( 13 | calculation() 14 | ) 15 | -------------------------------------------------------------------------------- /test/sdl/optimization-tests/optimization_test_6.mr: -------------------------------------------------------------------------------- 1 | private import "../../../demos/piranha/standard-library/standard_library.mr" as std 2 | 3 | node container { 4 | input s; 5 | output out: s.d; 6 | } 7 | 8 | node calculation { 9 | output d: vector_add(vector(1, 2, 3, 4), vector(5, 6, 7, 8)); 10 | } 11 | 12 | container( 13 | calculation() 14 | ) 15 | -------------------------------------------------------------------------------- /test/sdl/optimization-tests/optimization_test_7.mr: -------------------------------------------------------------------------------- 1 | private import "../../../demos/piranha/standard-library/standard_library.mr" as std 2 | 3 | auto node test { 4 | output constant: 1; 5 | output d: constant + 2; 6 | } 7 | -------------------------------------------------------------------------------- /test/sdl/position_attribute_test.mr: -------------------------------------------------------------------------------- 1 | import attribute_definition_test 2 | 3 | TestNode positionalNode ( 4 | 5, 5 | 6, 6 | "kaboom" 7 | ) -------------------------------------------------------------------------------- /test/sdl/reference_resolution.mr: -------------------------------------------------------------------------------- 1 | private node ChildNode { 2 | input main_in; 3 | output main_out: main_in; 4 | } 5 | 6 | private node TestNode { 7 | input A; 8 | output B: childNode.main_out; 9 | output C: childNode; // Test the default behavior 10 | 11 | ChildNode childNode( 12 | main_in: A 13 | ) 14 | } 15 | 16 | TestNode testNodeInstance( 17 | A: "Hello World" 18 | ) 19 | -------------------------------------------------------------------------------- /test/sdl/resolution-tests/resolution_errors_1.mr: -------------------------------------------------------------------------------- 1 | private node ChildNode { 2 | input main_in; 3 | output main_out: main_in; 4 | } 5 | 6 | private node TestNode { 7 | input A; 8 | output B: childNode.main_out; 9 | output C: childNode; // Test the default behavior 10 | 11 | ChildNode childNode( 12 | main_in: A 13 | ) 14 | } 15 | 16 | private node NewNode { 17 | input test_in; 18 | output test_out: testNodeInstance; 19 | 20 | // Accessing internal members in this manner should fail 21 | output should_fail: myNode.childNode; // AccessingInternalMember 22 | output should_also_fail: nonsense; // UnresolvedReference 23 | output accessing_input: myNode.A; // This is okay 24 | output doesnt_exit: myNode.nonsense; // UndefinedMember 25 | 26 | TestNode myNode( 27 | A: "Hi" 28 | ) 29 | } 30 | 31 | TestNode testNodeInstance( 32 | A: "Hello World", 33 | A: "Boom" // ERROR 34 | ) 35 | -------------------------------------------------------------------------------- /test/sdl/resolution-tests/resolution_errors_2.mr: -------------------------------------------------------------------------------- 1 | private node EmptyNode { 2 | } 3 | 4 | private node ProblemNode { 5 | output test: 46; // SymbolUsedMultipleTimes 6 | 7 | FakeNode test( // SymbolUsedMultipleTimes, UndefinedNodeType 8 | fake_input: 50 9 | ) 10 | } 11 | 12 | ProblemNode same_name() // SymbolUsedMultipleTimes 13 | ProblemNode same_name() // SymbolUsedMultipleTimes 14 | 15 | private node GoodNode { 16 | input test; 17 | output test_out: test; 18 | } 19 | 20 | GoodNode okay_node( 21 | test: same_name 22 | ) 23 | 24 | GoodNode bad_node( 25 | test: some_type // UnresolvedReference 26 | ) 27 | 28 | GoodNode unconnected() // InputNotConnected 29 | 30 | private node NodeWithBadOutput { 31 | output boom; // OutputWithNoDefinition 32 | } 33 | 34 | private node BuiltinExample => BuiltinNode { 35 | // This works because this node defines the interface to 36 | // a built-in type 37 | output good [EmptyNode]; 38 | } 39 | 40 | private node BuiltinExampleBad => BuiltinNode { 41 | // This doesn't work because built-in nodes 42 | // can't have their outputs redefined 43 | output good: "boom"; // BuiltinOutputWithDefinition 44 | } 45 | 46 | GoodNode overdefinition( 47 | "positional input", // InputSpecifiedMultipleTimesPositional 48 | test: "non-positional input" // InputSpecifiedMultipleTimes 49 | ) 50 | -------------------------------------------------------------------------------- /test/sdl/runtime-tests/runtime_error_test.mr: -------------------------------------------------------------------------------- 1 | private import "../../../demos/piranha/standard-library/standard_library.mr" as std 2 | 3 | throw_runtime_error(true) 4 | throw_runtime_error(false) 5 | -------------------------------------------------------------------------------- /test/sdl/sample_lib/dependency_tree.mr: -------------------------------------------------------------------------------- 1 | private import example_dependency 2 | 3 | node NewNode1 { 4 | input A; 5 | output B: "Hello world"; 6 | } 7 | 8 | node NewNode2 { 9 | input A; 10 | output B: "Hello mars"; 11 | } 12 | -------------------------------------------------------------------------------- /test/sdl/sample_lib/example_dependency.mr: -------------------------------------------------------------------------------- 1 | public node FileImage { 2 | output Port: "Test"; 3 | } 4 | -------------------------------------------------------------------------------- /test/sdl/sample_lib/test_lib.mr: -------------------------------------------------------------------------------- 1 | module { 2 | @author: "Ange Yaghi" 3 | @date: "2019-06-11" 4 | } 5 | 6 | @author: "Ange Yaghi" 7 | @comment: "Hypothetical 'add' implementation" 8 | public node Add { 9 | input A; 10 | input B; 11 | alias output C: A + B; 12 | } 13 | 14 | @author: "Ange Yaghi" 15 | @comment: "This is just a test node" 16 | public node SampleNode { 17 | input A; 18 | input B; 19 | alias output C: add_mod; // This should take the default output 'C' 20 | 21 | Add add_mod(A, B) 22 | } 23 | -------------------------------------------------------------------------------- /test/sdl/single_empty_node.mr: -------------------------------------------------------------------------------- 1 | FileImage testImage () 2 | -------------------------------------------------------------------------------- /test/sdl/single_node_bool.mr: -------------------------------------------------------------------------------- 1 | ArbNode boolTestNode ( 2 | test_false: false, 3 | test_true: true 4 | ) // Test comment 5 | -------------------------------------------------------------------------------- /test/sdl/single_node_builtin.mr: -------------------------------------------------------------------------------- 1 | module { 2 | @author: "Ange Yaghi" 3 | @date: "2019-05-30" 4 | } 5 | 6 | private import "test.sdl" 7 | private import test 8 | 9 | /* Multiline test comment. 10 | * Second line. 11 | */ 12 | 13 | @author: "Ange Yaghi" 14 | @comment: "This is just a test node" 15 | "Check out this multiline comment" 16 | public node NewNode => BuiltinNode { 17 | // Inputs 18 | @doc: "Main input" 19 | alias input A; 20 | input B; 21 | 22 | // Outputs 23 | @doc: "Main output" 24 | alias output A_out; 25 | output B_out; 26 | } 27 | -------------------------------------------------------------------------------- /test/sdl/single_node_data_access.mr: -------------------------------------------------------------------------------- 1 | SampleNode node1( 2 | color: rgb(255, 255, 0xff).r, 3 | name: scene.file.name 4 | ) 5 | -------------------------------------------------------------------------------- /test/sdl/single_node_definition.mr: -------------------------------------------------------------------------------- 1 | module { 2 | @author: "Ange Yaghi" 3 | @date: "2019-05-30" 4 | } 5 | 6 | private import "test.sdl" 7 | private import test 8 | 9 | @author: "Ange Yaghi" 10 | @comment: "This is just a test node" 11 | public node NewNode { 12 | // Inputs 13 | @doc: "Main input" 14 | input A; 15 | input B; 16 | 17 | // Outputs 18 | @doc: "Main output" 19 | output A_out: A; 20 | output B_out: B; 21 | } 22 | -------------------------------------------------------------------------------- /test/sdl/single_node_import_statement.mr: -------------------------------------------------------------------------------- 1 | private import "test.sdl" 2 | private import test 3 | 4 | SampleNode node1 ( 5 | eq: a + (b / c) 6 | ) 7 | -------------------------------------------------------------------------------- /test/sdl/single_node_inline_node.mr: -------------------------------------------------------------------------------- 1 | FileImage testImage ( 2 | test1: test, 3 | test2: InlineNode(inline_attrib:test), 4 | test3: InlineNode2(test) 5 | ) 6 | -------------------------------------------------------------------------------- /test/sdl/single_node_simple_eq.mr: -------------------------------------------------------------------------------- 1 | SampleNode node1 ( 2 | eq: a + (b / c) 3 | ) 4 | -------------------------------------------------------------------------------- /test/sdl/single_node_single_attrib.mr: -------------------------------------------------------------------------------- 1 | FileImage testImage (test:test) // Test comment 2 | -------------------------------------------------------------------------------- /test/sdl/single_node_single_int.mr: -------------------------------------------------------------------------------- 1 | FileImage testImage ( 2 | test_dec: 10, 3 | test_hex_1: 0x10 4 | ) // Test comment 5 | -------------------------------------------------------------------------------- /test/sdl/single_node_string_attrib.mr: -------------------------------------------------------------------------------- 1 | FileImage testImage (test:"test") // Test comment 2 | -------------------------------------------------------------------------------- /test/sdl/single_node_two_attribs.mr: -------------------------------------------------------------------------------- 1 | FileImage testImage ( 2 | test1: test, 3 | test2: test 4 | ) 5 | -------------------------------------------------------------------------------- /test/sdl/single_node_vector_float.mr: -------------------------------------------------------------------------------- 1 | FileImage testImage ( 2 | test_float: float2(10.123, 15.456) 3 | ) // Test comment 4 | -------------------------------------------------------------------------------- /test/sdl/single_node_vector_int.mr: -------------------------------------------------------------------------------- 1 | FileImage testImage ( 2 | test_dec: int2(10, 15), 3 | test_hex_1: int2(0x10, 0xFf) 4 | ) // Test comment 5 | -------------------------------------------------------------------------------- /test/sdl/stress-testing/deep_error.mr: -------------------------------------------------------------------------------- 1 | private node test { 2 | input x; 3 | input y; 4 | 5 | output a: x; 6 | output b: y; 7 | } 8 | 9 | private node empty {} 10 | 11 | private node half_good { 12 | output b: 5; 13 | } 14 | 15 | private node even_harder { 16 | input v; 17 | output _v: v; 18 | } 19 | 20 | private node straight_through { 21 | input x; 22 | output a: x; 23 | } 24 | 25 | private node confusion { 26 | input some_input; 27 | output test: test(some_input.a, some_input.b); // Undefined member x3 28 | 29 | even_harder internal_node( 30 | empty() 31 | ) 32 | } 33 | 34 | private node top_confusion { 35 | input some_input; 36 | input other; 37 | output __out: 38 | confusion( 39 | straight_through(some_input) 40 | ); 41 | output __out2: confusion(other); 42 | } 43 | 44 | top_confusion test(5, 6) 45 | 46 | public node int_channel => __piranha__int {} 47 | public node literal_int => __piranha__literal_int { 48 | alias output __out [int_channel]; 49 | } 50 | 51 | public node float_channel => __piranha__float {} 52 | public node literal_float => __piranha__literal_float { 53 | alias output __out [float_channel]; 54 | } 55 | 56 | public node string_channel => __piranha__string {} 57 | public node literal_string => __piranha__literal_string { 58 | alias output __out [string_channel]; 59 | } 60 | -------------------------------------------------------------------------------- /test/sdl/stress-testing/deep_error_isolated.mr: -------------------------------------------------------------------------------- 1 | private node confusion { 2 | input some_input; 3 | output test: some_input.a; // Undefined member x2 4 | } 5 | 6 | private node top_confusion { 7 | input other; 8 | output __out2: confusion(other); 9 | } 10 | 11 | top_confusion test(5) 12 | 13 | public node int_channel => __piranha__int {} 14 | public node literal_int => __piranha__literal_int { 15 | alias output __out [int_channel]; 16 | } 17 | 18 | public node float_channel => __piranha__float {} 19 | public node literal_float => __piranha__literal_float { 20 | alias output __out [float_channel]; 21 | } 22 | 23 | public node string_channel => __piranha__string {} 24 | public node literal_string => __piranha__literal_string { 25 | alias output __out [string_channel]; 26 | } 27 | -------------------------------------------------------------------------------- /test/sdl/stress-testing/node_argument_stress_test_1.mr: -------------------------------------------------------------------------------- 1 | private node test { 2 | input x; 3 | input y; 4 | 5 | output a: x; 6 | output b: y; 7 | } 8 | 9 | private node empty {} 10 | 11 | private node half_good { 12 | output b: 5; 13 | } 14 | 15 | private node even_harder { 16 | input v; 17 | alias output _v: v; 18 | } 19 | 20 | private node confusion { 21 | input some_input; 22 | output test: test(some_input.a, some_input.b); // UndefinedMember x4 23 | output internal_test: internal_node.a; // UndefinedMember 24 | 25 | even_harder internal_node( 26 | empty() 27 | ) 28 | } 29 | 30 | // Should work 31 | confusion good( 32 | test(5, 5) 33 | ) 34 | 35 | // Should work 36 | confusion good_but_hard( 37 | even_harder( 38 | test(5, 5) 39 | ) 40 | ) 41 | 42 | // Shouldn't work 43 | confusion bad(empty()) 44 | 45 | // Should only cause one error 46 | confusion half_good(half_good()) 47 | 48 | // Should only cause one error 49 | confusion bad_and_hard( 50 | even_harder(half_good()) 51 | ) 52 | 53 | public node int_channel => __piranha__int {} 54 | public node literal_int => __piranha__literal_int { 55 | alias output __out [int_channel]; 56 | } 57 | 58 | public node float_channel => __piranha__float {} 59 | public node literal_float => __piranha__literal_float { 60 | alias output __out [float_channel]; 61 | } 62 | 63 | public node string_channel => __piranha__string {} 64 | public node literal_string => __piranha__literal_string { 65 | alias output __out [string_channel]; 66 | } 67 | -------------------------------------------------------------------------------- /test/sdl/stress-testing/stress_test_1.mr: -------------------------------------------------------------------------------- 1 | private node ExplicitDefault { 2 | input object; 3 | output object_default: object.hello_world; 4 | output object_default_pointer: object.hello_world; 5 | output object_reference: object; 6 | } 7 | 8 | private node HelloWorldNode { 9 | output hello_world: "Hello World"; 10 | } 11 | 12 | private node HelloWorldContainer { 13 | output hello_world: HelloWorldNode(); 14 | } 15 | 16 | private node float => some_builtin_float_class { 17 | input __in; 18 | } 19 | 20 | private node vector2d => some_builtin_vector_class { 21 | input __in_x: 0.0; 22 | input __in_y: 0.0; 23 | 24 | output x [float]; 25 | output y [::float]; 26 | } 27 | 28 | private node dual_vector { 29 | output output1: vector2d(0, 1); 30 | output output2: vector2d(1, 2); 31 | } 32 | 33 | private node confusion { 34 | output output1: local; 35 | output output2: 1.0; 36 | output vector_test: local_vector.x; 37 | 38 | dual_vector local() 39 | vector2d local_vector() 40 | } 41 | 42 | private node container { 43 | output output1: dual_vector(); 44 | output output2: confusion(); 45 | } 46 | 47 | container test_container() 48 | 49 | private node test { 50 | output test1: container.output1.output1.x; // UnresolvedReference 51 | output test2: container.output1.x; // UnresolvedReference 52 | output test3: container.output1.z; // UnresolvedReference 53 | 54 | output test4: test_container.output1.output1.x; // Okay 55 | output test5: test_container.output1.x; // UndefinedMember 56 | output test6: test_container.output1.z; // UndefinedMember 57 | 58 | output test7: internal_container.output1.output1.x; // Okay 59 | output test8: internal_container.output1.output1.x; // Okay 60 | output test9: internal_container.output1.z; // UndefinedMember 61 | 62 | output test16: hello_world_default.hello_world; // UndefinedMember 63 | output test17: hello_world_default.object_default.hello_world; // Okay 64 | output test19: hello_world_default.object_reference.hello_world; // Okay 65 | output test20: hello_world_default.object_reference.hello_world; // Okay 66 | output test21: hello_world_default.object_reference.hello_world; // Okay 67 | output test22: hello_world_default.object_reference.fake; // UndefinedMember 68 | 69 | container internal_container() 70 | HelloWorldContainer hello_world() 71 | ExplicitDefault hello_world_default(hello_world) 72 | } 73 | 74 | test test() 75 | 76 | public node int_channel => __piranha__int {} 77 | public node literal_int => __piranha__literal_int { 78 | alias output __out [int_channel]; 79 | } 80 | 81 | public node float_channel => __piranha__float {} 82 | public node literal_float => __piranha__literal_float { 83 | alias output __out [float_channel]; 84 | } 85 | 86 | public node string_channel => __piranha__string {} 87 | public node literal_string => __piranha__literal_string { 88 | alias output __out [string_channel]; 89 | } 90 | -------------------------------------------------------------------------------- /test/sdl/stress-testing/stress_test_1_isolated.mr: -------------------------------------------------------------------------------- 1 | private node ExplicitDefault { 2 | input object; 3 | default output object_default: object^.hello_world; 4 | output object_reference: object; 5 | } 6 | 7 | private node HelloWorldNode { 8 | input text; 9 | default output hello_world: text; 10 | } 11 | 12 | private node HelloWorldContainer { 13 | input text; 14 | default output hello_world: HelloWorldNode(text); 15 | } 16 | 17 | private node test { 18 | output test22: hello_world_default.object_reference->fake; // UndefinedMember 19 | 20 | HelloWorldContainer hello_world("Hello World") 21 | ExplicitDefault hello_world_default(hello_world) 22 | } 23 | 24 | test test() 25 | -------------------------------------------------------------------------------- /test/sdl/syntax_error.mr: -------------------------------------------------------------------------------- 1 | SampleNode node1( 2 | color: rgb(255, 255, 0xff).r ~, 3 | synax_err: test ~, 4 | name: scene.file.name 5 | ) technically_a_valid_token 6 | -------------------------------------------------------------------------------- /test/sdl/two_nodes.mr: -------------------------------------------------------------------------------- 1 | FileImage testImage ( 2 | test1: test, 3 | test2: test 4 | ) 5 | 6 | FileImage testImage2 ( 7 | test1: test, 8 | test2: test /* Test block comment */ 9 | ) 10 | -------------------------------------------------------------------------------- /test/sdl/visibility-tests/color.mr: -------------------------------------------------------------------------------- 1 | @doc: "Defines a basic color class" 2 | public node Color { 3 | input in_r: 0.0; 4 | input in_g: 0.0; 5 | input in_b: 0.0; 6 | 7 | output r: in_r; 8 | output g: in_g; 9 | output b: in_b; 10 | } 11 | -------------------------------------------------------------------------------- /test/sdl/visibility-tests/some_library.mr: -------------------------------------------------------------------------------- 1 | module { 2 | @doc: "This is intended to be a standard library of some sort" 3 | } 4 | 5 | private import color 6 | 7 | @doc: "Converts scalar quantity to a color" 8 | private node Converter { 9 | input s: 0.0; 10 | output rgb: color::Color(s, s, s); 11 | } 12 | 13 | @doc: "Simple node to generate gray" 14 | public node Gray { 15 | output rgb: ::Converter(0.5); 16 | } 17 | -------------------------------------------------------------------------------- /test/sdl/visibility-tests/visibility_test_1.mr: -------------------------------------------------------------------------------- 1 | private import some_library as lib 2 | 3 | lib::Color myColor() // UndefinedNodeType - Color is defined in a different module 4 | lib::Converter myConverter() // UndefinedNodeType 5 | ::Converter myOtherconverter() // UndefinedNodeType 6 | 7 | lib::Gray myGray() // No error 8 | ::Gray myOtherGray() // UndefinedNodeType 9 | Gray myOtherOtherGray() // No error 10 | -------------------------------------------------------------------------------- /test/sdl/visibility-tests/visibility_test_2.mr: -------------------------------------------------------------------------------- 1 | private import some_library as lib 2 | private import color 3 | 4 | @doc: "Define a new version of this same node name" 5 | private node Gray { 6 | input s: 0.5; 7 | output gray: color::Color(s, s, s) ; 8 | } 9 | 10 | private node Test { 11 | output testCase1: Gray().gray; // Okay 12 | output testCase2: Gray().rgb; // UndefinedMember 13 | output testCase3: Color(); // Okay 14 | output testCase4: ::Color(); // UndefinedNodeType 15 | output testCase5: lib::Gray().rgb; // Okay 16 | output testCase6: lib::Gray().gray; // UndefinedMember 17 | } 18 | -------------------------------------------------------------------------------- /test/test_rules.h: -------------------------------------------------------------------------------- 1 | #ifndef TEST_GENERATOR_H 2 | #define TEST_GENERATOR_H 3 | 4 | #include "../include/language_rules.h" 5 | 6 | class TestRules : public piranha::LanguageRules { 7 | public: 8 | TestRules(); 9 | ~TestRules(); 10 | 11 | protected: 12 | virtual void registerBuiltinNodeTypes(); 13 | }; 14 | 15 | #endif /* TEST_GENERATOR_H */ 16 | -------------------------------------------------------------------------------- /test/utilities.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "test_rules.h" 4 | #include "utilities.h" 5 | 6 | #include "../include/compilation_error.h" 7 | #include "../include/error_list.h" 8 | #include "../include/compiler.h" 9 | 10 | bool findError(const ErrorList *errorList, const ErrorCode_struct &errorCode, int line, 11 | const IrCompilationUnit *unit, bool instantiationError) { 12 | int errorCount = errorList->getErrorCount(); 13 | 14 | for (int i = 0; i < errorCount; i++) { 15 | CompilationError *error = errorList->getCompilationError(i); 16 | if (unit == nullptr || error->getCompilationUnit() == unit) { 17 | if (error->getErrorCode().code == errorCode.code && error->getErrorCode().stage == errorCode.stage) { 18 | if (line == -1 || error->getErrorLocation()->lineStart == line) { 19 | if (error->isInstantiationError() == instantiationError) { 20 | return true; 21 | } 22 | } 23 | } 24 | } 25 | } 26 | 27 | return false; 28 | } 29 | 30 | IrCompilationUnit *compileFile(const std::string &filename, const ErrorList **errList, LanguageRules **outputRules, Compiler **_compiler) { 31 | TestRules *rules = new TestRules(); 32 | rules->initialize(); 33 | 34 | piranha::Compiler *compiler = new Compiler(rules); 35 | IrCompilationUnit *unit = compiler->compile(IR_TEST_FILES + filename); 36 | EXPECT_NE(unit, nullptr); 37 | 38 | if (errList != nullptr) *errList = compiler->getErrorList(); 39 | if (_compiler != nullptr) *_compiler = compiler; 40 | if (outputRules != nullptr) *outputRules = rules; 41 | else delete rules; 42 | 43 | return unit; 44 | } 45 | 46 | IrCompilationUnit *compileToUnit( 47 | const std::string &filename, const ErrorList **errList, 48 | LanguageRules **outputRules, Compiler **_compiler) 49 | { 50 | TestRules *rules = new TestRules(); 51 | rules->initialize(); 52 | 53 | Compiler *compiler = new Compiler(rules); 54 | 55 | IrCompilationUnit *unit = compiler->compile(IR_TEST_FILES + filename); 56 | EXPECT_NE(unit, nullptr); 57 | 58 | if (errList != nullptr) *errList = compiler->getErrorList(); 59 | if (outputRules != nullptr) *outputRules = rules; 60 | else delete rules; 61 | 62 | if (_compiler != nullptr) *_compiler = compiler; 63 | else { 64 | compiler->free(); 65 | delete compiler; 66 | } 67 | 68 | return unit; 69 | } 70 | -------------------------------------------------------------------------------- /test/utilities.h: -------------------------------------------------------------------------------- 1 | #ifndef TEST_UTILITIES_H 2 | #define TEST_UTILITIES_H 3 | 4 | #include "../include/error_list.h" 5 | #include "../include/compilation_error.h" 6 | #include "../include/compiler.h" 7 | 8 | #include 9 | 10 | using namespace piranha; 11 | 12 | #define CMF_PATH "../../demos/cmfs/" 13 | #define WORKSPACE_PATH "../../workspace/" 14 | #define TMP_PATH (WORKSPACE_PATH "tmp/") 15 | #define IR_TEST_FILES "../../test/sdl/" 16 | 17 | #define CHECK_IR_POS(IrParserStructure, _colStart, _colEnd, _lineStart, _lineEnd) \ 18 | EXPECT_EQ((IrParserStructure)->getSummaryToken()->colStart, (_colStart)); \ 19 | EXPECT_EQ((IrParserStructure)->getSummaryToken()->colEnd, (_colEnd)); \ 20 | EXPECT_EQ((IrParserStructure)->getSummaryToken()->lineStart, (_lineStart)); \ 21 | EXPECT_EQ((IrParserStructure)->getSummaryToken()->lineEnd, (_lineEnd)); 22 | 23 | #define EXPECT_ERROR_CODE(error, code_) \ 24 | EXPECT_EQ((error)->getErrorCode().stage, code_.stage); \ 25 | EXPECT_EQ((error)->getErrorCode().code, code_.code); 26 | 27 | #define EXPECT_ERROR_CODE_LINE(error, code_, line) \ 28 | EXPECT_EQ((error)->getErrorCode().stage, code_.stage); \ 29 | EXPECT_EQ((error)->getErrorCode().code, code_.code); \ 30 | EXPECT_EQ((error)->getErrorLocation()->lineStart, line); 31 | 32 | bool findError(const ErrorList *errorList, const ErrorCode_struct &errorCode, 33 | int line = -1, const IrCompilationUnit *unit = nullptr, bool instantiationError = false); 34 | 35 | IrCompilationUnit *compileFile( 36 | const std::string &filename, const ErrorList **errList = nullptr, 37 | LanguageRules **outputRules = nullptr, Compiler **compiler = nullptr); 38 | IrCompilationUnit *compileToUnit( 39 | const std::string &filename, const ErrorList **errList = nullptr, 40 | LanguageRules **outputRules = nullptr, Compiler **compiler = nullptr); 41 | 42 | #endif /* TEST_UTILITIES_H */ 43 | -------------------------------------------------------------------------------- /utilities/src/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | int main() { 11 | std::string fname; 12 | 13 | std::cout << "Enter filename: "; 14 | std::cin >> fname; 15 | 16 | manta::RawFile rawFile; 17 | manta::ImagePlane sceneBuffer; 18 | bool result = rawFile.readRawFile(fname.c_str(), &sceneBuffer); 19 | 20 | if (!result) { 21 | std::cout << "Failed to open file" << std::endl; 22 | return 0; 23 | } 24 | 25 | std::cout << "Width: " << sceneBuffer.getWidth() << std::endl; 26 | std::cout << "Height: " << sceneBuffer.getHeight() << std::endl; 27 | std::cout << "Max: " << sceneBuffer.getMax() << std::endl; 28 | std::cout << "Min: " << sceneBuffer.getMin() << std::endl; 29 | 30 | // Remove the file extension 31 | for (int i = (int)fname.length(); i >= 0; i--) { 32 | if (fname[i] == '.') { 33 | fname = fname.substr(0, i); 34 | } 35 | } 36 | 37 | manta::ImagePlane temp; 38 | temp.copyFrom(&sceneBuffer); 39 | manta::ImagePlane prev; 40 | 41 | bool prevValid = false; 42 | int iteration = 0; 43 | 44 | // Editing loop 45 | bool done = false; 46 | while (!done) { 47 | std::string command; 48 | std::cout << "-------------------------------" << std::endl; 49 | std::cout << "Command: "; 50 | std::cin >> command; 51 | 52 | bool write = false; 53 | if (command == "scale" || command == "s") { 54 | manta::math::real scale; 55 | std::cout << "Scale factor: "; 56 | std::cin >> scale; 57 | 58 | temp.scale(scale); 59 | 60 | write = true; 61 | } 62 | else if (command == "undo" || command == "u") { 63 | if (prevValid) { 64 | temp.destroy(); 65 | temp.copyFrom(&prev); 66 | write = true; 67 | } 68 | else { 69 | std::cout << "Nothing to undo" << std::endl; 70 | } 71 | } 72 | else if (command == "gamma" || command == "g") { 73 | manta::math::real gamma_div, gamma_num; 74 | std::cout << "Scale factor: " << std::endl; 75 | std::cout << " Num: "; 76 | std::cin >> gamma_num; 77 | std::cout << " Div: "; 78 | std::cin >> gamma_div; 79 | 80 | temp.applyGammaCurve(gamma_num / gamma_div); 81 | 82 | write = true; 83 | } 84 | else if (command == "reset" || command == "r") { 85 | if (temp.isInitialized()) temp.destroy(); 86 | temp.copyFrom(&sceneBuffer); 87 | write = true; 88 | } 89 | else if (command == "quit" || command == "q") { 90 | write = false; 91 | done = true; 92 | } 93 | 94 | if (write) { 95 | prev.copyFrom(&temp); 96 | prevValid = true; 97 | 98 | std::stringstream ss; 99 | ss << "_E" << iteration; 100 | 101 | manta::SaveImageData(temp.getBuffer(), temp.getWidth(), temp.getHeight(), (fname + ss.str() + ".bmp").c_str()); 102 | 103 | iteration++; 104 | } 105 | } 106 | 107 | if (temp.isInitialized()) temp.destroy(); 108 | if (prev.isInitialized()) prev.destroy(); 109 | if (sceneBuffer.isInitialized()) sceneBuffer.destroy(); 110 | 111 | return 0; 112 | } 113 | --------------------------------------------------------------------------------