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.
- data/LICENSE +23 -0
- data/README.md +33 -0
- data/ajlisp.gemspec +20 -0
- data/lib/ajlisp.rb +128 -0
- data/lib/ajlisp/at_constant_atom.rb +30 -0
- data/lib/ajlisp/context.rb +27 -0
- data/lib/ajlisp/dot_verb_atom.rb +31 -0
- data/lib/ajlisp/file_source.rb +10 -0
- data/lib/ajlisp/fprimitive.rb +23 -0
- data/lib/ajlisp/fprimitive_closure.rb +48 -0
- data/lib/ajlisp/fprimitive_define.rb +30 -0
- data/lib/ajlisp/fprimitive_definef.rb +30 -0
- data/lib/ajlisp/fprimitive_definem.rb +30 -0
- data/lib/ajlisp/fprimitive_do.rb +25 -0
- data/lib/ajlisp/fprimitive_flambda.rb +21 -0
- data/lib/ajlisp/fprimitive_if.rb +34 -0
- data/lib/ajlisp/fprimitive_lambda.rb +21 -0
- data/lib/ajlisp/fprimitive_let.rb +38 -0
- data/lib/ajlisp/fprimitive_macro_closure.rb +13 -0
- data/lib/ajlisp/fprimitive_mlambda.rb +21 -0
- data/lib/ajlisp/fprimitive_quote.rb +19 -0
- data/lib/ajlisp/input_source.rb +37 -0
- data/lib/ajlisp/lexer.rb +132 -0
- data/lib/ajlisp/list.rb +106 -0
- data/lib/ajlisp/named_atom.rb +34 -0
- data/lib/ajlisp/nil_atom.rb +39 -0
- data/lib/ajlisp/parser.rb +80 -0
- data/lib/ajlisp/primitive.rb +19 -0
- data/lib/ajlisp/primitive_add.rb +29 -0
- data/lib/ajlisp/primitive_closure.rb +49 -0
- data/lib/ajlisp/primitive_comparisons.rb +84 -0
- data/lib/ajlisp/primitive_cons.rb +19 -0
- data/lib/ajlisp/primitive_divide.rb +25 -0
- data/lib/ajlisp/primitive_eval.rb +19 -0
- data/lib/ajlisp/primitive_first.rb +19 -0
- data/lib/ajlisp/primitive_list.rb +19 -0
- data/lib/ajlisp/primitive_load.rb +34 -0
- data/lib/ajlisp/primitive_multiply.rb +25 -0
- data/lib/ajlisp/primitive_predicates.rb +58 -0
- data/lib/ajlisp/primitive_rest.rb +19 -0
- data/lib/ajlisp/primitive_subtract.rb +25 -0
- data/lib/ajlisp/string_source.rb +28 -0
- data/lib/ajlisp/token.rb +23 -0
- data/lib/core.lsp +40 -0
- data/test/and.lsp +1 -0
- data/test/append.lsp +1 -0
- data/test/backquote.lsp +7 -0
- data/test/cond.lsp +1 -0
- data/test/define123.lsp +4 -0
- data/test/definem.lsp +1 -0
- data/test/dodefine123.lsp +5 -0
- data/test/mapcond.lsp +13 -0
- data/test/mapfirst.lsp +10 -0
- data/test/mycons.lsp +3 -0
- data/test/test.rb +42 -0
- data/test/test_at_constant_atom.rb +34 -0
- data/test/test_context.rb +37 -0
- data/test/test_dot_verb_atom.rb +29 -0
- data/test/test_evaluate.rb +289 -0
- data/test/test_evaluate_files.rb +136 -0
- data/test/test_file_source.rb +11 -0
- data/test/test_fprimitive_closure.rb +29 -0
- data/test/test_fprimitive_define.rb +65 -0
- data/test/test_fprimitive_definef.rb +20 -0
- data/test/test_fprimitive_definem.rb +20 -0
- data/test/test_fprimitive_do.rb +18 -0
- data/test/test_fprimitive_flambda.rb +15 -0
- data/test/test_fprimitive_if.rb +29 -0
- data/test/test_fprimitive_lambda.rb +15 -0
- data/test/test_fprimitive_let.rb +18 -0
- data/test/test_fprimitive_macro_closure.rb +17 -0
- data/test/test_fprimitive_mlambda.rb +12 -0
- data/test/test_fprimitive_quote.rb +35 -0
- data/test/test_lexer.rb +208 -0
- data/test/test_list.rb +102 -0
- data/test/test_load.rb +74 -0
- data/test/test_named_atom.rb +33 -0
- data/test/test_parser.rb +252 -0
- data/test/test_primitive_add.rb +26 -0
- data/test/test_primitive_closure.rb +29 -0
- data/test/test_primitive_cons.rb +39 -0
- data/test/test_primitive_eval.rb +13 -0
- data/test/test_primitive_first.rb +25 -0
- data/test/test_primitive_list.rb +27 -0
- data/test/test_primitive_rest.rb +29 -0
- data/test/test_string_source.rb +10 -0
- data/test/test_token.rb +14 -0
- metadata +131 -0
@@ -0,0 +1,34 @@
|
|
1
|
+
|
2
|
+
module AjLisp
|
3
|
+
|
4
|
+
class PrimitiveLoad < Primitive
|
5
|
+
private_class_method :new
|
6
|
+
|
7
|
+
@@instance = nil
|
8
|
+
|
9
|
+
def self.instance
|
10
|
+
@@instance = new unless @@instance
|
11
|
+
return @@instance
|
12
|
+
end
|
13
|
+
|
14
|
+
def apply(context, args)
|
15
|
+
result = nil
|
16
|
+
|
17
|
+
args.each do |filename|
|
18
|
+
source = FileSource.new filename # File.expand_path(filename, File.dirname(__FILE__))
|
19
|
+
lexer = Lexer.new source
|
20
|
+
parser = Parser.new lexer
|
21
|
+
expr = parser.parseExpression
|
22
|
+
|
23
|
+
|
24
|
+
while expr
|
25
|
+
result = AjLisp::evaluate AjLisp::context, expr
|
26
|
+
expr = parser.parseExpression
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
return result
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
|
2
|
+
module AjLisp
|
3
|
+
|
4
|
+
class PrimitiveMultiply < Primitive
|
5
|
+
private_class_method :new
|
6
|
+
|
7
|
+
@@instance = nil
|
8
|
+
|
9
|
+
def self.instance
|
10
|
+
@@instance = new unless @@instance
|
11
|
+
return @@instance
|
12
|
+
end
|
13
|
+
|
14
|
+
def apply(context, args)
|
15
|
+
result = 1
|
16
|
+
|
17
|
+
args.each do |arg|
|
18
|
+
result *= arg
|
19
|
+
end
|
20
|
+
|
21
|
+
return result
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
|
2
|
+
module AjLisp
|
3
|
+
|
4
|
+
class PrimitiveNilPredicate < Primitive
|
5
|
+
private_class_method :new
|
6
|
+
|
7
|
+
@@instance = nil
|
8
|
+
|
9
|
+
def self.instance
|
10
|
+
@@instance = new unless @@instance
|
11
|
+
return @@instance
|
12
|
+
end
|
13
|
+
|
14
|
+
def apply(context, args)
|
15
|
+
return ((args[0] == nil) or (args[0].is_a? NilAtom))
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
class PrimitiveAtomPredicate < Primitive
|
20
|
+
private_class_method :new
|
21
|
+
|
22
|
+
@@instance = nil
|
23
|
+
|
24
|
+
def self.instance
|
25
|
+
@@instance = new unless @@instance
|
26
|
+
return @@instance
|
27
|
+
end
|
28
|
+
|
29
|
+
def apply(context, args)
|
30
|
+
if args[0] == nil
|
31
|
+
return false
|
32
|
+
end
|
33
|
+
|
34
|
+
if args[0].is_a? List
|
35
|
+
return false
|
36
|
+
end
|
37
|
+
|
38
|
+
return true
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
class PrimitiveListPredicate < Primitive
|
43
|
+
private_class_method :new
|
44
|
+
|
45
|
+
@@instance = nil
|
46
|
+
|
47
|
+
def self.instance
|
48
|
+
@@instance = new unless @@instance
|
49
|
+
return @@instance
|
50
|
+
end
|
51
|
+
|
52
|
+
def apply(context, args)
|
53
|
+
return args[0].is_a? List
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
|
@@ -0,0 +1,19 @@
|
|
1
|
+
|
2
|
+
module AjLisp
|
3
|
+
|
4
|
+
class PrimitiveRest < Primitive
|
5
|
+
private_class_method :new
|
6
|
+
|
7
|
+
@@instance = nil
|
8
|
+
|
9
|
+
def self.instance
|
10
|
+
@@instance = new unless @@instance
|
11
|
+
return @@instance
|
12
|
+
end
|
13
|
+
|
14
|
+
def apply(context, args)
|
15
|
+
return args[0].rest
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
|
2
|
+
module AjLisp
|
3
|
+
|
4
|
+
class PrimitiveSubtract < Primitive
|
5
|
+
private_class_method :new
|
6
|
+
|
7
|
+
@@instance = nil
|
8
|
+
|
9
|
+
def self.instance
|
10
|
+
@@instance = new unless @@instance
|
11
|
+
return @@instance
|
12
|
+
end
|
13
|
+
|
14
|
+
def apply(context, args)
|
15
|
+
result = args.shift
|
16
|
+
|
17
|
+
args.each do |arg|
|
18
|
+
result -= arg
|
19
|
+
end
|
20
|
+
|
21
|
+
return result
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
|
2
|
+
module AjLisp
|
3
|
+
|
4
|
+
class StringSource
|
5
|
+
def initialize(text)
|
6
|
+
@text = text
|
7
|
+
@position = 0
|
8
|
+
@chars = []
|
9
|
+
end
|
10
|
+
|
11
|
+
def nextChar
|
12
|
+
char = @chars.pop
|
13
|
+
|
14
|
+
if char
|
15
|
+
return char
|
16
|
+
end
|
17
|
+
|
18
|
+
char = @text[@position]
|
19
|
+
@position += 1
|
20
|
+
return char
|
21
|
+
end
|
22
|
+
|
23
|
+
def pushChar(ch)
|
24
|
+
@chars.push ch
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
data/lib/ajlisp/token.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
|
2
|
+
module AjLisp
|
3
|
+
|
4
|
+
class Token
|
5
|
+
attr_reader :value
|
6
|
+
attr_reader :type
|
7
|
+
|
8
|
+
def initialize(value, type)
|
9
|
+
@value = value
|
10
|
+
@type = type
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
class TokenType
|
15
|
+
INTEGER = 1
|
16
|
+
REAL = 2
|
17
|
+
STRING = 3
|
18
|
+
ATOM = 4
|
19
|
+
SEPARATOR = 5
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
|
data/lib/core.lsp
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
(define definem (mlambda x (list 'define (first x) (cons 'mlambda (rest x)))))
|
2
|
+
|
3
|
+
(define append (x y) (if (nil? x) y (cons (first x) (append (rest x) y))))
|
4
|
+
|
5
|
+
(definem cond lst (if (nil? lst) false (list 'if (first (first lst)) (cons 'do (rest (first lst))) (cons 'cond (rest lst)))))
|
6
|
+
|
7
|
+
(definem and lst (if (nil? lst) true (list 'cond (list (first lst) (cons 'and (rest lst))) '(true false))))
|
8
|
+
|
9
|
+
(define mapcond (fn lst)
|
10
|
+
(if (nil? lst)
|
11
|
+
nil
|
12
|
+
(if (fn (first lst))
|
13
|
+
(cons
|
14
|
+
(first lst)
|
15
|
+
(mapcond fn (rest lst))
|
16
|
+
)
|
17
|
+
(mapcond fn (rest lst))
|
18
|
+
)
|
19
|
+
)
|
20
|
+
)
|
21
|
+
|
22
|
+
(define mapfirst (fn lst)
|
23
|
+
(if (nil? lst)
|
24
|
+
nil
|
25
|
+
(cons
|
26
|
+
(fn (first lst))
|
27
|
+
(mapfirst fn (rest lst))
|
28
|
+
)
|
29
|
+
)
|
30
|
+
)
|
31
|
+
|
32
|
+
(definem backquote (lst) (cond
|
33
|
+
((nil? lst) nil)
|
34
|
+
((atom? lst) (list 'quote lst))
|
35
|
+
((= (first lst) 'unquote) (first (rest lst)))
|
36
|
+
((and (list? (first lst)) (= (first (first lst)) 'unquote-slice)) (list 'append (first (rest (first lst))) (list 'backquote (rest lst))))
|
37
|
+
(true (list 'cons (list 'backquote (first lst)) (list 'backquote (rest lst))))
|
38
|
+
))
|
39
|
+
|
40
|
+
|
data/test/and.lsp
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
(definem and lst (if (nil? lst) true (list 'cond (list (first lst) (cons 'and (rest lst))) '(true false))))
|
data/test/append.lsp
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
(define append (x y) (if (nil? x) y (cons (first x) (append (rest x) y))))
|
data/test/backquote.lsp
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
(definem backquote (lst) (cond
|
2
|
+
((nil? lst) nil)
|
3
|
+
((atom? lst) (list 'quote lst))
|
4
|
+
((= (first lst) 'unquote) (first (rest lst)))
|
5
|
+
((and (list? (first lst)) (= (first (first lst)) 'unquote-slice)) (list 'append (first (rest (first lst))) (list 'backquote (rest lst))))
|
6
|
+
(true (list 'cons (list 'backquote (first lst)) (list 'backquote (rest lst))))
|
7
|
+
))
|
data/test/cond.lsp
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
(definem cond lst (if (nil? lst) false (list 'if (first (first lst)) (cons 'do (rest (first lst))) (cons 'cond (rest lst)))))
|
data/test/define123.lsp
ADDED
data/test/definem.lsp
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
(define definem (mlambda x (list 'define (first x) (cons 'mlambda (rest x)))))
|
data/test/mapcond.lsp
ADDED
data/test/mapfirst.lsp
ADDED
data/test/mycons.lsp
ADDED
data/test/test.rb
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
|
2
|
+
require 'ajlisp'
|
3
|
+
require 'test/unit'
|
4
|
+
|
5
|
+
require "test_list.rb"
|
6
|
+
require "test_named_atom.rb"
|
7
|
+
require "test_dot_verb_atom.rb"
|
8
|
+
require "test_at_constant_atom.rb"
|
9
|
+
require "test_context.rb"
|
10
|
+
require "test_string_source.rb"
|
11
|
+
require "test_file_source.rb"
|
12
|
+
require "test_token.rb"
|
13
|
+
require "test_lexer.rb"
|
14
|
+
require "test_parser.rb"
|
15
|
+
|
16
|
+
require "test_primitive_first.rb"
|
17
|
+
require "test_primitive_rest.rb"
|
18
|
+
require "test_primitive_cons.rb"
|
19
|
+
require "test_primitive_list.rb"
|
20
|
+
require "test_primitive_closure.rb"
|
21
|
+
|
22
|
+
require "test_primitive_add.rb"
|
23
|
+
|
24
|
+
require "test_primitive_eval"
|
25
|
+
|
26
|
+
require "test_fprimitive_quote.rb"
|
27
|
+
require "test_fprimitive_lambda.rb"
|
28
|
+
require "test_fprimitive_let.rb"
|
29
|
+
require "test_fprimitive_closure.rb"
|
30
|
+
require "test_fprimitive_flambda.rb"
|
31
|
+
require "test_fprimitive_mlambda.rb"
|
32
|
+
require "test_fprimitive_define.rb"
|
33
|
+
require "test_fprimitive_definef.rb"
|
34
|
+
require "test_fprimitive_definem.rb"
|
35
|
+
require "test_fprimitive_do.rb"
|
36
|
+
require "test_fprimitive_if.rb"
|
37
|
+
require "test_fprimitive_macro_closure.rb"
|
38
|
+
|
39
|
+
require "test_evaluate"
|
40
|
+
require "test_evaluate_files"
|
41
|
+
require "test_load"
|
42
|
+
|
@@ -0,0 +1,34 @@
|
|
1
|
+
|
2
|
+
require 'ajlisp'
|
3
|
+
require 'test/unit'
|
4
|
+
|
5
|
+
module AjLisp
|
6
|
+
|
7
|
+
class TestAtConstantAtom < Test::Unit::TestCase
|
8
|
+
def test_initialize
|
9
|
+
atom = AjLisp::AtConstantAtom.new("@String")
|
10
|
+
assert_equal "@String".intern, atom.name
|
11
|
+
assert_equal "String", atom.constant
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_initialize_with_colons
|
15
|
+
atom = AjLisp::AtConstantAtom.new("@AjLisp::List")
|
16
|
+
assert_equal "@AjLisp::List".intern, atom.name
|
17
|
+
assert_equal "AjLisp::List", atom.constant
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_evaluate
|
21
|
+
atom = AjLisp::AtConstantAtom.new("@String")
|
22
|
+
result = atom.evaluate nil
|
23
|
+
assert_equal String, result
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_nested_constant
|
27
|
+
atom = AjLisp::AtConstantAtom.new("@AjLisp::List")
|
28
|
+
result = atom.evaluate nil
|
29
|
+
assert_equal AjLisp::List, result
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
|
@@ -0,0 +1,37 @@
|
|
1
|
+
|
2
|
+
require 'ajlisp'
|
3
|
+
require 'test/unit'
|
4
|
+
|
5
|
+
class TestContext < Test::Unit::TestCase
|
6
|
+
def test_initialize
|
7
|
+
context = AjLisp::Context.new
|
8
|
+
assert_not_nil(context)
|
9
|
+
end
|
10
|
+
|
11
|
+
def test_not_defined_is_nil
|
12
|
+
context = AjLisp::Context.new
|
13
|
+
assert_nil(context.getValue(:foo))
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_set_and_get_value
|
17
|
+
context = AjLisp::Context.new
|
18
|
+
context.setValue(:foo, "bar")
|
19
|
+
assert_equal("bar", context.getValue(:foo))
|
20
|
+
end
|
21
|
+
|
22
|
+
def test_get_value_from_parent
|
23
|
+
parent = AjLisp::Context.new
|
24
|
+
parent.setValue(:foo, "bar")
|
25
|
+
context = AjLisp::Context.new(parent)
|
26
|
+
assert_equal("bar", context.getValue(:foo))
|
27
|
+
end
|
28
|
+
|
29
|
+
def test_override_value_from_parent
|
30
|
+
parent = AjLisp::Context.new
|
31
|
+
parent.setValue(:foo, "bar")
|
32
|
+
context = AjLisp::Context.new(parent)
|
33
|
+
context.setValue(:foo, "bar2")
|
34
|
+
assert_equal("bar2", context.getValue(:foo))
|
35
|
+
assert_equal("bar", parent.getValue(:foo))
|
36
|
+
end
|
37
|
+
end
|