ajlisp 0.0.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.
Files changed (88) hide show
  1. data/LICENSE +23 -0
  2. data/README.md +33 -0
  3. data/ajlisp.gemspec +20 -0
  4. data/lib/ajlisp.rb +128 -0
  5. data/lib/ajlisp/at_constant_atom.rb +30 -0
  6. data/lib/ajlisp/context.rb +27 -0
  7. data/lib/ajlisp/dot_verb_atom.rb +31 -0
  8. data/lib/ajlisp/file_source.rb +10 -0
  9. data/lib/ajlisp/fprimitive.rb +23 -0
  10. data/lib/ajlisp/fprimitive_closure.rb +48 -0
  11. data/lib/ajlisp/fprimitive_define.rb +30 -0
  12. data/lib/ajlisp/fprimitive_definef.rb +30 -0
  13. data/lib/ajlisp/fprimitive_definem.rb +30 -0
  14. data/lib/ajlisp/fprimitive_do.rb +25 -0
  15. data/lib/ajlisp/fprimitive_flambda.rb +21 -0
  16. data/lib/ajlisp/fprimitive_if.rb +34 -0
  17. data/lib/ajlisp/fprimitive_lambda.rb +21 -0
  18. data/lib/ajlisp/fprimitive_let.rb +38 -0
  19. data/lib/ajlisp/fprimitive_macro_closure.rb +13 -0
  20. data/lib/ajlisp/fprimitive_mlambda.rb +21 -0
  21. data/lib/ajlisp/fprimitive_quote.rb +19 -0
  22. data/lib/ajlisp/input_source.rb +37 -0
  23. data/lib/ajlisp/lexer.rb +132 -0
  24. data/lib/ajlisp/list.rb +106 -0
  25. data/lib/ajlisp/named_atom.rb +34 -0
  26. data/lib/ajlisp/nil_atom.rb +39 -0
  27. data/lib/ajlisp/parser.rb +80 -0
  28. data/lib/ajlisp/primitive.rb +19 -0
  29. data/lib/ajlisp/primitive_add.rb +29 -0
  30. data/lib/ajlisp/primitive_closure.rb +49 -0
  31. data/lib/ajlisp/primitive_comparisons.rb +84 -0
  32. data/lib/ajlisp/primitive_cons.rb +19 -0
  33. data/lib/ajlisp/primitive_divide.rb +25 -0
  34. data/lib/ajlisp/primitive_eval.rb +19 -0
  35. data/lib/ajlisp/primitive_first.rb +19 -0
  36. data/lib/ajlisp/primitive_list.rb +19 -0
  37. data/lib/ajlisp/primitive_load.rb +34 -0
  38. data/lib/ajlisp/primitive_multiply.rb +25 -0
  39. data/lib/ajlisp/primitive_predicates.rb +58 -0
  40. data/lib/ajlisp/primitive_rest.rb +19 -0
  41. data/lib/ajlisp/primitive_subtract.rb +25 -0
  42. data/lib/ajlisp/string_source.rb +28 -0
  43. data/lib/ajlisp/token.rb +23 -0
  44. data/lib/core.lsp +40 -0
  45. data/test/and.lsp +1 -0
  46. data/test/append.lsp +1 -0
  47. data/test/backquote.lsp +7 -0
  48. data/test/cond.lsp +1 -0
  49. data/test/define123.lsp +4 -0
  50. data/test/definem.lsp +1 -0
  51. data/test/dodefine123.lsp +5 -0
  52. data/test/mapcond.lsp +13 -0
  53. data/test/mapfirst.lsp +10 -0
  54. data/test/mycons.lsp +3 -0
  55. data/test/test.rb +42 -0
  56. data/test/test_at_constant_atom.rb +34 -0
  57. data/test/test_context.rb +37 -0
  58. data/test/test_dot_verb_atom.rb +29 -0
  59. data/test/test_evaluate.rb +289 -0
  60. data/test/test_evaluate_files.rb +136 -0
  61. data/test/test_file_source.rb +11 -0
  62. data/test/test_fprimitive_closure.rb +29 -0
  63. data/test/test_fprimitive_define.rb +65 -0
  64. data/test/test_fprimitive_definef.rb +20 -0
  65. data/test/test_fprimitive_definem.rb +20 -0
  66. data/test/test_fprimitive_do.rb +18 -0
  67. data/test/test_fprimitive_flambda.rb +15 -0
  68. data/test/test_fprimitive_if.rb +29 -0
  69. data/test/test_fprimitive_lambda.rb +15 -0
  70. data/test/test_fprimitive_let.rb +18 -0
  71. data/test/test_fprimitive_macro_closure.rb +17 -0
  72. data/test/test_fprimitive_mlambda.rb +12 -0
  73. data/test/test_fprimitive_quote.rb +35 -0
  74. data/test/test_lexer.rb +208 -0
  75. data/test/test_list.rb +102 -0
  76. data/test/test_load.rb +74 -0
  77. data/test/test_named_atom.rb +33 -0
  78. data/test/test_parser.rb +252 -0
  79. data/test/test_primitive_add.rb +26 -0
  80. data/test/test_primitive_closure.rb +29 -0
  81. data/test/test_primitive_cons.rb +39 -0
  82. data/test/test_primitive_eval.rb +13 -0
  83. data/test/test_primitive_first.rb +25 -0
  84. data/test/test_primitive_list.rb +27 -0
  85. data/test/test_primitive_rest.rb +29 -0
  86. data/test/test_string_source.rb +10 -0
  87. data/test/test_token.rb +14 -0
  88. metadata +131 -0
@@ -0,0 +1,102 @@
1
+ require 'ajlisp'
2
+ require 'test/unit'
3
+
4
+ module AjLisp
5
+
6
+ class TestList < Test::Unit::TestCase
7
+ def test_initialize
8
+ list = List.new
9
+ assert_not_nil(list)
10
+ end
11
+
12
+ def test_first_is_nil
13
+ list = List.new
14
+ assert_nil(list.first)
15
+ end
16
+
17
+ def test_rest_is_nil
18
+ list = List.new
19
+ assert_nil(list.rest)
20
+ end
21
+
22
+ def test_create_with_first
23
+ list = List.new("foo")
24
+ assert_equal("foo", list.first)
25
+ assert_nil(list.rest)
26
+ end
27
+
28
+ def test_create_with_first_and_rest
29
+ rest = List.new("bar")
30
+ list = List.new("foo", rest)
31
+ assert_equal("foo", list.first)
32
+ assert_not_nil(list.rest)
33
+ assert_equal("bar", list.rest.first)
34
+ assert_nil(list.rest.rest)
35
+ end
36
+
37
+ def test_create_from_array
38
+ list = List.make [1, "a", "foo"]
39
+ assert_not_nil list
40
+ assert_equal 1, list.first
41
+ assert_equal "a", list.rest.first
42
+ assert_equal "foo", list.rest.rest.first
43
+ assert_nil list.rest.rest.rest
44
+ end
45
+
46
+ def test_create_from_nested_array
47
+ list = List.make [1, ["a", "b"], "foo"]
48
+ assert_not_nil list
49
+ assert_equal 1, list.first
50
+
51
+ assert_equal "a", list.rest.first.first
52
+ assert_equal "b", list.rest.first.rest.first
53
+ assert_nil list.rest.first.rest.rest
54
+
55
+ assert_equal "foo", list.rest.rest.first
56
+ assert_nil list.rest.rest.rest
57
+ end
58
+
59
+ def test_create_from_array_with_symbols
60
+ list = List.make [1, :a, :foo]
61
+ assert_not_nil list
62
+ assert_equal 1, list.first
63
+ assert list.rest.first.is_a? AjLisp::NamedAtom
64
+ assert_equal :a, list.rest.first.name
65
+ assert list.rest.rest.first.is_a? AjLisp::NamedAtom
66
+ assert_equal :foo, list.rest.rest.first.name
67
+ end
68
+
69
+ def test_simple_list_to_string
70
+ list = List.make [:a, :b]
71
+ assert_equal "(a b)", list.to_s
72
+ end
73
+
74
+ def test_nested_list_to_string
75
+ list = List.make [:a, [:b, :c, [:d, :e]], :f]
76
+ assert_equal "(a (b c (d e)) f)", list.to_s
77
+ end
78
+
79
+ def test_list_with_numbers_and_strings_to_string
80
+ list = List.make [:a, ["b", 2, [:d, :e]], :f]
81
+ assert_equal '(a ("b" 2 (d e)) f)', list.to_s
82
+ end
83
+
84
+ def test_simple_list_is_equal_to_list
85
+ list = List.make [:a, :b]
86
+ list2 = List.make [:a, :b]
87
+ list3 = List.make [:a, :c]
88
+ assert list.isEqualTo(list2)
89
+ assert !list.isEqualTo(list3)
90
+ assert !list3.isEqualTo(list)
91
+ assert list.isEqualTo(list)
92
+ assert list2.isEqualTo(list)
93
+ end
94
+
95
+ def test_empty_list
96
+ list = List.make []
97
+
98
+ assert_nil list
99
+ end
100
+ end
101
+
102
+ end
@@ -0,0 +1,74 @@
1
+ require 'ajlisp'
2
+ require 'test/unit'
3
+
4
+ module AjLisp
5
+
6
+ class TestEvaluateLoad < Test::Unit::TestCase
7
+ def test_evaluate_define123
8
+ result = loadFile("define123.lsp")
9
+
10
+ assert_equal 3, result
11
+ assert_equal 1, AjLisp::context.getValue(:one)
12
+ assert_equal 2, AjLisp::context.getValue(:two)
13
+ assert_equal 3, AjLisp::context.getValue(:three)
14
+ end
15
+
16
+ def test_evaluate_dodefine123
17
+ result = loadFile("dodefine123.lsp")
18
+
19
+ assert_equal 3, result
20
+ assert_equal 1, AjLisp::context.getValue(:one)
21
+ assert_equal 2, AjLisp::context.getValue(:two)
22
+ assert_equal 3, AjLisp::context.getValue(:three)
23
+ end
24
+
25
+ def test_evaluate_mycons
26
+ result = loadFile("mycons.lsp")
27
+
28
+ assert_not_nil result
29
+ assert result.is_a? List
30
+ assert_equal :a, result.first.name
31
+ assert_equal :b, result.rest.first.name
32
+ assert_nil result.rest.rest
33
+ end
34
+
35
+ def test_evaluate_append
36
+ loadFile("append.lsp")
37
+
38
+ assert_equal "(1 2 3 4 5)", evaluateText("(append (list 1 2) (list 3 4 5))").to_s
39
+ assert_equal "(1 2)", evaluateText("(append (list 1 2) nil)").to_s
40
+ evaluateText("(define x '(b b))")
41
+ assert_equal "(b b)", evaluateText("(append x nil)").to_s
42
+ assert_equal "(b b b b)", evaluateText("(append x x)").to_s
43
+ end
44
+
45
+ def test_evaluate_mapfirst
46
+ loadFile("mapfirst.lsp")
47
+
48
+ assert_equal "((1) (2) (3))", evaluateText("(mapfirst list (list 1 2 3))").to_s
49
+ assert_equal "(1 2 3)", evaluateText("(mapfirst first (quote ((1) (2) (3))))").to_s
50
+ end
51
+
52
+ def test_evaluate_mapcond
53
+ loadFile("mapcond.lsp")
54
+
55
+ assert_equal "((2))", evaluateText("(mapcond list? (list 1 (list 2) 3))").to_s
56
+ assert_equal "(nil)", evaluateText("(mapcond nil? (list 1 nil 3))").to_s
57
+ end
58
+
59
+ def loadFile(filename)
60
+ fullname = File.expand_path(filename, File.dirname(__FILE__))
61
+ text = '(load "' + fullname + '")'
62
+ return evaluateText(text)
63
+ end
64
+
65
+ def evaluateText(text)
66
+ source = StringSource.new text
67
+ lexer = Lexer.new source
68
+ parser = Parser.new lexer
69
+ expr = parser.parseExpression
70
+ return AjLisp::evaluate AjLisp::context, expr
71
+ end
72
+ end
73
+
74
+ end
@@ -0,0 +1,33 @@
1
+
2
+ require 'ajlisp'
3
+ require 'test/unit'
4
+
5
+ class TestNamedAtom < Test::Unit::TestCase
6
+ def test_initialize
7
+ atom = AjLisp::NamedAtom.new("a")
8
+ assert_equal(:a, atom.name)
9
+ end
10
+
11
+ def test_evaluate_in_context
12
+ atom = AjLisp::NamedAtom.new("foo")
13
+ context = AjLisp::Context.new
14
+ context.setValue(:foo, "bar")
15
+ assert_equal("bar", atom.evaluate(context))
16
+ end
17
+
18
+ def test_atom_to_string
19
+ atom = AjLisp::NamedAtom.new("foo")
20
+ assert_equal "foo", atom.to_s
21
+ end
22
+
23
+ def test_atom_is_equal
24
+ atom = AjLisp::NamedAtom.new("foo")
25
+ atom2 = AjLisp::NamedAtom.new("foo")
26
+ atom3 = AjLisp::NamedAtom.new("bar")
27
+
28
+ assert atom.isEqualTo(atom2)
29
+ assert atom2.isEqualTo(atom)
30
+ assert !atom.isEqualTo(atom3)
31
+ assert !atom3.isEqualTo(atom)
32
+ end
33
+ end
@@ -0,0 +1,252 @@
1
+ require 'ajlisp'
2
+ require 'test/unit'
3
+
4
+ module AjLisp
5
+
6
+ class TestParser < Test::Unit::TestCase
7
+ def test_parse_atom
8
+ source = StringSource.new "atom"
9
+ lexer = Lexer.new source
10
+ parser = Parser.new lexer
11
+
12
+ expr = parser.parseExpression
13
+
14
+ assert_not_nil expr
15
+ assert expr.is_a? NamedAtom
16
+ assert_equal :atom, expr.name
17
+
18
+ assert_nil parser.parseExpression
19
+ end
20
+
21
+ def test_parse_add_atom
22
+ source = StringSource.new "+"
23
+ lexer = Lexer.new source
24
+ parser = Parser.new lexer
25
+
26
+ expr = parser.parseExpression
27
+
28
+ assert_not_nil expr
29
+ assert expr.is_a? NamedAtom
30
+ assert_equal :+, expr.name
31
+
32
+ assert_nil parser.parseExpression
33
+ end
34
+
35
+ def test_parse_integer
36
+ source = StringSource.new "123"
37
+ lexer = Lexer.new source
38
+ parser = Parser.new lexer
39
+
40
+ expr = parser.parseExpression
41
+
42
+ assert_not_nil expr
43
+ assert expr.is_a? Fixnum
44
+ assert_equal 123, expr
45
+
46
+ assert_nil parser.parseExpression
47
+ end
48
+
49
+ def test_parse_string
50
+ source = StringSource.new '"foo"'
51
+ lexer = Lexer.new source
52
+ parser = Parser.new lexer
53
+
54
+ expr = parser.parseExpression
55
+
56
+ assert_not_nil expr
57
+ assert expr.is_a? String
58
+ assert_equal "foo", expr
59
+
60
+ assert_nil parser.parseExpression
61
+ end
62
+
63
+ def test_parse_simple_list
64
+ source = StringSource.new "(foo bar)"
65
+ lexer = Lexer.new source
66
+ parser = Parser.new lexer
67
+
68
+ expr = parser.parseExpression
69
+
70
+ assert_not_nil expr
71
+ assert expr.is_a? List
72
+ assert_equal :foo, expr.first.name
73
+ assert_equal :bar, expr.rest.first.name
74
+ assert_nil expr.rest.rest
75
+
76
+ assert_nil parser.parseExpression
77
+ end
78
+
79
+ def test_parse_add_list
80
+ source = StringSource.new "(+ 1 2)"
81
+ lexer = Lexer.new source
82
+ parser = Parser.new lexer
83
+
84
+ expr = parser.parseExpression
85
+
86
+ assert_not_nil expr
87
+ assert expr.is_a? List
88
+ assert_equal :+, expr.first.name
89
+ assert_equal 1, expr.rest.first
90
+ assert_equal 2, expr.rest.rest.first
91
+ assert_nil expr.rest.rest.rest
92
+
93
+ assert_nil parser.parseExpression
94
+ end
95
+
96
+ def test_parse_list_with_list
97
+ source = StringSource.new "(cons (a b))"
98
+ lexer = Lexer.new source
99
+ parser = Parser.new lexer
100
+
101
+ expr = parser.parseExpression
102
+
103
+ assert_not_nil expr
104
+ assert expr.is_a? List
105
+ assert_equal :cons, expr.first.name
106
+ assert expr.rest.is_a? List
107
+
108
+ assert_nil parser.parseExpression
109
+ end
110
+
111
+ def test_parse_list_with_two_lists
112
+ source = StringSource.new "(cons (quote a) (quote (a b)))"
113
+ lexer = Lexer.new source
114
+ parser = Parser.new lexer
115
+
116
+ expr = parser.parseExpression
117
+
118
+ assert_not_nil expr
119
+ assert expr.is_a? List
120
+ assert_equal :cons, expr.first.name
121
+ assert expr.rest.is_a? List
122
+ assert expr.rest.first.is_a? List
123
+ assert expr.rest.rest.first.is_a? List
124
+
125
+ assert_nil parser.parseExpression
126
+ end
127
+
128
+ def test_parse_verb_atom
129
+ source = StringSource.new ".do"
130
+ lexer = Lexer.new source
131
+ parser = Parser.new lexer
132
+
133
+ expr = parser.parseExpression
134
+
135
+ assert_not_nil expr
136
+ assert expr.is_a? DotVerbAtom
137
+ assert_equal ".do".intern, expr.name
138
+
139
+ assert_nil parser.parseExpression
140
+ end
141
+
142
+ def test_parse_constant_atom
143
+ source = StringSource.new "@String"
144
+ lexer = Lexer.new source
145
+ parser = Parser.new lexer
146
+
147
+ expr = parser.parseExpression
148
+
149
+ assert_not_nil expr
150
+ assert expr.is_a? AtConstantAtom
151
+ assert_equal :@String, expr.name
152
+ assert_equal "String", expr.constant
153
+
154
+ assert_nil parser.parseExpression
155
+ end
156
+
157
+ def test_parse_quoted_atom
158
+ source = StringSource.new "'a"
159
+ lexer = Lexer.new source
160
+ parser = Parser.new lexer
161
+
162
+ expr = parser.parseExpression
163
+
164
+ assert_not_nil expr
165
+ assert expr.is_a? List
166
+ assert_equal :quote, expr.first.name
167
+ assert_equal :a, expr.rest.first.name
168
+
169
+ assert_nil parser.parseExpression
170
+ end
171
+
172
+ def test_parse_quoted_list
173
+ source = StringSource.new "'(a b)"
174
+ lexer = Lexer.new source
175
+ parser = Parser.new lexer
176
+
177
+ expr = parser.parseExpression
178
+
179
+ assert_not_nil expr
180
+ assert expr.is_a? List
181
+ assert_equal :quote, expr.first.name
182
+ assert_equal :a, expr.rest.first.first.name
183
+ assert_equal :b, expr.rest.first.rest.first.name
184
+
185
+ assert_nil parser.parseExpression
186
+ end
187
+
188
+ def test_parse_backquoted_list
189
+ source = StringSource.new "`(a b)"
190
+ lexer = Lexer.new source
191
+ parser = Parser.new lexer
192
+
193
+ expr = parser.parseExpression
194
+
195
+ assert_not_nil expr
196
+ assert expr.is_a? List
197
+ assert_equal :backquote, expr.first.name
198
+ assert_equal :a, expr.rest.first.first.name
199
+ assert_equal :b, expr.rest.first.rest.first.name
200
+
201
+ assert_nil parser.parseExpression
202
+ end
203
+
204
+ def test_parse_backquoted_atom
205
+ source = StringSource.new "`a"
206
+ lexer = Lexer.new source
207
+ parser = Parser.new lexer
208
+
209
+ expr = parser.parseExpression
210
+
211
+ assert_not_nil expr
212
+ assert expr.is_a? List
213
+ assert_equal :backquote, expr.first.name
214
+ assert_equal :a, expr.rest.first.name
215
+ assert_nil expr.rest.rest
216
+
217
+ assert_nil parser.parseExpression
218
+ end
219
+
220
+ def test_parse_unquoted_list
221
+ source = StringSource.new ",(a b)"
222
+ lexer = Lexer.new source
223
+ parser = Parser.new lexer
224
+
225
+ expr = parser.parseExpression
226
+
227
+ assert_not_nil expr
228
+ assert expr.is_a? List
229
+ assert_equal :unquote, expr.first.name
230
+ assert_equal :a, expr.rest.first.first.name
231
+ assert_equal :b, expr.rest.first.rest.first.name
232
+
233
+ assert_nil parser.parseExpression
234
+ end
235
+
236
+ def test_parse_empty_list
237
+ source = StringSource.new "()"
238
+ lexer = Lexer.new source
239
+ parser = Parser.new lexer
240
+
241
+ expr = parser.parseExpression
242
+
243
+ assert_not_nil expr
244
+ assert expr.is_a? List
245
+ assert expr.is_a? EmptyList
246
+
247
+ assert_nil parser.parseExpression
248
+ end
249
+ end
250
+
251
+ end
252
+