kalc 0.8.1 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Gemfile +1 -1
- data/Gemfile.lock +14 -13
- data/bin/ikalc +2 -2
- data/bin/kalc +2 -2
- data/kalc.gemspec +16 -16
- data/lib/kalc.rb +5 -5
- data/lib/kalc/ast.rb +36 -35
- data/lib/kalc/environment.rb +2 -2
- data/lib/kalc/grammar.rb +53 -53
- data/lib/kalc/interpreter.rb +39 -53
- data/lib/kalc/repl.rb +17 -21
- data/lib/kalc/transform.rb +18 -18
- data/lib/kalc/version.rb +1 -1
- data/spec/grammar_spec.rb +51 -51
- data/spec/interpreter_spec.rb +53 -53
- data/spec/stdlib_spec.rb +26 -26
- metadata +37 -32
data/lib/kalc/interpreter.rb
CHANGED
@@ -17,7 +17,7 @@ module Kalc
|
|
17
17
|
env.add_function(:OR, lambda { |cxt, *args|
|
18
18
|
retval = false
|
19
19
|
args.each do |arg|
|
20
|
-
if arg.eval(cxt)
|
20
|
+
if arg.eval(cxt)
|
21
21
|
retval = true
|
22
22
|
break
|
23
23
|
end
|
@@ -25,14 +25,14 @@ module Kalc
|
|
25
25
|
retval
|
26
26
|
})
|
27
27
|
|
28
|
-
env.add_function(:NOT, lambda { |cxt, val|
|
28
|
+
env.add_function(:NOT, lambda { |cxt, val|
|
29
29
|
!val.eval(cxt)
|
30
30
|
})
|
31
31
|
|
32
32
|
env.add_function(:AND, lambda { |cxt, *args|
|
33
33
|
retval = true
|
34
34
|
args.each do |arg|
|
35
|
-
|
35
|
+
unless arg.eval(cxt)
|
36
36
|
retval = false
|
37
37
|
break
|
38
38
|
end
|
@@ -40,29 +40,29 @@ module Kalc
|
|
40
40
|
retval
|
41
41
|
})
|
42
42
|
|
43
|
-
env.add_function(:RAND, lambda { |cxt, val|
|
43
|
+
env.add_function(:RAND, lambda { |cxt, val|
|
44
44
|
rand(val.eval(cxt))
|
45
45
|
})
|
46
46
|
|
47
|
-
env.add_function(:SYSTEM, lambda { |cxt, val|
|
47
|
+
env.add_function(:SYSTEM, lambda { |cxt, val|
|
48
48
|
throw "Nope. I don't think so!"
|
49
49
|
})
|
50
50
|
|
51
51
|
# IS?
|
52
|
-
env.add_function(:ISLOGICAL, lambda { |cxt, val|
|
52
|
+
env.add_function(:ISLOGICAL, lambda { |cxt, val|
|
53
53
|
newval = val.eval(cxt)
|
54
54
|
newval == true || newval == false
|
55
55
|
})
|
56
56
|
|
57
|
-
env.add_function(:ISNONTEXT, lambda { |cxt, val|
|
57
|
+
env.add_function(:ISNONTEXT, lambda { |cxt, val|
|
58
58
|
!val.eval(cxt).is_a? String
|
59
59
|
})
|
60
60
|
|
61
|
-
env.add_function(:ISNUMBER, lambda { |cxt, val|
|
61
|
+
env.add_function(:ISNUMBER, lambda { |cxt, val|
|
62
62
|
val.eval(cxt).is_a? Numeric
|
63
63
|
})
|
64
64
|
|
65
|
-
env.add_function(:ISTEXT, lambda { |cxt, val|
|
65
|
+
env.add_function(:ISTEXT, lambda { |cxt, val|
|
66
66
|
val.eval(cxt).is_a? String
|
67
67
|
})
|
68
68
|
|
@@ -71,27 +71,27 @@ module Kalc
|
|
71
71
|
val.eval(cxt).abs
|
72
72
|
})
|
73
73
|
|
74
|
-
env.add_function(:DEGREES, lambda { |
|
74
|
+
env.add_function(:DEGREES, lambda { |cxt, val|
|
75
75
|
val.eval(cxt) * (180.0 / Math::PI)
|
76
76
|
})
|
77
77
|
|
78
|
-
env.add_function(:PRODUCT, lambda { |cxt, *args|
|
78
|
+
env.add_function(:PRODUCT, lambda { |cxt, *args|
|
79
79
|
args.map { |a| a.eval(cxt) }.inject(:*)
|
80
80
|
})
|
81
81
|
|
82
|
-
env.add_function(:RADIANS, lambda { |cxt, val|
|
82
|
+
env.add_function(:RADIANS, lambda { |cxt, val|
|
83
83
|
val.eval(cxt) * (Math::PI / 180.0)
|
84
84
|
})
|
85
85
|
|
86
|
-
env.add_function(:ROUND, lambda { |cxt, num, digits|
|
86
|
+
env.add_function(:ROUND, lambda { |cxt, num, digits|
|
87
87
|
num.eval(cxt).round(digits.eval(cxt))
|
88
88
|
})
|
89
89
|
|
90
|
-
env.add_function(:SUM, lambda { |cxt, *args|
|
90
|
+
env.add_function(:SUM, lambda { |cxt, *args|
|
91
91
|
args.map { |a| a.eval(cxt) }.inject(:+)
|
92
92
|
})
|
93
93
|
|
94
|
-
env.add_function(:TRUNC, lambda { |cxt, val|
|
94
|
+
env.add_function(:TRUNC, lambda { |cxt, val|
|
95
95
|
Integer(val.eval(cxt))
|
96
96
|
})
|
97
97
|
|
@@ -99,15 +99,8 @@ module Kalc
|
|
99
99
|
Math.log(val.eval(cxt))
|
100
100
|
})
|
101
101
|
|
102
|
-
math_funs =
|
103
|
-
|
104
|
-
'cbrt', 'cos', 'cosh',
|
105
|
-
'erf', 'erfc', 'exp',
|
106
|
-
'gamma',
|
107
|
-
'lgamma', 'log', 'log2', 'log10',
|
108
|
-
'sin', 'sinh', 'sqrt',
|
109
|
-
'tan', 'tanh',
|
110
|
-
]
|
102
|
+
math_funs =
|
103
|
+
%w(acos acosh asin asinh atan atanh cbrt cos cosh erf erfc exp gamma lgamma log log2 log10 sin sinh sqrt tan tanh)
|
111
104
|
|
112
105
|
math_funs.each do |math_fun|
|
113
106
|
env.add_function(math_fun.upcase.to_sym, lambda { |cxt, val|
|
@@ -116,19 +109,12 @@ module Kalc
|
|
116
109
|
end
|
117
110
|
|
118
111
|
# Strings
|
119
|
-
string_funs =
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
'length', 'size', 'lstrip',
|
126
|
-
'succ', 'next',
|
127
|
-
'oct', 'ord',
|
128
|
-
'reverse', 'rstrip',
|
129
|
-
'strip', 'swapcase', 'to_c', 'to_f', 'to_i', 'to_r',
|
130
|
-
'upcase'
|
131
|
-
]
|
112
|
+
string_funs =
|
113
|
+
%w(chomp chop chr clear count
|
114
|
+
downcase
|
115
|
+
hex
|
116
|
+
inspect intern
|
117
|
+
to_sym length size lstrip succ next oct ord reverse rstrip strip swapcase to_c to_f to_i to_r upcase)
|
132
118
|
|
133
119
|
string_funs.each do |str_fun|
|
134
120
|
env.add_function(str_fun.upcase.to_sym, lambda { |cxt, val|
|
@@ -140,7 +126,7 @@ module Kalc
|
|
140
126
|
Integer(val.eval(cxt)).chr
|
141
127
|
})
|
142
128
|
|
143
|
-
env.add_function(:CLEAN, lambda { |cxt, val|
|
129
|
+
env.add_function(:CLEAN, lambda { |cxt, val|
|
144
130
|
val.eval(cxt).gsub(/\P{ASCII}/, '')
|
145
131
|
})
|
146
132
|
|
@@ -148,7 +134,7 @@ module Kalc
|
|
148
134
|
val.eval(cxt).ord
|
149
135
|
})
|
150
136
|
|
151
|
-
env.add_function(:CONCATENATE, lambda { |cxt, *args|
|
137
|
+
env.add_function(:CONCATENATE, lambda { |cxt, *args|
|
152
138
|
args.map { |a| a.eval(cxt) }.join
|
153
139
|
})
|
154
140
|
|
@@ -167,11 +153,11 @@ module Kalc
|
|
167
153
|
|
168
154
|
env.add_function(:FIXED, lambda { |cxt, val, decimal_places, no_commas|
|
169
155
|
output = "%.#{Integer(decimal_places.eval(cxt))}f" % Float(val.eval(cxt))
|
170
|
-
output = output.to_s.reverse.scan(/(?:\d*\.)?\d{1,3}-?/).join(',').reverse if no_commas.eval(cxt)
|
156
|
+
output = output.to_s.reverse.scan(/(?:\d*\.)?\d{1,3}-?/).join(',').reverse if !no_commas.eval(cxt)
|
171
157
|
output
|
172
158
|
})
|
173
159
|
|
174
|
-
env.add_function(:LEFT, lambda { |cxt, val, number_of_characters|
|
160
|
+
env.add_function(:LEFT, lambda { |cxt, val, number_of_characters|
|
175
161
|
num = Integer(number_of_characters.eval(cxt)) - 1
|
176
162
|
val.eval(cxt)[0..num]
|
177
163
|
})
|
@@ -180,12 +166,12 @@ module Kalc
|
|
180
166
|
val.eval(cxt).length
|
181
167
|
})
|
182
168
|
|
183
|
-
env.add_function(:LOWER, lambda { |cxt, val|
|
169
|
+
env.add_function(:LOWER, lambda { |cxt, val|
|
184
170
|
val.eval(cxt).downcase
|
185
171
|
})
|
186
172
|
|
187
173
|
env.add_function(:MID, lambda { |cxt, val, start_position, number_of_characters|
|
188
|
-
|
174
|
+
|
189
175
|
start = Integer(start_position.eval(cxt)) - 1
|
190
176
|
chars = Integer(number_of_characters.eval(cxt)) - 1
|
191
177
|
|
@@ -193,7 +179,7 @@ module Kalc
|
|
193
179
|
})
|
194
180
|
|
195
181
|
env.add_function(:PROPER, lambda { |cxt, val|
|
196
|
-
val.eval(cxt).split(
|
182
|
+
val.eval(cxt).split(' ').map { |c| c.capitalize }.join(' ')
|
197
183
|
})
|
198
184
|
|
199
185
|
env.add_function(:REPLACE, lambda { |cxt, val, start_position, number_of_chars, new_text|
|
@@ -204,7 +190,7 @@ module Kalc
|
|
204
190
|
output
|
205
191
|
})
|
206
192
|
|
207
|
-
env.add_function(:REPT, lambda { |cxt, val, number_of_times|
|
193
|
+
env.add_function(:REPT, lambda { |cxt, val, number_of_times|
|
208
194
|
val.eval(cxt) * Integer(number_of_times.eval(cxt))
|
209
195
|
})
|
210
196
|
|
@@ -218,7 +204,7 @@ module Kalc
|
|
218
204
|
string2.eval(cxt).downcase[start..-1].index(string1.eval(cxt).downcase) + 1
|
219
205
|
})
|
220
206
|
|
221
|
-
env.add_function(:SUBSTITUTE, lambda { |cxt, val, old_text, new_text|
|
207
|
+
env.add_function(:SUBSTITUTE, lambda { |cxt, val, old_text, new_text|
|
222
208
|
val.eval(cxt).gsub(old_text.eval(cxt), new_text.eval(cxt))
|
223
209
|
})
|
224
210
|
|
@@ -226,7 +212,7 @@ module Kalc
|
|
226
212
|
val.eval(cxt).strip
|
227
213
|
})
|
228
214
|
|
229
|
-
env.add_function(:UPPER, lambda { |cxt, val|
|
215
|
+
env.add_function(:UPPER, lambda { |cxt, val|
|
230
216
|
val.eval(cxt).upcase
|
231
217
|
})
|
232
218
|
|
@@ -235,28 +221,28 @@ module Kalc
|
|
235
221
|
})
|
236
222
|
|
237
223
|
# Regular expressions
|
238
|
-
|
224
|
+
|
239
225
|
env.add_function(:REGEXP_MATCH, lambda { |cxt, val, regex|
|
240
226
|
r = regex.eval(cxt)
|
241
227
|
/#{r}/.match(val.eval(cxt))
|
242
228
|
})
|
243
|
-
|
229
|
+
|
244
230
|
env.add_function(:REGEXP_REPLACE, lambda { |cxt, val, regex, to_replace|
|
245
231
|
r = regex.eval(cxt)
|
246
232
|
|
247
233
|
val.eval(cxt).gsub(/#{r}/, to_replace.eval(cxt))
|
248
234
|
})
|
249
|
-
|
235
|
+
|
250
236
|
# Debug
|
251
|
-
env.add_function(:P, lambda { |cxt, *output|
|
237
|
+
env.add_function(:P, lambda { |cxt, *output|
|
252
238
|
p output
|
253
239
|
})
|
254
240
|
|
255
|
-
env.add_function(:PP, lambda { |cxt, *output|
|
241
|
+
env.add_function(:PP, lambda { |cxt, *output|
|
256
242
|
pp output
|
257
243
|
})
|
258
244
|
|
259
|
-
env.add_function(:PUTS, lambda { |cxt, output|
|
245
|
+
env.add_function(:PUTS, lambda { |cxt, output|
|
260
246
|
puts output.eval(cxt)
|
261
247
|
})
|
262
248
|
|
data/lib/kalc/repl.rb
CHANGED
@@ -17,35 +17,31 @@ module Kalc
|
|
17
17
|
# Load Kalc with debug
|
18
18
|
load_env
|
19
19
|
|
20
|
-
puts
|
21
|
-
puts
|
20
|
+
puts 'You are ready to go. Have fun!'
|
21
|
+
puts ''
|
22
22
|
|
23
|
-
|
24
|
-
|
25
|
-
function_list = [
|
26
|
-
'quit', 'exit', 'functions', 'variables', 'ast'
|
27
|
-
] + @kalc.interpreter.env.functions.map { |f| f.first }
|
23
|
+
function_list = %w(quit exit functions variables ast) + @kalc.interpreter.env.functions.map { |f| f.first }
|
28
24
|
|
29
25
|
begin
|
30
|
-
comp = proc { |s| function_list.grep(
|
31
|
-
Readline.completion_append_character =
|
26
|
+
comp = proc { |s| function_list.grep(/^#{Regexp.escape(s)}/) }
|
27
|
+
Readline.completion_append_character = ''
|
32
28
|
Readline.completion_proc = comp
|
33
29
|
|
34
30
|
while input = Readline.readline("kalc-#{Kalc::VERSION} > ", true)
|
35
31
|
begin
|
36
32
|
case
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
33
|
+
when (input == 'quit' || input == 'exit')
|
34
|
+
break
|
35
|
+
when input == 'functions'
|
36
|
+
puts @kalc.interpreter.env.functions.map { |f| f.first }.join(', ')
|
37
|
+
when input == 'variables'
|
38
|
+
puts @kalc.interpreter.env.variables.map { |v| "#{v[0]} = #{v[1]}" }.join("\n\r")
|
39
|
+
when input == 'reload'
|
40
|
+
load_env
|
41
|
+
when input == 'ast'
|
42
|
+
pp @kalc.ast
|
43
|
+
when input != ''
|
44
|
+
puts @kalc.run(input)
|
49
45
|
end
|
50
46
|
rescue Parslet::ParseFailed => e
|
51
47
|
puts e, g.root.error_tree
|
data/lib/kalc/transform.rb
CHANGED
@@ -1,24 +1,24 @@
|
|
1
1
|
module Kalc
|
2
2
|
class Transform < Parslet::Transform
|
3
3
|
|
4
|
-
rule(:condition => subtree(:condition)) {
|
5
|
-
condition
|
4
|
+
rule(:condition => subtree(:condition)) {
|
5
|
+
condition
|
6
6
|
}
|
7
7
|
|
8
|
-
rule(:left => subtree(:left), :ops => []) {
|
9
|
-
left
|
8
|
+
rule(:left => subtree(:left), :ops => []) {
|
9
|
+
left
|
10
10
|
}
|
11
11
|
|
12
|
-
rule(:right => subtree(:right), :ops => []) {
|
13
|
-
right
|
12
|
+
rule(:right => subtree(:right), :ops => []) {
|
13
|
+
right
|
14
14
|
}
|
15
15
|
|
16
|
-
rule(:left => subtree(:left), :non_ops => []) {
|
17
|
-
left
|
16
|
+
rule(:left => subtree(:left), :non_ops => []) {
|
17
|
+
left
|
18
18
|
}
|
19
19
|
|
20
|
-
rule(:right => subtree(:right), :non_ops => []) {
|
21
|
-
right
|
20
|
+
rule(:right => subtree(:right), :non_ops => []) {
|
21
|
+
right
|
22
22
|
}
|
23
23
|
|
24
24
|
rule(:commands => sequence(:commands)) {
|
@@ -53,8 +53,8 @@ module Kalc
|
|
53
53
|
Ast::BooleanValue.new(boolean)
|
54
54
|
}
|
55
55
|
|
56
|
-
rule(:number => simple(:number)) {
|
57
|
-
Ast::FloatingPointNumber.new(number)
|
56
|
+
rule(:number => simple(:number)) {
|
57
|
+
Ast::FloatingPointNumber.new(number)
|
58
58
|
}
|
59
59
|
|
60
60
|
rule(:non_ops => subtree(:non_ops)) {
|
@@ -65,11 +65,11 @@ module Kalc
|
|
65
65
|
Ast::Ops.new(left, ops)
|
66
66
|
}
|
67
67
|
|
68
|
-
rule(:left => simple(:left), :right => simple(:right), :operator => simple(:operator)) {
|
68
|
+
rule(:left => simple(:left), :right => simple(:right), :operator => simple(:operator)) {
|
69
69
|
Ast::Arithmetic.new(left, right, operator)
|
70
70
|
}
|
71
71
|
|
72
|
-
rule(:condition => simple(:condition), :true_cond => simple(:true_cond), :false_cond => simple(:false_cond)) {
|
72
|
+
rule(:condition => simple(:condition), :true_cond => simple(:true_cond), :false_cond => simple(:false_cond)) {
|
73
73
|
Ast::Conditional.new(condition, true_cond, false_cond)
|
74
74
|
}
|
75
75
|
|
@@ -89,7 +89,7 @@ module Kalc
|
|
89
89
|
paren_list
|
90
90
|
}
|
91
91
|
|
92
|
-
rule(:paren_list =>
|
92
|
+
rule(:paren_list => '()') {
|
93
93
|
[]
|
94
94
|
}
|
95
95
|
|
@@ -98,7 +98,7 @@ module Kalc
|
|
98
98
|
}
|
99
99
|
|
100
100
|
rule(:function_call => {:name => simple(:name),
|
101
|
-
|
101
|
+
:variable_list => sequence(:variable_list)}) {
|
102
102
|
Ast::FunctionCall.new(name, variable_list)
|
103
103
|
}
|
104
104
|
|
@@ -107,8 +107,8 @@ module Kalc
|
|
107
107
|
}
|
108
108
|
|
109
109
|
rule(:function_definition => {:name => simple(:name),
|
110
|
-
|
111
|
-
|
110
|
+
:argument_list => sequence(:argument_list),
|
111
|
+
:body => simple(:body)}) {
|
112
112
|
Ast::FunctionDefinition.new(name, argument_list, body)
|
113
113
|
}
|
114
114
|
end
|
data/lib/kalc/version.rb
CHANGED
data/spec/grammar_spec.rb
CHANGED
@@ -3,13 +3,13 @@ require 'spec_helper'
|
|
3
3
|
describe Kalc::Grammar do
|
4
4
|
let(:grammar) { Kalc::Grammar.new }
|
5
5
|
|
6
|
-
context
|
6
|
+
context 'integers' do
|
7
7
|
1.upto(10) do |i|
|
8
8
|
it { grammar.should parse("#{i}") }
|
9
9
|
end
|
10
10
|
end
|
11
11
|
|
12
|
-
context
|
12
|
+
context 'floats' do
|
13
13
|
1.upto(10) do |i|
|
14
14
|
1.upto(10) do |n|
|
15
15
|
it { grammar.should parse("#{i}.#{n}") }
|
@@ -17,7 +17,7 @@ describe Kalc::Grammar do
|
|
17
17
|
end
|
18
18
|
end
|
19
19
|
|
20
|
-
context
|
20
|
+
context 'basic integer math' do
|
21
21
|
1.upto(10) do |i|
|
22
22
|
it { grammar.should parse("#{i} - #{i}") }
|
23
23
|
it { grammar.should parse("#{i} + #{i}") }
|
@@ -27,7 +27,7 @@ describe Kalc::Grammar do
|
|
27
27
|
end
|
28
28
|
end
|
29
29
|
|
30
|
-
context
|
30
|
+
context 'basic float math' do
|
31
31
|
1.upto(10) do |i|
|
32
32
|
1.upto(10) do |n|
|
33
33
|
it { grammar.should parse("#{i}.#{n} - #{i}.#{n}") }
|
@@ -39,71 +39,71 @@ describe Kalc::Grammar do
|
|
39
39
|
end
|
40
40
|
end
|
41
41
|
|
42
|
-
context
|
43
|
-
it { grammar.should parse(
|
44
|
-
it { grammar.should_not parse(
|
42
|
+
context 'Logical expressions' do
|
43
|
+
it { grammar.should parse('3 && 1') }
|
44
|
+
it { grammar.should_not parse('&& 1') }
|
45
45
|
|
46
|
-
it { grammar.should parse(
|
47
|
-
it { grammar.should_not parse(
|
46
|
+
it { grammar.should parse('3 || 1') }
|
47
|
+
it { grammar.should_not parse('|| 1') }
|
48
48
|
end
|
49
49
|
|
50
|
-
context
|
51
|
-
it { grammar.should parse(
|
52
|
-
it { grammar.should parse(
|
53
|
-
it { grammar.should parse(
|
54
|
-
it { grammar.should parse(
|
50
|
+
context 'Comparison expressions' do
|
51
|
+
it { grammar.should parse('3 > 1') }
|
52
|
+
it { grammar.should parse('3 < 1') }
|
53
|
+
it { grammar.should parse('3 >= 1') }
|
54
|
+
it { grammar.should parse('3 <= 1') }
|
55
55
|
|
56
|
-
it { grammar.should_not parse(
|
57
|
-
it { grammar.should_not parse(
|
58
|
-
it { grammar.should_not parse(
|
59
|
-
it { grammar.should_not parse(
|
56
|
+
it { grammar.should_not parse('> 1') }
|
57
|
+
it { grammar.should_not parse('< 1') }
|
58
|
+
it { grammar.should_not parse('>= 1') }
|
59
|
+
it { grammar.should_not parse('<= 1') }
|
60
60
|
end
|
61
61
|
|
62
|
-
context
|
63
|
-
it { grammar.should parse(
|
64
|
-
it { grammar.should parse(
|
62
|
+
context 'Equality' do
|
63
|
+
it { grammar.should parse('3 == 1') }
|
64
|
+
it { grammar.should parse('2 != 1') }
|
65
65
|
end
|
66
66
|
|
67
|
-
context
|
68
|
-
it { grammar.should parse(
|
69
|
-
it { grammar.should parse(
|
70
|
-
it { grammar.should parse(
|
71
|
-
it { grammar.should parse(
|
72
|
-
it { grammar.should parse(
|
73
|
-
it { grammar.should parse(
|
74
|
-
it { grammar.should parse(
|
67
|
+
context 'Block' do
|
68
|
+
it { grammar.should parse('(2 + 1)') }
|
69
|
+
it { grammar.should parse('(2 + 1) + 1') }
|
70
|
+
it { grammar.should parse('(2 + 1) * (1 / 2) + 3') }
|
71
|
+
it { grammar.should parse('(2 + 1) + (1 + 2) + ((3 + 2) / (2 + 1)) * 9') }
|
72
|
+
it { grammar.should parse('(2 + 1) - (1)') }
|
73
|
+
it { grammar.should parse('(2 ) + ( 1)') }
|
74
|
+
it { grammar.should parse('((2) + ( 1 ))') }
|
75
75
|
end
|
76
76
|
|
77
|
-
context
|
78
|
-
it { grammar.should parse(
|
79
|
-
it { grammar.should parse(
|
80
|
-
it { grammar.should parse(
|
81
|
-
it { grammar.should parse(
|
82
|
-
it { grammar.should parse(
|
77
|
+
context 'Ternary expressions' do
|
78
|
+
it { grammar.should parse('3 > 2 ? 1 : 5') }
|
79
|
+
it { grammar.should parse('3 > 2 || 4 <= 5 ? 1 : 5') }
|
80
|
+
it { grammar.should parse('(3 > (2 + 4)) ? 1 : 5') }
|
81
|
+
it { grammar.should parse('IF(2 > 3, 3 > 2 ? 1 : 5, 7)') }
|
82
|
+
it { grammar.should parse('3 > 2 ? 1 : 5 > 4 ? 7 : 5') }
|
83
83
|
end
|
84
84
|
|
85
|
-
context
|
86
|
-
it { grammar.should parse(
|
87
|
-
it { grammar.should parse(
|
88
|
-
it { grammar.should parse(
|
85
|
+
context 'AND statements' do
|
86
|
+
it { grammar.should parse('AND(1, 2, 3)') }
|
87
|
+
it { grammar.should parse('AND(1, 2, 3, 4, 5, 6)') }
|
88
|
+
it { grammar.should parse('AND(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)') }
|
89
89
|
end
|
90
90
|
|
91
|
-
context
|
92
|
-
it { grammar.should parse(
|
93
|
-
it { grammar.should parse(
|
94
|
-
it { grammar.should parse(
|
91
|
+
context 'OR statements' do
|
92
|
+
it { grammar.should parse('OR(1, 2, 3)') }
|
93
|
+
it { grammar.should parse('OR(1, 2, 3, 4, 5, 6)') }
|
94
|
+
it { grammar.should parse('OR(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)') }
|
95
95
|
end
|
96
96
|
|
97
|
-
context
|
98
|
-
it { grammar.should parse(
|
99
|
-
it { grammar.should parse(
|
100
|
-
it { grammar.should parse(
|
101
|
-
it { grammar.should parse(
|
97
|
+
context 'IF statements' do
|
98
|
+
it { grammar.should parse('IF(3, 2, 1)') }
|
99
|
+
it { grammar.should parse('IF(3 > 1, 2, 1)') }
|
100
|
+
it { grammar.should parse('IF((3 > 1) || (2 < 1), 2, 1)') }
|
101
|
+
it { grammar.should parse('IF(OR(1 > 3, 2 < 5), 3, 2)') }
|
102
102
|
end
|
103
103
|
|
104
|
-
context
|
105
|
-
it { grammar.should parse(
|
106
|
-
it { grammar.should parse(
|
104
|
+
context 'Nested IF statements' do
|
105
|
+
it { grammar.should parse('IF(3 > 2, IF(2 < 3, 1, 3), 5)') }
|
106
|
+
it { grammar.should parse('IF(3 > 2, IF(2 < 3, 1, 3), IF(5 > 1, 3, 9))') }
|
107
107
|
end
|
108
108
|
|
109
109
|
end
|