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,30 @@
1
+
2
+ module AjLisp
3
+
4
+ class FPrimitiveDefinem < FPrimitive
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
+ atom = args[0]
16
+
17
+ if args.length > 2
18
+ args.shift
19
+ arguments = args.shift
20
+ value = AjLisp::FPrimitiveMacroClosure.new arguments, args
21
+ else
22
+ value = AjLisp::evaluate(context, args[1])
23
+ end
24
+
25
+ AjLisp::context.setValue atom.name, value
26
+ return value
27
+ end
28
+ end
29
+
30
+ end
@@ -0,0 +1,25 @@
1
+
2
+ module AjLisp
3
+
4
+ class FPrimitiveDo < FPrimitive
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 |arg|
18
+ result = AjLisp::evaluate context, arg
19
+ end
20
+
21
+ return result
22
+ end
23
+ end
24
+
25
+ end
@@ -0,0 +1,21 @@
1
+
2
+ module AjLisp
3
+
4
+ class FPrimitiveFLambda < FPrimitive
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
+ arguments = args[0]
16
+ args.shift
17
+ return FPrimitiveClosure.new arguments, args, context
18
+ end
19
+ end
20
+
21
+ end
@@ -0,0 +1,34 @@
1
+
2
+ module AjLisp
3
+
4
+ class FPrimitiveIf < FPrimitive
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
+ condition = args[0]
16
+ args.shift
17
+ thenform = args[0]
18
+ args.shift
19
+
20
+ if AjLisp::evaluate context, condition
21
+ return AjLisp::evaluate context, thenform
22
+ end
23
+
24
+ result = nil
25
+
26
+ args.each do |arg|
27
+ result = AjLisp::evaluate context, arg
28
+ end
29
+
30
+ return result
31
+ end
32
+ end
33
+
34
+ end
@@ -0,0 +1,21 @@
1
+
2
+ module AjLisp
3
+
4
+ class FPrimitiveLambda < FPrimitive
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
+ arguments = args[0]
16
+ args.shift
17
+ return PrimitiveClosure.new arguments, args, context
18
+ end
19
+ end
20
+
21
+ end
@@ -0,0 +1,38 @@
1
+
2
+ module AjLisp
3
+
4
+ class FPrimitiveLet < FPrimitive
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
+ arguments = args[0]
16
+ args.shift
17
+
18
+ newcontext = AjLisp::Context.new context
19
+
20
+ while arguments
21
+ pair = arguments.first
22
+ atom = pair.first
23
+ value = AjLisp::evaluate(context, pair.rest.first)
24
+ newcontext.setValue atom.name, value
25
+ arguments = arguments.rest
26
+ end
27
+
28
+ result = nil
29
+
30
+ args.each do |arg|
31
+ result = AjLisp::evaluate context, arg
32
+ end
33
+
34
+ return result
35
+ end
36
+ end
37
+
38
+ end
@@ -0,0 +1,13 @@
1
+
2
+ module AjLisp
3
+
4
+ class FPrimitiveMacroClosure < FPrimitiveClosure
5
+
6
+ def apply(context, args)
7
+ result = super(context, args)
8
+ return AjLisp::evaluate context, result
9
+ end
10
+
11
+ end
12
+
13
+ end
@@ -0,0 +1,21 @@
1
+
2
+ module AjLisp
3
+
4
+ class FPrimitiveMLambda < FPrimitive
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
+ arguments = args[0]
16
+ args.shift
17
+ return FPrimitiveMacroClosure.new arguments, args, context
18
+ end
19
+ end
20
+
21
+ end
@@ -0,0 +1,19 @@
1
+
2
+ module AjLisp
3
+
4
+ class FPrimitiveQuote < FPrimitive
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]
16
+ end
17
+ end
18
+
19
+ end
@@ -0,0 +1,37 @@
1
+
2
+ module AjLisp
3
+
4
+ class InputSource
5
+ def initialize
6
+ @line = ""
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
+ while @line.length <= @position
19
+ @line = gets
20
+ @position = 0
21
+
22
+ if @line == nil
23
+ return nil
24
+ end
25
+ end
26
+
27
+ char = @line[@position]
28
+ @position += 1
29
+ return char
30
+ end
31
+
32
+ def pushChar(ch)
33
+ @chars.push ch
34
+ end
35
+ end
36
+
37
+ end
@@ -0,0 +1,132 @@
1
+
2
+ module AjLisp
3
+
4
+ class Lexer
5
+ @@separators = "()"
6
+
7
+ def initialize(source)
8
+ @source = source
9
+ @tokens = []
10
+ end
11
+
12
+ def nextToken
13
+ if @tokens.length > 0
14
+ return @tokens.pop
15
+ end
16
+
17
+ char = @source.nextChar
18
+
19
+ while char and char =~ /\s/
20
+ char = @source.nextChar
21
+ end
22
+
23
+ if char == nil
24
+ return nil
25
+ end
26
+
27
+ if char == ?"
28
+ return nextString
29
+ end
30
+
31
+ if @@separators.include? char
32
+ return Token.new char, TokenType::SEPARATOR
33
+ end
34
+
35
+ if char =~ /\d/
36
+ return nextInteger char
37
+ end
38
+
39
+ if char == ?. or char == ?@
40
+ return nextSpecialAtom char
41
+ end
42
+
43
+ if char =~ /\w/
44
+ return nextAtom char
45
+ end
46
+
47
+ if char == ?' or char == ?` or char == ?,
48
+ return Token.new char, TokenType::ATOM
49
+ end
50
+
51
+ return nextSpecialAtom char
52
+ end
53
+
54
+ def pushToken(token)
55
+ @tokens.push(token)
56
+ end
57
+
58
+ private
59
+
60
+ def nextString
61
+ value = ""
62
+
63
+ char = @source.nextChar
64
+
65
+ while char
66
+ if char != ?"
67
+ value += char
68
+ char = @source.nextChar
69
+ else
70
+ break
71
+ end
72
+ end
73
+
74
+ return Token.new value, TokenType::STRING
75
+ end
76
+
77
+ def nextAtom(firstch)
78
+ value = firstch
79
+
80
+ char = @source.nextChar
81
+
82
+ while char
83
+ if not char =~ /\s/ and not @@separators.include? char
84
+ value += char
85
+ char = @source.nextChar
86
+ else
87
+ @source.pushChar char
88
+ break
89
+ end
90
+ end
91
+
92
+ return Token.new value, TokenType::ATOM
93
+ end
94
+
95
+ def nextSpecialAtom(firstch)
96
+ value = firstch
97
+
98
+ char = @source.nextChar
99
+
100
+ while char
101
+ if not char =~ /\s/ and not @@separators.include? char
102
+ value += char
103
+ char = @source.nextChar
104
+ else
105
+ @source.pushChar char
106
+ break
107
+ end
108
+ end
109
+
110
+ return Token.new value, TokenType::ATOM
111
+ end
112
+
113
+ def nextInteger(firstch)
114
+ value = firstch
115
+
116
+ char = @source.nextChar
117
+
118
+ while char
119
+ if char =~ /\d/
120
+ value += char
121
+ char = @source.nextChar
122
+ else
123
+ @source.pushChar char
124
+ break
125
+ end
126
+ end
127
+
128
+ return Token.new value, TokenType::INTEGER
129
+ end
130
+ end
131
+
132
+ end
@@ -0,0 +1,106 @@
1
+
2
+ module AjLisp
3
+
4
+ class List
5
+ attr_reader :first
6
+ attr_reader :rest
7
+
8
+ def initialize(first=nil, rest=nil)
9
+ @first = first
10
+ @rest = rest
11
+ end
12
+
13
+ def evaluate(context)
14
+ form = AjLisp::evaluate(context, @first)
15
+ form.evaluate(context, self)
16
+ end
17
+
18
+ def to_s
19
+ result = "("
20
+
21
+ first = @first
22
+
23
+ result += AjLisp::to_s(first)
24
+
25
+ rest = @rest
26
+
27
+ while rest
28
+ result += " "
29
+ first = rest.first
30
+ result += AjLisp::to_s(first)
31
+ rest = rest.rest
32
+ end
33
+
34
+ result += ")"
35
+
36
+ return result
37
+ end
38
+
39
+ def isEqualTo(list)
40
+ if not list.is_a? List
41
+ return false
42
+ end
43
+
44
+ if @first != list.first
45
+ if @first.is_a? List or @first.is_a? NamedAtom
46
+ if !@first.isEqualTo(list.first)
47
+ return false
48
+ end
49
+ else
50
+ return false
51
+ end
52
+ end
53
+
54
+ if @rest == nil and list.rest == nil
55
+ return true
56
+ end
57
+
58
+ if @rest.is_a? List
59
+ return @rest.isEqualTo(list.rest)
60
+ end
61
+
62
+ return false
63
+ end
64
+
65
+ def self.make(array)
66
+ if array and array.length > 0
67
+ first = array.shift
68
+
69
+ if first.is_a? Array
70
+ first = make(first)
71
+ elsif first.is_a? Symbol
72
+ first = NamedAtom.new first
73
+ end
74
+
75
+ if array.length == 0
76
+ return List.new first, nil
77
+ end
78
+
79
+ return List.new first, make(array)
80
+ end
81
+
82
+ return nil
83
+ end
84
+ end
85
+
86
+ class EmptyList < List
87
+ #private_class_method :new
88
+
89
+ @@instance = nil
90
+
91
+ def self.instance
92
+ @@instance = new unless @@instance
93
+ return @@instance
94
+ end
95
+
96
+ def to_s
97
+ return "()"
98
+ end
99
+
100
+ def isEqualTo(list)
101
+ return list.is_a? EmptyList
102
+ end
103
+ end
104
+
105
+
106
+ end