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
@@ -0,0 +1,35 @@
|
|
1
|
+
module WriteParameters
|
2
|
+
|
3
|
+
def write_params(params,parenthesis=['(',')'])
|
4
|
+
line = ''
|
5
|
+
unless params.empty?
|
6
|
+
line += parenthesis[0]
|
7
|
+
params.each_with_index do |var,i|
|
8
|
+
line += var.write
|
9
|
+
unless var.object_id ==params.last.object_id
|
10
|
+
line += ', '
|
11
|
+
end
|
12
|
+
end
|
13
|
+
line += parenthesis[1]
|
14
|
+
return line
|
15
|
+
end
|
16
|
+
return ''
|
17
|
+
end
|
18
|
+
|
19
|
+
def describe_params(params,parenthesis=['(',')'])
|
20
|
+
line = ''
|
21
|
+
unless params.empty?
|
22
|
+
line += parenthesis[0]
|
23
|
+
params.each_with_index do |var,i|
|
24
|
+
line += var.describe
|
25
|
+
unless var.object_id ==params.last.object_id
|
26
|
+
line += ', '
|
27
|
+
end
|
28
|
+
end
|
29
|
+
line += parenthesis[1]
|
30
|
+
return line
|
31
|
+
end
|
32
|
+
return ''
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
@@ -0,0 +1,116 @@
|
|
1
|
+
# This module is shared between the Statement and BlockStatement classes. It
|
2
|
+
# ensures that both those classes have a statement id and a structure type.
|
3
|
+
#
|
4
|
+
module ActsAsStatement
|
5
|
+
|
6
|
+
# TODO I think I should start to fade out statement_type - I should start by finding calls where it
|
7
|
+
# is needed.
|
8
|
+
def statement_type
|
9
|
+
if @statement_type.nil?
|
10
|
+
@statement_type = identify_statement_type
|
11
|
+
end
|
12
|
+
raise UnknownStatementType.new('No statement type has been defined for this statement "'+self.write+'" ['+self.class.to_s+']') if @statement_type.nil?
|
13
|
+
return @statement_type
|
14
|
+
end
|
15
|
+
|
16
|
+
# Returns true if the statement (treated as an array) has all the
|
17
|
+
# same classes as the array supplied.
|
18
|
+
#
|
19
|
+
# @param classes An array of classes that this statement is
|
20
|
+
# compared to.
|
21
|
+
#
|
22
|
+
def classes_match?(*classes)
|
23
|
+
return false unless classes.length == self.length
|
24
|
+
self.zip(classes) do |x,y|
|
25
|
+
return false unless x.instance_of?(y)
|
26
|
+
end
|
27
|
+
return true
|
28
|
+
end
|
29
|
+
|
30
|
+
protected
|
31
|
+
|
32
|
+
# Attempts to identify the type of statement this is by its contents.
|
33
|
+
#
|
34
|
+
def identify_statement_type
|
35
|
+
case self.length
|
36
|
+
when 0
|
37
|
+
return StatementStructure::BLANK_STATEMENT
|
38
|
+
when 1
|
39
|
+
return StatementStructure::IF_STATEMENT if first.kind_of?(IfContainer)
|
40
|
+
#return StatementStructure::USAGE_STATEMENT if self.classes_match?(InstanceCallContainer)
|
41
|
+
if self.classes_match?(InstanceCallContainer)
|
42
|
+
if first.method_call.destructive?
|
43
|
+
return StatementStructure::MODIFYING_STATEMENT
|
44
|
+
else
|
45
|
+
return StatementStructure::USAGE_STATEMENT
|
46
|
+
end
|
47
|
+
end
|
48
|
+
# TODO Not sure if this should be a usage_statement
|
49
|
+
return StatementStructure::USAGE_STATEMENT if self.classes_match?(DefCall)
|
50
|
+
|
51
|
+
when 2
|
52
|
+
return StatementStructure::RETURN_STATEMENT if first.kind_of?(Return)
|
53
|
+
when 3
|
54
|
+
# TODO This should distinguish between modifying statements e.g. chop! and push
|
55
|
+
# var = var.chop
|
56
|
+
return StatementStructure::DECLARATION_STATEMENT if self.classes_match?(Unknown,Equal,InstanceCallContainer)
|
57
|
+
return StatementStructure::DECLARATION_STATEMENT if self.classes_match?(Unknown,Equal,ClassMethodCallContainer)
|
58
|
+
# TODO Is there a difference between a Literal and a LiteralDeclaration
|
59
|
+
return StatementStructure::DECLARATION_STATEMENT if self.classes_match?(Unknown,Equal,Literal)
|
60
|
+
return StatementStructure::DECLARATION_STATEMENT if self.classes_match?(Unknown,Equal,StringVariable)
|
61
|
+
return StatementStructure::DECLARATION_STATEMENT if self.classes_match?(Unknown,Equal,ArrayVariable)
|
62
|
+
return StatementStructure::DECLARATION_STATEMENT if self.classes_match?(Unknown,Equal,FixnumVariable)
|
63
|
+
return StatementStructure::DECLARATION_STATEMENT if self.classes_match?(Unknown,Equal,StatementVariable)
|
64
|
+
return StatementStructure::DECLARATION_STATEMENT if self.classes_match?(Unknown,Equal,RuntimeMethodParameter)
|
65
|
+
return StatementStructure::DECLARATION_STATEMENT if self.classes_match?(Unknown,Equal,LiteralDeclaration)
|
66
|
+
return StatementStructure::DECLARATION_STATEMENT if self.classes_match?(Unknown,Equal,NilVariable)
|
67
|
+
return StatementStructure::DECLARATION_STATEMENT if self.classes_match?(Unknown,Equal,DefCall)
|
68
|
+
return StatementStructure::DECLARATION_STATEMENT if self.classes_match?(Unknown,Equal,Fixnum)
|
69
|
+
return StatementStructure::DECLARATION_STATEMENT if self.classes_match?(Unknown,Equal,UnknownVariable)
|
70
|
+
return StatementStructure::DECLARATION_STATEMENT if self.classes_match?(StringVariable,Equal,Literal)
|
71
|
+
return StatementStructure::DECLARATION_STATEMENT if self.classes_match?(StringVariable,Equal,LiteralDeclaration)
|
72
|
+
return StatementStructure::DECLARATION_STATEMENT if self.classes_match?(StringVariable,Equal,DefCall)
|
73
|
+
return StatementStructure::DECLARATION_STATEMENT if self.classes_match?(StringVariable,Equal,ArrayAccess)
|
74
|
+
return StatementStructure::DECLARATION_STATEMENT if self.classes_match?(FixnumVariable,Equal,InstanceCallContainer)
|
75
|
+
return StatementStructure::DECLARATION_STATEMENT if self.classes_match?(FixnumVariable,Equal,Literal)
|
76
|
+
return StatementStructure::DECLARATION_STATEMENT if self.classes_match?(FixnumVariable,Equal,DefCall)
|
77
|
+
return StatementStructure::DECLARATION_STATEMENT if self.classes_match?(ArrayVariable,Equal,Literal)
|
78
|
+
return StatementStructure::DECLARATION_STATEMENT if self.classes_match?(ArrayVariable,Equal,DefCall)
|
79
|
+
return StatementStructure::DECLARATION_STATEMENT if self.classes_match?(StatementVariable,Equal,DefCall)
|
80
|
+
return StatementStructure::DECLARATION_STATEMENT if self.classes_match?(VariableContainer,Equal,Literal)
|
81
|
+
# TODO I don't know if this should be possible/allowed
|
82
|
+
return StatementStructure::DECLARATION_STATEMENT if self.classes_match?(Unknown,Equal,Unknown)
|
83
|
+
# TODO I'm not sure whether ArrayAccess should be USAGE_STATEMENT
|
84
|
+
return StatementStructure::DECLARATION_STATEMENT if self.classes_match?(Unknown,Equal,ArrayAccess)
|
85
|
+
return StatementStructure::DECLARATION_STATEMENT if self.classes_match?(StringVariable,Equal,InstanceCallContainer)
|
86
|
+
return StatementStructure::DECLARATION_STATEMENT if self.classes_match?(MethodUsageVariable,Equal,ClassMethodCallContainer)
|
87
|
+
return StatementStructure::DECLARATION_STATEMENT if self.classes_match?(StatementVariable,Equal,ClassMethodCallContainer)
|
88
|
+
return StatementStructure::DECLARATION_STATEMENT if self.classes_match?(RuntimeMethodParameter,Equal,DefCall)
|
89
|
+
return StatementStructure::DECLARATION_STATEMENT if self.classes_match?(UnknownVariable,Equal,InstanceCallContainer)
|
90
|
+
return StatementStructure::DECLARATION_STATEMENT if self.classes_match?(RuntimeMethodParameter,Equal,ClassMethodCallContainer)
|
91
|
+
when 5
|
92
|
+
if self.classes_match?(Unknown,Equal,Unknown,Addition,Unknown)
|
93
|
+
return StatementStructure::DECLARATION_STATEMENT
|
94
|
+
end
|
95
|
+
if self.classes_match?(Unknown,Equal,Unknown,Subtract,Unknown)
|
96
|
+
return StatementStructure::DECLARATION_STATEMENT
|
97
|
+
end
|
98
|
+
if self.classes_match?(Unknown,Equal,FixnumVariable,Addition,FixnumVariable)
|
99
|
+
return StatementStructure::DECLARATION_STATEMENT
|
100
|
+
end
|
101
|
+
if self.classes_match?(Unknown,Equal,InstanceCallContainer,Addition,InstanceCallContainer )
|
102
|
+
return StatementStructure::DECLARATION_STATEMENT
|
103
|
+
end
|
104
|
+
if self.classes_match?(Unknown,Equal,MethodParameter,Addition,MethodParameter )
|
105
|
+
return StatementStructure::DECLARATION_STATEMENT
|
106
|
+
end
|
107
|
+
return StatementStructure::DECLARATION_STATEMENT if self.classes_match?(Unknown,Equal,StringVariable,Addition,StringVariable)
|
108
|
+
# TODO I don't know if I want this classed as a declaration statement since it might be replacing the
|
109
|
+
# value of a variable.
|
110
|
+
return StatementStructure::DECLARATION_STATEMENT if self.classes_match?(FixnumVariable,Equal,FixnumVariable,Addition,FixnumVariable)
|
111
|
+
end
|
112
|
+
|
113
|
+
raise StandardError.new('Unable to determine statement type for "'+self.write+'"'+self.inject('') {|x,y| x += y.class.to_s+' : ' })
|
114
|
+
end
|
115
|
+
|
116
|
+
end
|
@@ -0,0 +1,96 @@
|
|
1
|
+
# TODO I am duplicating variables here with array, index, subject and method_call
|
2
|
+
class ArrayAccess < InstanceCallContainer
|
3
|
+
include VariableIncluded
|
4
|
+
|
5
|
+
attr_reader :array, :index
|
6
|
+
|
7
|
+
def initialize(array,index)
|
8
|
+
@array = array
|
9
|
+
@index = index
|
10
|
+
super(@array,'[Array Access]',index)
|
11
|
+
end
|
12
|
+
|
13
|
+
def write
|
14
|
+
return @array.write+'['+@index.write+']'
|
15
|
+
end
|
16
|
+
|
17
|
+
def describe
|
18
|
+
return @array.describe+'['+@index.describe+']'
|
19
|
+
end
|
20
|
+
|
21
|
+
def response
|
22
|
+
return eval(@array.literalise.write+'['+@index.write+']').to_var
|
23
|
+
end
|
24
|
+
|
25
|
+
def cauldron_method_calls
|
26
|
+
return @array[@index].cauldron_method_calls
|
27
|
+
end
|
28
|
+
|
29
|
+
def copy
|
30
|
+
return ArrayAccess.new(@array.copy,@index.copy)
|
31
|
+
end
|
32
|
+
|
33
|
+
def variable
|
34
|
+
return @array.copy
|
35
|
+
end
|
36
|
+
|
37
|
+
def closure
|
38
|
+
return ['[',']']
|
39
|
+
end
|
40
|
+
|
41
|
+
# Returns all the elements that match the selection criteria just
|
42
|
+
# like the select method. However is this contains an array it
|
43
|
+
# will seach the array.
|
44
|
+
#
|
45
|
+
# @param results An array of current results that match the requirement
|
46
|
+
# of the block.
|
47
|
+
# @param block .
|
48
|
+
#
|
49
|
+
def select_all(results=[],&block)
|
50
|
+
results.push(@array) if block.call(@array)
|
51
|
+
results.push(@index) if block.call(@index)
|
52
|
+
if @array.respond_to?(:select_all)
|
53
|
+
@array.select_all(results,&block)
|
54
|
+
end
|
55
|
+
if @index.respond_to?(:select_all)
|
56
|
+
@index.select_all(results,&block)
|
57
|
+
end
|
58
|
+
return results
|
59
|
+
end
|
60
|
+
|
61
|
+
# Returns true if the passed argument is the same kind of ArrayAccess - in
|
62
|
+
# that it is the same class, array and index.
|
63
|
+
#
|
64
|
+
# @param to The array access that is being compared with this array access
|
65
|
+
# instance to determine if their equivalent.
|
66
|
+
#
|
67
|
+
def equivalent?(to)
|
68
|
+
return false if to.class != self.class
|
69
|
+
return false unless to.array.equivalent?(@array)
|
70
|
+
#return false unless to.array == @array
|
71
|
+
return false unless to.index.equivalent?(@index)
|
72
|
+
#return false unless to.index == @index
|
73
|
+
return true
|
74
|
+
end
|
75
|
+
|
76
|
+
# Returns a string calling the specfied index. e.g. "[4]"
|
77
|
+
#
|
78
|
+
def to_literal_string
|
79
|
+
return write
|
80
|
+
end
|
81
|
+
|
82
|
+
def replace_theory_variables!(mapping)
|
83
|
+
if @array.kind_of?(TheoryVariable) && mapping.has_key?(@array.theory_variable_id)
|
84
|
+
@array = mapping[@array.theory_variable_id].copy
|
85
|
+
elsif @array.respond_to?(:replace_theory_variables!)
|
86
|
+
@array.replace_theory_variables!(mapping)
|
87
|
+
end
|
88
|
+
if @index.kind_of?(TheoryVariable) && mapping.has_key?(@index.theory_variable_id)
|
89
|
+
@index = mapping[@index.theory_variable_id].copy
|
90
|
+
elsif @index.respond_to?(:replace_theory_variables!)
|
91
|
+
@index.replace_theory_variables!(mapping)
|
92
|
+
end
|
93
|
+
|
94
|
+
end
|
95
|
+
|
96
|
+
end
|
@@ -0,0 +1,348 @@
|
|
1
|
+
# A nested statement is a special kind of statement group that contains
|
2
|
+
# a opening statement. For example the .each method of an array would
|
3
|
+
# be a nested statement.
|
4
|
+
#
|
5
|
+
# Below is the parser intrepretaiton for var1.any? { |x| x.include? var2.id }
|
6
|
+
#
|
7
|
+
# var1.any? do |x|
|
8
|
+
# var2 = var1.chop
|
9
|
+
# end
|
10
|
+
#
|
11
|
+
# s(:iter,
|
12
|
+
# s(:call,
|
13
|
+
# s(:call, nil, :var1, s(:arglist)),
|
14
|
+
# :any?,
|
15
|
+
# s(:arglist)
|
16
|
+
# ),
|
17
|
+
# s(:lasgn, :x),
|
18
|
+
# s(:lasgn,
|
19
|
+
# :var2,
|
20
|
+
# s(:call,
|
21
|
+
# s(:call, nil, :var1, s(:arglist)),
|
22
|
+
# :chop,
|
23
|
+
# s(:arglist)
|
24
|
+
# )
|
25
|
+
# )
|
26
|
+
# )
|
27
|
+
#
|
28
|
+
# =========================
|
29
|
+
#
|
30
|
+
# var1.any? { |x| x.include? var2.id }
|
31
|
+
#
|
32
|
+
# s(:iter,
|
33
|
+
# s(:call,
|
34
|
+
# s(:call, nil, :var1, s(:arglist)),
|
35
|
+
# :any?,
|
36
|
+
# s(:arglist)
|
37
|
+
# ),
|
38
|
+
# s(:lasgn, :x),
|
39
|
+
# s(:call,
|
40
|
+
# s(:lvar, :x),
|
41
|
+
# :include?,
|
42
|
+
# s(:arglist,
|
43
|
+
# s(:call,
|
44
|
+
# s(:call, nil, :var2, s(:arglist)),
|
45
|
+
# :id,
|
46
|
+
# s(:arglist)
|
47
|
+
# )
|
48
|
+
# )
|
49
|
+
# )
|
50
|
+
# )
|
51
|
+
#
|
52
|
+
# TODO I might just combine BlockStatement and StatementGroup since you
|
53
|
+
# all groups of statements have a containing statement even if
|
54
|
+
# that statement is a method.
|
55
|
+
#
|
56
|
+
# e.g. ['garrus','wrex'].each do |x|
|
57
|
+
# # internal_statements
|
58
|
+
# end
|
59
|
+
#
|
60
|
+
# This is equivalent to :iter of the parser
|
61
|
+
#
|
62
|
+
class BlockStatement < OpenStatement
|
63
|
+
include ActsAsTrackable
|
64
|
+
include ActsAsStatement
|
65
|
+
|
66
|
+
# TODO I'm not sure whether I need to use a statement since a instance call will generally do. Although
|
67
|
+
# I'll need to fix the tabbing in "write" if I stop it from using statements.
|
68
|
+
#
|
69
|
+
def initialize(statement,block_container=BlockContainer.new(BlockVariable.new),*internal_statements)
|
70
|
+
super(statement,*internal_statements)
|
71
|
+
#@statement = statement
|
72
|
+
|
73
|
+
raise StandardError.new('Expecting block_container ') unless block_container.kind_of?(BlockContainer)
|
74
|
+
@block_container = block_container
|
75
|
+
|
76
|
+
end
|
77
|
+
|
78
|
+
def write(tab=0)
|
79
|
+
l = @statement.write(tab)+' '+Do.new.write+" "+@block_container.write+"\n"
|
80
|
+
self.each do |x|
|
81
|
+
l += x.write(tab+1)+"\n"
|
82
|
+
end
|
83
|
+
tab.times {l += "\t" }
|
84
|
+
l += 'end'+"\n"
|
85
|
+
return l
|
86
|
+
end
|
87
|
+
|
88
|
+
def write_with_uniq_id(tab=0)
|
89
|
+
# Check the file type of tab
|
90
|
+
raise StandardError.new('Unexpexted class "'+tab.class.to_s+'" for Fixnum (number of tabs)') unless tab.kind_of? Fixnum
|
91
|
+
|
92
|
+
line = @statement.write_with_uniq_id(tab)+Do.new.write+" "+@block_container.write_with_uniq_id+"\n"
|
93
|
+
self.each do |x|
|
94
|
+
if x.respond_to?('write_with_uniq_id')
|
95
|
+
line += x.write_with_uniq_id(tab+1)+"\n"
|
96
|
+
else
|
97
|
+
line += x.write(tab+1)+"\n"
|
98
|
+
end
|
99
|
+
end
|
100
|
+
tab.times {line += "\t" }
|
101
|
+
line += 'end'+"\n"
|
102
|
+
return line
|
103
|
+
|
104
|
+
end
|
105
|
+
|
106
|
+
# Writes out the nested statement with the appropriate tabbing but
|
107
|
+
# also includes the value of variables within the output. This
|
108
|
+
# method presumes that the nested statement has been realised.
|
109
|
+
#
|
110
|
+
def write_with_value(tab=0)
|
111
|
+
l = @statement.write_with_value(tab)+" "+Do.new.write+" "+@block_container.write_with_value+"\n"
|
112
|
+
self.each do |x|
|
113
|
+
l += x.write_with_value(tab+1)+"\n"
|
114
|
+
end
|
115
|
+
tab.times {l += "\t" }
|
116
|
+
l += 'end'+"\n"
|
117
|
+
return l
|
118
|
+
end
|
119
|
+
|
120
|
+
def copy
|
121
|
+
|
122
|
+
result = BlockStatement.new(@statement.copy,@block_container.copy,*self.collect {|x| x.copy})
|
123
|
+
# TODO This means the scope id is being incremented for statements only exist for the declaration
|
124
|
+
result.scope_id = scope_id
|
125
|
+
result.scope = scope.copy
|
126
|
+
result.statement_level = statement_level
|
127
|
+
return result
|
128
|
+
end
|
129
|
+
|
130
|
+
# Creates a copy of the current nested statement but without any statements
|
131
|
+
#
|
132
|
+
def copy_base
|
133
|
+
result = BlockStatement.new(@statement.copy,@block_container.copy)
|
134
|
+
# TODO This means the scope id is being incremented for statements only exist for the declaration
|
135
|
+
result.scope_id = scope_id
|
136
|
+
return result
|
137
|
+
end
|
138
|
+
|
139
|
+
# This is a quick check that really only applies to standard statements. It checks
|
140
|
+
# that the statement doesn't just re-declare an existing variable e.g.
|
141
|
+
# var_a = var_b would be classed as simple.
|
142
|
+
#
|
143
|
+
def is_simple?
|
144
|
+
return false
|
145
|
+
end
|
146
|
+
|
147
|
+
# Returns all the variables used in the statement since the
|
148
|
+
# statement should never declare new variables.
|
149
|
+
#
|
150
|
+
def not_declared_variables
|
151
|
+
return @statement.variables
|
152
|
+
end
|
153
|
+
|
154
|
+
# Returns the id of the block variable - although the terminolgy
|
155
|
+
# of declared might imply a = sign essential it is declared here.
|
156
|
+
# TODO My approach implies only one block variable but there could
|
157
|
+
# be more than that. I should allow multiple block variables.
|
158
|
+
def declared_variable_id
|
159
|
+
raise StandardError.new('Not allowing multiple block variables just yet') if @block_container.length > 1
|
160
|
+
return @block_container.first.variable_id
|
161
|
+
end
|
162
|
+
|
163
|
+
# Returns an unpdated nested statement that has been fully realised.
|
164
|
+
#
|
165
|
+
# @param method_map A history object for the nested statement or method the
|
166
|
+
# nested statement resides.
|
167
|
+
#
|
168
|
+
def realise2(method_map)
|
169
|
+
|
170
|
+
# Start by realising the containing method
|
171
|
+
opening_statement = @statement.realise2(method_map)
|
172
|
+
|
173
|
+
# Now realise the block container
|
174
|
+
block_container = @block_container.realise2(method_map)
|
175
|
+
|
176
|
+
# Finally realise the internal statements
|
177
|
+
copied_internal_statements = []
|
178
|
+
self.each do |x|
|
179
|
+
copied_internal_statements.push(x.realise2(method_map))
|
180
|
+
end
|
181
|
+
|
182
|
+
# Now create a duplicate nested statement
|
183
|
+
result = BlockStatement.new(opening_statement,block_container,*copied_internal_statements)
|
184
|
+
result.scope_id = scope_id
|
185
|
+
result.scope = scope.copy
|
186
|
+
result.statement_level = statement_level
|
187
|
+
return result
|
188
|
+
|
189
|
+
end
|
190
|
+
|
191
|
+
# TODO This seems wrong there is no block or opening statement
|
192
|
+
def to_literal_string
|
193
|
+
a = ''
|
194
|
+
self.each do |x|
|
195
|
+
a += x.to_literal_string
|
196
|
+
end
|
197
|
+
return a
|
198
|
+
end
|
199
|
+
|
200
|
+
# Returns true if the opening statement and all internal statements
|
201
|
+
# have been realised.
|
202
|
+
#
|
203
|
+
def realised?
|
204
|
+
return false unless @statement.realised?
|
205
|
+
return false unless @block_container.realised?
|
206
|
+
return false unless self.all? {|x| x.realised? }
|
207
|
+
return true
|
208
|
+
end
|
209
|
+
|
210
|
+
# Returns an array of all the unrealised variables in the nested statement
|
211
|
+
#
|
212
|
+
def unrealised_variables
|
213
|
+
results = []
|
214
|
+
results += @statement.unrealised_variables
|
215
|
+
results += @block_container.unrealised_variables
|
216
|
+
self.each do |x|
|
217
|
+
results += x.unrealised_variables
|
218
|
+
end
|
219
|
+
return results
|
220
|
+
end
|
221
|
+
|
222
|
+
# Returns each unrealised variable
|
223
|
+
#
|
224
|
+
def each_unrealised_variable
|
225
|
+
unrealised_variables.each do |x|
|
226
|
+
yield x
|
227
|
+
end
|
228
|
+
end
|
229
|
+
|
230
|
+
# Returns the number of statements represented by this nested statement.
|
231
|
+
#
|
232
|
+
# NOTE I have been counting the opening statement and closing statement
|
233
|
+
# as separate statements. I'm not sure if this is the write
|
234
|
+
# approach though. I might have line_count and statement_count
|
235
|
+
#
|
236
|
+
def statement_count
|
237
|
+
return self.inject(2) {|count,x| count += x.statement_count}
|
238
|
+
end
|
239
|
+
|
240
|
+
# Returns the first copy of a variable it can find.
|
241
|
+
#
|
242
|
+
# TODO Really it should find the latest version of the variable
|
243
|
+
# working backwards like the RuntimeMethod call. Although
|
244
|
+
# this might be a redundant concept since I don't think there
|
245
|
+
# can ever be more than one variable with the exact id.
|
246
|
+
#
|
247
|
+
def find_variable(id)
|
248
|
+
failed_to_find = lambda{raise StandardError.new("Unable to find variable with id "+id.to_s) }
|
249
|
+
return variables.detect(failed_to_find) {|x| x.variable_id == id}
|
250
|
+
end
|
251
|
+
|
252
|
+
# Returns an array of all the variables contained within the nested
|
253
|
+
# statement.
|
254
|
+
#
|
255
|
+
def variables
|
256
|
+
results = []
|
257
|
+
results += @statement.variables.collect {|x| x.copy}
|
258
|
+
results += @block_container.variables.collect {|x| x.copy}
|
259
|
+
self.each {|x| results += x.variables}
|
260
|
+
return results
|
261
|
+
end
|
262
|
+
|
263
|
+
def find_statement_that_declares_variable(id)
|
264
|
+
@block_container.each do |x|
|
265
|
+
if x.variable_id == id
|
266
|
+
return self.copy
|
267
|
+
end
|
268
|
+
end
|
269
|
+
self.each do |y|
|
270
|
+
if y.kind_of?(Statement)
|
271
|
+
if y.declared_variable_id == id then return y.copy end
|
272
|
+
next
|
273
|
+
end
|
274
|
+
if y.kind_of?(BlockStatement)
|
275
|
+
y.find_statement_that_declares_variable(variable_id)
|
276
|
+
end
|
277
|
+
end
|
278
|
+
# TODO I would rather a custom error
|
279
|
+
raise StandardError.new('Failed to find statement that declared variable id '+id.to_s)
|
280
|
+
end
|
281
|
+
|
282
|
+
# TODO This duplicates allot of the calls in the super.trackify method
|
283
|
+
# Returns a new block statement that has been trackified. A
|
284
|
+
# trackified block statement has a statement call after each
|
285
|
+
# line.
|
286
|
+
#
|
287
|
+
# @param tracking_method A runtime tracking method instance
|
288
|
+
# @param line An array thats length represents the current line.
|
289
|
+
#
|
290
|
+
def trackify(tracking_method,line)
|
291
|
+
|
292
|
+
# First copy the base nested statement and repopulate it
|
293
|
+
result = copy_base
|
294
|
+
|
295
|
+
# Start by trackifying the opening statement
|
296
|
+
opening_variables = abstract_variables_for_tracking(@statement,@block_container)
|
297
|
+
result.push(tracking_statement(tracking_method,line,@statement,opening_variables))
|
298
|
+
|
299
|
+
# For each line in the nested statement include a tracking call
|
300
|
+
# TODO I don't think this would trackify further open statements
|
301
|
+
self.each do |x|
|
302
|
+
result.push(x.copy)
|
303
|
+
|
304
|
+
# Now include a tracking call for after the statement
|
305
|
+
line_variables = abstract_variables_for_tracking(x)
|
306
|
+
# TODO Check that the line is going up
|
307
|
+
result.push tracking_statement(tracking_method,line,x,line_variables)
|
308
|
+
end
|
309
|
+
|
310
|
+
return result
|
311
|
+
|
312
|
+
end
|
313
|
+
|
314
|
+
# Returns a duplicate of this nested statement up until the
|
315
|
+
# the specified limt.
|
316
|
+
#
|
317
|
+
# TODO I need to use an array rather than a fixnum for the limit
|
318
|
+
# since scope is lost otherwise. This seems a bit of hack
|
319
|
+
# and I should revise.
|
320
|
+
#
|
321
|
+
def partial(limit)
|
322
|
+
|
323
|
+
# Check that limit is greater 0
|
324
|
+
raise StandardError.new('At least one line is required to create nested statement') if limit == 0
|
325
|
+
|
326
|
+
# Add the nested statement and reduce the limit
|
327
|
+
result = copy_base
|
328
|
+
limit.pop
|
329
|
+
|
330
|
+
# Goes through each statement contained in the nested statement and adds it
|
331
|
+
# to the returned nested method until the limit has been reached or this
|
332
|
+
# nested statement has exhausted its statements.
|
333
|
+
index = 0
|
334
|
+
while(limit.length >0 && index < self.length)
|
335
|
+
x = self[index]
|
336
|
+
if x.kind_of?(Statement)
|
337
|
+
result.push(x.copy)
|
338
|
+
index += 1
|
339
|
+
limit.pop
|
340
|
+
elsif x.kind_of(BlockStatement)
|
341
|
+
result.push(x.partial(limit))
|
342
|
+
index += 1
|
343
|
+
end
|
344
|
+
end
|
345
|
+
return result
|
346
|
+
end
|
347
|
+
|
348
|
+
end
|