cauldron 0.1.3 → 0.1.5

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 (409) hide show
  1. data/.gitignore +51 -0
  2. data/Gemfile +6 -3
  3. data/Gemfile.lock +16 -3
  4. data/Rakefile +94 -92
  5. data/VERSION +1 -1
  6. data/bin/cauldron +2 -2
  7. data/cauldron.gemspec +15 -451
  8. data/features/cauldron_new_approach.feature +46 -0
  9. data/features/step_definitions/cauldron_steps.rb +11 -0
  10. data/features/step_definitions/terminal_steps.rb +0 -2
  11. data/features/support/env.rb +11 -1
  12. data/features/support/hooks.rb +5 -0
  13. data/lib/cauldron.rb +13 -7
  14. data/lib/cauldron/array_reverse_operator.rb +39 -0
  15. data/lib/cauldron/concat_operator.rb +34 -0
  16. data/lib/cauldron/if_relationship.rb +37 -0
  17. data/lib/cauldron/numeric_operator.rb +45 -0
  18. data/lib/cauldron/pot.rb +54 -162
  19. data/lib/cauldron/relationship.rb +5 -0
  20. data/lib/cauldron/terminal.rb +4 -60
  21. data/lib/cauldron/version.rb +3 -0
  22. data/lib/core/string.rb +21 -0
  23. data/sandbox.rb +27 -6
  24. data/spec/cauldron/array_reverse_operator_spec.rb +59 -0
  25. data/spec/cauldron/concat_operator_spec.rb +89 -0
  26. data/spec/cauldron/if_relationship_spec.rb +25 -0
  27. data/spec/cauldron/numeric_operator_spec.rb +70 -0
  28. data/spec/cauldron/pot_spec.rb +81 -151
  29. data/spec/cauldron/terminal_spec.rb +1 -39
  30. data/spec/examples/adding_if_statement.yml +13 -0
  31. data/spec/examples/simple_head_theory.txt +13 -0
  32. data/spec/spec_helper.rb +1 -14
  33. data/tasks/theory_tasks.rake +207 -207
  34. metadata +92 -532
  35. data/cauldron/.autotest +0 -23
  36. data/cauldron/History.txt +0 -6
  37. data/cauldron/Manifest.txt +0 -8
  38. data/cauldron/README.txt +0 -57
  39. data/cauldron/Rakefile +0 -27
  40. data/cauldron/bin/cauldron +0 -3
  41. data/cauldron/lib/cauldron.rb +0 -3
  42. data/cauldron/test/test_cauldron.rb +0 -8
  43. data/features/cauldron_example_cases.feature +0 -13
  44. data/features/cauldron_generates_runtime_method.feature +0 -16
  45. data/features/cauldron_generates_single_paramter_methods.feature +0 -25
  46. data/features/cauldron_interactive_start_terminal.feature +0 -17
  47. data/features/cauldron_quit_terminal.feature +0 -9
  48. data/features/cauldron_start_terminal.feature +0 -12
  49. data/features/support/method_1.example +0 -3
  50. data/features/support/method_2.example +0 -6
  51. data/lib/Chain.rb +0 -771
  52. data/lib/ChainMapping.rb +0 -172
  53. data/lib/CodeHandler.rb +0 -513
  54. data/lib/Mapping.rb +0 -27
  55. data/lib/MappingValues.rb +0 -24
  56. data/lib/PartialChain.rb +0 -253
  57. data/lib/Theory.rb +0 -295
  58. data/lib/UnifiedChain.rb +0 -351
  59. data/lib/cauldron/conversion.rb +0 -15
  60. data/lib/cauldron/demos.rb +0 -280
  61. data/lib/cauldron/env.rb +0 -1
  62. data/lib/cauldron/sexp2cauldron.rb +0 -139
  63. data/lib/cauldron/theory_factory.rb +0 -10
  64. data/lib/cauldron/util/home.rb +0 -21
  65. data/lib/cauldron/util/saver.rb +0 -45
  66. data/lib/core/ActsAsCode.rb +0 -25
  67. data/lib/core/BlockToken.rb +0 -33
  68. data/lib/core/CCall.rb +0 -7
  69. data/lib/core/CTestCase.rb +0 -27
  70. data/lib/core/ClassMethodCallContainer.rb +0 -58
  71. data/lib/core/Container.rb +0 -95
  72. data/lib/core/InstanceCallContainer.rb +0 -298
  73. data/lib/core/MethodUsage.rb +0 -65
  74. data/lib/core/PrintVariables.rb +0 -25
  75. data/lib/core/TheoryGenerator.rb +0 -753
  76. data/lib/core/Token.rb +0 -7
  77. data/lib/core/assignment/Assignment.rb +0 -18
  78. data/lib/core/assignment/Equal.rb +0 -39
  79. data/lib/core/assignment/Equivalent.rb +0 -20
  80. data/lib/core/assignment/NotEqual.rb +0 -14
  81. data/lib/core/call_container/CallContainer.rb +0 -72
  82. data/lib/core/class_method_call/New.rb +0 -15
  83. data/lib/core/class_method_call/RuntimeClassMethodCall.rb +0 -31
  84. data/lib/core/declaration/Declaration.rb +0 -16
  85. data/lib/core/declaration/LiteralDeclaration.rb +0 -47
  86. data/lib/core/declaration/VariableDeclaration.rb +0 -59
  87. data/lib/core/instance_call/ArrayEach.rb +0 -23
  88. data/lib/core/instance_call/ArrayLength.rb +0 -15
  89. data/lib/core/instance_call/Chop.rb +0 -19
  90. data/lib/core/instance_call/Copy.rb +0 -22
  91. data/lib/core/instance_call/DeclaredVariable.rb +0 -18
  92. data/lib/core/instance_call/InstanceCall.rb +0 -77
  93. data/lib/core/instance_call/Params.rb +0 -15
  94. data/lib/core/instance_call/Push.rb +0 -20
  95. data/lib/core/instance_call/StringLength.rb +0 -32
  96. data/lib/core/instance_call/Times.rb +0 -20
  97. data/lib/core/instance_call/instance_calls.rb +0 -176
  98. data/lib/core/instance_call/length_equal.rb +0 -15
  99. data/lib/core/kernal/EvalCall.rb +0 -15
  100. data/lib/core/kernal/LocalVariablesCall.rb +0 -15
  101. data/lib/core/literal/Literal.rb +0 -111
  102. data/lib/core/literal/Raw.rb +0 -23
  103. data/lib/core/literal/RuntimeMethodLiteral.rb +0 -21
  104. data/lib/core/literal/StatementLiteral.rb +0 -28
  105. data/lib/core/method_call/AvailableVariablesCall.rb +0 -25
  106. data/lib/core/method_call/ClassCall.rb +0 -33
  107. data/lib/core/method_call/DefCall.rb +0 -72
  108. data/lib/core/method_call/EvaluateClassCall.rb +0 -29
  109. data/lib/core/method_call/MethodNameCall.rb +0 -27
  110. data/lib/core/method_call/ToDeclarationCall.rb +0 -15
  111. data/lib/core/requirement/Requirement.rb +0 -292
  112. data/lib/core/runtime_class/ArrayClass.rb +0 -19
  113. data/lib/core/runtime_class/ClassCallClass.rb +0 -23
  114. data/lib/core/runtime_class/ClassEvaluationClass.rb +0 -19
  115. data/lib/core/runtime_class/ClassName.rb +0 -18
  116. data/lib/core/runtime_class/DefCallClass.rb +0 -21
  117. data/lib/core/runtime_class/EqualClass.rb +0 -19
  118. data/lib/core/runtime_class/FixnumClass.rb +0 -15
  119. data/lib/core/runtime_class/InstanceCallClass.rb +0 -19
  120. data/lib/core/runtime_class/InstanceCallContainerClass.rb +0 -16
  121. data/lib/core/runtime_class/InstanceClassCallClass.rb +0 -19
  122. data/lib/core/runtime_class/LiteralClass.rb +0 -19
  123. data/lib/core/runtime_class/MethodParameterClass.rb +0 -27
  124. data/lib/core/runtime_class/MethodUsageClass.rb +0 -27
  125. data/lib/core/runtime_class/RequirementClass.rb +0 -19
  126. data/lib/core/runtime_class/ReturnClass.rb +0 -21
  127. data/lib/core/runtime_class/RuntimeClass.rb +0 -30
  128. data/lib/core/runtime_class/RuntimeClassClass.rb +0 -19
  129. data/lib/core/runtime_class/RuntimeMethodClass.rb +0 -34
  130. data/lib/core/runtime_class/StatementClass.rb +0 -53
  131. data/lib/core/runtime_class/StringClass.rb +0 -23
  132. data/lib/core/runtime_class/StringLengthClass.rb +0 -19
  133. data/lib/core/runtime_class/StringVariableClass.rb +0 -19
  134. data/lib/core/runtime_class/ThisClass.rb +0 -15
  135. data/lib/core/runtime_class/UnknownClass.rb +0 -23
  136. data/lib/core/runtime_class/class_names.rb +0 -95
  137. data/lib/core/runtime_class/runtime_class.rb +0 -123
  138. data/lib/core/runtime_method/ActsAsRuntimeMethod.rb +0 -293
  139. data/lib/core/runtime_method/ParametersContainer.rb +0 -29
  140. data/lib/core/runtime_method/RealisedRuntimeMethod.rb +0 -94
  141. data/lib/core/runtime_method/RuntimeMethod.rb +0 -814
  142. data/lib/core/runtime_method/WriteParameters.rb +0 -35
  143. data/lib/core/statement/ActsAsStatement.rb +0 -20
  144. data/lib/core/statement/ArrayAccess.rb +0 -122
  145. data/lib/core/statement/BlockStatement.rb +0 -348
  146. data/lib/core/statement/DeclarationStatement.rb +0 -19
  147. data/lib/core/statement/HackStatement.rb +0 -25
  148. data/lib/core/statement/HashAccess.rb +0 -18
  149. data/lib/core/statement/OpenStatement.rb +0 -178
  150. data/lib/core/statement/RealisedStatement.rb +0 -5
  151. data/lib/core/statement/SingleLineBlockStatement.rb +0 -39
  152. data/lib/core/statement/Statement.rb +0 -1091
  153. data/lib/core/statement/StatementGroup.rb +0 -157
  154. data/lib/core/statement/StatementStructure2.rb +0 -224
  155. data/lib/core/statement/TheoryStatement.rb +0 -68
  156. data/lib/core/statement/TopologicalStatements.rb +0 -34
  157. data/lib/core/syntax/Addition.rb +0 -26
  158. data/lib/core/syntax/BlockContainer.rb +0 -102
  159. data/lib/core/syntax/Boolean.rb +0 -15
  160. data/lib/core/syntax/Code.rb +0 -11
  161. data/lib/core/syntax/Do.rb +0 -20
  162. data/lib/core/syntax/False.rb +0 -12
  163. data/lib/core/syntax/If.rb +0 -36
  164. data/lib/core/syntax/Nil.rb +0 -15
  165. data/lib/core/syntax/Return.rb +0 -33
  166. data/lib/core/syntax/Subtract.rb +0 -19
  167. data/lib/core/syntax/This.rb +0 -40
  168. data/lib/core/syntax/True.rb +0 -20
  169. data/lib/core/syntax/syntax.rb +0 -24
  170. data/lib/core/tracking/ActsAsTrackable.rb +0 -65
  171. data/lib/core/tracking/History.rb +0 -167
  172. data/lib/core/tracking/RuntimeTrackingMethod.rb +0 -32
  173. data/lib/core/tracking/Step.rb +0 -52
  174. data/lib/core/variable/ArrayVariable.rb +0 -76
  175. data/lib/core/variable/BaseVariable.rb +0 -152
  176. data/lib/core/variable/BlockVariable.rb +0 -92
  177. data/lib/core/variable/FixnumVariable.rb +0 -35
  178. data/lib/core/variable/HistoryVariable.rb +0 -8
  179. data/lib/core/variable/MethodParameter.rb +0 -179
  180. data/lib/core/variable/MethodUsageVariable.rb +0 -60
  181. data/lib/core/variable/NilVariable.rb +0 -29
  182. data/lib/core/variable/RuntimeMethodParameter.rb +0 -67
  183. data/lib/core/variable/StatementVariable.rb +0 -72
  184. data/lib/core/variable/StepVariable.rb +0 -7
  185. data/lib/core/variable/StringVariable.rb +0 -46
  186. data/lib/core/variable/TypeVariable.rb +0 -72
  187. data/lib/core/variable/Unknown.rb +0 -102
  188. data/lib/core/variable/UnknownVariable.rb +0 -29
  189. data/lib/core/variable/Variable.rb +0 -70
  190. data/lib/core/variable/VariableContainer.rb +0 -28
  191. data/lib/core/variable/VariableIncluded.rb +0 -27
  192. data/lib/core/variable/VariableReference.rb +0 -85
  193. data/lib/error/FailedToFindStatementContainerError.rb +0 -7
  194. data/lib/error/FailedToFindStatementError.rb +0 -7
  195. data/lib/error/FailedToFindVariableError.rb +0 -7
  196. data/lib/error/FailedToLiteraliseError.rb +0 -7
  197. data/lib/error/FailedVariableMatch.rb +0 -7
  198. data/lib/error/ImproperStatementUsageError.rb +0 -7
  199. data/lib/error/IncompatiableRequirementsError.rb +0 -7
  200. data/lib/error/InvalidStatementError.rb +0 -7
  201. data/lib/error/MethodSizeError.rb +0 -7
  202. data/lib/error/RuntimeSyntaxError.rb +0 -7
  203. data/lib/error/UnexpectedStatementTypeError.rb +0 -7
  204. data/lib/error/UnknownStatementType.rb +0 -7
  205. data/lib/error/UnliteralisableError.rb +0 -7
  206. data/lib/implemented_chain.rb +0 -35
  207. data/lib/intrinsic/IntrinsicLastRuntimeMethod.rb +0 -20
  208. data/lib/intrinsic/IntrinsicLiteral.rb +0 -26
  209. data/lib/intrinsic/IntrinsicObject.rb +0 -22
  210. data/lib/intrinsic/IntrinsicRuntimeMethod.rb +0 -27
  211. data/lib/intrinsic/IntrinsicTestCases.rb +0 -17
  212. data/lib/logger/StandardLogger.rb +0 -62
  213. data/lib/required.rb +0 -222
  214. data/lib/ruby_code/Array.rb +0 -95
  215. data/lib/ruby_code/Fixnum.rb +0 -39
  216. data/lib/ruby_code/Hash.rb +0 -25
  217. data/lib/ruby_code/NilClass.rb +0 -19
  218. data/lib/ruby_code/Object.rb +0 -24
  219. data/lib/ruby_code/String.rb +0 -63
  220. data/lib/ruby_code/Symbol.rb +0 -7
  221. data/lib/standard_library/Tasks.rb +0 -12
  222. data/lib/theories.rb +0 -166
  223. data/lib/theory/ActionImplementation.rb +0 -17
  224. data/lib/theory/TheoryAction.rb +0 -100
  225. data/lib/theory/TheoryChainValidator.rb +0 -103
  226. data/lib/theory/TheoryComponent.rb +0 -59
  227. data/lib/theory/TheoryConnector.rb +0 -756
  228. data/lib/theory/TheoryDependent.rb +0 -135
  229. data/lib/theory/TheoryImplementation.rb +0 -75
  230. data/lib/theory/TheoryResult.rb +0 -131
  231. data/lib/theory/TheoryVariable.rb +0 -63
  232. data/lib/theory/theory_collection.rb +0 -62
  233. data/lib/util/ClassEvaluation.rb +0 -44
  234. data/lib/util/CodeEvaluation.rb +0 -39
  235. data/lib/util/DeclarationStatementEvaluation.rb +0 -32
  236. data/lib/util/MethodEvaluation.rb +0 -49
  237. data/lib/util/MethodTester.rb +0 -71
  238. data/lib/util/MethodValidation.rb +0 -149
  239. data/lib/util/MethodWriter.rb +0 -66
  240. data/lib/util/Parser.rb +0 -305
  241. data/lib/util/StatementCheck.rb +0 -44
  242. data/lib/util/StringToTheory.rb +0 -142
  243. data/lib/util/System.rb +0 -8
  244. data/spec/cauldron/chain_spec.rb +0 -24
  245. data/spec/cauldron/demos_spec.rb +0 -30
  246. data/spec/cauldron/runtime_method_spec.rb +0 -92
  247. data/spec/cauldron/saver_spec.rb +0 -45
  248. data/spec/cauldron/sexp_2_cauldron_spec.rb +0 -118
  249. data/spec/cauldron/theory_action_spec.rb +0 -25
  250. data/spec/cauldron/theory_connector_spec.rb +0 -52
  251. data/spec/cauldron/theory_spec.rb +0 -59
  252. data/spec/cauldron/unified_chain_spec.rb +0 -140
  253. data/test/fixtures/chains/1/declaration.txt +0 -26
  254. data/test/fixtures/chains/1/dump +0 -0
  255. data/test/fixtures/chains/2/declaration.txt +0 -26
  256. data/test/fixtures/chains/2/dump +0 -0
  257. data/test/fixtures/chains/3/declaration.txt +0 -26
  258. data/test/fixtures/chains/3/dump +0 -0
  259. data/test/fixtures/implementation_results/0/declaration.txt +0 -3
  260. data/test/fixtures/implementation_results/0/dump +0 -0
  261. data/test/fixtures/theories/0/declaration.txt +0 -9
  262. data/test/fixtures/theories/0/desc +0 -10
  263. data/test/fixtures/theories/0/dump +0 -0
  264. data/test/fixtures/theories/1/declaration.txt +0 -15
  265. data/test/fixtures/theories/1/desc +0 -11
  266. data/test/fixtures/theories/1/dump +0 -0
  267. data/test/fixtures/theories/10/declaration.txt +0 -23
  268. data/test/fixtures/theories/10/desc +0 -17
  269. data/test/fixtures/theories/10/dump +0 -0
  270. data/test/fixtures/theories/11/declaration.txt +0 -20
  271. data/test/fixtures/theories/11/desc +0 -14
  272. data/test/fixtures/theories/11/dump +0 -0
  273. data/test/fixtures/theories/12/declaration.txt +0 -18
  274. data/test/fixtures/theories/12/desc +0 -12
  275. data/test/fixtures/theories/12/dump +0 -0
  276. data/test/fixtures/theories/13/declaration.txt +0 -24
  277. data/test/fixtures/theories/13/desc +0 -20
  278. data/test/fixtures/theories/13/dump +0 -0
  279. data/test/fixtures/theories/14/declaration.txt +0 -26
  280. data/test/fixtures/theories/14/desc +0 -20
  281. data/test/fixtures/theories/14/dump +0 -0
  282. data/test/fixtures/theories/15/declaration.txt +0 -20
  283. data/test/fixtures/theories/15/desc +0 -14
  284. data/test/fixtures/theories/15/dump +0 -0
  285. data/test/fixtures/theories/16/declaration.txt +0 -30
  286. data/test/fixtures/theories/16/desc +0 -14
  287. data/test/fixtures/theories/16/dump +0 -0
  288. data/test/fixtures/theories/17/declaration.txt +0 -25
  289. data/test/fixtures/theories/17/desc +0 -11
  290. data/test/fixtures/theories/17/dump +0 -0
  291. data/test/fixtures/theories/18/declaration.txt +0 -23
  292. data/test/fixtures/theories/18/desc +0 -11
  293. data/test/fixtures/theories/18/dump +0 -0
  294. data/test/fixtures/theories/19/declaration.txt +0 -23
  295. data/test/fixtures/theories/19/desc +0 -11
  296. data/test/fixtures/theories/19/dump +0 -0
  297. data/test/fixtures/theories/2/declaration.txt +0 -12
  298. data/test/fixtures/theories/2/desc +0 -10
  299. data/test/fixtures/theories/2/dump +0 -0
  300. data/test/fixtures/theories/20/declaration.txt +0 -23
  301. data/test/fixtures/theories/20/desc +0 -17
  302. data/test/fixtures/theories/20/dump +0 -0
  303. data/test/fixtures/theories/3/declaration.txt +0 -19
  304. data/test/fixtures/theories/3/desc +0 -11
  305. data/test/fixtures/theories/3/dump +0 -0
  306. data/test/fixtures/theories/4/declaration.txt +0 -11
  307. data/test/fixtures/theories/4/desc +0 -11
  308. data/test/fixtures/theories/4/dump +0 -0
  309. data/test/fixtures/theories/5/declaration.txt +0 -6
  310. data/test/fixtures/theories/5/desc +0 -9
  311. data/test/fixtures/theories/5/dump +0 -0
  312. data/test/fixtures/theories/6/declaration.txt +0 -13
  313. data/test/fixtures/theories/6/desc +0 -11
  314. data/test/fixtures/theories/6/dump +0 -0
  315. data/test/fixtures/theories/7/declaration.txt +0 -19
  316. data/test/fixtures/theories/7/desc +0 -11
  317. data/test/fixtures/theories/7/dump +0 -0
  318. data/test/fixtures/theories/8/declaration.txt +0 -21
  319. data/test/fixtures/theories/8/desc +0 -11
  320. data/test/fixtures/theories/8/dump +0 -0
  321. data/test/fixtures/theories/9/declaration.txt +0 -24
  322. data/test/fixtures/theories/9/desc +0 -20
  323. data/test/fixtures/theories/9/dump +0 -0
  324. data/test/fixtures/theory_implementations/0/declaration.txt +0 -11
  325. data/test/fixtures/theory_implementations/0/desc.txt +0 -9
  326. data/test/fixtures/theory_implementations/0/dump +0 -0
  327. data/test/fixtures/theory_implementations/0/theory_id +0 -1
  328. data/test/fixtures/theory_implementations/1/declaration.txt +0 -11
  329. data/test/fixtures/theory_implementations/1/desc.txt +0 -9
  330. data/test/fixtures/theory_implementations/1/dump +0 -1
  331. data/test/fixtures/theory_implementations/1/theory_id +0 -1
  332. data/test/fixtures/theory_implementations/2/declaration.txt +0 -11
  333. data/test/fixtures/theory_implementations/2/desc.txt +0 -9
  334. data/test/fixtures/theory_implementations/2/dump +0 -0
  335. data/test/fixtures/theory_implementations/2/theory_id +0 -1
  336. data/test/output/simple_method.txt +0 -5
  337. data/test/output/test_method/first_possible_method.txt +0 -6
  338. data/test/output/test_simple_cases/simple_case_01.txt +0 -8
  339. data/test/output/test_simple_cases/simple_case_02.txt +0 -7
  340. data/test/output/test_simple_cases/simple_case_03.txt +0 -8
  341. data/test/output/test_simple_cases/simple_case_04.txt +0 -8
  342. data/test/output/test_simple_cases/simple_case_05.txt +0 -8
  343. data/test/output/test_simple_cases/simple_case_06.txt +0 -9
  344. data/test/output/test_simple_cases/simple_case_07.txt +0 -9
  345. data/test/output/test_simple_cases/simple_case_08.txt +0 -9
  346. data/test/tc_describe.rb +0 -46
  347. data/test/tc_method.rb +0 -130
  348. data/test/tc_requirement.rb +0 -30
  349. data/test/tc_suite_complete.rb +0 -26
  350. data/test/tc_variable.rb +0 -52
  351. data/test/ts_complete.rb +0 -74
  352. data/test/ts_stable.rb +0 -81
  353. data/test/unit/core/declaration/tc_literal_declaration.rb +0 -34
  354. data/test/unit/core/method_call/tc_class_call.rb +0 -20
  355. data/test/unit/core/runtime_method/tc_realised_runtime_method.rb +0 -132
  356. data/test/unit/core/runtime_method/tc_runtime_method.rb +0 -546
  357. data/test/unit/core/statement/tc_array_access.rb +0 -63
  358. data/test/unit/core/statement/tc_block_statement.rb +0 -53
  359. data/test/unit/core/statement/tc_hack_statement.rb +0 -26
  360. data/test/unit/core/statement/tc_open_statement.rb +0 -79
  361. data/test/unit/core/statement/tc_statement.rb +0 -483
  362. data/test/unit/core/statement/tc_statement_group.rb +0 -35
  363. data/test/unit/core/statement/tc_statement_replace_variable.rb +0 -61
  364. data/test/unit/core/statement/tc_theory_statement.rb +0 -53
  365. data/test/unit/core/syntax/tc_block_container.rb +0 -32
  366. data/test/unit/core/syntax/tc_if_container.rb +0 -39
  367. data/test/unit/core/tc_class_method_call.rb +0 -34
  368. data/test/unit/core/tc_container.rb +0 -41
  369. data/test/unit/core/tc_ctest_case.rb +0 -25
  370. data/test/unit/core/tc_instance_call_container.rb +0 -93
  371. data/test/unit/core/tc_literal.rb +0 -30
  372. data/test/unit/core/tc_theory_generator.rb +0 -336
  373. data/test/unit/core/tc_theory_generator_heavy.rb +0 -42
  374. data/test/unit/core/tracking/tc_history.rb +0 -104
  375. data/test/unit/core/tracking/tc_step.rb +0 -65
  376. data/test/unit/core/variable/tc_array_variable.rb +0 -61
  377. data/test/unit/core/variable/tc_block_variable.rb +0 -17
  378. data/test/unit/core/variable/tc_fixnum_variable.rb +0 -54
  379. data/test/unit/core/variable/tc_method_parameter_variable.rb +0 -22
  380. data/test/unit/core/variable/tc_runtime_method_variable.rb +0 -32
  381. data/test/unit/core/variable/tc_string_variable.rb +0 -37
  382. data/test/unit/core/variable/tc_unknown.rb +0 -24
  383. data/test/unit/core/variable/tc_variable_reference.rb +0 -28
  384. data/test/unit/ruby_code/tc_array.rb +0 -64
  385. data/test/unit/ruby_code/tc_fixnum.rb +0 -18
  386. data/test/unit/ruby_code/tc_hash.rb +0 -41
  387. data/test/unit/ruby_code/tc_string.rb +0 -38
  388. data/test/unit/tc_chain.rb +0 -434
  389. data/test/unit/tc_chain_mapping.rb +0 -62
  390. data/test/unit/tc_chain_with_case_1.rb +0 -169
  391. data/test/unit/tc_instance_call.rb +0 -40
  392. data/test/unit/tc_method_usage.rb +0 -35
  393. data/test/unit/tc_pot.rb +0 -124
  394. data/test/unit/tc_runtime_tracking_method.rb +0 -40
  395. data/test/unit/tc_theory.rb +0 -531
  396. data/test/unit/tc_variable_declaration.rb +0 -32
  397. data/test/unit/theory/tc_theory_action.rb +0 -108
  398. data/test/unit/theory/tc_theory_action_implementation.rb +0 -23
  399. data/test/unit/theory/tc_theory_chain_validator.rb +0 -340
  400. data/test/unit/theory/tc_theory_connector.rb +0 -361
  401. data/test/unit/theory/tc_theory_dependent.rb +0 -153
  402. data/test/unit/theory/tc_theory_implementation.rb +0 -137
  403. data/test/unit/theory/tc_theory_result.rb +0 -112
  404. data/test/unit/theory/tc_theory_variable.rb +0 -45
  405. data/test/unit/util/tc_method_validation.rb +0 -101
  406. data/test/unit/util/tc_parser.rb +0 -110
  407. data/test/unit/util/tc_string_to_theory.rb +0 -300
  408. data/test/unit/variable/tc_method_usage_variable.rb +0 -25
  409. data/tmp/runtime_method_evaluation.rb +0 -16
@@ -1,19 +0,0 @@
1
- # This class represents statements that declare new variables.
2
- # e.g. var = 'test'.chop
3
- # var1 = var2.pop
4
- #
5
- class DeclarationStatement < Statement
6
-
7
- def initialize(*parameters)
8
- super(*parameters)
9
- end
10
-
11
- # Returns the declared variable. So in he case where
12
- # there is var = 8 it would return var. This is always
13
- # the first entry.
14
- #
15
- def declared
16
- return self.first
17
- end
18
-
19
- end
@@ -1,25 +0,0 @@
1
- # This is a temporary statement that simple writes out the string provided to it. It
2
- # is used by the RuntimeTrackingMethod and is simple used now because I am not
3
- # able to create hashes just yet. I hope to remove this class in the foreseable
4
- # future(15/07/09) - lets see.
5
- #
6
- class HackStatement < Statement
7
-
8
- def initialize(statement_text)
9
- super()
10
- @statement_text = statement_text
11
- @confirmed = true
12
- @statement_type = 'Hack'
13
- end
14
-
15
- def write(tab=0)
16
- l = ''
17
- tab.times {|x| l += "\t" }
18
- return l+@statement_text
19
- end
20
-
21
- def copy
22
- return HackStatement.new(@statement_text.dup)
23
- end
24
-
25
- end
@@ -1,18 +0,0 @@
1
- class HashAccess
2
-
3
- attr_reader :hash, :key
4
-
5
- def initialize(array,index)
6
- @hash = array
7
- @key = index
8
- end
9
-
10
- def write
11
- return @hash.write+'['+@key.write+']'
12
- end
13
-
14
- def copy
15
- return HashAccess.new(@hash.copy,@key.copy)
16
- end
17
-
18
- end
@@ -1,178 +0,0 @@
1
- # This class represents the structure where a statement is declared
2
- # but doesn't close on the same line. Instead it can contain any
3
- # number of other statements.
4
- #
5
- # for example
6
- #
7
- # if var_a == 'test'.select_all {|x| x.kind_of?(TheoryVariable)}
8
- # # do something
9
- # end
10
- #
11
- class OpenStatement < StatementGroup
12
- include ActsAsTrackable
13
- include ActsAsCode
14
-
15
-
16
- def initialize(open_statement,*statements)
17
- super(*statements)
18
- @statement = open_statement
19
- end
20
-
21
- def write(tab=0)
22
- line = @statement.write(tab)+"\n"
23
- line += super(tab+1)
24
- tab.times {line += " " }
25
- line += "end"
26
- return line
27
- end
28
-
29
- def describe(tab=0)
30
- line = @statement.describe(tab)+"\n"
31
- line += super(tab+1)
32
- tab.times {line += "\t" }
33
- line += "end\n"
34
- return line
35
- end
36
-
37
- # Creates a copy of the current nested statement but without any statements
38
- #
39
- def copy_base
40
- result = self.class.new(@statement.copy)
41
- # TODO This means the scope id is being incremented for statements only exist for the declaration
42
- result.scope_id = scope_id
43
- return result
44
- end
45
-
46
- # Returns all the variables used in the opening statement as well as any
47
- # child statements.
48
- #
49
- # TODO Write tests for this
50
- def variables
51
- return self.select_all([]){|x| x.kind_of?(Variable)}
52
- end
53
-
54
- def tokens
55
- return self.select_all([]){|x| x.kind_of?(Token)}
56
- end
57
-
58
- # Overrides the default array select_all method to include
59
- # the opening statement and contents of the open statement.
60
- #
61
- def select_all(results=[],&block)
62
- @statement.select_all(results,&block)
63
- return super(results,&block)
64
- end
65
-
66
- # Create a duplicate of this OpenStatement instance
67
- #
68
- # TODO Write tests for this
69
- #
70
- def copy
71
- result = self.class.new(@statement.copy,*self.collect {|x| x.copy })
72
- result.scope_id = scope_id
73
- result.scope = scope
74
- result.statement_level = statement_level
75
- return result
76
- end
77
-
78
- # Returns a new open statement that has been trackified. A
79
- # trackified open statement has a statement call after each
80
- # line.
81
- #
82
- # @param tracking_method A runtime tracking method instance
83
- # @param line An array thats length represents the current line.
84
- #
85
- def trackify(tracking_method,line)
86
-
87
- # First copy the base open statement and repopulate it
88
- result = copy_base
89
-
90
- # Start by trackifying the opening statement
91
- opening_variables = abstract_variables_for_tracking(@statement)
92
- track_statement = tracking_statement(
93
- tracking_method,
94
- line,
95
- statement_id.to_literal,
96
- opening_variables,
97
- @statement
98
- )
99
- result.push(track_statement)
100
-
101
- # For each line in the open statement include a tracking call
102
- # TODO I don't think this would trackify further open statements
103
- self.each do |x|
104
- result.push(x.copy)
105
-
106
- # Now include a tracking call for after the statement
107
- line_variables = abstract_variables_for_tracking(x)
108
- # TODO Check that the line is going up
109
- result.push tracking_statement(
110
- tracking_method,
111
- line,
112
- x.statement_id,
113
- line_variables,
114
- x
115
- )
116
- end
117
-
118
- return result
119
-
120
- end
121
-
122
- def replace_theory_variables!(mapping)
123
- @statement.replace_theory_variables!(mapping)
124
- self.each_with_index do |x,i|
125
- if x.kind_of?(TheoryVariable) && mapping.has_key?(x.theory_variable_id)
126
- self[i] = mapping[x.theory_variable_id].copy
127
- next
128
- end
129
- self[i].respond_to?(:replace_theory_variables!)
130
- self[i].replace_theory_variables!(mapping) if self[i].respond_to?(:replace_theory_variables!)
131
- end
132
- end
133
-
134
- def subst_variable!(id,var)
135
- @statement.subst_variable!(id,var)
136
- self.each do |statement|
137
- statement.subst_variable!(id,var)
138
- end
139
- end
140
-
141
- # Returns the statement_id of the embeded statement.
142
- #
143
- # TODO The nested statement should maybe have an idea
144
- # of its own. It should probably have two ids
145
- # to indicate at what point additional statements
146
- # added e.g. inside/outside statement.
147
- #
148
- def statement_id
149
- return @statement.statement_id
150
- end
151
-
152
- # TODO This seems wrong there is no opening statement
153
- def to_literal_string
154
- a = ''
155
- self.each do |x|
156
- a += x.to_literal_string
157
- end
158
- return a
159
- end
160
-
161
- # Returns true if the opening statement and all internal statements
162
- # have been realised.
163
- #
164
- def realised?
165
- return false unless @statement.realised?
166
- return false unless self.all? {|x| x.realised? }
167
- return true
168
- end
169
-
170
- def has?(&block)
171
- self.each do |x|
172
- return true if block.call(x)
173
- end
174
- return true if block.call(@statement)
175
- return false
176
- end
177
-
178
- end
@@ -1,5 +0,0 @@
1
- class RealisedStatement < Array
2
- include PrintVariables
3
- include ActsAsStatement
4
-
5
- end
@@ -1,39 +0,0 @@
1
- # TODO It is probably a bit overkill to create a new class for this.
2
- #
3
- # This is the same as the block statement except it uses the curly bracket syntax
4
- #
5
- class SingleLineBlockStatement < BlockStatement
6
-
7
- def initialize(statement,block_container=BlockContainer.new(BlockVariable.new),*internal_statements)
8
- super(statement,block_container,*internal_statements)
9
- end
10
-
11
- def write(tab=0)
12
- l = @statement.write(tab)+'{ '+@block_container.write+' '
13
- self.each do |x|
14
- l += x.write
15
- end
16
- l += '} '
17
- return l
18
- end
19
-
20
- def describe(tab=0)
21
- l = @statement.describe(tab)+'{ '+@block_container.describe+' '
22
- self.each do |x|
23
- l += x.describe
24
- end
25
- l += '} '
26
- return l
27
- end
28
-
29
- def copy
30
-
31
- result = SingleLineBlockStatement.new(@statement.copy,@block_container.copy,*self.collect {|x| x.copy})
32
- # TODO This means the scope id is being incremented for statements only exist for the declaration
33
- result.scope_id = scope_id
34
- result.scope = scope.copy
35
- result.statement_level = statement_level
36
- return result
37
- end
38
-
39
- end
@@ -1,1091 +0,0 @@
1
- class Statement
2
- include PrintVariables
3
- include ActsAsStatement
4
- include ActsAsCode
5
-
6
- attr_reader :statement_id, :scope, :statement_level, :statement_id
7
- # TODO scope and statement level are confusing - not sure of the difference (I think it's legacy)
8
- attr_writer :scope, :statement_level, :overrides, :statement_id
9
-
10
- @@statement_id = 0
11
-
12
- #
13
- # @params parameters Any number of elements to make up the statement possible classes
14
- # include Equal, Addition, Unknown, StringVariable, Literal e.t.c
15
- # &block [OPTIONAL] A block can also be provided to preview the statement from being
16
- # reviewed and therefore preventing changes to variables uniq_id.
17
- #
18
- def initialize(*parameters)
19
- super()
20
-
21
- #
22
- @overrides = nil
23
- @confirmed = false
24
-
25
- # Sets the flag that indicates the structure of the statement
26
- @structure = nil
27
-
28
- @nodes = []
29
-
30
- # Add the parameters to the array
31
- parameters.each do |code|
32
- @nodes.push(code.copy)
33
- end
34
-
35
- # TODO I might change the statement_id to be determined by the structure
36
- # of the statement.
37
- @statement_id = @@statement_id
38
- @@statement_id += 1
39
-
40
- # Review completed statement
41
- if block_given?
42
- values = yield
43
- review if (values[:review])
44
- else
45
- review
46
- end
47
-
48
- end
49
-
50
- # Resets the globablly used value for statements id
51
- #
52
- def self.reset_global_id
53
- #http://www.zenspider.com/Languages/Ruby/QuickRef.html
54
- unless $".include?('test/unit.rb')
55
- StandardLogger.log 'WARNING: Resetting variable id, this should only be done for tests'
56
- end
57
- @@statement_id = 0
58
- end
59
-
60
- # If this statement declares a variable determine whether the
61
- # the variable has been previously declared. If so mark this
62
- # statement as an "overrides" statement otherwise flag it
63
- # as not.
64
- #
65
- def identify_overriding_statements(already_declared=[])
66
- [BaseVariable,Equal].zip(@nodes) do |x,y|
67
- return unless y.kind_of?(x)
68
- end
69
- already_declared.each do |x|
70
- if x[:variable_id] == declared_variable_id
71
- @overrides = true
72
- return
73
- end
74
- end
75
- already_declared.push({:variable_id => declared_variable_id})
76
- @overrides = false
77
- end
78
-
79
- # Returns this statement if it has the correct id
80
- #
81
- # @param id The id of the statement should exist
82
- #
83
- def find_statement(id)
84
- if self.statement_id == id
85
- return self
86
- end
87
- raise FailedToFindStatementError.new('Couldn\'t find statement with id '+id.to_s)
88
- end
89
-
90
- # Returns true if the statement overrides an existing variable.
91
- # So if a = 6 but a was already set to 4 then this would be
92
- # an overriding statement.
93
- #
94
- def overrides?
95
- return @overrides
96
- end
97
-
98
- # Returns an array of variables in this statement
99
- #
100
- def variables
101
- return self.select_all([]){|x| x.kind_of?(Variable)}
102
- end
103
-
104
- # Returns an array of all the tokens in the statement. A token
105
- # is any literal, variable, intrinsic runtime or intrinsic testcase
106
- #
107
- def tokens
108
- return self.select_all([]){|x| x.kind_of?(Token)}
109
- end
110
-
111
- #
112
- def each_variable
113
- variables.each { |x| yield x }
114
- end
115
-
116
- # Attempt to convert the statement into a string without any references
117
- # to variables where possible. So varA = varB.chop might become
118
- # "varA = 'test'chop"
119
- #
120
- def literalise
121
-
122
- # Go through each element in the statement and attempt to literalise it
123
- line = ''
124
- self.each do |code|
125
- unless code.kind_of? Variable or code.kind_of? InstanceCallContainer
126
- line += code.write
127
- next
128
- end
129
- if code.kind_of?(Variable)
130
- if code.literalisable?
131
- literal = code.literalise
132
- line += literal.write
133
- next
134
- end
135
- line += code.write
136
- elsif code.kind_of?(InstanceCallContainer)
137
- if(code.subject.literalisable?)
138
- literal = code.subject.literalise
139
- line += literal.write+'.'+code.method_call.write
140
- next
141
- end
142
- line += code.write
143
- end
144
- end
145
- return line
146
- end
147
-
148
- # TODO Maybe use a opject to handle the output of the statement.
149
- def write(tab=0)
150
-
151
- # Check the file type of tab
152
- raise StandardError.new('Unexpexted class "'+tab.class.to_s+'" for Fixnum (number of tabs)') unless tab.kind_of? Fixnum
153
-
154
- line = ''
155
- tab.times {line += " " }
156
- self.each do |code|
157
- line += code.write
158
- break if code.object_id == self.last.object_id
159
- end
160
- return line
161
- end
162
-
163
- def describe(tab=0)
164
- # Check the file type of tab
165
- raise StandardError.new('Unexpexted class "'+tab.class.to_s+'" for Fixnum (number of tabs)') unless tab.kind_of? Fixnum
166
-
167
- line = ''
168
- tab.times {line += "\t" }
169
- self.each do |code|
170
- line += code.describe
171
- break if code.object_id == self.last.object_id
172
- end
173
- return line
174
- end
175
-
176
- def write_with_uniq_id(tab=0)
177
- # Check the file type of tab
178
- raise StandardError.new('Unexpexted class "'+tab.class.to_s+'" for Fixnum (number of tabs)') unless tab.kind_of? Fixnum
179
-
180
- line = ''
181
- tab.times {line += "\t" }
182
- self.each do |code|
183
- # TODO Doesn't need a space on the last code element
184
- #line += code.write_with_uniq_id+' '
185
- if code.respond_to?('write_with_uniq_id')
186
- line += code.write_with_uniq_id+' '
187
- next
188
- end
189
- line += code.write+' '
190
- end
191
- return line
192
- end
193
-
194
- # NOTE This method should only be used on realised statements
195
- def write_with_value(tab=0)
196
-
197
- # Check the file type of tab
198
- raise StandardError.new('Unexpexted class "'+tab.class.to_s+'" for Fixnum (number of tabs)') unless tab.kind_of? Fixnum
199
-
200
- line = ''
201
- tab.times {line += "\t" }
202
- self.each do |code|
203
-
204
- if code.kind_of?(Variable)
205
-
206
- line += code.write+'('+code.value.write+')'
207
- next
208
- end
209
-
210
- line += code.write
211
-
212
- end
213
- return line
214
-
215
- end
216
-
217
- # Returns a string containing the written version of the statement
218
- # but any variables will have there id in brackets after them.
219
- #
220
- # TODO This method is duplicated with requirements
221
- #
222
- def write_with_variable_id(tab=0,context=self)
223
-
224
- line = ''
225
- tab.times {line += "\t" }
226
- self.each do |x|
227
- if x.kind_of? Variable
228
- line += x.write+'('+x.variable_id.to_s+') '
229
- next
230
- end
231
- if x.kind_of? InstanceCallContainer
232
- line += x.write+'('+x.subject.variable_id.to_s+')'
233
- next
234
- end
235
- line += x.write
236
- end
237
- return line
238
-
239
- end
240
-
241
-
242
- # Creates a copy of the statement. The copy's variables should have
243
- # the same variable ids but should be different instances. When
244
- # all the code elements are added the statement is ascessed and the
245
- # the requirements updated approriately.
246
- #
247
- def copy
248
- # tmp = self.collect{|x| x.copy}
249
- # result = self.class.new(*tmp) {{:review=>false}}
250
- # result.statement_level = statement_level
251
- # return result
252
- return Marshal.load(Marshal.dump(self))
253
- end
254
-
255
- # Returns true if the statement contains any calls to a runtime
256
- # method.
257
- #
258
- def contains_method_call?
259
- return self.any? {|x| x.kind_of?(DefCall)}
260
- end
261
-
262
- # Adds the new piece of code to the statement and update
263
- # the variables requirements to accomodate any change.
264
- #
265
- def push(code)
266
-
267
- # Add the new piece of code to the statement
268
- #array_push(code)
269
- @nodes << code
270
-
271
- # Update the requirements to reflect the change
272
- update
273
-
274
- end
275
-
276
- def add(element)
277
- push(element)
278
- end
279
-
280
- def select_all(results=[],&block)
281
- return @nodes.select_all(results,&block)
282
- end
283
-
284
- def each
285
- @nodes.each {|x| yield x}
286
- end
287
-
288
- def last
289
- return @nodes.last
290
- end
291
-
292
- def each_with_index
293
- @nodes.each_with_index do |x,i|
294
- yield x, i
295
- end
296
- end
297
-
298
- def []=(index,value)
299
- @nodes[index] = value
300
- end
301
-
302
- def [](index)
303
- return @nodes[index]
304
- end
305
-
306
- def length
307
- return @nodes.length
308
- end
309
-
310
- def select_all(results=[],&block)
311
- return @nodes.select_all(results,&block)
312
- end
313
-
314
- def first
315
- @nodes.first
316
- end
317
-
318
- def clear
319
- @nodes.clear
320
- end
321
-
322
- # Indicates whether the statement is one that assigns
323
- # a value to another. Essential "Does the statement
324
- # contain an equals sign?"
325
- #
326
- def assignment?
327
- if detect_class(Equivalent).nil?
328
- return false
329
- end
330
- return true
331
- end
332
-
333
- #
334
- def right_hand_side
335
- l, r = self.split(Equivalent)
336
- return r
337
- end
338
-
339
- def left_hand_side
340
- l, r = self.split(Equivalent)
341
- return l
342
- end
343
-
344
- # Indicates whether the statement has been confirmed.
345
- #
346
- def confirmed?
347
- return @confirmed
348
- end
349
-
350
- # This writes and evalutes the syntax of a statement to
351
- # determine whether it can be used by it self.
352
- #
353
- # So something like var1 = var0.chop would fail since
354
- # var0 doesn't exist. It needs to write to a different
355
- # class to avoid the situation where the statement
356
- # 'return false' would perceived as invalid syntax.
357
- #
358
- def valid_syntax?
359
- return StatementCheck.new.valid_syntax?(self.write)
360
- end
361
-
362
- # yeilds each variable that is not declared in the statement and
363
- # isn't known e.g. cat be literalised in the statement.
364
- #
365
- def each_untyped_variable
366
- untyped_variables.each do |x|
367
- yield x
368
- end
369
- end
370
-
371
- # Returns an array of all the untyped variables in the statement.
372
- # Excluding any declared variables in the statement.
373
- #
374
- def untyped_variables
375
- x = []
376
- not_declared_variables.each do |y|
377
- x.push(y) unless y.kind_of?(TypeVariable)
378
- end
379
- return x
380
- end
381
-
382
- # Returns each of the variables that aren't realised. In that
383
- # they aren't TypeVariables and don't have a literal value.
384
- #
385
- def unrealised_variables
386
- results = []
387
- variables.each do |x|
388
- unless x.kind_of?(TypeVariable)
389
- results.push(x)
390
- next
391
- end
392
- if x.value.nil? and !x.kind_of?(NilVariable)
393
- results.push(x)
394
- end
395
- end
396
- return results
397
- end
398
-
399
- # Displays each of the unrealised variables within the statement
400
- #
401
- def each_unrealised_variable
402
- unrealised_variables.each do |x|
403
- yield x
404
- end
405
- end
406
-
407
- # Returns an array of all the undeclared variables in the
408
- # statement. An undeclared variable is simply a
409
- # variable not declared in the statement but used in it.
410
- # e.g. var_c = var_a+var_b var_a and var_b are the undeclared
411
- # variable.
412
- #
413
- def not_declared_variables()
414
-
415
- # The statement shouldn't be valid if there are undeclared variables
416
- return [] if valid_syntax?
417
-
418
- # Find any excluded variables(ones that are delcared within the statement)
419
- # e.g. var = 'test'.chop
420
- declared_variables = []
421
- if( (self[0].kind_of? Variable)&&(self[1].class == Equal) )
422
- declared_variables.push(self[0].copy)
423
- end
424
-
425
- # Attempt to find all the undeclared variables
426
- undeclared = []
427
- variables.each do |x|
428
- next if declared_variables.any? {|y| y.uniq_id == x.uniq_id}
429
- undeclared.push(x.copy)
430
- end
431
- return undeclared
432
-
433
- end
434
-
435
- # TODO It would be nicer to a subst that allows a block passed though
436
- # e.g. a.subst(sub) {|x| x.variable_id == 9}
437
- #
438
- # Returns a new statement that is a duplicate of this statement
439
- # but with the specified variable replaced.
440
- #
441
- # TODO Use the name nest for more than one statement
442
- # TODO Write allot!! of tests for this
443
- #
444
- # @param id The id of the variable that will be replaced from the statement
445
- #
446
- def subst(id,var,context=self)
447
- return self.copy.subst!(var){|x| x.uniq_id == id}
448
- end
449
-
450
- def subst!(var,&block)
451
-
452
- # TODO I should probably check whether anything was substituted or or not
453
- self.each_with_index do |x,i|
454
- next unless x.kind_of?(Variable) or x.kind_of?(InstanceCallContainer)
455
-
456
- # Essentially checks whether element is an InstanceCallContainer
457
- if x.respond_to?(:subst!)
458
- self[i] = x.subst!(var,&block)
459
- next
460
- end
461
-
462
- if block.call(x)
463
- self[i] = var.copy
464
- end
465
- end
466
- return self
467
- end
468
-
469
- # TODO I should have a realised statement class
470
-
471
- # # Finds each element that satisfy the
472
- # #
473
- # # @param var The variable to replace any elements that match the block.
474
- # #
475
- # def replace_variable_if(var,&block)
476
- # container = []
477
- # @nodes.each do |x|
478
- # if x.kind_of?(Variable)
479
- # if block.call(x)
480
- # container.push(var)
481
- # next
482
- # end
483
- # end
484
- # if x.kind_of?(InstanceCallContainer)
485
- # container.push(x.replace_variable_if(var,&block))
486
- # next
487
- # end
488
- # container.push(x.copy)
489
- # end
490
- # #return self.copy(*container)
491
- # copied = self.copy().clear
492
- # container.each {|x| copied.push(x) }
493
- # return copied
494
- #
495
- # end
496
-
497
- # Returns a variable instance with the contextual requirements for the statement.
498
- # TODO Don't really need these contextual_variable calls
499
- #
500
- def context_variable(id)
501
- return find_variable(id)
502
- end
503
-
504
- def contextual_variable(id)
505
- return context_variable(id)
506
- end
507
-
508
- # Returns the variable or instance call that contains
509
- # the variable with the specidied id. It doesn't search
510
- # the requirements.
511
- #
512
- # @param id The id of the variable that should be returned
513
- #
514
- # TODO Write test to retrieve declarared variable in a statement with two variables
515
- # e.g. varA = varB-varC
516
- #
517
- def find_variable(id)
518
- results = variables.select() {|x| x.variable_id == id}
519
- if results.empty?
520
- raise FailedToFindVariableError.new('Couldn\'t find variable with id = '+id.to_s+' in "'+self.write+'"')
521
- end
522
- return results.first
523
- end
524
-
525
- # Returns the variable in this statement with uniq_id specified. In
526
- # the event the variable resides in a instance call then that is
527
- # returned.
528
- #
529
- def find_actual_variable(uniq_id)
530
- target = self.variables.select {|x| x.uniq_id == uniq_id}
531
- return target[0] unless target.empty?
532
- raise FailedToFindVariableError.new('Couldn\'t find a variable with the id '+uniq_id.to_s+' in "'+self.write+'"')
533
- end
534
-
535
- def replace_variable!(uniq_id,var)
536
-
537
- # Find the variable to be replaced
538
- target = self.find_actual_variable(uniq_id)
539
-
540
- #raise StandardError.new('Both target and variable should be the same class('+target.class.to_s+' != '+var.class.to_s+')') unless(target.kind_of?(var.class))
541
- # TODO Should check for two variable kinds to two instance call kinds
542
- self.each_with_index do |code,i|
543
-
544
- # TODO Need to test with changing instance calls
545
- next unless code.kind_of?(Variable) or code.kind_of?(InstanceCallContainer)
546
-
547
- if(code.variable_id==target.variable_id)
548
-
549
- if code.kind_of?(Variable)
550
- self[i] = var
551
- elsif code.kind_of?(InstanceCallContainer)
552
- self[i].subject = var
553
- end
554
- return self
555
- end
556
- end
557
-
558
- end
559
-
560
- # TODO Not sure whether both replace_variable! and subst_variable! are both needed - either ways
561
- # their names aren't descriptive enough to distinguish that one uses the uniq_id and one uses
562
- # the variable.
563
- #
564
- def subst_variable!(id,var)
565
- # => TODO Use replace_variable_if?
566
- self.each_with_index do |token,i|
567
- if token.kind_of?(Variable) && id == token.variable_id
568
- self[i] = var
569
- next
570
- end
571
- if token.kind_of?(Container)
572
- self[i] = token.subst_variable!(id,var)
573
- end
574
- end
575
- self
576
- end
577
-
578
- # Returns the id of the variable declared in this statement
579
- #
580
- def declared_variable_id
581
- raise UnexpectedStatementTypeError.new('Should be declaration statement type '+self.write) unless decalares_variable?
582
- return self[0].variable_id
583
- end
584
-
585
- # Retuns an array of all the variable ids required for the
586
- # statement.
587
- #
588
- def required_variable_ids
589
- results = self.variables.collect {|x| x.variable_id}
590
- return (results-[declared_variable_id])
591
- end
592
-
593
- # Returns true if the statement is simple. In that it just re-declares
594
- # an existing variable e.g. var_a = var_b.
595
- #
596
- def is_simple?
597
- return false unless decalares_variable?
598
- # TODO Look at what you call the right hand side of the equation
599
- if right_hand_side.length == 1 && right_hand_side[0].kind_of?(Variable)
600
- return true
601
- end
602
- return false
603
- end
604
-
605
- # TODO Write tests
606
- # This method writes the statement out as a literal string. In the sense
607
- # that any of the variables used in the statement are converted to literals
608
- # and written. Unknown variables are not written yet though.
609
- #
610
- # This method is called during tracking to give an indication what the statement
611
- # being tracked is doing.
612
- #
613
- # TODO I am treating unknown variables as a special case that is the same
614
- # value e.g. 'var' - but for determining equivalent processes it isn't
615
- # ideal becuase you loose track of what variables is used in each
616
- # statement. Although I'll wait unitl I can come up with an example
617
- # and come up with a solution then.
618
- #
619
- def to_literal_string
620
- return @nodes.inject('') do |complete,part|
621
- complete += part.to_literal_string
622
- end
623
- end
624
-
625
- # Returns the number of statments in the statement. This will always
626
- # be one but nested statements may have more.
627
- #
628
- def statement_count
629
- return 1
630
- end
631
-
632
- # Returns true if the statement contains the same undeclared variables
633
- # as the statement provided as well as the same number of elements.
634
- #
635
- # @param statement The statement thats undeclared variables are being compared.
636
- #
637
- def same_not_declared_variables?(statement)
638
- return false if statement.length != self.length
639
- statement.not_declared_variables.each do |x|
640
- return false unless self.not_declared_variables.any? {|y| y.variable_id == x.variable_id}
641
- end
642
- return true
643
- end
644
-
645
- # Adds this statement to array of overriding statements if it
646
- # overrides an existing variable.
647
- #
648
- # @param overriding_statements An array containing other overriding statements.
649
- #
650
- def find_overriding_statements(overriding_statements=[])
651
- overriding_statements.push self if self.overrides?
652
- return overriding_statements
653
- end
654
-
655
- # Returns an updated statement where all the variables within the statement
656
- # have been realised. If the statement resides inside a nested statement
657
- # or multiple nested statements the variables will be changed into a Dynamic
658
- # Variable. These dynamic variables contain multiple variables with different
659
- # values but the same variable_id.
660
- #
661
- # For example:
662
- #
663
- # 3.times do |var_a|
664
- # var_b = var_a+1
665
- # end
666
- #
667
- # In the above case var_b would be a dynamic variable would contain 3 FixnumVariable
668
- # with the values 1,2,3. The statement itself doesn't indicate that it is nested, it
669
- # is still just a regular statement.
670
- #
671
- # In a more complex example where we have two nested statements we might have something
672
- # like the following:
673
- #
674
- # 2.times do |var_a|
675
- # 2.times do |var_b|
676
- # var_c = var_b+1
677
- # end
678
- # end
679
- #
680
- # We would end up with another dynamic variable with the values 1,2,1,2.
681
- #
682
- # The final tricky situation is when variables are overwritten. As a rule block
683
- # variables are never overwritten - I should also include the subject of a loop
684
- # as well.
685
- #
686
- # For example:
687
- #
688
- # var_a = 0
689
- # 3.times do |var_b|
690
- # var_a += var_b
691
- # end
692
- #
693
- # In this situation there will be 3 versions of var_a the first one, the dynamic internal
694
- # one and a post statement variable. The post statement variable will have a statement
695
- # dependencey on the above nested statement. The internal variable will have a scope
696
- # depenencey on the nested statement.
697
- #
698
- # TODO I suspect my approach to this is wrong. I pass in the history instance with
699
- # all the information and then try to work out the realised value for this statement
700
- # but it would probably be easier if the history instance itself to determine this.
701
- #
702
- def realise2(method_map)
703
- return copy if realised?
704
-
705
- raise StandardError.new('Unexpected data type ') unless method_map.kind_of?(History)
706
- # Create a duplcate statement to be modified
707
- result = self.copy
708
-
709
- # Find value(s) for each unrealised variable.
710
- realised_variables = []
711
- each_unrealised_variable do |x|
712
- if x.kind_of?(BlockVariable)
713
- realised_variables.push(method_map.find_realised_variable(x.variable_id,x.uniq_id,'BlockVariable'))
714
- else
715
- realised_variables.push(method_map.find_realised_variable(x.variable_id,x.uniq_id))
716
- end
717
- # TODO Change to elsif x.kind_of?(Variable)
718
- end
719
-
720
- # Substitue the realised variables for the unrealised ones
721
- self.each_unrealised_variable do |var|
722
- catch(:variable_substituted) do
723
- realised_variables.each do |z|
724
- if z.uniq_id == var.uniq_id
725
- result.replace_variable!(var.uniq_id,z)
726
- throw :variable_substituted
727
- end
728
- end
729
- raise StandardError.new('Couldn\'t find realised value for variable with id '+var.variable_id.to_s+' in "'+self.write+'"')
730
- end
731
- end
732
- return result
733
-
734
- end
735
-
736
- # Returns an array of all the RuntimeMethods instances contained in this
737
- # statement. In all likelyhood there will no more than one.
738
- #
739
- def find_all_required_runtime_methods
740
- defcalls = @nodes.find_all {|x| x.kind_of?(DefCall)}
741
- return defcalls.collect {|x| x.runtime_method}
742
- end
743
-
744
- # Returns true if the statement has been fully realsied - in that all the variables
745
- # contained within it are realised. Otherwise it returns false.
746
- #
747
- def realised?
748
- return self.variables.all? {|x| x.realised?}
749
- end
750
-
751
- # Returns the statement as a StatementVariable
752
- #
753
- # @param id The id of the variable to give to the returned statement
754
- # variable.
755
- #
756
- def to_var(id=nil,uniq_id=nil)
757
- var = StatementVariable.new(self.copy) {{:variable_id => id,:uniq_id=>uniq_id}}
758
- return var
759
- end
760
-
761
- # Returns true if the statement declares a variable
762
- def decalares_variable?
763
- return true if self[0].kind_of?(Variable) and self[1].kind_of?(Equal)
764
- return false
765
- end
766
-
767
- # Returns the variable declared in the statement. (if one exists)
768
- #
769
- def declared_variable
770
- raise ImproperStatementUsageError.new(self.write+' does not declare a variable') unless decalares_variable?
771
- return nil if declared_variable_id.nil?
772
- return self[0]
773
- end
774
-
775
- # Returns true if this statement creates a new variable. A variable is considered created
776
- # if it is declared in the variable or it modifies a variable. e.g. var_a.chop! or var_a.push(var_b)
777
- #
778
- def creates_variable?
779
- created_variable
780
- return true
781
- rescue ImproperStatementUsageError
782
- return false
783
- end
784
-
785
- # Returns the id of the created variable in this statement or raises an error if
786
- # no variable is created.
787
- #
788
- def created_variable_id
789
- return created_variable.variable_id
790
- end
791
-
792
- # Returns the variable created by this statement or raises an error if the
793
- # statement doesn't create a variable.
794
- #
795
- def created_variable
796
-
797
- # Check if the statement declares a new variable
798
- begin
799
- return declared_variable
800
- rescue ImproperStatementUsageError => e
801
- if first.kind_of?(InstanceCallContainer)
802
- if first.subject.kind_of?(Variable) and first.method_call.destructive?
803
- return first.subject
804
- end
805
- end
806
- raise ImproperStatementUsageError.new(self.write+' statement does not create a new variable "'+e+"'")
807
- end
808
-
809
- end
810
-
811
- # TODO Write tests for this
812
- # Returns true if this statement is equivalent to the statement
813
- # supplied. They are equalvalent if they have the same length,
814
- # classes and values.
815
- #
816
- # @param statement The statement that this statement is being compared to
817
- #
818
- def equivalent?(statement)
819
- return false unless statement.length == self.length
820
-
821
- # TODO It would be nice to come up with a method to itterate through
822
- # groups in an array.
823
- # e.g. [self,statement].each_pair do |x,y|
824
- # end
825
- # where x is the first element in self and y is the first element in statement
826
- # TODO I think Unknowns should only be accepted if they are the first paramter in
827
- # a declaration statement. Current var_a = Unknown.chop is the same as var_b = var_c.chop
828
- self.each_with_index do |elem,i|
829
- return false unless elem.equivalent?(statement[i])
830
- end
831
- return true
832
-
833
- # # TODO Tidy this up - pass the element to each other
834
- # # e.g.
835
- # # self.each_with_index do |elem,i|
836
- # # return false unless eleme.equivalent?(statement[i])
837
- # # end
838
- # #
839
- # self.each_with_index do |elem,i|
840
- # return false if statement[i].class == elem.class
841
- # if(elem.kind_of?(Variable))
842
- # return false if elem.variable_id != statement[i].variable_id
843
- # elsif(elem.kind_of?(InstanceCallContainer))
844
- # return false if elem.variable_id != statement[i].variable_id
845
- # return false if elem.method_call != statement[i].method_call
846
- # end
847
- # end
848
- # return true
849
- end
850
-
851
- def has?(&block)
852
- self.each do |x|
853
- return true if block.call(x)
854
- end
855
- return false
856
- end
857
-
858
- def cauldron_method_calls
859
- return ['.statement_id']
860
- end
861
-
862
- def map_to(mapping)
863
-
864
- # Duplicate the current statement before it is rewritten
865
- rewritten_statement = self.copy
866
-
867
- # Find all the containers that contain TheoryVariables
868
- # NOTE The statement is put in an array because select all doesn't include the array itself
869
- containers = [rewritten_statement].select_all {|x| x.respond_to?(:has?)}
870
- theory_variable_containers = containers.select {|x| x.has? {|y| y.kind_of?(Variable)}}
871
-
872
- # Rewrite the statement replacing the values
873
- theory_variable_containers.each do |z|
874
- z.replace_variables!(mapping)
875
- end
876
-
877
- return rewritten_statement
878
- #return TheoryDependent.new(rewritten_statement,@theory_component_id)
879
- end
880
-
881
- protected
882
-
883
- # @param var The subsitute variable
884
- # @param id The id of the substitee
885
- # @param target The instance call being substituted
886
- #
887
- def subst_instance_call(var,id,target,context)
888
-
889
- # Duplicate the current statement (variables are not in context)
890
- copied_statement = self.copy
891
-
892
- # 2. Outside the context of the statement does the variable meet the requirements
893
- #begin
894
-
895
- # If the target is a instance call does the new variable meet the requirements of the instance call?
896
- var_with_instance_call = nil
897
-
898
- # Can the replacing variable be litralised?
899
- if(var.literalisable?)
900
-
901
- # Change the variable into a literal instance
902
- begin
903
- literal_instance = var.literalise
904
- rescue StandardError => e
905
- StandardLogger.log('literalise: '+e)
906
- end
907
-
908
- # Retrieve the instance call requirements and use the litralised variable with them
909
- unless target.method_call.valid_syntax?(literal_instance)
910
- raise RuntimeSyntaxError.new(literal_instance.write+' doesn\'t have the method "'+target.method_call.write+'"')
911
- end
912
-
913
- # The substitute variable can use the same instance call as the variable being substituted
914
- var_with_instance_call = InstanceCallContainer.new(var,target.method_call.copy)
915
-
916
- else
917
-
918
- # TODO Write tests to test variables that can't be literalised
919
- # self.class == String can use the .chop method call
920
-
921
- # Does the substitute variable meet the requirements of the target variable
922
- if(var.meets_requirements?(target.subject))
923
-
924
- # The individual variables can be replaced - but can it use the same method call as the target
925
- var_with_instance_call = InstanceCallContainer.new(var,target.method_call.copy)
926
-
927
- else
928
- StandardLogger.log(var.write_variable_id+' doesn\'t meet the requirements of '+target.subject.write)
929
-
930
- end
931
- end
932
-
933
- # At this point the variable being substitued either doesn't make an instance call or makes a valid one
934
- # Now we need to see whether it is valid with in the context of the statement.
935
-
936
- # Get the requirements added to the variable in the context of the statement
937
- reqs = requirements_for(target.subject)
938
-
939
- # If there are no requirements then its fine to use
940
- if(reqs.empty?)
941
- copied_statement = self.copy
942
- #copied_statement.replace_variable!(id,var_with_instance_call)
943
- copied_statement.replace_variable!(id,var_with_instance_call.subject)
944
- return copied_statement
945
- end
946
- StandardLogger.log('Statement: haven\'t accounted for requirements')
947
- return
948
-
949
- end
950
-
951
- #
952
- # @param var The variable that is being substituted into the statement
953
- # @param id The id of the variable to be included in the statement
954
- # @param target The variable in the statement that will be replaced
955
- #
956
- def subst_variable_call(var,id,target,context)
957
-
958
- # The variable must meet the requirements of the statement - so add it to a duplicate statement
959
- copied_statement = self.copy
960
- copied_statement.replace_variable!(id,var)
961
-
962
- return copied_statement
963
-
964
- end
965
-
966
- # Returns a copy of the variable with the id supplied, otherwise
967
- # raise an exception. This variable is not in the context of
968
- # the statement.
969
- #
970
- # @param id The id of the variable that should exist in this statement
971
- #
972
- def copy_original_variable(id)
973
- self.each do |code|
974
- next unless code.kind_of? Variable or code.kind_of? InstanceCallContainer
975
- return code.copy if code.variable_id == id
976
- end
977
- end
978
-
979
- # Updates any of the requirements of the variables if
980
- # it's needed and confirms the statement so it can be
981
- # used in a method.
982
- # TODO This class might be redundant
983
- #
984
- # Write tests for exceptable statements
985
- #
986
- def update
987
-
988
- # Narrow down what type of statement it is. Does it contain a equal or equivalent sign?
989
- equivaltent_assignment = detect_class(Equivalent)
990
-
991
- unless equivaltent_assignment.nil?
992
- begin
993
- #update_requirements
994
- @confirmed = true
995
- rescue InvalidStatementError
996
- end
997
- return
998
- end
999
-
1000
- # Check if the statement contains return syntax
1001
- if detect_class(Return)
1002
-
1003
- # Check there are two
1004
- unless self.length == 2
1005
- @confirmed = false
1006
- return
1007
- end
1008
- @confirmed = true
1009
- return
1010
- end
1011
-
1012
- if self.length == 1 and detect_class(DefCall)
1013
- @confirmed = true
1014
- end
1015
-
1016
- end
1017
-
1018
- # Returns the two arrays split between the kind of class
1019
- # provided.
1020
- #
1021
- # @param klass
1022
- #
1023
- def split klass
1024
-
1025
- # Find the index of the equivalent assignment
1026
- equivaltent_assignment = detect_class(klass)
1027
- if equivaltent_assignment.nil? then raise InvalidStatementError.new('No equivalent assignment found when spliting') end
1028
- equalivalent_index = self.index(equivaltent_assignment)
1029
-
1030
- # Slice the array between the two values
1031
- left = self.slice(0...equalivalent_index)
1032
- right = self.slice((equalivalent_index+1)...self.length)
1033
-
1034
- # Check there is only ever one thing on the left hand side of the equation
1035
- if(left.length > 1) then throw InvalidStatementError.new('"Equivalent statements" can only have one value on the left hand side') end
1036
-
1037
- return [left, right]
1038
-
1039
- end
1040
-
1041
- # Returns the first instance with the class declared.
1042
- #
1043
- # @param class_name The kind of class that is being searched for e.g. Equal or Equivalent
1044
- #
1045
- def detect_class(class_name)
1046
- not_found = lambda{raise StandardError.new(''+class_name.to_s+' could not be found')}
1047
- begin
1048
- return self.detect(not_found) {|x| x.kind_of? class_name}
1049
- rescue StandardError
1050
- return nil
1051
- end
1052
- end
1053
-
1054
- # Returns the requirement for the declared variable in the statement
1055
- #
1056
- def declared_variable_requirement
1057
-
1058
- # Check that this statement declares a variable (they all should)
1059
- if(detect_class(Equal).nil?)then raise StandardError.new('Expecting statement to declare a variable') end
1060
-
1061
- # Check that the equals sign is the second code
1062
- unless(self[1].kind_of?(Equal)) then raise StandardError.new('Expecting statement to include equal sign as secound code element') end
1063
-
1064
- # Return the requirement of the declared variable
1065
- declaration_requirement = Requirement.new(This.new,Equal.new,*self[2..self.length])
1066
-
1067
- return declaration_requirement
1068
-
1069
- end
1070
-
1071
- # Currently this involves changing the 'uniq_id' of any
1072
- # variables modified in the statment.
1073
- # e.g. var_a.push(9)
1074
- #
1075
- def review
1076
-
1077
- # TODO I have dropped this for now I don't know if it is redundent or not - it effect
1078
- # tc_statement.rb test_created_variable
1079
- # # A modifying statement would be "var_16.push('Normandy SR2')"
1080
- # if statement_type == StatementStructure::MODIFYING_STATEMENT
1081
- # created_variable.uniq_id_history.push(created_variable.uniq_id)
1082
- # created_variable.increament_uniq_id!
1083
- # end
1084
- rescue StandardError => e
1085
- # TODO I shouldn't really need this it is just temporary because of the way
1086
- # structures are created in StatementStructure2.statements - they create a
1087
- # partial statement.
1088
- StandardLogger.instance.warning(e)
1089
- end
1090
-
1091
- end