cauldron 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.document +5 -0
- data/Gemfile +13 -0
- data/LICENSE.txt +20 -0
- data/README +1 -0
- data/README.rdoc +19 -0
- data/Rakefile +53 -0
- data/VERSION +1 -0
- data/bin/cauldron +10 -0
- data/cauldron/.autotest +23 -0
- data/cauldron/History.txt +6 -0
- data/cauldron/Manifest.txt +8 -0
- data/cauldron/README.txt +57 -0
- data/cauldron/Rakefile +27 -0
- data/cauldron/bin/cauldron +3 -0
- data/cauldron/lib/cauldron.rb +3 -0
- data/cauldron/test/test_cauldron.rb +8 -0
- data/features/cauldron_example_cases.feature +13 -0
- data/features/cauldron_generates_runtime_method.feature +12 -0
- data/features/cauldron_start_terminal.feature +13 -0
- data/features/step_definitions/cauldron_steps.rb +16 -0
- data/features/step_definitions/terminal_steps.rb +34 -0
- data/features/support/env.rb +19 -0
- data/lib/Chain.rb +879 -0
- data/lib/ChainMapping.rb +172 -0
- data/lib/CodeHandler.rb +517 -0
- data/lib/Mapping.rb +26 -0
- data/lib/MappingValues.rb +24 -0
- data/lib/ScopeDependencies.rb +7 -0
- data/lib/Theory.rb +274 -0
- data/lib/UnifiedChain.rb +110 -0
- data/lib/cauldron.rb +6 -0
- data/lib/cauldron/conversion.rb +15 -0
- data/lib/cauldron/pot.rb +134 -0
- data/lib/cauldron/sexp2cauldron.rb +156 -0
- data/lib/cauldron/terminal.rb +120 -0
- data/lib/cauldron/theory_factory.rb +10 -0
- data/lib/core/ActsAsCode.rb +25 -0
- data/lib/core/BlockToken.rb +33 -0
- data/lib/core/CCall.rb +7 -0
- data/lib/core/CTestCase.rb +27 -0
- data/lib/core/ClassMethodCallContainer.rb +45 -0
- data/lib/core/Container.rb +85 -0
- data/lib/core/InstanceCallContainer.rb +272 -0
- data/lib/core/MethodUsage.rb +66 -0
- data/lib/core/PrintVariables.rb +25 -0
- data/lib/core/TheoryGenerator.rb +764 -0
- data/lib/core/Token.rb +7 -0
- data/lib/core/assignment/Assignment.rb +18 -0
- data/lib/core/assignment/Equal.rb +39 -0
- data/lib/core/assignment/Equivalent.rb +20 -0
- data/lib/core/assignment/NotEqual.rb +14 -0
- data/lib/core/call_container/CallContainer.rb +66 -0
- data/lib/core/class_method_call/New.rb +15 -0
- data/lib/core/class_method_call/RuntimeClassMethodCall.rb +31 -0
- data/lib/core/declaration/Declaration.rb +16 -0
- data/lib/core/declaration/LiteralDeclaration.rb +47 -0
- data/lib/core/declaration/VariableDeclaration.rb +59 -0
- data/lib/core/instance_call/ArrayEach.rb +23 -0
- data/lib/core/instance_call/ArrayLength.rb +15 -0
- data/lib/core/instance_call/Chop.rb +28 -0
- data/lib/core/instance_call/Copy.rb +22 -0
- data/lib/core/instance_call/DeclaredVariable.rb +18 -0
- data/lib/core/instance_call/InstanceCall.rb +77 -0
- data/lib/core/instance_call/Params.rb +15 -0
- data/lib/core/instance_call/Push.rb +20 -0
- data/lib/core/instance_call/StringLength.rb +32 -0
- data/lib/core/instance_call/Times.rb +20 -0
- data/lib/core/instance_call/instance_calls.rb +168 -0
- data/lib/core/instance_call/length_equal.rb +15 -0
- data/lib/core/kernal/EvalCall.rb +15 -0
- data/lib/core/kernal/LocalVariablesCall.rb +15 -0
- data/lib/core/literal/Literal.rb +111 -0
- data/lib/core/literal/Raw.rb +23 -0
- data/lib/core/literal/RuntimeMethodLiteral.rb +21 -0
- data/lib/core/literal/StatementLiteral.rb +28 -0
- data/lib/core/method_call/AvailableVariablesCall.rb +25 -0
- data/lib/core/method_call/ClassCall.rb +33 -0
- data/lib/core/method_call/DefCall.rb +72 -0
- data/lib/core/method_call/EvaluateClassCall.rb +29 -0
- data/lib/core/method_call/MethodNameCall.rb +27 -0
- data/lib/core/method_call/ToDeclarationCall.rb +15 -0
- data/lib/core/requirement/Requirement.rb +291 -0
- data/lib/core/runtime_class/ArrayClass.rb +19 -0
- data/lib/core/runtime_class/ClassCallClass.rb +23 -0
- data/lib/core/runtime_class/ClassEvaluationClass.rb +19 -0
- data/lib/core/runtime_class/ClassName.rb +18 -0
- data/lib/core/runtime_class/DefCallClass.rb +21 -0
- data/lib/core/runtime_class/EqualClass.rb +19 -0
- data/lib/core/runtime_class/FixnumClass.rb +15 -0
- data/lib/core/runtime_class/IfStatementClass.rb +12 -0
- data/lib/core/runtime_class/InstanceCallClass.rb +19 -0
- data/lib/core/runtime_class/InstanceCallContainerClass.rb +16 -0
- data/lib/core/runtime_class/InstanceClassCallClass.rb +19 -0
- data/lib/core/runtime_class/LiteralClass.rb +19 -0
- data/lib/core/runtime_class/MethodParameterClass.rb +27 -0
- data/lib/core/runtime_class/MethodUsageClass.rb +27 -0
- data/lib/core/runtime_class/RequirementClass.rb +19 -0
- data/lib/core/runtime_class/ReturnClass.rb +21 -0
- data/lib/core/runtime_class/RuntimeClass.rb +30 -0
- data/lib/core/runtime_class/RuntimeClassClass.rb +19 -0
- data/lib/core/runtime_class/RuntimeMethodClass.rb +34 -0
- data/lib/core/runtime_class/StatementClass.rb +53 -0
- data/lib/core/runtime_class/StringClass.rb +23 -0
- data/lib/core/runtime_class/StringLengthClass.rb +19 -0
- data/lib/core/runtime_class/StringVariableClass.rb +19 -0
- data/lib/core/runtime_class/ThisClass.rb +15 -0
- data/lib/core/runtime_class/UnknownClass.rb +23 -0
- data/lib/core/runtime_class/class_names.rb +95 -0
- data/lib/core/runtime_class/runtime_class.rb +123 -0
- data/lib/core/runtime_method/ActsAsRuntimeMethod.rb +300 -0
- data/lib/core/runtime_method/ParametersContainer.rb +29 -0
- data/lib/core/runtime_method/RealisedRuntimeMethod.rb +94 -0
- data/lib/core/runtime_method/RuntimeMethod.rb +817 -0
- data/lib/core/runtime_method/WriteParameters.rb +35 -0
- data/lib/core/statement/ActsAsStatement.rb +116 -0
- data/lib/core/statement/ArrayAccess.rb +96 -0
- data/lib/core/statement/BlockStatement.rb +348 -0
- data/lib/core/statement/DeclarationStatement.rb +19 -0
- data/lib/core/statement/HackStatement.rb +25 -0
- data/lib/core/statement/HashAccess.rb +18 -0
- data/lib/core/statement/OpenStatement.rb +171 -0
- data/lib/core/statement/RealisedStatement.rb +5 -0
- data/lib/core/statement/SingleLineBlockStatement.rb +39 -0
- data/lib/core/statement/Statement.rb +1223 -0
- data/lib/core/statement/StatementDependencies.rb +271 -0
- data/lib/core/statement/StatementGroup.rb +157 -0
- data/lib/core/statement/StatementStructure2.rb +224 -0
- data/lib/core/statement/TheoryStatement.rb +60 -0
- data/lib/core/statement/TopologicalStatements.rb +34 -0
- data/lib/core/structure/DeclareNewInstanceStructure.rb +49 -0
- data/lib/core/structure/DeclareRuntimeMethodStructure.rb +34 -0
- data/lib/core/structure/DeclareVariableAsLiteralStructure.rb +31 -0
- data/lib/core/structure/DeclareVariableAsVariableStructure.rb +52 -0
- data/lib/core/structure/FixnumAdditionStructure.rb +56 -0
- data/lib/core/structure/InstanceCallContainerStructure.rb +50 -0
- data/lib/core/structure/InstanceCallStructure.rb +53 -0
- data/lib/core/structure/InstanceMethodCallStructure.rb +21 -0
- data/lib/core/structure/ReturnStructure.rb +20 -0
- data/lib/core/structure/StatementStructure.rb +11 -0
- data/lib/core/syntax/Addition.rb +25 -0
- data/lib/core/syntax/BlockContainer.rb +130 -0
- data/lib/core/syntax/Boolean.rb +15 -0
- data/lib/core/syntax/Code.rb +11 -0
- data/lib/core/syntax/Do.rb +20 -0
- data/lib/core/syntax/False.rb +12 -0
- data/lib/core/syntax/If.rb +28 -0
- data/lib/core/syntax/IfContainer.rb +100 -0
- data/lib/core/syntax/Nil.rb +15 -0
- data/lib/core/syntax/Return.rb +33 -0
- data/lib/core/syntax/Subtract.rb +19 -0
- data/lib/core/syntax/This.rb +40 -0
- data/lib/core/syntax/True.rb +20 -0
- data/lib/core/syntax/syntax.rb +24 -0
- data/lib/core/tracking/ActsAsTrackable.rb +65 -0
- data/lib/core/tracking/History.rb +167 -0
- data/lib/core/tracking/RuntimeTrackingMethod.rb +32 -0
- data/lib/core/tracking/Step.rb +52 -0
- data/lib/core/variable/ArrayVariable.rb +76 -0
- data/lib/core/variable/BaseVariable.rb +154 -0
- data/lib/core/variable/BlockVariable.rb +92 -0
- data/lib/core/variable/FixnumVariable.rb +36 -0
- data/lib/core/variable/HistoryVariable.rb +8 -0
- data/lib/core/variable/MethodParameter.rb +206 -0
- data/lib/core/variable/MethodUsageVariable.rb +60 -0
- data/lib/core/variable/NilVariable.rb +29 -0
- data/lib/core/variable/RuntimeMethodParameter.rb +67 -0
- data/lib/core/variable/StatementVariable.rb +72 -0
- data/lib/core/variable/StepVariable.rb +7 -0
- data/lib/core/variable/StringVariable.rb +46 -0
- data/lib/core/variable/TypeVariable.rb +72 -0
- data/lib/core/variable/Unknown.rb +116 -0
- data/lib/core/variable/UnknownVariable.rb +29 -0
- data/lib/core/variable/Variable.rb +70 -0
- data/lib/core/variable/VariableContainer.rb +28 -0
- data/lib/core/variable/VariableIncluded.rb +27 -0
- data/lib/core/variable/VariableReference.rb +85 -0
- data/lib/error/FailedToFindStatementContainerError.rb +7 -0
- data/lib/error/FailedToFindStatementError.rb +7 -0
- data/lib/error/FailedToFindVariableError.rb +7 -0
- data/lib/error/FailedToLiteraliseError.rb +7 -0
- data/lib/error/FailedVariableMatch.rb +7 -0
- data/lib/error/ImproperStatementUsageError.rb +7 -0
- data/lib/error/IncompatiableRequirementsError.rb +7 -0
- data/lib/error/InvalidStatementError.rb +7 -0
- data/lib/error/MethodSizeError.rb +7 -0
- data/lib/error/RuntimeSyntaxError.rb +7 -0
- data/lib/error/UnexpectedStatementTypeError.rb +7 -0
- data/lib/error/UnknownStatementType.rb +7 -0
- data/lib/error/UnliteralisableError.rb +7 -0
- data/lib/implemented_chain.rb +34 -0
- data/lib/intrinsic/IntrinsicLastRuntimeMethod.rb +20 -0
- data/lib/intrinsic/IntrinsicLiteral.rb +26 -0
- data/lib/intrinsic/IntrinsicObject.rb +22 -0
- data/lib/intrinsic/IntrinsicRuntimeMethod.rb +27 -0
- data/lib/intrinsic/IntrinsicTestCases.rb +17 -0
- data/lib/logger/StandardLogger.rb +62 -0
- data/lib/required.rb +236 -0
- data/lib/ruby_code/Array.rb +95 -0
- data/lib/ruby_code/Fixnum.rb +39 -0
- data/lib/ruby_code/Hash.rb +25 -0
- data/lib/ruby_code/NilClass.rb +19 -0
- data/lib/ruby_code/Object.rb +24 -0
- data/lib/ruby_code/String.rb +86 -0
- data/lib/ruby_code/Symbol.rb +7 -0
- data/lib/standard_library/Tasks.rb +12 -0
- data/lib/theories.rb +143 -0
- data/lib/theory/ActionImplementation.rb +17 -0
- data/lib/theory/TheoryAction.rb +70 -0
- data/lib/theory/TheoryChainValidator.rb +101 -0
- data/lib/theory/TheoryComponent.rb +42 -0
- data/lib/theory/TheoryConnector.rb +755 -0
- data/lib/theory/TheoryDependent.rb +135 -0
- data/lib/theory/TheoryImplementation.rb +74 -0
- data/lib/theory/TheoryResult.rb +131 -0
- data/lib/theory/TheoryVariable.rb +63 -0
- data/lib/theory/theory_collection.rb +62 -0
- data/lib/util/ClassEvaluation.rb +68 -0
- data/lib/util/CodeEvaluation.rb +35 -0
- data/lib/util/DeclarationStatementEvaluation.rb +31 -0
- data/lib/util/MethodEvaluation.rb +49 -0
- data/lib/util/MethodTester.rb +71 -0
- data/lib/util/MethodValidation.rb +145 -0
- data/lib/util/MethodWriter.rb +66 -0
- data/lib/util/Parser.rb +299 -0
- data/lib/util/StatementCheck.rb +42 -0
- data/lib/util/StringToTheory.rb +119 -0
- data/lib/util/System.rb +8 -0
- data/spec/cauldron/pot_spec.rb +6 -0
- data/spec/cauldron/runtime_method_spec.rb +36 -0
- data/spec/cauldron/sexp_2_cauldron_spec.rb +26 -0
- data/spec/cauldron/terminal_spec.rb +38 -0
- data/spec/cauldron/theory_action_spec.rb +5 -0
- data/spec/spec_helper.rb +4 -0
- data/test/fixtures/chains/1/declaration.txt +26 -0
- data/test/fixtures/chains/1/dump +0 -0
- data/test/fixtures/chains/2/declaration.txt +26 -0
- data/test/fixtures/chains/2/dump +0 -0
- data/test/fixtures/chains/3/declaration.txt +26 -0
- data/test/fixtures/chains/3/dump +0 -0
- data/test/fixtures/implementation_results/0/declaration.txt +3 -0
- data/test/fixtures/implementation_results/0/dump +0 -0
- data/test/fixtures/theories/0/declaration.txt +9 -0
- data/test/fixtures/theories/0/desc +10 -0
- data/test/fixtures/theories/0/dump +0 -0
- data/test/fixtures/theories/1/declaration.txt +15 -0
- data/test/fixtures/theories/1/desc +11 -0
- data/test/fixtures/theories/1/dump +0 -0
- data/test/fixtures/theories/10/declaration.txt +23 -0
- data/test/fixtures/theories/10/desc +17 -0
- data/test/fixtures/theories/10/dump +0 -0
- data/test/fixtures/theories/11/declaration.txt +20 -0
- data/test/fixtures/theories/11/desc +14 -0
- data/test/fixtures/theories/11/dump +0 -0
- data/test/fixtures/theories/12/declaration.txt +18 -0
- data/test/fixtures/theories/12/desc +12 -0
- data/test/fixtures/theories/12/dump +0 -0
- data/test/fixtures/theories/13/declaration.txt +24 -0
- data/test/fixtures/theories/13/desc +20 -0
- data/test/fixtures/theories/13/dump +0 -0
- data/test/fixtures/theories/14/declaration.txt +26 -0
- data/test/fixtures/theories/14/desc +20 -0
- data/test/fixtures/theories/14/dump +0 -0
- data/test/fixtures/theories/15/declaration.txt +20 -0
- data/test/fixtures/theories/15/desc +14 -0
- data/test/fixtures/theories/15/dump +0 -0
- data/test/fixtures/theories/16/declaration.txt +30 -0
- data/test/fixtures/theories/16/desc +14 -0
- data/test/fixtures/theories/16/dump +0 -0
- data/test/fixtures/theories/17/declaration.txt +25 -0
- data/test/fixtures/theories/17/desc +11 -0
- data/test/fixtures/theories/17/dump +0 -0
- data/test/fixtures/theories/18/declaration.txt +23 -0
- data/test/fixtures/theories/18/desc +11 -0
- data/test/fixtures/theories/18/dump +0 -0
- data/test/fixtures/theories/19/declaration.txt +23 -0
- data/test/fixtures/theories/19/desc +11 -0
- data/test/fixtures/theories/19/dump +0 -0
- data/test/fixtures/theories/2/declaration.txt +12 -0
- data/test/fixtures/theories/2/desc +10 -0
- data/test/fixtures/theories/2/dump +0 -0
- data/test/fixtures/theories/20/declaration.txt +23 -0
- data/test/fixtures/theories/20/desc +17 -0
- data/test/fixtures/theories/20/dump +0 -0
- data/test/fixtures/theories/3/declaration.txt +19 -0
- data/test/fixtures/theories/3/desc +11 -0
- data/test/fixtures/theories/3/dump +0 -0
- data/test/fixtures/theories/4/declaration.txt +11 -0
- data/test/fixtures/theories/4/desc +11 -0
- data/test/fixtures/theories/4/dump +0 -0
- data/test/fixtures/theories/5/declaration.txt +6 -0
- data/test/fixtures/theories/5/desc +9 -0
- data/test/fixtures/theories/5/dump +0 -0
- data/test/fixtures/theories/6/declaration.txt +13 -0
- data/test/fixtures/theories/6/desc +11 -0
- data/test/fixtures/theories/6/dump +0 -0
- data/test/fixtures/theories/7/declaration.txt +19 -0
- data/test/fixtures/theories/7/desc +11 -0
- data/test/fixtures/theories/7/dump +0 -0
- data/test/fixtures/theories/8/declaration.txt +21 -0
- data/test/fixtures/theories/8/desc +11 -0
- data/test/fixtures/theories/8/dump +0 -0
- data/test/fixtures/theories/9/declaration.txt +24 -0
- data/test/fixtures/theories/9/desc +20 -0
- data/test/fixtures/theories/9/dump +0 -0
- data/test/fixtures/theory_implementations/0/declaration.txt +11 -0
- data/test/fixtures/theory_implementations/0/desc.txt +9 -0
- data/test/fixtures/theory_implementations/0/dump +0 -0
- data/test/fixtures/theory_implementations/0/theory_id +1 -0
- data/test/fixtures/theory_implementations/1/desc.txt +9 -0
- data/test/fixtures/theory_implementations/1/dump +0 -0
- data/test/fixtures/theory_implementations/1/theory_id +1 -0
- data/test/fixtures/theory_implementations/2/desc.txt +9 -0
- data/test/fixtures/theory_implementations/2/dump +0 -0
- data/test/fixtures/theory_implementations/2/theory_id +1 -0
- data/test/output/simple_method.txt +6 -0
- data/test/output/test_method/first_possible_method.txt +6 -0
- data/test/output/test_simple_cases/simple_case_01.txt +8 -0
- data/test/output/test_simple_cases/simple_case_02.txt +7 -0
- data/test/output/test_simple_cases/simple_case_03.txt +8 -0
- data/test/output/test_simple_cases/simple_case_04.txt +8 -0
- data/test/output/test_simple_cases/simple_case_05.txt +8 -0
- data/test/output/test_simple_cases/simple_case_06.txt +9 -0
- data/test/output/test_simple_cases/simple_case_07.txt +9 -0
- data/test/output/test_simple_cases/simple_case_08.txt +9 -0
- data/test/tc_contextual_variables.rb +87 -0
- data/test/tc_describe.rb +47 -0
- data/test/tc_method.rb +133 -0
- data/test/tc_requirement.rb +30 -0
- data/test/tc_suite_complete.rb +26 -0
- data/test/tc_variable.rb +52 -0
- data/test/ts_complete.rb +84 -0
- data/test/ts_stable.rb +81 -0
- data/test/unit/core/declaration/tc_literal_declaration.rb +34 -0
- data/test/unit/core/method_call/tc_class_call.rb +20 -0
- data/test/unit/core/runtime_method/tc_realised_runtime_method.rb +129 -0
- data/test/unit/core/runtime_method/tc_runtime_method.rb +616 -0
- data/test/unit/core/statement/tc_array_access.rb +63 -0
- data/test/unit/core/statement/tc_block_statement.rb +51 -0
- data/test/unit/core/statement/tc_hack_statement.rb +26 -0
- data/test/unit/core/statement/tc_open_statement.rb +70 -0
- data/test/unit/core/statement/tc_statement.rb +681 -0
- data/test/unit/core/statement/tc_statement_dependencies.rb +146 -0
- data/test/unit/core/statement/tc_statement_group.rb +35 -0
- data/test/unit/core/statement/tc_statement_replace_variable.rb +61 -0
- data/test/unit/core/statement/tc_theory_statement.rb +51 -0
- data/test/unit/core/structure/tc_declare_new_instance_structure.rb +41 -0
- data/test/unit/core/structure/tc_declare_variable_as_literal_structure.rb +41 -0
- data/test/unit/core/structure/tc_declare_variable_as_variable_structure.rb +66 -0
- data/test/unit/core/structure/tc_instance_call_container_structure.rb +41 -0
- data/test/unit/core/structure/tc_return_structure.rb +32 -0
- data/test/unit/core/syntax/tc_block_container.rb +32 -0
- data/test/unit/core/syntax/tc_if_container.rb +39 -0
- data/test/unit/core/tc_class_method_call.rb +34 -0
- data/test/unit/core/tc_container.rb +41 -0
- data/test/unit/core/tc_ctest_case.rb +25 -0
- data/test/unit/core/tc_instance_call_container.rb +93 -0
- data/test/unit/core/tc_literal.rb +30 -0
- data/test/unit/core/tc_theory_generator.rb +336 -0
- data/test/unit/core/tc_theory_generator_heavy.rb +42 -0
- data/test/unit/core/tracking/tc_history.rb +102 -0
- data/test/unit/core/tracking/tc_step.rb +65 -0
- data/test/unit/core/variable/tc_array_variable.rb +61 -0
- data/test/unit/core/variable/tc_block_variable.rb +17 -0
- data/test/unit/core/variable/tc_fixnum_variable.rb +54 -0
- data/test/unit/core/variable/tc_method_parameter_variable.rb +22 -0
- data/test/unit/core/variable/tc_runtime_method_variable.rb +32 -0
- data/test/unit/core/variable/tc_string_variable.rb +37 -0
- data/test/unit/core/variable/tc_unknown.rb +24 -0
- data/test/unit/core/variable/tc_variable_reference.rb +28 -0
- data/test/unit/ruby_code/tc_array.rb +64 -0
- data/test/unit/ruby_code/tc_fixnum.rb +18 -0
- data/test/unit/ruby_code/tc_hash.rb +41 -0
- data/test/unit/ruby_code/tc_string.rb +38 -0
- data/test/unit/tc_chain.rb +434 -0
- data/test/unit/tc_chain_mapping.rb +62 -0
- data/test/unit/tc_chain_with_case_1.rb +169 -0
- data/test/unit/tc_instance_call.rb +40 -0
- data/test/unit/tc_instance_call_structure.rb +35 -0
- data/test/unit/tc_method_usage.rb +35 -0
- data/test/unit/tc_pot.rb +124 -0
- data/test/unit/tc_runtime_tracking_method.rb +40 -0
- data/test/unit/tc_statement_structure_2.rb +43 -0
- data/test/unit/tc_theory.rb +533 -0
- data/test/unit/tc_variable_declaration.rb +32 -0
- data/test/unit/theory/tc_theory_action.rb +80 -0
- data/test/unit/theory/tc_theory_action_implementation.rb +23 -0
- data/test/unit/theory/tc_theory_chain_validator.rb +340 -0
- data/test/unit/theory/tc_theory_connector.rb +396 -0
- data/test/unit/theory/tc_theory_dependent.rb +151 -0
- data/test/unit/theory/tc_theory_implementation.rb +133 -0
- data/test/unit/theory/tc_theory_result.rb +111 -0
- data/test/unit/theory/tc_theory_variable.rb +45 -0
- data/test/unit/util/tc_method_validation.rb +98 -0
- data/test/unit/util/tc_parser.rb +108 -0
- data/test/unit/util/tc_string_to_theory.rb +299 -0
- data/test/unit/variable/tc_method_usage_variable.rb +25 -0
- data/tmp/runtime_method_evaluation.rb +10 -0
- metadata +522 -0
data/lib/ChainMapping.rb
ADDED
@@ -0,0 +1,172 @@
|
|
1
|
+
# note about the global mapping=>
|
2
|
+
#
|
3
|
+
# This method needs to map the theory variables used in one theory to the
|
4
|
+
# rest. This basically means there is a global theory that has a respective
|
5
|
+
# id in each of the other theories in the chain. e.g.
|
6
|
+
#
|
7
|
+
# +----------+--------+--------+--------+--------+
|
8
|
+
# |Global #ID| head | link#2 | link#3 | link#4 |
|
9
|
+
# +----------+--------+--------+--------+--------+
|
10
|
+
# | 0 | 1 | 1 | 2 | 89 |
|
11
|
+
# +----------+--------+--------+--------+--------+
|
12
|
+
# | 1 | 2 | 4 | 6 | 1 |
|
13
|
+
# +----------+--------+--------+--------+--------+
|
14
|
+
|
15
|
+
class ChainMapping
|
16
|
+
attr_reader :mapping, :history
|
17
|
+
|
18
|
+
def initialize(mapping={},history=[])
|
19
|
+
@history, @mapping = history, mapping
|
20
|
+
end
|
21
|
+
|
22
|
+
def copy
|
23
|
+
return ChainMapping.new(@mapping.copy,@history.copy)
|
24
|
+
end
|
25
|
+
|
26
|
+
# Returns the global id for the this theory variable in this theory.
|
27
|
+
#
|
28
|
+
# @param theory_id The id of the theory that is being retreived
|
29
|
+
# @param variable_id The id of the theory variable in the context of the single theory
|
30
|
+
#
|
31
|
+
def find_global(theory_instance_id,variable_id)
|
32
|
+
res = @mapping.detect do |key,value|
|
33
|
+
value.has_key?(theory_instance_id) && value[theory_instance_id] == variable_id
|
34
|
+
end
|
35
|
+
return nil if res.nil?
|
36
|
+
return res[0]
|
37
|
+
end
|
38
|
+
|
39
|
+
def same?(chain_map)
|
40
|
+
return false if @mapping.length != chain_map.mapping.length
|
41
|
+
return false if @history.length != chain_map.history.length
|
42
|
+
return @history == chain_map.history
|
43
|
+
end
|
44
|
+
|
45
|
+
# Adds a new variable mapping to a global id
|
46
|
+
# TODO Assigning global_id should probably not be allowed publically
|
47
|
+
#
|
48
|
+
def add_mapping(global_id,theory_instance_id,variable_id)
|
49
|
+
if @mapping[global_id].nil?
|
50
|
+
@mapping[global_id] = {}
|
51
|
+
end
|
52
|
+
# TODO Write tests to check that the error is raised
|
53
|
+
unless @mapping[global_id][theory_instance_id].nil?
|
54
|
+
if @mapping[global_id][theory_instance_id] != variable_id
|
55
|
+
raise ChainMappingError.new('This global variable has already been defined')
|
56
|
+
end
|
57
|
+
end
|
58
|
+
# TODO Should check that the theory_id#variable_id has not already been assigned to a global id
|
59
|
+
@mapping[global_id][theory_instance_id] = variable_id
|
60
|
+
end
|
61
|
+
|
62
|
+
# TODO I'd like to change global ids to letters for clarity
|
63
|
+
# Returns the next key that hasn't been defined in the mapping
|
64
|
+
def next_free_global_id
|
65
|
+
a = (0..100).to_a.detect() {|x| !@mapping.has_key?(x)}
|
66
|
+
raise StandardError.new('No more free global id') if a.nil?
|
67
|
+
return a
|
68
|
+
end
|
69
|
+
|
70
|
+
# Returns a string listing all the dependent to result connections
|
71
|
+
# that have been made.
|
72
|
+
#
|
73
|
+
def display_history
|
74
|
+
@history.each do |x|
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
# TODO This is temporary - it doesn't resolve the issue of the same theory
|
79
|
+
# being used twice.
|
80
|
+
# Returns all the components that have been sucessfully connected to another
|
81
|
+
# component.
|
82
|
+
#
|
83
|
+
def connected_component_ids
|
84
|
+
@history.inject([]) {|total,x| total += x}
|
85
|
+
end
|
86
|
+
|
87
|
+
# Either returns an updated chain mapping if the mapping works or returns the
|
88
|
+
# existing mapping.
|
89
|
+
#
|
90
|
+
def apply_mapping_update(theory_a,component_a_id,theory_b,component_b_id)
|
91
|
+
updated_mapping = copy
|
92
|
+
begin
|
93
|
+
updated_mapping.connect(theory_a,component_a_id,theory_b,component_b_id)
|
94
|
+
rescue ChainMappingError => e
|
95
|
+
StandardLogger.instance.warning e
|
96
|
+
return self.copy
|
97
|
+
end
|
98
|
+
return updated_mapping
|
99
|
+
end
|
100
|
+
|
101
|
+
# TODO I need to include a mapping that doesn't declare a globlal_id. A global id only needs
|
102
|
+
# identified when connecting separate theories.
|
103
|
+
|
104
|
+
# TODO Mapping is not about theory_component_id it is about what is connected to what and
|
105
|
+
# when - consider when the same theory is added twice but connected differently.
|
106
|
+
|
107
|
+
# TODO This needs wrapped in some transaction incase one of the mappings won't work
|
108
|
+
# or in the wider context some of the other connections won't work.
|
109
|
+
|
110
|
+
# Updates the global mapping to connect the two theories so that
|
111
|
+
# they share the same global mapping
|
112
|
+
#
|
113
|
+
# TODO Need to include the theories instance id
|
114
|
+
#
|
115
|
+
def connect(theory_a,component_a_id,theory_b,component_b_id)
|
116
|
+
|
117
|
+
# Retrieve each of the components
|
118
|
+
component_a = theory_a.find_component(component_a_id)
|
119
|
+
component_b = theory_b.find_component(component_b_id)
|
120
|
+
|
121
|
+
# Check that the number of variables match
|
122
|
+
unless component_a.theory_variables.length == component_b.theory_variables.length
|
123
|
+
raise ChainMappingError.new('These components do not have the same number of variables')
|
124
|
+
end
|
125
|
+
|
126
|
+
# Go through each variable and confirm they have the same global mapping
|
127
|
+
component_a.theory_variables.zip(component_b.theory_variables) do |variable_a,variable_b|
|
128
|
+
|
129
|
+
# Do any of the theory variables already have a global id
|
130
|
+
global_var_a = find_global(theory_a.theory_instance_id,variable_a.theory_variable_id)
|
131
|
+
global_var_b = find_global(theory_b.theory_instance_id,variable_b.theory_variable_id)
|
132
|
+
|
133
|
+
# Nearly variables has been added as global - add new global connections
|
134
|
+
if ([global_var_a,global_var_b].all? {|x| x.nil?})
|
135
|
+
mapping_global_id = next_free_global_id
|
136
|
+
add_mapping(mapping_global_id,theory_a.theory_instance_id,variable_a.theory_variable_id)
|
137
|
+
add_mapping(mapping_global_id,theory_b.theory_instance_id,variable_b.theory_variable_id)
|
138
|
+
else
|
139
|
+
|
140
|
+
# If both the global ids are defined then they should be the same value.
|
141
|
+
if([global_var_a,global_var_b].all? {|x| !x.nil? })
|
142
|
+
if global_var_a != global_var_b
|
143
|
+
raise ChainMappingError.new(
|
144
|
+
'Both global ids have already been defiend but are not equal '+global_var_a.to_s+' and '+global_var_b.to_s
|
145
|
+
)
|
146
|
+
end
|
147
|
+
next
|
148
|
+
end
|
149
|
+
|
150
|
+
# Get the id of the only defined global id
|
151
|
+
global_id = [global_var_a,global_var_b].detect {|x| !x.nil? }
|
152
|
+
|
153
|
+
# Add the mapping for both
|
154
|
+
add_mapping(global_id,theory_a.theory_instance_id,variable_a.theory_variable_id)
|
155
|
+
add_mapping(global_id,theory_b.theory_instance_id,variable_b.theory_variable_id)
|
156
|
+
end
|
157
|
+
|
158
|
+
end
|
159
|
+
|
160
|
+
@history.unshift([theory_a.theory_instance_id,component_a_id,theory_b.theory_instance_id,component_b_id])
|
161
|
+
|
162
|
+
end
|
163
|
+
|
164
|
+
end
|
165
|
+
|
166
|
+
class ChainMappingError < StandardError
|
167
|
+
|
168
|
+
def initialize(msg)
|
169
|
+
super(msg)
|
170
|
+
end
|
171
|
+
|
172
|
+
end
|
data/lib/CodeHandler.rb
ADDED
@@ -0,0 +1,517 @@
|
|
1
|
+
# TODO Look into matrix
|
2
|
+
require "matrix"
|
3
|
+
require "tsort"
|
4
|
+
|
5
|
+
# A code handler continualy considers how to extend the complexity
|
6
|
+
# of a method in a custom class given the intial starting methods
|
7
|
+
# already availble within the class.
|
8
|
+
#
|
9
|
+
# It also can refactor the code into separate methods thereby
|
10
|
+
# reusing the same functionality.
|
11
|
+
#
|
12
|
+
# Essentially it just tries to create as many uniquely new variables as it
|
13
|
+
# can. Note they are consider unique if the process to create them is
|
14
|
+
# new, NOT whether or not there value is new.
|
15
|
+
#
|
16
|
+
# TODO Look up dynamic refactoring
|
17
|
+
#
|
18
|
+
class CodeHandler
|
19
|
+
|
20
|
+
attr_reader :runtime_methods
|
21
|
+
attr_writer :default_structures
|
22
|
+
|
23
|
+
@@CODE_HANDLER_ID = 0
|
24
|
+
|
25
|
+
def initialize(runtime_methods=[],structures=nil)
|
26
|
+
@runtime_methods = runtime_methods
|
27
|
+
@entrance_method = create_entrance_method
|
28
|
+
@code_handler_id = @@CODE_HANDLER_ID
|
29
|
+
@@CODE_HANDLER_ID += 1
|
30
|
+
|
31
|
+
# These are the default statement structures if non-are supplied
|
32
|
+
@default_structures = [
|
33
|
+
DeclareVariableAsVariableStructure.new,
|
34
|
+
StatementStructure2.new(StatementStructure2.declared_runtime_method),
|
35
|
+
StatementStructure2.new(StatementStructure2.declared_array),
|
36
|
+
StatementStructure2.new(StatementStructure2.declared_string_addition),
|
37
|
+
DeclareNewInstanceStructure.new(MethodUsageClass.new,RuntimeMethodClass.new)
|
38
|
+
]
|
39
|
+
|
40
|
+
# If structures are supplied the overwrite the default structures
|
41
|
+
@default_structures = structures unless structures.nil?
|
42
|
+
end
|
43
|
+
|
44
|
+
# Returns a string that prints out how the dynamic code for the
|
45
|
+
# code handler currently looks.
|
46
|
+
#
|
47
|
+
def write
|
48
|
+
|
49
|
+
dynamic_code = "class #{class_name}"+"\n"
|
50
|
+
|
51
|
+
# Include each of the avaialble runtime methods
|
52
|
+
@runtime_methods.each do |x|
|
53
|
+
dynamic_code += x.write(ParametersContainer.new,1)
|
54
|
+
end
|
55
|
+
|
56
|
+
# Now add the entrance method
|
57
|
+
dynamic_code += @entrance_method.write(ParametersContainer.new,1)
|
58
|
+
|
59
|
+
dynamic_code += "end"
|
60
|
+
return dynamic_code
|
61
|
+
end
|
62
|
+
|
63
|
+
# Returns an array of method instances containing various numbers of statements.
|
64
|
+
#
|
65
|
+
# 1. At this point we are creating a statement to go straight into a method or
|
66
|
+
# into a nested statement. First we find all the available variables in the
|
67
|
+
# context. For this to work the variables should be saved with a scope. At
|
68
|
+
# this point it isn't concerning it's self with the dependencies for the variable.
|
69
|
+
# It does however have to take into consideration scope. As such every nested
|
70
|
+
# statement maintains an array of it's level e.g. [5,7] for a two level nested
|
71
|
+
# statement. This would mean that varibles with a scope level of 5 or 7 would
|
72
|
+
# be valid consideration.
|
73
|
+
#
|
74
|
+
# 2. Next using the variables available to it it constructs a number of different
|
75
|
+
# statements.
|
76
|
+
#
|
77
|
+
# 3. From this statement it needs to work backwards to construct the full method.
|
78
|
+
# It does this by finding all the dependencies that have the same scope level.
|
79
|
+
# After that has been done, if finds and adds all the dependcies on the other
|
80
|
+
# scope level.
|
81
|
+
#
|
82
|
+
# 4. With the method constructed the value for the new variable can be asscertained.
|
83
|
+
# The asscertained value gets added to available array. Also if a variable is
|
84
|
+
# overwritten within the nested statement then its value is included with a scope
|
85
|
+
# value outside the nested statement. Specifically a scope level the same as the
|
86
|
+
# variable that was overridden. The variable simple has a depencey on the nested
|
87
|
+
# statement. This allows it to rebuild the statements in the correct order. It
|
88
|
+
# can then check the scopes and wrap the nested statement accordingly.
|
89
|
+
#
|
90
|
+
# @param count The number of itterations to go through when generating new
|
91
|
+
# runtime method arrangements.
|
92
|
+
# @param additional_available Any additional values that should be made available when
|
93
|
+
# generating statements.
|
94
|
+
#
|
95
|
+
def itterate(count=1,additional_available=[])
|
96
|
+
|
97
|
+
# Create an array to contain the vessels currently available
|
98
|
+
initial_copied_method = @entrance_method.copy
|
99
|
+
initial_copied_method.clear
|
100
|
+
vessels = [initial_copied_method]
|
101
|
+
|
102
|
+
# Create the array to contain the available variables and the initial runtime method calls
|
103
|
+
available = []
|
104
|
+
available += additional_available
|
105
|
+
@runtime_methods.each {|x| available += x.callable_combinations}
|
106
|
+
|
107
|
+
# Set the scope id for all the method calls
|
108
|
+
available.each {|x| x.scope_id = initial_copied_method.scope_id}
|
109
|
+
|
110
|
+
# Maintains all the statements and their dependencies
|
111
|
+
dependencies = StatementDependencies.new
|
112
|
+
|
113
|
+
# Completed methods
|
114
|
+
results = []
|
115
|
+
|
116
|
+
# Itterate over the number of times specified
|
117
|
+
count.times do |i|
|
118
|
+
|
119
|
+
# Keep track of the newly created variables
|
120
|
+
newly_created_variable = []
|
121
|
+
|
122
|
+
# Keeps track of newly created vessels
|
123
|
+
newly_created_vessels = []
|
124
|
+
|
125
|
+
# For each vessel create appropriate statements
|
126
|
+
vessels.each do |vessel|
|
127
|
+
|
128
|
+
# Find potential new statements available to the current vessel
|
129
|
+
new_statement_results = find_possible_new_statements(vessel,available,dependencies)
|
130
|
+
|
131
|
+
# Find the statement dependencies for each statement
|
132
|
+
new_statement_results.each do |y|
|
133
|
+
|
134
|
+
# Create the vessel for the new statement
|
135
|
+
new_vessel = vessel.copy
|
136
|
+
|
137
|
+
# Create a runtime method with the statement and all the dependencies
|
138
|
+
copied_method = build_minimalist_method(@entrance_method,y,dependencies)
|
139
|
+
|
140
|
+
# Realise the generated method
|
141
|
+
begin
|
142
|
+
realised_method = copied_method.realise2(ParametersContainer.new,@runtime_methods)
|
143
|
+
rescue ImproperStatementUsageError => e
|
144
|
+
|
145
|
+
# TODO I have rejected statements "var = <#statement_variable>.declare_variable" if the statement
|
146
|
+
# variable doesn't represent a declaration statement. I don't know if this is the right way to
|
147
|
+
# do things. It might be better to return a NilVariable or prevent it from ever being created.
|
148
|
+
|
149
|
+
# TODO I should check this is logged
|
150
|
+
StandardLogger.instance.warning('Method rejeceted')
|
151
|
+
StandardLogger.instance.warning(e)
|
152
|
+
next
|
153
|
+
end
|
154
|
+
|
155
|
+
results.push(realised_method)
|
156
|
+
|
157
|
+
# TODO I should determine the nature of the statement and then
|
158
|
+
# determine the new variables available.
|
159
|
+
# - I should maybe save structures with statements.
|
160
|
+
|
161
|
+
raise StandardError.new('Statement type has not defined for this statement') if y.statement_type.nil?
|
162
|
+
|
163
|
+
# Determine the id of the statement that declares the value
|
164
|
+
#case(y.statement_type)
|
165
|
+
# when StatementStructure::DECLARATION_STATEMENT
|
166
|
+
if((y.statement_type == StatementStructure::MODIFYING_STATEMENT)or(y.statement_type == StatementStructure::DECLARATION_STATEMENT))
|
167
|
+
|
168
|
+
#declared_variable_id = y.created_variable.variable_id
|
169
|
+
variable_uniq_id = y.created_variable.uniq_id
|
170
|
+
|
171
|
+
# Find the value of the variable within the realised method and set it's scope
|
172
|
+
#resulting_variable = realised_method.find_variable(declared_variable_id)
|
173
|
+
resulting_variable = realised_method.find_variable(variable_uniq_id)
|
174
|
+
|
175
|
+
if y.kind_of?(BlockStatement)
|
176
|
+
resulting_variable.scope_id = y.scope_id
|
177
|
+
resulting_variable.clear
|
178
|
+
else
|
179
|
+
resulting_variable.scope_id = vessel.scope_id
|
180
|
+
end
|
181
|
+
newly_created_variable.push(resulting_variable)
|
182
|
+
|
183
|
+
#new_vessel = realised_method.find_statement_that_declares_variable(declared_variable_id)
|
184
|
+
# TODO Check this works with uniq_id
|
185
|
+
new_vessel = realised_method.find_statement_that_created_variable(variable_uniq_id)
|
186
|
+
|
187
|
+
# Find the statement from the typed method that declares the variable
|
188
|
+
# NOTE I wonder if it would be quicker and safe to add the realised statement here
|
189
|
+
#declaring_statement = realised_method.find_statement_that_declares_variable(declared_variable_id)
|
190
|
+
# TODO Check this works with uniq_id
|
191
|
+
declaring_statement = realised_method.find_statement_that_created_variable(variable_uniq_id)
|
192
|
+
dependencies.push(declaring_statement)
|
193
|
+
|
194
|
+
# If the new statement was a nested statement then add as vessel
|
195
|
+
if y.kind_of?(BlockStatement)
|
196
|
+
new_vessels_scope = [new_vessel.scope_id]
|
197
|
+
new_vessels_scope += vessel.scope
|
198
|
+
new_vessel.scope = new_vessels_scope
|
199
|
+
new_vessel.clear
|
200
|
+
newly_created_vessels.push(new_vessel)
|
201
|
+
end
|
202
|
+
|
203
|
+
# when StatementStructure::MODIFYING_STATEMENT:
|
204
|
+
|
205
|
+
# # exit
|
206
|
+
# # Need to save modified statement;
|
207
|
+
# StandardLogger.instance.warning('I think I need to treat modifying statements as if they declare new variables')
|
208
|
+
#
|
209
|
+
# # TODO I'm not certain this isn't going to add loads of statement
|
210
|
+
# StandardLogger.instance.info('Statement ID: '+y.statement_id.to_s)
|
211
|
+
# StandardLogger.instance.info(': '+y.write)
|
212
|
+
#
|
213
|
+
# # Adding the statement the newly modified statement
|
214
|
+
# dependencies.push(realised_method.select {|stment| stment.statement_id == y.statement_id}.first)
|
215
|
+
# elsif(StatementStructure::USAGE_STATEMENT)
|
216
|
+
else
|
217
|
+
raise StandardError.new('Unknown statement_type "'+y.statement_type+'" "'+y.write+'"')
|
218
|
+
end
|
219
|
+
|
220
|
+
end
|
221
|
+
|
222
|
+
end
|
223
|
+
|
224
|
+
# Add the new variables to available list
|
225
|
+
# TODO newly_created_variable is an array - it should be newly_created_variables
|
226
|
+
available += newly_created_variable
|
227
|
+
|
228
|
+
# Add the new vessel to the list
|
229
|
+
vessels += newly_created_vessels
|
230
|
+
|
231
|
+
end
|
232
|
+
return results
|
233
|
+
|
234
|
+
end
|
235
|
+
|
236
|
+
def self.reset_global_id
|
237
|
+
#http://www.zenspider.com/Languages/Ruby/QuickRef.html
|
238
|
+
unless $".include?('test/unit.rb')
|
239
|
+
StandardLogger.log 'WARNING: Resetting variable id, this should only be done for tests'
|
240
|
+
end
|
241
|
+
@@CODE_HANDLER_ID = 0
|
242
|
+
end
|
243
|
+
|
244
|
+
def class_name
|
245
|
+
return "RuntimeCodeHandler"+@code_handler_id.to_s
|
246
|
+
end
|
247
|
+
|
248
|
+
protected
|
249
|
+
|
250
|
+
# Returns an array of new statements after removing any statements
|
251
|
+
# that have previously been considered when generating code.
|
252
|
+
#
|
253
|
+
# TODO This needs re-thought for seanarios when new containers become
|
254
|
+
# available.
|
255
|
+
#
|
256
|
+
# @param possible_statements
|
257
|
+
# @param considered_statements
|
258
|
+
#
|
259
|
+
def new_statements(possible_statements,considered_statements)
|
260
|
+
|
261
|
+
# TODO I imagine there is a nicer way of doing this method using Procs or
|
262
|
+
# passing blocks.
|
263
|
+
|
264
|
+
results = StatementGroup.new
|
265
|
+
possible_statements.each do |x|
|
266
|
+
|
267
|
+
# Declare the statement that is being considered - for block statements
|
268
|
+
# e.g. test.each do |x| only the "test.each" bit is considered
|
269
|
+
if x.kind_of?(BlockStatement)
|
270
|
+
subject = x.opening_statement
|
271
|
+
end
|
272
|
+
subject ||= x
|
273
|
+
|
274
|
+
catch(:already_exists) do
|
275
|
+
considered_statements.each do |y|
|
276
|
+
|
277
|
+
if y.kind_of?(BlockStatement)
|
278
|
+
other = y.opening_statement
|
279
|
+
end
|
280
|
+
other ||= y
|
281
|
+
|
282
|
+
catch(:different_from_this_statement) do
|
283
|
+
|
284
|
+
# Checks whether the statements are equivalent
|
285
|
+
if subject.equivalent?(other)
|
286
|
+
throw :already_exists
|
287
|
+
end
|
288
|
+
throw :different_from_this_statement
|
289
|
+
end
|
290
|
+
end
|
291
|
+
results.push(x)
|
292
|
+
end
|
293
|
+
end
|
294
|
+
return results
|
295
|
+
end
|
296
|
+
|
297
|
+
# Return the next set of available statements given the
|
298
|
+
# elements avialable.
|
299
|
+
#
|
300
|
+
def next_statements(available=[])
|
301
|
+
|
302
|
+
# Collect a number of runtime variables
|
303
|
+
results = StatementGroup.new
|
304
|
+
statement_structures.each do |structure|
|
305
|
+
results += structure.statements(available)
|
306
|
+
end
|
307
|
+
return results
|
308
|
+
end
|
309
|
+
|
310
|
+
# Retuns a runtime method instance that is the starting
|
311
|
+
# point when generating unique variable journeys.
|
312
|
+
#
|
313
|
+
def create_entrance_method
|
314
|
+
return RuntimeMethod.new(MethodUsage.new,NilVariable.new)
|
315
|
+
end
|
316
|
+
|
317
|
+
# Returns an array of potential statement structures
|
318
|
+
# e.g.
|
319
|
+
#
|
320
|
+
# Structure.new(Unknown,Equal,FixnumVariable,Addition,FixnumVariable)
|
321
|
+
#
|
322
|
+
# TODO Write more tests for StatementStructure2
|
323
|
+
# TODO I don't know if I want to declare the structures here. It might be
|
324
|
+
# nicer to keep them with the variables. They need to be with the variables
|
325
|
+
# since even if they were created by the same StatementStrucutre this is
|
326
|
+
# no guarantee that they will have the same the structure. e..g
|
327
|
+
#
|
328
|
+
# var_a.push(var_b);
|
329
|
+
#
|
330
|
+
def statement_structures
|
331
|
+
return @default_structures
|
332
|
+
end
|
333
|
+
|
334
|
+
# Returns the current runtime class instance
|
335
|
+
def to_runtime_class
|
336
|
+
runtime_class = RuntimeClass.new(class_name)
|
337
|
+
@runtime_methods.each do |x|
|
338
|
+
runtime_class.push x.copy
|
339
|
+
end
|
340
|
+
runtime_class.push @entrance_method
|
341
|
+
return runtime_class
|
342
|
+
end
|
343
|
+
|
344
|
+
# Returns an array of statements that need
|
345
|
+
# DEPENDENCY - check ruby code
|
346
|
+
# TODO Look up Matrix in ruby p694
|
347
|
+
def requisite_statements_for(entrance_method,statement,journeys)
|
348
|
+
statement.required_variable_ids.each do |x|
|
349
|
+
journeys[x].each do |y|
|
350
|
+
entrance_method.push(y)
|
351
|
+
end
|
352
|
+
end
|
353
|
+
end
|
354
|
+
|
355
|
+
# Returns an array of statements based on the available variables and
|
356
|
+
# previously created statements.
|
357
|
+
#
|
358
|
+
def create_statements(available,dependencies,vessel)
|
359
|
+
|
360
|
+
# Now attempt to create statements with each of the elements
|
361
|
+
statements = next_statements(available)
|
362
|
+
|
363
|
+
# Remove out of scope dependencies
|
364
|
+
# If a statement is used in a new scope it should be considered a new statement
|
365
|
+
# NOTE For now I wont allow this
|
366
|
+
|
367
|
+
# Remove statements that may have been considered at previous itteration
|
368
|
+
statements = new_statements(statements,dependencies)
|
369
|
+
|
370
|
+
# Remove any statements that simple declare an existing variable var_a = var_b
|
371
|
+
# TODO With better structures this shouldn't be necessary
|
372
|
+
statements = statements.remove_simple
|
373
|
+
|
374
|
+
return statements
|
375
|
+
end
|
376
|
+
|
377
|
+
# Returns an updated array of variables thats scope is with
|
378
|
+
# the tolerance specified.
|
379
|
+
#
|
380
|
+
# @param available A array of available variables
|
381
|
+
# @param scope An array indicating the scope to allow e.g.
|
382
|
+
# [5,7].
|
383
|
+
#
|
384
|
+
def filter_within_scope(available,scope)
|
385
|
+
results = available.find_all {|x| scope.any?{|y| x.scope_id==y} }
|
386
|
+
return results
|
387
|
+
end
|
388
|
+
|
389
|
+
# Returns an array of statements in the order of their depenence.
|
390
|
+
#
|
391
|
+
# @param dependencies A statement dependencies instance containing the
|
392
|
+
# depenency structure.
|
393
|
+
# @param statement The most recently added statement that's depenencies
|
394
|
+
# need found for.
|
395
|
+
#
|
396
|
+
def find_prerequisite_statements(dependencies,statement)
|
397
|
+
|
398
|
+
# TODO Call this method within dependencies
|
399
|
+
# Find the dependcies for the statement - the last one is the current statement
|
400
|
+
required_ids = dependencies.tsort_for_statement(statement)
|
401
|
+
required_ids.pop
|
402
|
+
|
403
|
+
# Add the dependent statements
|
404
|
+
results = []
|
405
|
+
required_ids.each do |y|
|
406
|
+
dependencies.each do |z|
|
407
|
+
results.push(z.copy) if z.statement_id == y
|
408
|
+
end
|
409
|
+
end
|
410
|
+
return results
|
411
|
+
|
412
|
+
end
|
413
|
+
|
414
|
+
# Strips out all the variables that are used as part of the
|
415
|
+
# the nested statements. This is to avoid editing variables
|
416
|
+
# that are being itterated over. For example
|
417
|
+
#
|
418
|
+
# var_a = ['test']
|
419
|
+
# var_a.each do |x|
|
420
|
+
# var_a.push('test')
|
421
|
+
# end
|
422
|
+
#
|
423
|
+
# @param vars An array of in-scope variables (relative to the supplied vessel)
|
424
|
+
# @param vessel The nested statement or method thats structure is being considered
|
425
|
+
# @param dependencies The dependencey structure of all the statements.
|
426
|
+
#
|
427
|
+
def strip_dependent_variables(vars,vessel,dependencies)
|
428
|
+
# Go through each nested statement in scope and remove any variables used in the statemnet
|
429
|
+
# this is to prevent variables being itterated over being used in the nested statement.
|
430
|
+
nested_statements = dependencies.find_all {|x| x.kind_of?(BlockStatement)}
|
431
|
+
vessel.scope.each do |used_scope|
|
432
|
+
nested_statement = nested_statements.detect {|x| x.scope_id == used_scope}
|
433
|
+
next if nested_statement.nil?
|
434
|
+
|
435
|
+
# Find the id of the variable used in the nested statement and remove it as a in_scope_variables
|
436
|
+
# TODO This presumes allot about the position of the variable in the statement
|
437
|
+
vars.delete_if {|x| x.kind_of?(Variable) && x.variable_id == nested_statement.opening_statement.first.variable.variable_id }
|
438
|
+
end
|
439
|
+
return vars
|
440
|
+
end
|
441
|
+
|
442
|
+
# Returns an array of possible new statements given the currently
|
443
|
+
# available variables, scope limitations and statement dependencies.
|
444
|
+
#
|
445
|
+
# @param vessel A vessel is something that contains statements. This
|
446
|
+
# is either a nested statement or a runtime method.
|
447
|
+
# @param available Is an array of all the variables and method calls. Note
|
448
|
+
# this has not been tailored to suit the vessel so some
|
449
|
+
# of the variables shouldn't be available.
|
450
|
+
# @param dependencies A statement dependencies instance that maintains what statements
|
451
|
+
# are dependent on what.
|
452
|
+
#
|
453
|
+
def find_possible_new_statements(vessel,available,dependencies)
|
454
|
+
|
455
|
+
# Filter the array of available variables to only include those within scope.
|
456
|
+
in_scope_variables = filter_within_scope(available,vessel.scope)
|
457
|
+
|
458
|
+
# Strip out parent itterating variables
|
459
|
+
in_scope_variables = strip_dependent_variables(in_scope_variables,vessel,dependencies)
|
460
|
+
|
461
|
+
# Create statements with the available variables
|
462
|
+
new_statement_results = create_statements(in_scope_variables,dependencies,vessel)
|
463
|
+
|
464
|
+
# All new statements should have the statement level of the vessel scope_id
|
465
|
+
new_statement_results.each {|x| x.statement_level = vessel.scope_id}
|
466
|
+
|
467
|
+
return new_statement_results
|
468
|
+
|
469
|
+
end
|
470
|
+
|
471
|
+
# Returns an updated method that includes a specified statement and
|
472
|
+
# all of its dependencies in the correct order and depth.
|
473
|
+
#
|
474
|
+
# @param initial_method
|
475
|
+
#
|
476
|
+
def build_minimalist_method(initial_method,statement,dependencies)
|
477
|
+
|
478
|
+
# Find all the pre-requisite statements for the leading statement
|
479
|
+
prerequisite_statements = find_prerequisite_statements(dependencies,statement)
|
480
|
+
|
481
|
+
# Create an empty initial method to contain each arrangement
|
482
|
+
constructing_method = initial_method.copy
|
483
|
+
constructing_method.clear
|
484
|
+
|
485
|
+
# Add all the statement in their scope order
|
486
|
+
prerequisite_statements.copy.each do |remaining_statement|
|
487
|
+
unless remaining_statement.statement_level == constructing_method.scope_id
|
488
|
+
|
489
|
+
# Find the pre-requiste statement the statement should reside in
|
490
|
+
actual_statement = prerequisite_statements.delete_if {|z| z.statement_id == remaining_statement.statement_id}
|
491
|
+
|
492
|
+
prerequisite_statements.each do |h|
|
493
|
+
if h.kind_of?(StatementGroup)
|
494
|
+
if h.scope_id == actual_statement.statement_level
|
495
|
+
h.push(actual_statement)
|
496
|
+
break
|
497
|
+
end
|
498
|
+
end
|
499
|
+
end
|
500
|
+
exit
|
501
|
+
end
|
502
|
+
end
|
503
|
+
|
504
|
+
# Add each pre-requisite statement to the copied method
|
505
|
+
prerequisite_statements.each do |f|
|
506
|
+
constructing_method.push(f)
|
507
|
+
end
|
508
|
+
|
509
|
+
# Find the statement with the correct statement level and add the new statement
|
510
|
+
container_statement = constructing_method.find_container_at_level(statement.statement_level)
|
511
|
+
container_statement.push(statement)
|
512
|
+
|
513
|
+
return constructing_method
|
514
|
+
|
515
|
+
end
|
516
|
+
|
517
|
+
end
|