ajlisp 0.0.0

Sign up to get free protection for your applications and to get access to all the features.
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