simply_stored 0.3.9 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.md +38 -0
- data/README.md +45 -24
- data/lib/simply_stored/couch/association_property.rb +27 -0
- data/lib/simply_stored/couch/belongs_to.rb +5 -7
- data/lib/simply_stored/couch/finders.rb +5 -1
- data/lib/simply_stored/couch/has_and_belongs_to_many.rb +202 -0
- data/lib/simply_stored/couch/has_many.rb +6 -51
- data/lib/simply_stored/couch/has_one.rb +4 -29
- data/lib/simply_stored/couch/properties.rb +11 -0
- data/lib/simply_stored/couch.rb +38 -2
- data/lib/simply_stored/instance_methods.rb +68 -29
- data/lib/simply_stored.rb +3 -1
- data/test/{couchdb/couch_active_model_compatibility_test.rb → active_model_compatibility_test.rb} +2 -2
- data/test/{couchdb/couch_belongs_to_test.rb → belongs_to_test.rb} +13 -3
- data/test/{couchdb/couch_conflict_handling_test.rb → conflict_handling_test.rb} +3 -3
- data/test/{couchdb/couch_finder_test.rb → finder_test.rb} +8 -3
- data/test/fixtures/couch.rb +55 -0
- data/test/has_and_belongs_to_many_test.rb +639 -0
- data/test/{couchdb/couch_has_many_test.rb → has_many_test.rb} +13 -3
- data/test/{couchdb/couch_has_one_test.rb → has_one_test.rb} +13 -3
- data/test/{couchdb/couch_instance_lifecycle_test.rb → instance_lifecycle_test.rb} +3 -3
- data/test/{couchdb/couch_mass_assignment_protection_test.rb → mass_assignment_protection_test.rb} +3 -3
- data/test/{couchdb/couch_s3_test.rb → s3_test.rb} +3 -3
- data/test/{couchdb/couch_soft_deletable_test.rb → soft_deletable_test.rb} +3 -3
- data/test/test_helper.rb +1 -5
- data/test/{couchdb/couch_validations_test.rb → validations_test.rb} +3 -3
- data/test/{couchdb/custom_views_test.rb → views_test.rb} +3 -3
- metadata +36 -234
- data/lib/simply_stored/simpledb/associations.rb +0 -215
- data/lib/simply_stored/simpledb/attributes.rb +0 -173
- data/lib/simply_stored/simpledb/storag.rb +0 -85
- data/lib/simply_stored/simpledb/validations.rb +0 -88
- data/lib/simply_stored/simpledb.rb +0 -216
- data/test/fixtures/simpledb/item.rb +0 -11
- data/test/fixtures/simpledb/item_daddy.rb +0 -8
- data/test/fixtures/simpledb/log_item.rb +0 -3
- data/test/fixtures/simpledb/namespace_bar.rb +0 -5
- data/test/fixtures/simpledb/namespace_foo.rb +0 -7
- data/test/fixtures/simpledb/protected_item.rb +0 -3
- data/test/simply_stored_simpledb_test.rb +0 -1376
- data/test/vendor/dhaka-2.2.1/lib/dhaka/dot/dot.rb +0 -29
- data/test/vendor/dhaka-2.2.1/lib/dhaka/evaluator/evaluator.rb +0 -133
- data/test/vendor/dhaka-2.2.1/lib/dhaka/grammar/closure_hash.rb +0 -15
- data/test/vendor/dhaka-2.2.1/lib/dhaka/grammar/grammar.rb +0 -240
- data/test/vendor/dhaka-2.2.1/lib/dhaka/grammar/grammar_symbol.rb +0 -27
- data/test/vendor/dhaka-2.2.1/lib/dhaka/grammar/precedence.rb +0 -19
- data/test/vendor/dhaka-2.2.1/lib/dhaka/grammar/production.rb +0 -36
- data/test/vendor/dhaka-2.2.1/lib/dhaka/lexer/accept_actions.rb +0 -36
- data/test/vendor/dhaka-2.2.1/lib/dhaka/lexer/alphabet.rb +0 -21
- data/test/vendor/dhaka-2.2.1/lib/dhaka/lexer/compiled_lexer.rb +0 -46
- data/test/vendor/dhaka-2.2.1/lib/dhaka/lexer/dfa.rb +0 -121
- data/test/vendor/dhaka-2.2.1/lib/dhaka/lexer/lexeme.rb +0 -32
- data/test/vendor/dhaka-2.2.1/lib/dhaka/lexer/lexer.rb +0 -70
- data/test/vendor/dhaka-2.2.1/lib/dhaka/lexer/lexer_run.rb +0 -78
- data/test/vendor/dhaka-2.2.1/lib/dhaka/lexer/regex_grammar.rb +0 -392
- data/test/vendor/dhaka-2.2.1/lib/dhaka/lexer/regex_parser.rb +0 -2010
- data/test/vendor/dhaka-2.2.1/lib/dhaka/lexer/regex_tokenizer.rb +0 -14
- data/test/vendor/dhaka-2.2.1/lib/dhaka/lexer/specification.rb +0 -96
- data/test/vendor/dhaka-2.2.1/lib/dhaka/lexer/state.rb +0 -68
- data/test/vendor/dhaka-2.2.1/lib/dhaka/lexer/state_machine.rb +0 -37
- data/test/vendor/dhaka-2.2.1/lib/dhaka/parser/action.rb +0 -55
- data/test/vendor/dhaka-2.2.1/lib/dhaka/parser/channel.rb +0 -58
- data/test/vendor/dhaka-2.2.1/lib/dhaka/parser/compiled_parser.rb +0 -51
- data/test/vendor/dhaka-2.2.1/lib/dhaka/parser/conflict.rb +0 -54
- data/test/vendor/dhaka-2.2.1/lib/dhaka/parser/item.rb +0 -42
- data/test/vendor/dhaka-2.2.1/lib/dhaka/parser/parse_result.rb +0 -50
- data/test/vendor/dhaka-2.2.1/lib/dhaka/parser/parse_tree.rb +0 -66
- data/test/vendor/dhaka-2.2.1/lib/dhaka/parser/parser.rb +0 -165
- data/test/vendor/dhaka-2.2.1/lib/dhaka/parser/parser_methods.rb +0 -11
- data/test/vendor/dhaka-2.2.1/lib/dhaka/parser/parser_run.rb +0 -39
- data/test/vendor/dhaka-2.2.1/lib/dhaka/parser/parser_state.rb +0 -74
- data/test/vendor/dhaka-2.2.1/lib/dhaka/parser/token.rb +0 -22
- data/test/vendor/dhaka-2.2.1/lib/dhaka/runtime.rb +0 -51
- data/test/vendor/dhaka-2.2.1/lib/dhaka/tokenizer/tokenizer.rb +0 -190
- data/test/vendor/dhaka-2.2.1/lib/dhaka.rb +0 -62
- data/test/vendor/dhaka-2.2.1/test/all_tests.rb +0 -5
- data/test/vendor/dhaka-2.2.1/test/arithmetic/arithmetic_evaluator.rb +0 -64
- data/test/vendor/dhaka-2.2.1/test/arithmetic/arithmetic_evaluator_test.rb +0 -43
- data/test/vendor/dhaka-2.2.1/test/arithmetic/arithmetic_grammar.rb +0 -41
- data/test/vendor/dhaka-2.2.1/test/arithmetic/arithmetic_grammar_test.rb +0 -9
- data/test/vendor/dhaka-2.2.1/test/arithmetic/arithmetic_test_methods.rb +0 -9
- data/test/vendor/dhaka-2.2.1/test/arithmetic/arithmetic_tokenizer.rb +0 -39
- data/test/vendor/dhaka-2.2.1/test/arithmetic/arithmetic_tokenizer_test.rb +0 -38
- data/test/vendor/dhaka-2.2.1/test/arithmetic_precedence/arithmetic_precedence_evaluator.rb +0 -43
- data/test/vendor/dhaka-2.2.1/test/arithmetic_precedence/arithmetic_precedence_grammar.rb +0 -24
- data/test/vendor/dhaka-2.2.1/test/arithmetic_precedence/arithmetic_precedence_grammar_test.rb +0 -30
- data/test/vendor/dhaka-2.2.1/test/arithmetic_precedence/arithmetic_precedence_lexer_specification.rb +0 -23
- data/test/vendor/dhaka-2.2.1/test/arithmetic_precedence/arithmetic_precedence_parser_test.rb +0 -33
- data/test/vendor/dhaka-2.2.1/test/brackets/bracket_grammar.rb +0 -23
- data/test/vendor/dhaka-2.2.1/test/brackets/bracket_tokenizer.rb +0 -22
- data/test/vendor/dhaka-2.2.1/test/brackets/brackets_test.rb +0 -28
- data/test/vendor/dhaka-2.2.1/test/chittagong/chittagong_driver.rb +0 -46
- data/test/vendor/dhaka-2.2.1/test/chittagong/chittagong_driver_test.rb +0 -276
- data/test/vendor/dhaka-2.2.1/test/chittagong/chittagong_evaluator.rb +0 -284
- data/test/vendor/dhaka-2.2.1/test/chittagong/chittagong_evaluator_test.rb +0 -38
- data/test/vendor/dhaka-2.2.1/test/chittagong/chittagong_grammar.rb +0 -104
- data/test/vendor/dhaka-2.2.1/test/chittagong/chittagong_lexer.rb +0 -109
- data/test/vendor/dhaka-2.2.1/test/chittagong/chittagong_lexer_specification.rb +0 -37
- data/test/vendor/dhaka-2.2.1/test/chittagong/chittagong_lexer_test.rb +0 -58
- data/test/vendor/dhaka-2.2.1/test/chittagong/chittagong_parser.rb +0 -879
- data/test/vendor/dhaka-2.2.1/test/chittagong/chittagong_parser_test.rb +0 -55
- data/test/vendor/dhaka-2.2.1/test/chittagong/chittagong_test.rb +0 -170
- data/test/vendor/dhaka-2.2.1/test/core/another_lalr_but_not_slr_grammar.rb +0 -20
- data/test/vendor/dhaka-2.2.1/test/core/compiled_parser_test.rb +0 -44
- data/test/vendor/dhaka-2.2.1/test/core/dfa_test.rb +0 -170
- data/test/vendor/dhaka-2.2.1/test/core/evaluator_test.rb +0 -22
- data/test/vendor/dhaka-2.2.1/test/core/grammar_test.rb +0 -83
- data/test/vendor/dhaka-2.2.1/test/core/lalr_but_not_slr_grammar.rb +0 -19
- data/test/vendor/dhaka-2.2.1/test/core/lexer_test.rb +0 -139
- data/test/vendor/dhaka-2.2.1/test/core/malformed_grammar.rb +0 -7
- data/test/vendor/dhaka-2.2.1/test/core/malformed_grammar_test.rb +0 -8
- data/test/vendor/dhaka-2.2.1/test/core/nullable_grammar.rb +0 -21
- data/test/vendor/dhaka-2.2.1/test/core/parse_result_test.rb +0 -44
- data/test/vendor/dhaka-2.2.1/test/core/parser_state_test.rb +0 -24
- data/test/vendor/dhaka-2.2.1/test/core/parser_test.rb +0 -131
- data/test/vendor/dhaka-2.2.1/test/core/precedence_grammar.rb +0 -17
- data/test/vendor/dhaka-2.2.1/test/core/precedence_grammar_test.rb +0 -9
- data/test/vendor/dhaka-2.2.1/test/core/rr_conflict_grammar.rb +0 -21
- data/test/vendor/dhaka-2.2.1/test/core/simple_grammar.rb +0 -22
- data/test/vendor/dhaka-2.2.1/test/core/sr_conflict_grammar.rb +0 -16
- data/test/vendor/dhaka-2.2.1/test/dhaka_test_helper.rb +0 -17
- data/test/vendor/dhaka-2.2.1/test/fake_logger.rb +0 -17
- data/test/vendor/simplerdb-0.2/lib/simplerdb/client_exception.rb +0 -10
- data/test/vendor/simplerdb-0.2/lib/simplerdb/db.rb +0 -146
- data/test/vendor/simplerdb-0.2/lib/simplerdb/query_language.rb +0 -266
- data/test/vendor/simplerdb-0.2/lib/simplerdb/server.rb +0 -33
- data/test/vendor/simplerdb-0.2/lib/simplerdb/servlet.rb +0 -191
- data/test/vendor/simplerdb-0.2/lib/simplerdb.rb +0 -3
- data/test/vendor/simplerdb-0.2/test/functional_test.rb +0 -81
- data/test/vendor/simplerdb-0.2/test/query_evaluator_test.rb +0 -73
- data/test/vendor/simplerdb-0.2/test/query_parser_test.rb +0 -64
- data/test/vendor/simplerdb-0.2/test/simplerdb_test.rb +0 -80
@@ -1,276 +0,0 @@
|
|
1
|
-
require File.dirname(__FILE__) + '/../dhaka_test_helper'
|
2
|
-
require File.dirname(__FILE__) + "/chittagong_grammar"
|
3
|
-
require File.dirname(__FILE__) + "/chittagong_lexer_specification"
|
4
|
-
begin
|
5
|
-
require File.dirname(__FILE__) + "/chittagong_parser"
|
6
|
-
require File.dirname(__FILE__) + "/chittagong_lexer"
|
7
|
-
rescue LoadError
|
8
|
-
puts "Please run the rake command in the root folder to generate the lexer and parser required for this test."
|
9
|
-
exit
|
10
|
-
end
|
11
|
-
require File.dirname(__FILE__) + "/chittagong_driver"
|
12
|
-
|
13
|
-
class TestChittagongDriver < Test::Unit::TestCase
|
14
|
-
def setup
|
15
|
-
@driver = ChittagongDriver.new
|
16
|
-
end
|
17
|
-
|
18
|
-
def test_return_statement_not_allowed_in_main
|
19
|
-
# Programs with problems
|
20
|
-
program = "
|
21
|
-
|
22
|
-
if 1 > 2
|
23
|
-
return 5
|
24
|
-
end
|
25
|
-
|
26
|
-
print 2
|
27
|
-
"
|
28
|
-
assert_equal(
|
29
|
-
"Unexpected token return:
|
30
|
-
|
31
|
-
|
32
|
-
if 1 > 2
|
33
|
-
>>>return 5
|
34
|
-
end
|
35
|
-
|
36
|
-
print 2
|
37
|
-
", @driver.run(program))
|
38
|
-
end
|
39
|
-
|
40
|
-
def test_catches_unexpected_end_of_input
|
41
|
-
program = "
|
42
|
-
def"
|
43
|
-
assert_equal("Unexpected end of file.", @driver.run(program))
|
44
|
-
end
|
45
|
-
|
46
|
-
def test_catches_unexpected_characters
|
47
|
-
program = "
|
48
|
-
print 2
|
49
|
-
def #}
|
50
|
-
"
|
51
|
-
assert_equal(
|
52
|
-
"Unexpected character #:
|
53
|
-
|
54
|
-
print 2
|
55
|
-
def >>>#}
|
56
|
-
", @driver.run(program))
|
57
|
-
end
|
58
|
-
|
59
|
-
def test_catches_undefined_variables
|
60
|
-
program = "
|
61
|
-
x = 1
|
62
|
-
y = 2
|
63
|
-
def foo(n)
|
64
|
-
return 2
|
65
|
-
end
|
66
|
-
foo(1)
|
67
|
-
|
68
|
-
if x > y
|
69
|
-
print 999
|
70
|
-
print 777
|
71
|
-
else
|
72
|
-
print 66
|
73
|
-
end
|
74
|
-
|
75
|
-
print x
|
76
|
-
print y
|
77
|
-
print 2*3+c
|
78
|
-
print 888
|
79
|
-
|
80
|
-
"
|
81
|
-
|
82
|
-
assert_equal(
|
83
|
-
"66.0
|
84
|
-
1.0
|
85
|
-
2.0
|
86
|
-
Undefined variable c:
|
87
|
-
|
88
|
-
x = 1
|
89
|
-
y = 2
|
90
|
-
def foo(n)
|
91
|
-
return 2
|
92
|
-
end
|
93
|
-
foo(1)
|
94
|
-
|
95
|
-
if x > y
|
96
|
-
print 999
|
97
|
-
print 777
|
98
|
-
else
|
99
|
-
print 66
|
100
|
-
end
|
101
|
-
|
102
|
-
print x
|
103
|
-
print y
|
104
|
-
print 2*3+>>>c
|
105
|
-
print 888
|
106
|
-
|
107
|
-
", @driver.run(program))
|
108
|
-
end
|
109
|
-
|
110
|
-
def test_catches_undefined_functions
|
111
|
-
program = "
|
112
|
-
|
113
|
-
def foo(n)
|
114
|
-
bar(x)
|
115
|
-
end
|
116
|
-
|
117
|
-
foo(2)
|
118
|
-
|
119
|
-
"
|
120
|
-
assert_equal(
|
121
|
-
"Undefined function bar:
|
122
|
-
|
123
|
-
|
124
|
-
def foo(n)
|
125
|
-
>>>bar(x)
|
126
|
-
end
|
127
|
-
|
128
|
-
foo(2)
|
129
|
-
|
130
|
-
", @driver.run(program))
|
131
|
-
end
|
132
|
-
# lipi:variable_scoping
|
133
|
-
def test_variable_scope
|
134
|
-
program = "
|
135
|
-
x = 1
|
136
|
-
|
137
|
-
def bar(n)
|
138
|
-
print 999
|
139
|
-
end
|
140
|
-
|
141
|
-
def foo(n)
|
142
|
-
bar(x)
|
143
|
-
end
|
144
|
-
|
145
|
-
foo(2)
|
146
|
-
|
147
|
-
"
|
148
|
-
assert_equal(
|
149
|
-
"Undefined variable x:
|
150
|
-
|
151
|
-
x = 1
|
152
|
-
|
153
|
-
def bar(n)
|
154
|
-
print 999
|
155
|
-
end
|
156
|
-
|
157
|
-
def foo(n)
|
158
|
-
bar(>>>x)
|
159
|
-
end
|
160
|
-
|
161
|
-
foo(2)
|
162
|
-
|
163
|
-
", @driver.run(program))
|
164
|
-
end
|
165
|
-
# lipi:variable_scoping
|
166
|
-
|
167
|
-
def test_nested_function_calls
|
168
|
-
|
169
|
-
program = "
|
170
|
-
|
171
|
-
def foo(a)
|
172
|
-
return a + 2
|
173
|
-
end
|
174
|
-
|
175
|
-
def bar(b, c)
|
176
|
-
return b + c
|
177
|
-
end
|
178
|
-
|
179
|
-
def baz(x, y, z)
|
180
|
-
return foo(y) + bar(x, z)
|
181
|
-
end
|
182
|
-
|
183
|
-
print baz(foo(1), bar(2, 3), bar(6, 2))
|
184
|
-
|
185
|
-
"
|
186
|
-
assert_equal("18.0", @driver.run(program))
|
187
|
-
end
|
188
|
-
|
189
|
-
def test_wrong_number_of_arguments
|
190
|
-
|
191
|
-
program = "
|
192
|
-
|
193
|
-
def whatever(a, b)
|
194
|
-
return a + b
|
195
|
-
end
|
196
|
-
|
197
|
-
whatever(1, 2, 3)
|
198
|
-
|
199
|
-
"
|
200
|
-
assert_equal(
|
201
|
-
"Wrong number of arguments:
|
202
|
-
|
203
|
-
|
204
|
-
def whatever(a, b)
|
205
|
-
return a + b
|
206
|
-
end
|
207
|
-
|
208
|
-
whatever>>>(1, 2, 3)
|
209
|
-
|
210
|
-
", @driver.run(program))
|
211
|
-
|
212
|
-
end
|
213
|
-
|
214
|
-
def test_an_empty_program
|
215
|
-
program = ""
|
216
|
-
assert_equal("Unexpected end of file.", @driver.run(program))
|
217
|
-
end
|
218
|
-
|
219
|
-
def test_associating_equality_tests_should_show_an_error
|
220
|
-
program = "
|
221
|
-
def foo()
|
222
|
-
print 999
|
223
|
-
end
|
224
|
-
|
225
|
-
foo()
|
226
|
-
print 1 == 1 == 1"
|
227
|
-
|
228
|
-
assert_equal("Unexpected token ==:
|
229
|
-
|
230
|
-
def foo()
|
231
|
-
print 999
|
232
|
-
end
|
233
|
-
|
234
|
-
foo()
|
235
|
-
print 1 == 1 >>>== 1", @driver.run(program))
|
236
|
-
end
|
237
|
-
|
238
|
-
def test_catches_bad_decimal_points
|
239
|
-
program = "
|
240
|
-
a = .234
|
241
|
-
c = 23.523
|
242
|
-
b = 20..2
|
243
|
-
"
|
244
|
-
|
245
|
-
assert_equal("Unexpected character .:
|
246
|
-
|
247
|
-
a = .234
|
248
|
-
c = 23.523
|
249
|
-
b = 20.>>>.2
|
250
|
-
", @driver.run(program))
|
251
|
-
end
|
252
|
-
# lipi:recursive_fib
|
253
|
-
def test_recursive_fibonacci
|
254
|
-
program = "
|
255
|
-
|
256
|
-
def fib(n)
|
257
|
-
if n == 0
|
258
|
-
return 1
|
259
|
-
end
|
260
|
-
if n == 1
|
261
|
-
return 1
|
262
|
-
end
|
263
|
-
return fib(n-1) + fib(n-2)
|
264
|
-
end
|
265
|
-
|
266
|
-
x = 0
|
267
|
-
while x < 9
|
268
|
-
print fib(x)
|
269
|
-
x = x + 1
|
270
|
-
end
|
271
|
-
|
272
|
-
"
|
273
|
-
assert_equal(["1.0", "1.0", "2.0", "3.0", "5.0", "8.0", "13.0", "21.0", "34.0"].join("\n"), @driver.run(program))
|
274
|
-
end
|
275
|
-
# lipi:recursive_fib
|
276
|
-
end
|
@@ -1,284 +0,0 @@
|
|
1
|
-
require File.dirname(__FILE__) + '/chittagong_grammar'
|
2
|
-
|
3
|
-
class ChittagongEvaluator < Dhaka::Evaluator
|
4
|
-
|
5
|
-
self.grammar = ChittagongGrammar
|
6
|
-
|
7
|
-
define_evaluation_rules do
|
8
|
-
|
9
|
-
# No-ops
|
10
|
-
['no_terms', 'multiple_terms', 'single_term', 'some_terms'].each {|production_name| eval("for_#{production_name} do end")}
|
11
|
-
|
12
|
-
for_program do
|
13
|
-
evaluate(child_nodes[1])
|
14
|
-
end
|
15
|
-
|
16
|
-
for_multiple_main_body_statements do
|
17
|
-
first = evaluate(child_nodes[0])
|
18
|
-
return first if first.exception
|
19
|
-
evaluate(child_nodes[2])
|
20
|
-
end
|
21
|
-
|
22
|
-
for_multiple_function_body_statements do
|
23
|
-
first = evaluate(child_nodes[0])
|
24
|
-
return first if (first.exception || first.result)
|
25
|
-
evaluate(child_nodes[2])
|
26
|
-
end
|
27
|
-
# lipi:function_defs
|
28
|
-
for_function_definition do
|
29
|
-
function_name = evaluate(child_nodes[1])
|
30
|
-
arg_declarations = evaluate(child_nodes[3])
|
31
|
-
body = child_nodes[6]
|
32
|
-
@function_table[function_name] = Function.new(arg_declarations, body)
|
33
|
-
ChittagongSuccessResult.new(nil)
|
34
|
-
end
|
35
|
-
# lipi:function_defs
|
36
|
-
|
37
|
-
for_main_body_if_statement do
|
38
|
-
checked_if_statement
|
39
|
-
end
|
40
|
-
|
41
|
-
for_function_body_if_statement do
|
42
|
-
checked_if_statement
|
43
|
-
end
|
44
|
-
|
45
|
-
def checked_if_statement
|
46
|
-
condition_eval = evaluate(child_nodes[1])
|
47
|
-
return condition_eval if condition_eval.exception
|
48
|
-
return evaluate(child_nodes[3]) if condition_eval.result
|
49
|
-
ChittagongSuccessResult.new(nil)
|
50
|
-
end
|
51
|
-
|
52
|
-
for_main_body_if_else_statement do
|
53
|
-
checked_if_else_statement
|
54
|
-
end
|
55
|
-
|
56
|
-
for_function_body_if_else_statement do
|
57
|
-
checked_if_else_statement
|
58
|
-
end
|
59
|
-
|
60
|
-
def checked_if_else_statement
|
61
|
-
condition_eval = evaluate(child_nodes[1])
|
62
|
-
return condition_eval if condition_eval.exception
|
63
|
-
if condition_eval.result
|
64
|
-
evaluate(child_nodes[3])
|
65
|
-
else
|
66
|
-
evaluate(child_nodes[7])
|
67
|
-
end
|
68
|
-
end
|
69
|
-
|
70
|
-
for_main_body_while_statement do
|
71
|
-
checked_while_statement
|
72
|
-
end
|
73
|
-
|
74
|
-
for_function_body_while_statement do
|
75
|
-
checked_while_statement
|
76
|
-
end
|
77
|
-
|
78
|
-
def checked_while_statement
|
79
|
-
loop do
|
80
|
-
condition_eval = evaluate(child_nodes[1])
|
81
|
-
return condition_eval if condition_eval.exception
|
82
|
-
break unless condition_eval.result
|
83
|
-
body_eval = evaluate(child_nodes[3])
|
84
|
-
return body_eval if (body_eval.exception || body_eval.result)
|
85
|
-
end
|
86
|
-
ChittagongSuccessResult.new(nil)
|
87
|
-
end
|
88
|
-
|
89
|
-
for_assignment_statement do
|
90
|
-
rhs = evaluate(child_nodes[2])
|
91
|
-
return rhs if rhs.exception
|
92
|
-
@stack[-1][evaluate(child_nodes[0])] = rhs.result
|
93
|
-
ChittagongSuccessResult.new(nil)
|
94
|
-
end
|
95
|
-
|
96
|
-
for_print_statement do
|
97
|
-
rhs = evaluate(child_nodes[1])
|
98
|
-
return rhs if rhs.exception
|
99
|
-
@output_stream << rhs.result.to_s
|
100
|
-
ChittagongSuccessResult.new(nil)
|
101
|
-
end
|
102
|
-
|
103
|
-
for_function_call_statement do
|
104
|
-
checked_function_call
|
105
|
-
end
|
106
|
-
|
107
|
-
for_function_call_expression do
|
108
|
-
checked_function_call
|
109
|
-
end
|
110
|
-
# lipi:checked_function_call
|
111
|
-
def checked_function_call
|
112
|
-
function_name = evaluate(child_nodes[0])
|
113
|
-
return ChittagongExceptionResult.new("Undefined function #{function_name}",
|
114
|
-
child_nodes[0]) unless @function_table.has_key?(function_name)
|
115
|
-
|
116
|
-
arg_values = evaluate(child_nodes[2])
|
117
|
-
return arg_values if arg_values.exception
|
118
|
-
|
119
|
-
function = @function_table[function_name]
|
120
|
-
return ChittagongExceptionResult.new(
|
121
|
-
"Wrong number of arguments", child_nodes[1]
|
122
|
-
) unless function.args.size == arg_values.result.size
|
123
|
-
new_frame = {}
|
124
|
-
|
125
|
-
function.args.zip(arg_values.result).each do |arg_name, arg_value|
|
126
|
-
new_frame[arg_name] = arg_value
|
127
|
-
end
|
128
|
-
|
129
|
-
@stack << new_frame
|
130
|
-
result = evaluate(function.body)
|
131
|
-
@stack.pop
|
132
|
-
|
133
|
-
result
|
134
|
-
end
|
135
|
-
# lipi:checked_function_call
|
136
|
-
|
137
|
-
for_return_statement do
|
138
|
-
checked_unary_operation(child_nodes[1]){|x| x}
|
139
|
-
end
|
140
|
-
|
141
|
-
for_single_arg_declaration do
|
142
|
-
[evaluate(child_nodes[0])]
|
143
|
-
end
|
144
|
-
|
145
|
-
for_no_arg_decl do
|
146
|
-
[]
|
147
|
-
end
|
148
|
-
|
149
|
-
for_multiple_arg_declarations do
|
150
|
-
evaluate(child_nodes[0]) + [evaluate(child_nodes[2])]
|
151
|
-
end
|
152
|
-
|
153
|
-
for_no_args do
|
154
|
-
ChittagongSuccessResult.new([])
|
155
|
-
end
|
156
|
-
|
157
|
-
for_single_arg do
|
158
|
-
checked_unary_operation(child_nodes[0]) {|x| [x]}
|
159
|
-
end
|
160
|
-
|
161
|
-
for_multiple_args do
|
162
|
-
checked_binary_operation(child_nodes[0], child_nodes[2]) {|a, b| a + [b]}
|
163
|
-
end
|
164
|
-
|
165
|
-
for_variable_reference do
|
166
|
-
variable_name = evaluate(child_nodes[0])
|
167
|
-
return ChittagongExceptionResult.new("Undefined variable #{variable_name}", child_nodes[0]) unless @stack[-1].has_key? variable_name
|
168
|
-
ChittagongSuccessResult.new(@stack[-1][variable_name])
|
169
|
-
end
|
170
|
-
|
171
|
-
for_subtraction do
|
172
|
-
checked_binary_operation(child_nodes[0], child_nodes[2]){|a, b| a - b}
|
173
|
-
end
|
174
|
-
|
175
|
-
for_addition do
|
176
|
-
checked_binary_operation(child_nodes[0], child_nodes[2]){|a, b| a + b}
|
177
|
-
end
|
178
|
-
|
179
|
-
for_division do
|
180
|
-
checked_binary_operation(child_nodes[0], child_nodes[2]){|a, b| a.to_f / b}
|
181
|
-
end
|
182
|
-
|
183
|
-
for_multiplication do
|
184
|
-
checked_binary_operation(child_nodes[0], child_nodes[2]){|a, b| a * b}
|
185
|
-
end
|
186
|
-
|
187
|
-
for_power do
|
188
|
-
checked_binary_operation(child_nodes[0], child_nodes[2]){|a, b| a ** b}
|
189
|
-
end
|
190
|
-
|
191
|
-
for_less_than_comparison do
|
192
|
-
checked_binary_operation(child_nodes[0], child_nodes[2]){|a, b| a < b}
|
193
|
-
end
|
194
|
-
|
195
|
-
for_greater_than_comparison do
|
196
|
-
checked_binary_operation(child_nodes[0], child_nodes[2]){|a, b| a > b}
|
197
|
-
end
|
198
|
-
|
199
|
-
for_equality_comparison do
|
200
|
-
checked_binary_operation(child_nodes[0], child_nodes[2]){|a, b| a == b}
|
201
|
-
end
|
202
|
-
|
203
|
-
def checked_binary_operation node1, node2
|
204
|
-
node1_eval = evaluate(node1)
|
205
|
-
node2_eval = evaluate(node2)
|
206
|
-
return node1_eval if node1_eval.exception
|
207
|
-
return node2_eval if node2_eval.exception
|
208
|
-
ChittagongSuccessResult.new(yield(node1_eval.result, node2_eval.result))
|
209
|
-
end
|
210
|
-
|
211
|
-
for_negated_expression do
|
212
|
-
checked_unary_operation(child_nodes[1]){|x| -x}
|
213
|
-
end
|
214
|
-
|
215
|
-
for_negation do
|
216
|
-
checked_unary_operation(child_nodes[1]){|b| !b}
|
217
|
-
end
|
218
|
-
|
219
|
-
for_parenthetized_expression do
|
220
|
-
checked_unary_operation(child_nodes[1]){|x| x}
|
221
|
-
end
|
222
|
-
|
223
|
-
def checked_unary_operation node
|
224
|
-
node_eval = evaluate(node)
|
225
|
-
return node_eval if node_eval.exception
|
226
|
-
ChittagongSuccessResult.new(yield(node_eval.result))
|
227
|
-
end
|
228
|
-
|
229
|
-
for_function_name do
|
230
|
-
token_value
|
231
|
-
end
|
232
|
-
|
233
|
-
for_variable_name do
|
234
|
-
token_value
|
235
|
-
end
|
236
|
-
|
237
|
-
for_arg_declaration do
|
238
|
-
token_value
|
239
|
-
end
|
240
|
-
|
241
|
-
for_literal do
|
242
|
-
ChittagongSuccessResult.new(token_value.to_f)
|
243
|
-
end
|
244
|
-
|
245
|
-
def token_value
|
246
|
-
child_nodes.first.token.value
|
247
|
-
end
|
248
|
-
# lipi:initialize
|
249
|
-
def initialize(stack, output_stream)
|
250
|
-
@stack = stack
|
251
|
-
@function_table = {}
|
252
|
-
@output_stream = output_stream
|
253
|
-
end
|
254
|
-
# lipi:initialize
|
255
|
-
end
|
256
|
-
|
257
|
-
end
|
258
|
-
|
259
|
-
class ChittagongResult
|
260
|
-
attr_reader :exception
|
261
|
-
end
|
262
|
-
|
263
|
-
class ChittagongSuccessResult < ChittagongResult
|
264
|
-
attr_reader :result
|
265
|
-
def initialize(result)
|
266
|
-
@result = result
|
267
|
-
end
|
268
|
-
end
|
269
|
-
|
270
|
-
class ChittagongExceptionResult < ChittagongResult
|
271
|
-
attr_reader :node
|
272
|
-
def initialize(exception, node)
|
273
|
-
@exception = exception
|
274
|
-
@node = node
|
275
|
-
end
|
276
|
-
end
|
277
|
-
|
278
|
-
class Function
|
279
|
-
attr_reader :args, :body
|
280
|
-
def initialize(args, body)
|
281
|
-
@args = args
|
282
|
-
@body = body
|
283
|
-
end
|
284
|
-
end
|
@@ -1,38 +0,0 @@
|
|
1
|
-
require File.dirname(__FILE__) + '/../dhaka_test_helper'
|
2
|
-
require File.dirname(__FILE__) + "/chittagong_evaluator"
|
3
|
-
begin
|
4
|
-
require File.dirname(__FILE__) + "/chittagong_parser"
|
5
|
-
rescue LoadError
|
6
|
-
puts "Please run the rake command in the root folder to generate the lexer and parser required for this test."
|
7
|
-
exit
|
8
|
-
end
|
9
|
-
|
10
|
-
class TestChittagongEvaluator < Test::Unit::TestCase
|
11
|
-
def test_evaluates_a_simple_program
|
12
|
-
token_stream = build_tokens(
|
13
|
-
['newline'],
|
14
|
-
['word_literal', 'x'], ['='], ['numeric_literal', 23], ['newline'],
|
15
|
-
['print'], ['word_literal', 'x'], ['newline'],
|
16
|
-
['newline'],
|
17
|
-
['word_literal', 'y'], ['='], ['word_literal', 'x'], ['+'], ['word_literal', 'x'], ['newline'],
|
18
|
-
['print'], ['word_literal', 'y'], ['*'], ['word_literal', 'x'], ['newline'],
|
19
|
-
['if'], ['word_literal', 'x'], ['>'], ['word_literal', 'y'], ['newline'],
|
20
|
-
['print'], ['word_literal', 'x'], ['newline'],
|
21
|
-
['else'], ['newline'],
|
22
|
-
['print'], ['word_literal', 'y'], ['newline'],
|
23
|
-
['end'], ['newline'],
|
24
|
-
['newline'],
|
25
|
-
[Dhaka::END_SYMBOL_NAME]
|
26
|
-
)
|
27
|
-
stack = [{}]
|
28
|
-
output_stream = []
|
29
|
-
ChittagongEvaluator.new(stack, output_stream).evaluate(ChittagongParser.parse(token_stream))
|
30
|
-
assert_equal(23, stack[0]['x'])
|
31
|
-
assert_equal(46, stack[0]['y'])
|
32
|
-
assert_equal(["23.0", "1058.0", "46.0"], output_stream)
|
33
|
-
end
|
34
|
-
|
35
|
-
def build_tokens *tokens
|
36
|
-
tokens.collect {|token| Dhaka::Token.new(token[0], token[1], nil)}
|
37
|
-
end
|
38
|
-
end
|
@@ -1,104 +0,0 @@
|
|
1
|
-
class ChittagongGrammar < Dhaka::Grammar
|
2
|
-
|
3
|
-
precedences do
|
4
|
-
nonassoc %w| == |
|
5
|
-
nonassoc %w| < > |
|
6
|
-
left %w| + - |
|
7
|
-
left %w| * / |
|
8
|
-
nonassoc %w| ^ |
|
9
|
-
nonassoc %w| ! |
|
10
|
-
end
|
11
|
-
# lipi:grammar_overview
|
12
|
-
|
13
|
-
for_symbol(Dhaka::START_SYMBOL_NAME) do
|
14
|
-
program %w| opt_terms main_body opt_terms |
|
15
|
-
end
|
16
|
-
|
17
|
-
for_symbol('main_body') do
|
18
|
-
single_main_body_statement %w| main_body_statement |
|
19
|
-
multiple_main_body_statements %w| main_body terms main_body_statement |
|
20
|
-
end
|
21
|
-
|
22
|
-
for_symbol('main_body_statement') do
|
23
|
-
main_body_simple_statement %w| simple_statement |
|
24
|
-
function_definition %w| def function_name ( arg_declarations ) terms
|
25
|
-
function_body terms end |
|
26
|
-
main_body_if_statement %w| if expression terms main_body terms end |
|
27
|
-
main_body_if_else_statement %w| if expression terms main_body terms else terms main_body
|
28
|
-
terms end |
|
29
|
-
main_body_while_statement %w| while expression terms main_body terms end |
|
30
|
-
end
|
31
|
-
# lipi:grammar_overview
|
32
|
-
|
33
|
-
for_symbol('simple_statement') do
|
34
|
-
assignment_statement %w| var_name = expression |
|
35
|
-
print_statement %w| print expression |
|
36
|
-
function_call_statement %w| function_name ( arg_list ) |
|
37
|
-
end
|
38
|
-
|
39
|
-
for_symbol('function_body') do
|
40
|
-
single_function_body_statement %w| function_body_statement |
|
41
|
-
multiple_function_body_statements %w| function_body terms function_body_statement |
|
42
|
-
end
|
43
|
-
|
44
|
-
for_symbol('function_body_statement') do
|
45
|
-
function_body_simple_statement %w| simple_statement |
|
46
|
-
return_statement %w| return expression |
|
47
|
-
function_body_if_statement %w| if expression terms function_body terms end |
|
48
|
-
function_body_if_else_statement %w| if expression terms function_body terms else terms function_body terms end |
|
49
|
-
function_body_while_statement %w| while expression terms function_body terms end |
|
50
|
-
end
|
51
|
-
|
52
|
-
for_symbol('function_name') do
|
53
|
-
function_name %w| word_literal |
|
54
|
-
end
|
55
|
-
|
56
|
-
for_symbol('var_name') do
|
57
|
-
variable_name %w| word_literal |
|
58
|
-
end
|
59
|
-
|
60
|
-
for_symbol('arg_declarations') do
|
61
|
-
no_arg_decl %w| |
|
62
|
-
single_arg_declaration %w| arg_decl |
|
63
|
-
multiple_arg_declarations %w| arg_declarations , arg_decl |
|
64
|
-
end
|
65
|
-
|
66
|
-
for_symbol('arg_decl') do
|
67
|
-
arg_declaration %w| word_literal |
|
68
|
-
end
|
69
|
-
|
70
|
-
for_symbol('arg_list') do
|
71
|
-
no_args %w| |
|
72
|
-
single_arg %w| expression |
|
73
|
-
multiple_args %w| arg_list , expression |
|
74
|
-
end
|
75
|
-
# lipi:expressions
|
76
|
-
for_symbol('expression') do
|
77
|
-
negation %w| ! expression |
|
78
|
-
equality_comparison %w| expression == expression |
|
79
|
-
greater_than_comparison %w| expression > expression |
|
80
|
-
less_than_comparison %w| expression < expression |
|
81
|
-
addition %w| expression + expression |
|
82
|
-
subtraction %w| expression - expression |
|
83
|
-
multiplication %w| expression * expression |
|
84
|
-
division %w| expression / expression |
|
85
|
-
power %w| expression ^ expression |
|
86
|
-
literal %w| numeric_literal |
|
87
|
-
function_call_expression %w| function_name ( arg_list ) |
|
88
|
-
variable_reference %w| var_name |
|
89
|
-
parenthetized_expression %w| ( expression ) |
|
90
|
-
negated_expression %w| - expression |, :prec => '*'
|
91
|
-
end
|
92
|
-
# lipi:expressions
|
93
|
-
|
94
|
-
for_symbol('terms') do
|
95
|
-
single_term %w| newline |
|
96
|
-
multiple_terms %w| terms newline |
|
97
|
-
end
|
98
|
-
|
99
|
-
for_symbol('opt_terms') do
|
100
|
-
some_terms %w| terms |
|
101
|
-
no_terms %w| |
|
102
|
-
end
|
103
|
-
|
104
|
-
end
|