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