cauldron 0.1.0 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Gemfile +2 -0
- data/Rakefile +7 -0
- data/VERSION +1 -1
- data/features/cauldron_generates_runtime_method.feature +3 -2
- data/features/step_definitions/cauldron_steps.rb +0 -1
- data/features/support/method_1.example +3 -0
- data/features/support/method_2.example +6 -0
- data/lib/Chain.rb +140 -264
- data/lib/CodeHandler.rb +0 -4
- data/lib/ScopeDependencies.rb +1 -0
- data/lib/Theory.rb +12 -15
- data/lib/UnifiedChain.rb +265 -8
- data/lib/cauldron.rb +1 -1
- data/lib/cauldron/demos.rb +280 -0
- data/lib/cauldron/pot.rb +56 -30
- data/lib/cauldron/sexp2cauldron.rb +109 -126
- data/lib/cauldron/terminal.rb +5 -74
- data/lib/core/ClassMethodCallContainer.rb +14 -0
- data/lib/core/Container.rb +12 -2
- data/lib/core/InstanceCallContainer.rb +30 -4
- data/lib/core/TheoryGenerator.rb +2 -9
- data/lib/core/assignment/Equal.rb +1 -1
- data/lib/core/assignment/Equivalent.rb +1 -1
- data/lib/core/assignment/NotEqual.rb +1 -1
- data/lib/core/call_container/CallContainer.rb +7 -1
- data/lib/core/instance_call/Chop.rb +0 -9
- data/lib/core/instance_call/instance_calls.rb +8 -0
- data/lib/core/instance_call/length_equal.rb +1 -1
- data/lib/core/requirement/Requirement.rb +1 -0
- data/lib/core/runtime_class/class_names.rb +12 -12
- data/lib/core/runtime_method/ActsAsRuntimeMethod.rb +0 -7
- data/lib/core/runtime_method/RuntimeMethod.rb +59 -45
- data/lib/core/statement/ActsAsStatement.rb +1 -1
- data/lib/core/statement/ArrayAccess.rb +28 -2
- data/lib/core/statement/OpenStatement.rb +7 -0
- data/lib/core/statement/Statement.rb +22 -18
- data/lib/core/statement/TheoryStatement.rb +8 -1
- data/lib/core/syntax/Addition.rb +3 -2
- data/lib/core/syntax/If.rb +8 -0
- data/lib/core/syntax/Return.rb +1 -1
- data/lib/core/variable/BaseVariable.rb +0 -2
- data/lib/core/variable/MethodParameter.rb +4 -31
- data/lib/core/variable/Unknown.rb +1 -5
- data/lib/implemented_chain.rb +3 -2
- data/lib/required.rb +0 -1
- data/lib/ruby_code/String.rb +0 -17
- data/lib/theories.rb +25 -1
- data/lib/theory/TheoryAction.rb +35 -5
- data/lib/theory/TheoryChainValidator.rb +10 -8
- data/lib/theory/TheoryComponent.rb +17 -0
- data/lib/theory/TheoryConnector.rb +76 -9
- data/lib/theory/TheoryDependent.rb +2 -2
- data/lib/theory/TheoryImplementation.rb +7 -7
- data/lib/util/ClassEvaluation.rb +2 -7
- data/lib/util/MethodValidation.rb +10 -6
- data/lib/util/Parser.rb +26 -20
- data/lib/util/StringToTheory.rb +27 -3
- data/spec/cauldron/chain_spec.rb +24 -0
- data/spec/cauldron/demos_spec.rb +30 -0
- data/spec/cauldron/pot_spec.rb +66 -0
- data/spec/cauldron/runtime_method_spec.rb +47 -5
- data/spec/cauldron/sexp_2_cauldron_spec.rb +92 -0
- data/spec/cauldron/terminal_spec.rb +1 -1
- data/spec/cauldron/theory_action_spec.rb +20 -0
- data/spec/cauldron/theory_connector_spec.rb +52 -0
- data/spec/cauldron/theory_spec.rb +59 -0
- data/spec/cauldron/unified_chain_spec.rb +102 -0
- data/spec/spec_helper.rb +10 -1
- data/tasks/theory_tasks.rake +274 -0
- data/test/fixtures/implementation_results/0/dump +0 -0
- data/test/fixtures/theories/0/dump +0 -0
- data/test/fixtures/theories/1/dump +0 -0
- data/test/fixtures/theories/10/dump +0 -0
- data/test/fixtures/theories/11/dump +0 -0
- data/test/fixtures/theories/12/dump +0 -0
- data/test/fixtures/theories/13/declaration.txt +1 -1
- data/test/fixtures/theories/13/desc +1 -1
- data/test/fixtures/theories/13/dump +0 -0
- data/test/fixtures/theories/14/dump +0 -0
- data/test/fixtures/theories/15/dump +0 -0
- data/test/fixtures/theories/16/dump +0 -0
- data/test/fixtures/theories/17/dump +0 -0
- data/test/fixtures/theories/18/dump +0 -0
- data/test/fixtures/theories/19/dump +0 -0
- data/test/fixtures/theories/2/dump +0 -0
- data/test/fixtures/theories/20/declaration.txt +1 -1
- data/test/fixtures/theories/20/desc +1 -1
- data/test/fixtures/theories/20/dump +0 -0
- data/test/fixtures/theories/3/dump +0 -0
- data/test/fixtures/theories/4/dump +0 -0
- data/test/fixtures/theories/5/dump +0 -0
- data/test/fixtures/theories/6/dump +0 -0
- data/test/fixtures/theories/7/dump +0 -0
- data/test/fixtures/theories/8/dump +0 -0
- data/test/fixtures/theories/9/dump +0 -0
- data/test/fixtures/theory_implementations/0/declaration.txt +1 -1
- data/test/fixtures/theory_implementations/0/dump +0 -0
- data/test/fixtures/theory_implementations/1/declaration.txt +11 -0
- data/test/fixtures/theory_implementations/1/dump +0 -0
- data/test/fixtures/theory_implementations/2/declaration.txt +11 -0
- data/test/fixtures/theory_implementations/2/dump +0 -0
- data/test/output/simple_method.txt +0 -1
- data/test/tc_contextual_variables.rb +2 -41
- data/test/tc_describe.rb +1 -2
- data/test/tc_method.rb +2 -5
- data/test/unit/core/runtime_method/tc_realised_runtime_method.rb +5 -3
- data/test/unit/core/runtime_method/tc_runtime_method.rb +34 -56
- data/test/unit/core/statement/tc_block_statement.rb +2 -0
- data/test/unit/core/statement/tc_open_statement.rb +15 -6
- data/test/unit/core/statement/tc_statement.rb +4 -5
- data/test/unit/core/statement/tc_statement_dependencies.rb +1 -0
- data/test/unit/core/statement/tc_theory_statement.rb +2 -0
- data/test/unit/core/syntax/tc_if_container.rb +5 -5
- data/test/unit/core/tc_theory_generator_heavy.rb +1 -1
- data/test/unit/core/tracking/tc_history.rb +3 -1
- data/test/unit/core/variable/tc_method_parameter_variable.rb +2 -2
- data/test/unit/tc_chain_with_case_1.rb +1 -1
- data/test/unit/tc_method_usage.rb +1 -1
- data/test/unit/tc_theory.rb +8 -2
- data/test/unit/theory/tc_theory_action.rb +37 -5
- data/test/unit/theory/tc_theory_chain_validator.rb +3 -3
- data/test/unit/theory/tc_theory_connector.rb +2 -37
- data/test/unit/theory/tc_theory_dependent.rb +2 -0
- data/test/unit/theory/tc_theory_implementation.rb +5 -1
- data/test/unit/theory/tc_theory_result.rb +3 -2
- data/test/unit/util/tc_method_validation.rb +4 -1
- data/test/unit/util/tc_parser.rb +2 -0
- data/test/unit/util/tc_string_to_theory.rb +3 -2
- data/tmp/runtime_method_evaluation.rb +7 -4
- metadata +59 -13
- data/lib/core/syntax/IfContainer.rb +0 -100
|
@@ -12,12 +12,13 @@ class TheoryChainValidator
|
|
|
12
12
|
def build(runtime_method,test_cases,theory_implementation_chains,potential_values=[])
|
|
13
13
|
validated_chains = []
|
|
14
14
|
theory_implementation_chains.each do |chain|
|
|
15
|
-
validate_next_chain_link(validated_chains,chain,runtime_method.copy,test_cases,0)
|
|
15
|
+
validate_next_chain_link(validated_chains,chain,runtime_method.copy,test_cases.copy,0)
|
|
16
16
|
end
|
|
17
17
|
raise StandardError.new('Failed to generate a valid runtime method') if validated_chains.length == 0
|
|
18
18
|
|
|
19
19
|
# Select the first chain and return the runtime method it generates
|
|
20
|
-
|
|
20
|
+
results = build_method_from_chain(validated_chains.first,runtime_method.copy,test_cases.copy)
|
|
21
|
+
return results
|
|
21
22
|
|
|
22
23
|
end
|
|
23
24
|
|
|
@@ -27,6 +28,7 @@ class TheoryChainValidator
|
|
|
27
28
|
# to the validated chain array.
|
|
28
29
|
#
|
|
29
30
|
def validate_next_chain_link(validated_chains,chain,runtime_method,test_cases,position)
|
|
31
|
+
|
|
30
32
|
# Check that current link in the chain meets in dependencies
|
|
31
33
|
# if its dependents are met it isn't suppose to work
|
|
32
34
|
unless chain[position].meets_dependencies?(runtime_method.copy,test_cases.copy)
|
|
@@ -63,12 +65,12 @@ class TheoryChainValidator
|
|
|
63
65
|
end
|
|
64
66
|
else
|
|
65
67
|
# Theory was wrong
|
|
66
|
-
chain[position].results.each do |x|
|
|
67
|
-
unless x.validates?(result,test_cases)
|
|
68
|
-
StandardLogger.instance.info('The following result failed to be met')
|
|
69
|
-
StandardLogger.instance.info(x.write)
|
|
70
|
-
end
|
|
71
|
-
end
|
|
68
|
+
# chain[position].results.each do |x|
|
|
69
|
+
# unless x.validates?(result,test_cases)
|
|
70
|
+
# StandardLogger.instance.info('The following result failed to be met')
|
|
71
|
+
# StandardLogger.instance.info(x.write)
|
|
72
|
+
# end
|
|
73
|
+
# end
|
|
72
74
|
return nil
|
|
73
75
|
end
|
|
74
76
|
|
|
@@ -24,6 +24,23 @@ module TheoryComponent
|
|
|
24
24
|
return @statement.tokens
|
|
25
25
|
end
|
|
26
26
|
|
|
27
|
+
def statements_with_variable(variable_id)
|
|
28
|
+
|
|
29
|
+
# Duplicate the current statement before it is rewritten
|
|
30
|
+
rewritten_statement = @statement.copy
|
|
31
|
+
|
|
32
|
+
# Find all containers of VariableDeclarations that declare a TheoryVariable
|
|
33
|
+
containers = [rewritten_statement].select_all {|x| x.respond_to?(:has?)}
|
|
34
|
+
theory_variable_containers = containers.select {|x| x.has? {|y| y.kind_of?(TheoryVariable)}}
|
|
35
|
+
|
|
36
|
+
results = theory_variable_containers.select do |x|
|
|
37
|
+
reg = eval '/var'+variable_id.to_s+'/'
|
|
38
|
+
x.write.match(reg)
|
|
39
|
+
end
|
|
40
|
+
return results
|
|
41
|
+
|
|
42
|
+
end
|
|
43
|
+
|
|
27
44
|
# Returns an array of any of the accessors in the statement. An accessor
|
|
28
45
|
# is the chain to access a property e.g. in the following statement =>
|
|
29
46
|
#
|
|
@@ -38,6 +38,8 @@ class TheoryConnector
|
|
|
38
38
|
#
|
|
39
39
|
def generate_chains(runtime_method,test_cases,theories)
|
|
40
40
|
|
|
41
|
+
theories = remove_irrelevant_theories(theories)
|
|
42
|
+
|
|
41
43
|
# Create the inital chain (with the head and tail)
|
|
42
44
|
intial_chain = Chain.new
|
|
43
45
|
|
|
@@ -47,39 +49,104 @@ class TheoryConnector
|
|
|
47
49
|
# Create the initial chains
|
|
48
50
|
possible_chains = []
|
|
49
51
|
possible_head_theories.each do |x|
|
|
50
|
-
possible_chains += intial_chain.copy.
|
|
52
|
+
possible_chains += intial_chain.copy.extension_permutaions(x)
|
|
51
53
|
end
|
|
52
|
-
|
|
54
|
+
|
|
53
55
|
# Check the initial chains incase they're complete
|
|
54
56
|
complete_chains = []
|
|
55
57
|
if possible_chains.any? {|x| x.complete? }
|
|
56
58
|
complete_chains += possible_chains.select {|x| x.complete?}
|
|
57
59
|
possible_chains.delete_if {|x| x.complete?}
|
|
58
|
-
end
|
|
60
|
+
end
|
|
61
|
+
return complete_chains unless complete_chains.empty?
|
|
59
62
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
+
possible_chains.each do |chain|
|
|
64
|
+
|
|
65
|
+
# Remove the head theory to avoid it being re-used
|
|
66
|
+
head_free_theories = theories.copy
|
|
67
|
+
head_free_theories.delete_if {|theory| theory.theory_id == chain.first.theory_id}
|
|
68
|
+
|
|
69
|
+
complete_chains += complete_chain(chain,head_free_theories)
|
|
63
70
|
end
|
|
64
71
|
return complete_chains
|
|
65
72
|
|
|
66
73
|
end
|
|
67
74
|
|
|
68
|
-
|
|
75
|
+
def complete_chain(chain,theories)
|
|
76
|
+
chains = converge_chain(chain,theories)
|
|
77
|
+
return chains
|
|
78
|
+
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def converge_chain(chain,theories,step=0)
|
|
82
|
+
|
|
83
|
+
complete_chains = []
|
|
84
|
+
extended_chains = []
|
|
85
|
+
theories.each do |theory|
|
|
86
|
+
last_position = 1
|
|
87
|
+
chains = chain.add_link_to(theory,last_position,[])
|
|
88
|
+
next if chains.empty?
|
|
89
|
+
extended_chains += chains
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
# Are any of the chains complete
|
|
93
|
+
if extended_chains.any? {|x| x.complete? }
|
|
94
|
+
return extended_chains.select {|x| x.complete?}
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
closer_chains = []
|
|
98
|
+
extended_chains.each do |x|
|
|
99
|
+
if ((chain.unmet_dependents_ids-x.unmet_dependents_ids).length == chain.unmet_dependents_ids.length)
|
|
100
|
+
closer_chains << x
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
unless closer_chains.empty?
|
|
105
|
+
closer_chains.each do |x|
|
|
106
|
+
complete_chains += converge_chain(x,theories,step+1)
|
|
107
|
+
end
|
|
108
|
+
else
|
|
109
|
+
extended_chains.each do |x|
|
|
110
|
+
theories.each do |theory|
|
|
111
|
+
copied_chain = x.copy
|
|
112
|
+
last_position = 1
|
|
113
|
+
chains = copied_chain.add_link_to(theory,last_position,[])
|
|
114
|
+
chains.each do |z|
|
|
115
|
+
if ((chain.unmet_dependents_ids-z.unmet_dependents_ids).length == chain.unmet_dependents_ids.length)
|
|
116
|
+
complete_chains += converge_chain(z.copy,theories,step+1)
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
return complete_chains
|
|
124
|
+
end
|
|
125
|
+
|
|
69
126
|
def extend_chain(chain,theories)
|
|
127
|
+
|
|
70
128
|
complete_chains = []
|
|
71
129
|
theories.each do |x|
|
|
72
|
-
extended_chains = chain.copy.
|
|
130
|
+
extended_chains = chain.copy.extension_permutaions(x)
|
|
73
131
|
next if extended_chains.empty?
|
|
132
|
+
|
|
133
|
+
# Don't allow the same theory to be added twice - for now
|
|
134
|
+
updated_theories = theories.copy
|
|
135
|
+
updated_theories.delete_if {|theory| theory.theory_id == x.theory_id}
|
|
136
|
+
|
|
74
137
|
complete_chains += extended_chains.select {|y| y.complete?}
|
|
75
138
|
extended_chains.delete_if {|y| y.complete?}
|
|
76
139
|
extended_chains.each do |y|
|
|
77
|
-
complete_chains += extend_chain(y,
|
|
140
|
+
complete_chains += extend_chain(y,updated_theories)
|
|
78
141
|
end
|
|
79
142
|
end
|
|
80
143
|
return complete_chains
|
|
81
144
|
end
|
|
82
145
|
|
|
146
|
+
def remove_irrelevant_theories(theories)
|
|
147
|
+
theories.delete_if {|theory| theory.irrelevant? }
|
|
148
|
+
end
|
|
149
|
+
|
|
83
150
|
def create_possible_chains(runtime_method,test_cases,finish,theories)
|
|
84
151
|
|
|
85
152
|
# Generate the head theory - this is the starting point and doesn't have any dependents
|
|
@@ -56,10 +56,10 @@ class TheoryDependent
|
|
|
56
56
|
# the values in the mapping hash.
|
|
57
57
|
#
|
|
58
58
|
def map_to(mapping)
|
|
59
|
-
|
|
59
|
+
|
|
60
60
|
# Duplicate the current statement before it is rewritten
|
|
61
61
|
rewritten_statement = @statement.copy
|
|
62
|
-
|
|
62
|
+
|
|
63
63
|
# Find all the containers that contain TheoryVariables
|
|
64
64
|
# NOTE The statement is put in an array because select all doesn't include the array itself
|
|
65
65
|
containers = [rewritten_statement].select_all {|x| x.respond_to?(:has?)}
|
|
@@ -63,12 +63,12 @@ class TheoryImplementation < Theory
|
|
|
63
63
|
return false
|
|
64
64
|
end
|
|
65
65
|
|
|
66
|
-
# Returns all the theory vairables in this theory
|
|
67
|
-
# dependent.
|
|
68
|
-
#
|
|
69
|
-
# TODO What is the point in this - why only the actions?
|
|
70
|
-
def theory_variables
|
|
71
|
-
return @action.select_all {|x| x.kind_of?(TheoryVariable)}
|
|
72
|
-
end
|
|
66
|
+
# # Returns all the theory vairables in this theory
|
|
67
|
+
# # dependent.
|
|
68
|
+
# #
|
|
69
|
+
# # TODO What is the point in this - why only the actions?
|
|
70
|
+
# def theory_variables
|
|
71
|
+
# return @action.select_all {|x| x.kind_of?(TheoryVariable)}
|
|
72
|
+
# end
|
|
73
73
|
|
|
74
74
|
end
|
data/lib/util/ClassEvaluation.rb
CHANGED
|
@@ -4,10 +4,7 @@ class ClassEvaluation
|
|
|
4
4
|
#include WriteParameters
|
|
5
5
|
@@count = 0
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
# pass through parameters.
|
|
9
|
-
#
|
|
10
|
-
def evaluate_class(runtime_class,runtime_call,original_method=nil)
|
|
7
|
+
def evaluate_class(runtime_class,runtime_call)
|
|
11
8
|
|
|
12
9
|
# Create file to include the test method
|
|
13
10
|
#filepath = $LOC+File.join(['tmp','runtime_class_evaluation.rb'])
|
|
@@ -24,7 +21,6 @@ class ClassEvaluation
|
|
|
24
21
|
begin
|
|
25
22
|
return eval("#{runtime_class.class_name}.new.#{runtime_call}")
|
|
26
23
|
rescue NameError => e
|
|
27
|
-
StandardLogger.instance.error(original_method.write()) unless original_method.nil?
|
|
28
24
|
StandardLogger.instance.info(runtime_class.write)
|
|
29
25
|
raise e
|
|
30
26
|
end
|
|
@@ -43,7 +39,7 @@ class ClassEvaluation
|
|
|
43
39
|
# Include the sytax for the statement in the file
|
|
44
40
|
file << runtime_class.write
|
|
45
41
|
file.close
|
|
46
|
-
|
|
42
|
+
|
|
47
43
|
# Load the newly created class and check the statement
|
|
48
44
|
load filepath
|
|
49
45
|
begin
|
|
@@ -57,7 +53,6 @@ class ClassEvaluation
|
|
|
57
53
|
raise StandardError.new('Can only handle one parameter right now')
|
|
58
54
|
end
|
|
59
55
|
rescue NameError => e
|
|
60
|
-
StandardLogger.instance.error(original_method.write()) unless original_method.nil?
|
|
61
56
|
StandardLogger.instance.info(runtime_class.write)
|
|
62
57
|
raise e
|
|
63
58
|
end
|
|
@@ -118,20 +118,24 @@ class MethodValidation
|
|
|
118
118
|
)
|
|
119
119
|
)
|
|
120
120
|
# 5. return true if var_3.evaluate_class(var_2,var_1.method_name)<condition>
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
True.new,
|
|
125
|
-
If.new,
|
|
121
|
+
s = Statement.new(
|
|
122
|
+
If.new,
|
|
123
|
+
Container.new(
|
|
126
124
|
InstanceCallContainer.new(
|
|
127
125
|
var_3,
|
|
128
126
|
EvaluateClassCall.new,
|
|
129
127
|
var_2,
|
|
130
128
|
InstanceCallContainer.new(var_1,MethodNameCall.new)
|
|
131
129
|
),
|
|
132
|
-
Raw.new(condition)
|
|
130
|
+
Raw.new(condition)
|
|
133
131
|
)
|
|
134
132
|
)
|
|
133
|
+
os = OpenStatement.new(s)
|
|
134
|
+
os << Statement.new(Return.new,True.new)
|
|
135
|
+
test_method.push(os)
|
|
136
|
+
|
|
137
|
+
#test_method.push(s)
|
|
138
|
+
|
|
135
139
|
# 6. return false
|
|
136
140
|
test_method.push(
|
|
137
141
|
Statement.new(
|
data/lib/util/Parser.rb
CHANGED
|
@@ -119,25 +119,7 @@ class Parser
|
|
|
119
119
|
end
|
|
120
120
|
|
|
121
121
|
if sexp[0] == :if
|
|
122
|
-
|
|
123
|
-
#
|
|
124
|
-
# "if(var2 == var3)\nreturn true\nend"
|
|
125
|
-
# s(:if, s(:call, s(:call, nil, :var2, s(:arglist)), :==, s(:arglist, s(:call, nil, :var3, s(:arglist)))), s(:return, s(:true)), nil)
|
|
126
|
-
#
|
|
127
|
-
# "if(var2 != var3)\nreturn true\nend"
|
|
128
|
-
# s(:if, s(:call, s(:call, nil, :var2, s(:arglist)), :==, s(:arglist, s(:call, nil, :var3, s(:arglist)))), nil, s(:return, s(:true)))
|
|
129
|
-
#
|
|
130
|
-
internal_statements = (2...sexp.length).inject([]) do |total,x|
|
|
131
|
-
total << sexp[x] unless sexp[x].nil?
|
|
132
|
-
total
|
|
133
|
-
end
|
|
134
|
-
return OpenStatement.new(
|
|
135
|
-
IfContainer.new(
|
|
136
|
-
parse_token(sexp[1])
|
|
137
|
-
),
|
|
138
|
-
*internal_statements.collect {|x| parse_token(x)}
|
|
139
|
-
)
|
|
140
|
-
|
|
122
|
+
return self.parse_if(sexp)
|
|
141
123
|
end
|
|
142
124
|
|
|
143
125
|
if sexp[0] == :attrasgn
|
|
@@ -182,6 +164,29 @@ class Parser
|
|
|
182
164
|
raise StandardError.new("Could not find sexp '#{sexp[0].to_s}'")
|
|
183
165
|
end
|
|
184
166
|
|
|
167
|
+
def self.parse_if(sexp)
|
|
168
|
+
# TODO Look into the change in the nil position
|
|
169
|
+
#
|
|
170
|
+
# "if(var2 == var3)\nreturn true\nend"
|
|
171
|
+
# s(:if, s(:call, s(:call, nil, :var2, s(:arglist)), :==, s(:arglist, s(:call, nil, :var3, s(:arglist)))), s(:return, s(:true)), nil)
|
|
172
|
+
#
|
|
173
|
+
# "if(var2 != var3)\nreturn true\nend"
|
|
174
|
+
# s(:if, s(:call, s(:call, nil, :var2, s(:arglist)), :==, s(:arglist, s(:call, nil, :var3, s(:arglist)))), nil, s(:return, s(:true)))
|
|
175
|
+
#
|
|
176
|
+
internal_statements = (2...sexp.length).inject([]) do |total,x|
|
|
177
|
+
total << sexp[x] unless sexp[x].nil?
|
|
178
|
+
total
|
|
179
|
+
end
|
|
180
|
+
return OpenStatement.new(
|
|
181
|
+
Statement.new(
|
|
182
|
+
If.new,
|
|
183
|
+
Container.new(parse_token(sexp[1]))
|
|
184
|
+
),
|
|
185
|
+
*internal_statements.collect {|x| parse_token(x)}
|
|
186
|
+
)
|
|
187
|
+
|
|
188
|
+
end
|
|
189
|
+
|
|
185
190
|
def self.parse_simple_token(token)
|
|
186
191
|
if token.to_s.match(/^var(\d+)$/)
|
|
187
192
|
id = token.to_s.match(/^var(\d+)$/)[1].to_i
|
|
@@ -284,7 +289,8 @@ class Parser
|
|
|
284
289
|
'statement_id' => 'StatementID',
|
|
285
290
|
'last' => 'Last',
|
|
286
291
|
'select' => 'Select',
|
|
287
|
-
'-' => 'Subtract'
|
|
292
|
+
'-' => 'Subtract',
|
|
293
|
+
'first' => 'First'
|
|
288
294
|
}
|
|
289
295
|
# TODO Need to re-structure code to better suit the parser and how it handles != statements
|
|
290
296
|
if not affirmative
|
data/lib/util/StringToTheory.rb
CHANGED
|
@@ -41,7 +41,7 @@ class StringToTheory < Parser
|
|
|
41
41
|
def self.run(statement_string)
|
|
42
42
|
statement_string.gsub!(/<runtime_method>/,'runtime_method')
|
|
43
43
|
return super(statement_string)
|
|
44
|
-
|
|
44
|
+
|
|
45
45
|
end
|
|
46
46
|
|
|
47
47
|
# TODO This method is very similar to the Parser
|
|
@@ -69,17 +69,18 @@ class StringToTheory < Parser
|
|
|
69
69
|
'Unknown'=>'UnknownClass',
|
|
70
70
|
'Addition'=>'AdditionClass',
|
|
71
71
|
'Equal'=>'EqualClass',
|
|
72
|
+
'If'=>'IfClass',
|
|
72
73
|
'RuntimeMethod'=>'RuntimeMethodClass',
|
|
73
74
|
'CTestCase'=>'CTestCaseClass',
|
|
74
75
|
'Fixnum'=>'FixnumClass',
|
|
75
76
|
'Equivalent'=>'EquivalentClass',
|
|
76
77
|
'OpenStatement'=>'OpenStatementClass',
|
|
77
|
-
'IfContainer'=>'IfContainerClass',
|
|
78
78
|
'BlockStatement'=> 'BlockStatementClass',
|
|
79
79
|
'Container'=> 'ContainerClass',
|
|
80
80
|
'Subtract'=> 'SubtractClass',
|
|
81
81
|
'Times'=> 'TimesClass',
|
|
82
|
-
'Chop'=> 'ChopClass'
|
|
82
|
+
'Chop'=> 'ChopClass',
|
|
83
|
+
'TheoryStatement'=> 'TheoryStatementClass'
|
|
83
84
|
}
|
|
84
85
|
raise StandardError.new('Unkown constant '+token.to_s) unless constants.has_key?(token.to_s)
|
|
85
86
|
eval(constants[token.to_s]+'.new')
|
|
@@ -98,6 +99,29 @@ class StringToTheory < Parser
|
|
|
98
99
|
end
|
|
99
100
|
end
|
|
100
101
|
|
|
102
|
+
def self.parse_if(sexp)
|
|
103
|
+
# TODO Look into the change in the nil position
|
|
104
|
+
#
|
|
105
|
+
# "if(var2 == var3)\nreturn true\nend"
|
|
106
|
+
# s(:if, s(:call, s(:call, nil, :var2, s(:arglist)), :==, s(:arglist, s(:call, nil, :var3, s(:arglist)))), s(:return, s(:true)), nil)
|
|
107
|
+
#
|
|
108
|
+
# "if(var2 != var3)\nreturn true\nend"
|
|
109
|
+
# s(:if, s(:call, s(:call, nil, :var2, s(:arglist)), :==, s(:arglist, s(:call, nil, :var3, s(:arglist)))), nil, s(:return, s(:true)))
|
|
110
|
+
#
|
|
111
|
+
internal_statements = (2...sexp.length).inject([]) do |total,x|
|
|
112
|
+
total << sexp[x] unless sexp[x].nil?
|
|
113
|
+
total
|
|
114
|
+
end
|
|
115
|
+
return OpenStatement.new(
|
|
116
|
+
TheoryStatement.new(
|
|
117
|
+
If.new,
|
|
118
|
+
Container.new(parse_token(sexp[1]))
|
|
119
|
+
),
|
|
120
|
+
*internal_statements.collect {|x| parse_token(x)}
|
|
121
|
+
)
|
|
122
|
+
|
|
123
|
+
end
|
|
124
|
+
|
|
101
125
|
def self.parse_return(sexp)
|
|
102
126
|
return TheoryStatement.new(
|
|
103
127
|
*[sexp[0],sexp[1]].collect {|x| parse_token(x)}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
module Cauldron
|
|
4
|
+
|
|
5
|
+
describe 'Chain' do
|
|
6
|
+
|
|
7
|
+
describe '#complete?' do
|
|
8
|
+
it 'chain is complete with just "return param1"' do
|
|
9
|
+
temp = Object.new
|
|
10
|
+
temp.extend(Cauldron::Demos)
|
|
11
|
+
demo = temp.demo_one
|
|
12
|
+
demo[:chain].complete?.should == true
|
|
13
|
+
end
|
|
14
|
+
it 'chain is complete with "if param1 == \'carrot\'"' do
|
|
15
|
+
temp = Object.new
|
|
16
|
+
temp.extend(Cauldron::Demos)
|
|
17
|
+
demo = temp.demo_two
|
|
18
|
+
demo[:chain].complete?.should == true
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
module Cauldron
|
|
4
|
+
|
|
5
|
+
describe 'Demos' do
|
|
6
|
+
|
|
7
|
+
describe '#demo_one' do
|
|
8
|
+
it 'can generate a demo that can generate a simple runtime method' do
|
|
9
|
+
temp = Object.new
|
|
10
|
+
temp.extend(Cauldron::Demos)
|
|
11
|
+
demo = temp.demo_one
|
|
12
|
+
|
|
13
|
+
# => TODO Don't like this coupling
|
|
14
|
+
Cauldron::Pot.new.demo_works?(demo).should == true
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
describe '#demo_two' do
|
|
19
|
+
it 'generates a demo that can return two different values' do
|
|
20
|
+
temp = Object.new
|
|
21
|
+
temp.extend(Cauldron::Demos)
|
|
22
|
+
demo = temp.demo_two
|
|
23
|
+
|
|
24
|
+
Cauldron::Pot.new.demo_works?(demo).should == true
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
end
|