cauldron 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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