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 NamedAtom
|
5
|
+
attr_reader :name
|
6
|
+
|
7
|
+
def initialize(name)
|
8
|
+
if name.is_a? String
|
9
|
+
@name = name.intern
|
10
|
+
elsif name.is_a? Symbol
|
11
|
+
@name = name
|
12
|
+
else
|
13
|
+
raise "Name of Atom should be an String or Sysmbol"
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def evaluate(context)
|
18
|
+
return context.getValue(@name)
|
19
|
+
end
|
20
|
+
|
21
|
+
def to_s
|
22
|
+
return @name.to_s
|
23
|
+
end
|
24
|
+
|
25
|
+
def isEqualTo(atom)
|
26
|
+
if !atom.is_a? NamedAtom
|
27
|
+
return false
|
28
|
+
end
|
29
|
+
|
30
|
+
return @name == atom.name
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
|
2
|
+
module AjLisp
|
3
|
+
|
4
|
+
class NilAtom < NamedAtom
|
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 initialize()
|
15
|
+
super(:nil)
|
16
|
+
end
|
17
|
+
|
18
|
+
def evaluate(context)
|
19
|
+
return nil
|
20
|
+
end
|
21
|
+
|
22
|
+
def to_s
|
23
|
+
return "nil"
|
24
|
+
end
|
25
|
+
|
26
|
+
def isEqualTo(atom)
|
27
|
+
if atom.is_a? NilAtom
|
28
|
+
return true
|
29
|
+
end
|
30
|
+
|
31
|
+
if atom == nil
|
32
|
+
return true
|
33
|
+
end
|
34
|
+
|
35
|
+
return false
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
|
2
|
+
|
3
|
+
module AjLisp
|
4
|
+
|
5
|
+
class Parser
|
6
|
+
def initialize(lexer)
|
7
|
+
@lexer = lexer
|
8
|
+
end
|
9
|
+
|
10
|
+
def parseExpression
|
11
|
+
token = @lexer.nextToken
|
12
|
+
|
13
|
+
if token == nil
|
14
|
+
return nil
|
15
|
+
end
|
16
|
+
|
17
|
+
if token.type == TokenType::ATOM
|
18
|
+
if token.value[0,1] == "."
|
19
|
+
return DotVerbAtom.new token.value
|
20
|
+
end
|
21
|
+
|
22
|
+
if token.value[0,1] == "@"
|
23
|
+
return AtConstantAtom.new token.value
|
24
|
+
end
|
25
|
+
|
26
|
+
if token.value[0,1] == "'"
|
27
|
+
return List.make [NamedAtom.new("quote"), parseExpression]
|
28
|
+
end
|
29
|
+
|
30
|
+
if token.value[0,1] == "`"
|
31
|
+
return List.make [NamedAtom.new("backquote"), parseExpression]
|
32
|
+
end
|
33
|
+
|
34
|
+
if token.value[0,1] == ","
|
35
|
+
return List.make [NamedAtom.new("unquote"), parseExpression]
|
36
|
+
end
|
37
|
+
|
38
|
+
if token.value == "false"
|
39
|
+
return false
|
40
|
+
end
|
41
|
+
|
42
|
+
if token.value == "true"
|
43
|
+
return true
|
44
|
+
end
|
45
|
+
|
46
|
+
if token.value == "nil"
|
47
|
+
return NilAtom.instance
|
48
|
+
end
|
49
|
+
|
50
|
+
return NamedAtom.new token.value
|
51
|
+
end
|
52
|
+
|
53
|
+
if token.type == TokenType::INTEGER
|
54
|
+
return token.value.to_i
|
55
|
+
end
|
56
|
+
|
57
|
+
if token.type == TokenType::STRING
|
58
|
+
return token.value
|
59
|
+
end
|
60
|
+
|
61
|
+
if token.type == TokenType::SEPARATOR and token.value == "("
|
62
|
+
elements = []
|
63
|
+
token = @lexer.nextToken
|
64
|
+
|
65
|
+
while not (token.type == TokenType::SEPARATOR and token.value == ")")
|
66
|
+
@lexer.pushToken token
|
67
|
+
elements.push parseExpression
|
68
|
+
token = @lexer.nextToken
|
69
|
+
end
|
70
|
+
|
71
|
+
if elements.length == 0
|
72
|
+
return EmptyList.instance
|
73
|
+
else
|
74
|
+
return List::make elements
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
|
2
|
+
module AjLisp
|
3
|
+
|
4
|
+
class Primitive
|
5
|
+
def evaluate(context, list)
|
6
|
+
args = []
|
7
|
+
rest = list.rest
|
8
|
+
|
9
|
+
while rest != nil
|
10
|
+
args.push(AjLisp::evaluate(context, rest.first))
|
11
|
+
rest = rest.rest
|
12
|
+
end
|
13
|
+
|
14
|
+
return apply(context, args)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
|
@@ -0,0 +1,29 @@
|
|
1
|
+
|
2
|
+
module AjLisp
|
3
|
+
|
4
|
+
class PrimitiveAdd < 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 = 0
|
16
|
+
|
17
|
+
if args.length > 0 and not args[0].is_a? Numeric
|
18
|
+
result = ""
|
19
|
+
end
|
20
|
+
|
21
|
+
args.each do |arg|
|
22
|
+
result += arg
|
23
|
+
end
|
24
|
+
|
25
|
+
return result
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
|
2
|
+
module AjLisp
|
3
|
+
|
4
|
+
class PrimitiveClosure < Primitive
|
5
|
+
attr_reader :arguments
|
6
|
+
attr_reader :body
|
7
|
+
attr_reader :context
|
8
|
+
|
9
|
+
def initialize(arguments, body, context=nil)
|
10
|
+
@arguments = arguments
|
11
|
+
@body = body
|
12
|
+
@context = context
|
13
|
+
end
|
14
|
+
|
15
|
+
def apply(context, args)
|
16
|
+
newcontext = context
|
17
|
+
|
18
|
+
if @context then
|
19
|
+
newcontext = @context
|
20
|
+
end
|
21
|
+
|
22
|
+
if @arguments
|
23
|
+
newcontext = AjLisp::Context.new newcontext
|
24
|
+
|
25
|
+
if @arguments.is_a? NamedAtom
|
26
|
+
newcontext.setValue @arguments.name, AjLisp::List.make(args)
|
27
|
+
else
|
28
|
+
names = @arguments
|
29
|
+
|
30
|
+
args.each do |arg|
|
31
|
+
name = names.first.name
|
32
|
+
newcontext.setValue name, arg
|
33
|
+
names = names.rest
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
result = nil
|
39
|
+
|
40
|
+
@body.each do |form|
|
41
|
+
result = AjLisp::evaluate newcontext, form
|
42
|
+
end
|
43
|
+
|
44
|
+
return result
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
|
@@ -0,0 +1,84 @@
|
|
1
|
+
|
2
|
+
module AjLisp
|
3
|
+
|
4
|
+
class PrimitiveEqual < 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
|
+
if args[0].is_a? List or args[0].is_a? NamedAtom
|
16
|
+
return args[0].isEqualTo(args[1])
|
17
|
+
end
|
18
|
+
|
19
|
+
return args[0] == args[1]
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
class PrimitiveLess < Primitive
|
24
|
+
private_class_method :new
|
25
|
+
|
26
|
+
@@instance = nil
|
27
|
+
|
28
|
+
def self.instance
|
29
|
+
@@instance = new unless @@instance
|
30
|
+
return @@instance
|
31
|
+
end
|
32
|
+
|
33
|
+
def apply(context, args)
|
34
|
+
return args[0] < args[1]
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
class PrimitiveGreater < Primitive
|
39
|
+
private_class_method :new
|
40
|
+
|
41
|
+
@@instance = nil
|
42
|
+
|
43
|
+
def self.instance
|
44
|
+
@@instance = new unless @@instance
|
45
|
+
return @@instance
|
46
|
+
end
|
47
|
+
|
48
|
+
def apply(context, args)
|
49
|
+
return args[0] > args[1]
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
class PrimitiveLessEqual < Primitive
|
54
|
+
private_class_method :new
|
55
|
+
|
56
|
+
@@instance = nil
|
57
|
+
|
58
|
+
def self.instance
|
59
|
+
@@instance = new unless @@instance
|
60
|
+
return @@instance
|
61
|
+
end
|
62
|
+
|
63
|
+
def apply(context, args)
|
64
|
+
return args[0] <= args[1]
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
class PrimitiveGreaterEqual < Primitive
|
69
|
+
private_class_method :new
|
70
|
+
|
71
|
+
@@instance = nil
|
72
|
+
|
73
|
+
def self.instance
|
74
|
+
@@instance = new unless @@instance
|
75
|
+
return @@instance
|
76
|
+
end
|
77
|
+
|
78
|
+
def apply(context, args)
|
79
|
+
return args[0] >= args[1]
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
end
|
84
|
+
|
@@ -0,0 +1,19 @@
|
|
1
|
+
|
2
|
+
module AjLisp
|
3
|
+
|
4
|
+
class PrimitiveCons < 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 List.new(args[0], args[1])
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
|
2
|
+
module AjLisp
|
3
|
+
|
4
|
+
class PrimitiveDivide < 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,19 @@
|
|
1
|
+
|
2
|
+
module AjLisp
|
3
|
+
|
4
|
+
class PrimitiveEval < 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 AjLisp::evaluate context, args[0]
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
|
2
|
+
module AjLisp
|
3
|
+
|
4
|
+
class PrimitiveFirst < 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].first
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
|
2
|
+
module AjLisp
|
3
|
+
|
4
|
+
class PrimitiveList < 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 List.make args
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|