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,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