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