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.
Files changed (398) hide show
  1. data/.document +5 -0
  2. data/Gemfile +13 -0
  3. data/LICENSE.txt +20 -0
  4. data/README +1 -0
  5. data/README.rdoc +19 -0
  6. data/Rakefile +53 -0
  7. data/VERSION +1 -0
  8. data/bin/cauldron +10 -0
  9. data/cauldron/.autotest +23 -0
  10. data/cauldron/History.txt +6 -0
  11. data/cauldron/Manifest.txt +8 -0
  12. data/cauldron/README.txt +57 -0
  13. data/cauldron/Rakefile +27 -0
  14. data/cauldron/bin/cauldron +3 -0
  15. data/cauldron/lib/cauldron.rb +3 -0
  16. data/cauldron/test/test_cauldron.rb +8 -0
  17. data/features/cauldron_example_cases.feature +13 -0
  18. data/features/cauldron_generates_runtime_method.feature +12 -0
  19. data/features/cauldron_start_terminal.feature +13 -0
  20. data/features/step_definitions/cauldron_steps.rb +16 -0
  21. data/features/step_definitions/terminal_steps.rb +34 -0
  22. data/features/support/env.rb +19 -0
  23. data/lib/Chain.rb +879 -0
  24. data/lib/ChainMapping.rb +172 -0
  25. data/lib/CodeHandler.rb +517 -0
  26. data/lib/Mapping.rb +26 -0
  27. data/lib/MappingValues.rb +24 -0
  28. data/lib/ScopeDependencies.rb +7 -0
  29. data/lib/Theory.rb +274 -0
  30. data/lib/UnifiedChain.rb +110 -0
  31. data/lib/cauldron.rb +6 -0
  32. data/lib/cauldron/conversion.rb +15 -0
  33. data/lib/cauldron/pot.rb +134 -0
  34. data/lib/cauldron/sexp2cauldron.rb +156 -0
  35. data/lib/cauldron/terminal.rb +120 -0
  36. data/lib/cauldron/theory_factory.rb +10 -0
  37. data/lib/core/ActsAsCode.rb +25 -0
  38. data/lib/core/BlockToken.rb +33 -0
  39. data/lib/core/CCall.rb +7 -0
  40. data/lib/core/CTestCase.rb +27 -0
  41. data/lib/core/ClassMethodCallContainer.rb +45 -0
  42. data/lib/core/Container.rb +85 -0
  43. data/lib/core/InstanceCallContainer.rb +272 -0
  44. data/lib/core/MethodUsage.rb +66 -0
  45. data/lib/core/PrintVariables.rb +25 -0
  46. data/lib/core/TheoryGenerator.rb +764 -0
  47. data/lib/core/Token.rb +7 -0
  48. data/lib/core/assignment/Assignment.rb +18 -0
  49. data/lib/core/assignment/Equal.rb +39 -0
  50. data/lib/core/assignment/Equivalent.rb +20 -0
  51. data/lib/core/assignment/NotEqual.rb +14 -0
  52. data/lib/core/call_container/CallContainer.rb +66 -0
  53. data/lib/core/class_method_call/New.rb +15 -0
  54. data/lib/core/class_method_call/RuntimeClassMethodCall.rb +31 -0
  55. data/lib/core/declaration/Declaration.rb +16 -0
  56. data/lib/core/declaration/LiteralDeclaration.rb +47 -0
  57. data/lib/core/declaration/VariableDeclaration.rb +59 -0
  58. data/lib/core/instance_call/ArrayEach.rb +23 -0
  59. data/lib/core/instance_call/ArrayLength.rb +15 -0
  60. data/lib/core/instance_call/Chop.rb +28 -0
  61. data/lib/core/instance_call/Copy.rb +22 -0
  62. data/lib/core/instance_call/DeclaredVariable.rb +18 -0
  63. data/lib/core/instance_call/InstanceCall.rb +77 -0
  64. data/lib/core/instance_call/Params.rb +15 -0
  65. data/lib/core/instance_call/Push.rb +20 -0
  66. data/lib/core/instance_call/StringLength.rb +32 -0
  67. data/lib/core/instance_call/Times.rb +20 -0
  68. data/lib/core/instance_call/instance_calls.rb +168 -0
  69. data/lib/core/instance_call/length_equal.rb +15 -0
  70. data/lib/core/kernal/EvalCall.rb +15 -0
  71. data/lib/core/kernal/LocalVariablesCall.rb +15 -0
  72. data/lib/core/literal/Literal.rb +111 -0
  73. data/lib/core/literal/Raw.rb +23 -0
  74. data/lib/core/literal/RuntimeMethodLiteral.rb +21 -0
  75. data/lib/core/literal/StatementLiteral.rb +28 -0
  76. data/lib/core/method_call/AvailableVariablesCall.rb +25 -0
  77. data/lib/core/method_call/ClassCall.rb +33 -0
  78. data/lib/core/method_call/DefCall.rb +72 -0
  79. data/lib/core/method_call/EvaluateClassCall.rb +29 -0
  80. data/lib/core/method_call/MethodNameCall.rb +27 -0
  81. data/lib/core/method_call/ToDeclarationCall.rb +15 -0
  82. data/lib/core/requirement/Requirement.rb +291 -0
  83. data/lib/core/runtime_class/ArrayClass.rb +19 -0
  84. data/lib/core/runtime_class/ClassCallClass.rb +23 -0
  85. data/lib/core/runtime_class/ClassEvaluationClass.rb +19 -0
  86. data/lib/core/runtime_class/ClassName.rb +18 -0
  87. data/lib/core/runtime_class/DefCallClass.rb +21 -0
  88. data/lib/core/runtime_class/EqualClass.rb +19 -0
  89. data/lib/core/runtime_class/FixnumClass.rb +15 -0
  90. data/lib/core/runtime_class/IfStatementClass.rb +12 -0
  91. data/lib/core/runtime_class/InstanceCallClass.rb +19 -0
  92. data/lib/core/runtime_class/InstanceCallContainerClass.rb +16 -0
  93. data/lib/core/runtime_class/InstanceClassCallClass.rb +19 -0
  94. data/lib/core/runtime_class/LiteralClass.rb +19 -0
  95. data/lib/core/runtime_class/MethodParameterClass.rb +27 -0
  96. data/lib/core/runtime_class/MethodUsageClass.rb +27 -0
  97. data/lib/core/runtime_class/RequirementClass.rb +19 -0
  98. data/lib/core/runtime_class/ReturnClass.rb +21 -0
  99. data/lib/core/runtime_class/RuntimeClass.rb +30 -0
  100. data/lib/core/runtime_class/RuntimeClassClass.rb +19 -0
  101. data/lib/core/runtime_class/RuntimeMethodClass.rb +34 -0
  102. data/lib/core/runtime_class/StatementClass.rb +53 -0
  103. data/lib/core/runtime_class/StringClass.rb +23 -0
  104. data/lib/core/runtime_class/StringLengthClass.rb +19 -0
  105. data/lib/core/runtime_class/StringVariableClass.rb +19 -0
  106. data/lib/core/runtime_class/ThisClass.rb +15 -0
  107. data/lib/core/runtime_class/UnknownClass.rb +23 -0
  108. data/lib/core/runtime_class/class_names.rb +95 -0
  109. data/lib/core/runtime_class/runtime_class.rb +123 -0
  110. data/lib/core/runtime_method/ActsAsRuntimeMethod.rb +300 -0
  111. data/lib/core/runtime_method/ParametersContainer.rb +29 -0
  112. data/lib/core/runtime_method/RealisedRuntimeMethod.rb +94 -0
  113. data/lib/core/runtime_method/RuntimeMethod.rb +817 -0
  114. data/lib/core/runtime_method/WriteParameters.rb +35 -0
  115. data/lib/core/statement/ActsAsStatement.rb +116 -0
  116. data/lib/core/statement/ArrayAccess.rb +96 -0
  117. data/lib/core/statement/BlockStatement.rb +348 -0
  118. data/lib/core/statement/DeclarationStatement.rb +19 -0
  119. data/lib/core/statement/HackStatement.rb +25 -0
  120. data/lib/core/statement/HashAccess.rb +18 -0
  121. data/lib/core/statement/OpenStatement.rb +171 -0
  122. data/lib/core/statement/RealisedStatement.rb +5 -0
  123. data/lib/core/statement/SingleLineBlockStatement.rb +39 -0
  124. data/lib/core/statement/Statement.rb +1223 -0
  125. data/lib/core/statement/StatementDependencies.rb +271 -0
  126. data/lib/core/statement/StatementGroup.rb +157 -0
  127. data/lib/core/statement/StatementStructure2.rb +224 -0
  128. data/lib/core/statement/TheoryStatement.rb +60 -0
  129. data/lib/core/statement/TopologicalStatements.rb +34 -0
  130. data/lib/core/structure/DeclareNewInstanceStructure.rb +49 -0
  131. data/lib/core/structure/DeclareRuntimeMethodStructure.rb +34 -0
  132. data/lib/core/structure/DeclareVariableAsLiteralStructure.rb +31 -0
  133. data/lib/core/structure/DeclareVariableAsVariableStructure.rb +52 -0
  134. data/lib/core/structure/FixnumAdditionStructure.rb +56 -0
  135. data/lib/core/structure/InstanceCallContainerStructure.rb +50 -0
  136. data/lib/core/structure/InstanceCallStructure.rb +53 -0
  137. data/lib/core/structure/InstanceMethodCallStructure.rb +21 -0
  138. data/lib/core/structure/ReturnStructure.rb +20 -0
  139. data/lib/core/structure/StatementStructure.rb +11 -0
  140. data/lib/core/syntax/Addition.rb +25 -0
  141. data/lib/core/syntax/BlockContainer.rb +130 -0
  142. data/lib/core/syntax/Boolean.rb +15 -0
  143. data/lib/core/syntax/Code.rb +11 -0
  144. data/lib/core/syntax/Do.rb +20 -0
  145. data/lib/core/syntax/False.rb +12 -0
  146. data/lib/core/syntax/If.rb +28 -0
  147. data/lib/core/syntax/IfContainer.rb +100 -0
  148. data/lib/core/syntax/Nil.rb +15 -0
  149. data/lib/core/syntax/Return.rb +33 -0
  150. data/lib/core/syntax/Subtract.rb +19 -0
  151. data/lib/core/syntax/This.rb +40 -0
  152. data/lib/core/syntax/True.rb +20 -0
  153. data/lib/core/syntax/syntax.rb +24 -0
  154. data/lib/core/tracking/ActsAsTrackable.rb +65 -0
  155. data/lib/core/tracking/History.rb +167 -0
  156. data/lib/core/tracking/RuntimeTrackingMethod.rb +32 -0
  157. data/lib/core/tracking/Step.rb +52 -0
  158. data/lib/core/variable/ArrayVariable.rb +76 -0
  159. data/lib/core/variable/BaseVariable.rb +154 -0
  160. data/lib/core/variable/BlockVariable.rb +92 -0
  161. data/lib/core/variable/FixnumVariable.rb +36 -0
  162. data/lib/core/variable/HistoryVariable.rb +8 -0
  163. data/lib/core/variable/MethodParameter.rb +206 -0
  164. data/lib/core/variable/MethodUsageVariable.rb +60 -0
  165. data/lib/core/variable/NilVariable.rb +29 -0
  166. data/lib/core/variable/RuntimeMethodParameter.rb +67 -0
  167. data/lib/core/variable/StatementVariable.rb +72 -0
  168. data/lib/core/variable/StepVariable.rb +7 -0
  169. data/lib/core/variable/StringVariable.rb +46 -0
  170. data/lib/core/variable/TypeVariable.rb +72 -0
  171. data/lib/core/variable/Unknown.rb +116 -0
  172. data/lib/core/variable/UnknownVariable.rb +29 -0
  173. data/lib/core/variable/Variable.rb +70 -0
  174. data/lib/core/variable/VariableContainer.rb +28 -0
  175. data/lib/core/variable/VariableIncluded.rb +27 -0
  176. data/lib/core/variable/VariableReference.rb +85 -0
  177. data/lib/error/FailedToFindStatementContainerError.rb +7 -0
  178. data/lib/error/FailedToFindStatementError.rb +7 -0
  179. data/lib/error/FailedToFindVariableError.rb +7 -0
  180. data/lib/error/FailedToLiteraliseError.rb +7 -0
  181. data/lib/error/FailedVariableMatch.rb +7 -0
  182. data/lib/error/ImproperStatementUsageError.rb +7 -0
  183. data/lib/error/IncompatiableRequirementsError.rb +7 -0
  184. data/lib/error/InvalidStatementError.rb +7 -0
  185. data/lib/error/MethodSizeError.rb +7 -0
  186. data/lib/error/RuntimeSyntaxError.rb +7 -0
  187. data/lib/error/UnexpectedStatementTypeError.rb +7 -0
  188. data/lib/error/UnknownStatementType.rb +7 -0
  189. data/lib/error/UnliteralisableError.rb +7 -0
  190. data/lib/implemented_chain.rb +34 -0
  191. data/lib/intrinsic/IntrinsicLastRuntimeMethod.rb +20 -0
  192. data/lib/intrinsic/IntrinsicLiteral.rb +26 -0
  193. data/lib/intrinsic/IntrinsicObject.rb +22 -0
  194. data/lib/intrinsic/IntrinsicRuntimeMethod.rb +27 -0
  195. data/lib/intrinsic/IntrinsicTestCases.rb +17 -0
  196. data/lib/logger/StandardLogger.rb +62 -0
  197. data/lib/required.rb +236 -0
  198. data/lib/ruby_code/Array.rb +95 -0
  199. data/lib/ruby_code/Fixnum.rb +39 -0
  200. data/lib/ruby_code/Hash.rb +25 -0
  201. data/lib/ruby_code/NilClass.rb +19 -0
  202. data/lib/ruby_code/Object.rb +24 -0
  203. data/lib/ruby_code/String.rb +86 -0
  204. data/lib/ruby_code/Symbol.rb +7 -0
  205. data/lib/standard_library/Tasks.rb +12 -0
  206. data/lib/theories.rb +143 -0
  207. data/lib/theory/ActionImplementation.rb +17 -0
  208. data/lib/theory/TheoryAction.rb +70 -0
  209. data/lib/theory/TheoryChainValidator.rb +101 -0
  210. data/lib/theory/TheoryComponent.rb +42 -0
  211. data/lib/theory/TheoryConnector.rb +755 -0
  212. data/lib/theory/TheoryDependent.rb +135 -0
  213. data/lib/theory/TheoryImplementation.rb +74 -0
  214. data/lib/theory/TheoryResult.rb +131 -0
  215. data/lib/theory/TheoryVariable.rb +63 -0
  216. data/lib/theory/theory_collection.rb +62 -0
  217. data/lib/util/ClassEvaluation.rb +68 -0
  218. data/lib/util/CodeEvaluation.rb +35 -0
  219. data/lib/util/DeclarationStatementEvaluation.rb +31 -0
  220. data/lib/util/MethodEvaluation.rb +49 -0
  221. data/lib/util/MethodTester.rb +71 -0
  222. data/lib/util/MethodValidation.rb +145 -0
  223. data/lib/util/MethodWriter.rb +66 -0
  224. data/lib/util/Parser.rb +299 -0
  225. data/lib/util/StatementCheck.rb +42 -0
  226. data/lib/util/StringToTheory.rb +119 -0
  227. data/lib/util/System.rb +8 -0
  228. data/spec/cauldron/pot_spec.rb +6 -0
  229. data/spec/cauldron/runtime_method_spec.rb +36 -0
  230. data/spec/cauldron/sexp_2_cauldron_spec.rb +26 -0
  231. data/spec/cauldron/terminal_spec.rb +38 -0
  232. data/spec/cauldron/theory_action_spec.rb +5 -0
  233. data/spec/spec_helper.rb +4 -0
  234. data/test/fixtures/chains/1/declaration.txt +26 -0
  235. data/test/fixtures/chains/1/dump +0 -0
  236. data/test/fixtures/chains/2/declaration.txt +26 -0
  237. data/test/fixtures/chains/2/dump +0 -0
  238. data/test/fixtures/chains/3/declaration.txt +26 -0
  239. data/test/fixtures/chains/3/dump +0 -0
  240. data/test/fixtures/implementation_results/0/declaration.txt +3 -0
  241. data/test/fixtures/implementation_results/0/dump +0 -0
  242. data/test/fixtures/theories/0/declaration.txt +9 -0
  243. data/test/fixtures/theories/0/desc +10 -0
  244. data/test/fixtures/theories/0/dump +0 -0
  245. data/test/fixtures/theories/1/declaration.txt +15 -0
  246. data/test/fixtures/theories/1/desc +11 -0
  247. data/test/fixtures/theories/1/dump +0 -0
  248. data/test/fixtures/theories/10/declaration.txt +23 -0
  249. data/test/fixtures/theories/10/desc +17 -0
  250. data/test/fixtures/theories/10/dump +0 -0
  251. data/test/fixtures/theories/11/declaration.txt +20 -0
  252. data/test/fixtures/theories/11/desc +14 -0
  253. data/test/fixtures/theories/11/dump +0 -0
  254. data/test/fixtures/theories/12/declaration.txt +18 -0
  255. data/test/fixtures/theories/12/desc +12 -0
  256. data/test/fixtures/theories/12/dump +0 -0
  257. data/test/fixtures/theories/13/declaration.txt +24 -0
  258. data/test/fixtures/theories/13/desc +20 -0
  259. data/test/fixtures/theories/13/dump +0 -0
  260. data/test/fixtures/theories/14/declaration.txt +26 -0
  261. data/test/fixtures/theories/14/desc +20 -0
  262. data/test/fixtures/theories/14/dump +0 -0
  263. data/test/fixtures/theories/15/declaration.txt +20 -0
  264. data/test/fixtures/theories/15/desc +14 -0
  265. data/test/fixtures/theories/15/dump +0 -0
  266. data/test/fixtures/theories/16/declaration.txt +30 -0
  267. data/test/fixtures/theories/16/desc +14 -0
  268. data/test/fixtures/theories/16/dump +0 -0
  269. data/test/fixtures/theories/17/declaration.txt +25 -0
  270. data/test/fixtures/theories/17/desc +11 -0
  271. data/test/fixtures/theories/17/dump +0 -0
  272. data/test/fixtures/theories/18/declaration.txt +23 -0
  273. data/test/fixtures/theories/18/desc +11 -0
  274. data/test/fixtures/theories/18/dump +0 -0
  275. data/test/fixtures/theories/19/declaration.txt +23 -0
  276. data/test/fixtures/theories/19/desc +11 -0
  277. data/test/fixtures/theories/19/dump +0 -0
  278. data/test/fixtures/theories/2/declaration.txt +12 -0
  279. data/test/fixtures/theories/2/desc +10 -0
  280. data/test/fixtures/theories/2/dump +0 -0
  281. data/test/fixtures/theories/20/declaration.txt +23 -0
  282. data/test/fixtures/theories/20/desc +17 -0
  283. data/test/fixtures/theories/20/dump +0 -0
  284. data/test/fixtures/theories/3/declaration.txt +19 -0
  285. data/test/fixtures/theories/3/desc +11 -0
  286. data/test/fixtures/theories/3/dump +0 -0
  287. data/test/fixtures/theories/4/declaration.txt +11 -0
  288. data/test/fixtures/theories/4/desc +11 -0
  289. data/test/fixtures/theories/4/dump +0 -0
  290. data/test/fixtures/theories/5/declaration.txt +6 -0
  291. data/test/fixtures/theories/5/desc +9 -0
  292. data/test/fixtures/theories/5/dump +0 -0
  293. data/test/fixtures/theories/6/declaration.txt +13 -0
  294. data/test/fixtures/theories/6/desc +11 -0
  295. data/test/fixtures/theories/6/dump +0 -0
  296. data/test/fixtures/theories/7/declaration.txt +19 -0
  297. data/test/fixtures/theories/7/desc +11 -0
  298. data/test/fixtures/theories/7/dump +0 -0
  299. data/test/fixtures/theories/8/declaration.txt +21 -0
  300. data/test/fixtures/theories/8/desc +11 -0
  301. data/test/fixtures/theories/8/dump +0 -0
  302. data/test/fixtures/theories/9/declaration.txt +24 -0
  303. data/test/fixtures/theories/9/desc +20 -0
  304. data/test/fixtures/theories/9/dump +0 -0
  305. data/test/fixtures/theory_implementations/0/declaration.txt +11 -0
  306. data/test/fixtures/theory_implementations/0/desc.txt +9 -0
  307. data/test/fixtures/theory_implementations/0/dump +0 -0
  308. data/test/fixtures/theory_implementations/0/theory_id +1 -0
  309. data/test/fixtures/theory_implementations/1/desc.txt +9 -0
  310. data/test/fixtures/theory_implementations/1/dump +0 -0
  311. data/test/fixtures/theory_implementations/1/theory_id +1 -0
  312. data/test/fixtures/theory_implementations/2/desc.txt +9 -0
  313. data/test/fixtures/theory_implementations/2/dump +0 -0
  314. data/test/fixtures/theory_implementations/2/theory_id +1 -0
  315. data/test/output/simple_method.txt +6 -0
  316. data/test/output/test_method/first_possible_method.txt +6 -0
  317. data/test/output/test_simple_cases/simple_case_01.txt +8 -0
  318. data/test/output/test_simple_cases/simple_case_02.txt +7 -0
  319. data/test/output/test_simple_cases/simple_case_03.txt +8 -0
  320. data/test/output/test_simple_cases/simple_case_04.txt +8 -0
  321. data/test/output/test_simple_cases/simple_case_05.txt +8 -0
  322. data/test/output/test_simple_cases/simple_case_06.txt +9 -0
  323. data/test/output/test_simple_cases/simple_case_07.txt +9 -0
  324. data/test/output/test_simple_cases/simple_case_08.txt +9 -0
  325. data/test/tc_contextual_variables.rb +87 -0
  326. data/test/tc_describe.rb +47 -0
  327. data/test/tc_method.rb +133 -0
  328. data/test/tc_requirement.rb +30 -0
  329. data/test/tc_suite_complete.rb +26 -0
  330. data/test/tc_variable.rb +52 -0
  331. data/test/ts_complete.rb +84 -0
  332. data/test/ts_stable.rb +81 -0
  333. data/test/unit/core/declaration/tc_literal_declaration.rb +34 -0
  334. data/test/unit/core/method_call/tc_class_call.rb +20 -0
  335. data/test/unit/core/runtime_method/tc_realised_runtime_method.rb +129 -0
  336. data/test/unit/core/runtime_method/tc_runtime_method.rb +616 -0
  337. data/test/unit/core/statement/tc_array_access.rb +63 -0
  338. data/test/unit/core/statement/tc_block_statement.rb +51 -0
  339. data/test/unit/core/statement/tc_hack_statement.rb +26 -0
  340. data/test/unit/core/statement/tc_open_statement.rb +70 -0
  341. data/test/unit/core/statement/tc_statement.rb +681 -0
  342. data/test/unit/core/statement/tc_statement_dependencies.rb +146 -0
  343. data/test/unit/core/statement/tc_statement_group.rb +35 -0
  344. data/test/unit/core/statement/tc_statement_replace_variable.rb +61 -0
  345. data/test/unit/core/statement/tc_theory_statement.rb +51 -0
  346. data/test/unit/core/structure/tc_declare_new_instance_structure.rb +41 -0
  347. data/test/unit/core/structure/tc_declare_variable_as_literal_structure.rb +41 -0
  348. data/test/unit/core/structure/tc_declare_variable_as_variable_structure.rb +66 -0
  349. data/test/unit/core/structure/tc_instance_call_container_structure.rb +41 -0
  350. data/test/unit/core/structure/tc_return_structure.rb +32 -0
  351. data/test/unit/core/syntax/tc_block_container.rb +32 -0
  352. data/test/unit/core/syntax/tc_if_container.rb +39 -0
  353. data/test/unit/core/tc_class_method_call.rb +34 -0
  354. data/test/unit/core/tc_container.rb +41 -0
  355. data/test/unit/core/tc_ctest_case.rb +25 -0
  356. data/test/unit/core/tc_instance_call_container.rb +93 -0
  357. data/test/unit/core/tc_literal.rb +30 -0
  358. data/test/unit/core/tc_theory_generator.rb +336 -0
  359. data/test/unit/core/tc_theory_generator_heavy.rb +42 -0
  360. data/test/unit/core/tracking/tc_history.rb +102 -0
  361. data/test/unit/core/tracking/tc_step.rb +65 -0
  362. data/test/unit/core/variable/tc_array_variable.rb +61 -0
  363. data/test/unit/core/variable/tc_block_variable.rb +17 -0
  364. data/test/unit/core/variable/tc_fixnum_variable.rb +54 -0
  365. data/test/unit/core/variable/tc_method_parameter_variable.rb +22 -0
  366. data/test/unit/core/variable/tc_runtime_method_variable.rb +32 -0
  367. data/test/unit/core/variable/tc_string_variable.rb +37 -0
  368. data/test/unit/core/variable/tc_unknown.rb +24 -0
  369. data/test/unit/core/variable/tc_variable_reference.rb +28 -0
  370. data/test/unit/ruby_code/tc_array.rb +64 -0
  371. data/test/unit/ruby_code/tc_fixnum.rb +18 -0
  372. data/test/unit/ruby_code/tc_hash.rb +41 -0
  373. data/test/unit/ruby_code/tc_string.rb +38 -0
  374. data/test/unit/tc_chain.rb +434 -0
  375. data/test/unit/tc_chain_mapping.rb +62 -0
  376. data/test/unit/tc_chain_with_case_1.rb +169 -0
  377. data/test/unit/tc_instance_call.rb +40 -0
  378. data/test/unit/tc_instance_call_structure.rb +35 -0
  379. data/test/unit/tc_method_usage.rb +35 -0
  380. data/test/unit/tc_pot.rb +124 -0
  381. data/test/unit/tc_runtime_tracking_method.rb +40 -0
  382. data/test/unit/tc_statement_structure_2.rb +43 -0
  383. data/test/unit/tc_theory.rb +533 -0
  384. data/test/unit/tc_variable_declaration.rb +32 -0
  385. data/test/unit/theory/tc_theory_action.rb +80 -0
  386. data/test/unit/theory/tc_theory_action_implementation.rb +23 -0
  387. data/test/unit/theory/tc_theory_chain_validator.rb +340 -0
  388. data/test/unit/theory/tc_theory_connector.rb +396 -0
  389. data/test/unit/theory/tc_theory_dependent.rb +151 -0
  390. data/test/unit/theory/tc_theory_implementation.rb +133 -0
  391. data/test/unit/theory/tc_theory_result.rb +111 -0
  392. data/test/unit/theory/tc_theory_variable.rb +45 -0
  393. data/test/unit/util/tc_method_validation.rb +98 -0
  394. data/test/unit/util/tc_parser.rb +108 -0
  395. data/test/unit/util/tc_string_to_theory.rb +299 -0
  396. data/test/unit/variable/tc_method_usage_variable.rb +25 -0
  397. data/tmp/runtime_method_evaluation.rb +10 -0
  398. metadata +522 -0
@@ -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
@@ -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