rubylisp 0.2.1 → 1.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (59) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +129 -2
  3. data/bin/rubylisp +87 -12
  4. data/lib/rubylisp/atom.rb +25 -6
  5. data/lib/rubylisp/boolean.rb +9 -6
  6. data/lib/rubylisp/builtins.rb +19 -18
  7. data/lib/rubylisp/character.rb +14 -275
  8. data/lib/rubylisp/class_object.rb +56 -0
  9. data/lib/rubylisp/cons_cell.rb +56 -25
  10. data/lib/rubylisp/debug.rb +15 -19
  11. data/lib/rubylisp/environment.rb +27 -0
  12. data/lib/rubylisp/environment_frame.rb +31 -6
  13. data/lib/rubylisp/eof_object.rb +26 -0
  14. data/lib/rubylisp/exception.rb +61 -61
  15. data/lib/rubylisp/ext.rb +32 -6
  16. data/lib/rubylisp/ffi_new.rb +2 -1
  17. data/lib/rubylisp/ffi_send.rb +15 -5
  18. data/lib/rubylisp/frame.rb +5 -164
  19. data/lib/rubylisp/function.rb +4 -3
  20. data/lib/rubylisp/macro.rb +13 -8
  21. data/lib/rubylisp/{object.rb → native_object.rb} +0 -15
  22. data/lib/rubylisp/number.rb +5 -0
  23. data/lib/rubylisp/parser.rb +81 -52
  24. data/lib/rubylisp/port.rb +27 -0
  25. data/lib/rubylisp/prim_alist.rb +115 -0
  26. data/lib/rubylisp/prim_assignment.rb +61 -0
  27. data/lib/rubylisp/prim_character.rb +273 -0
  28. data/lib/rubylisp/{ffi_class.rb → prim_class_object.rb} +16 -69
  29. data/lib/rubylisp/prim_environment.rb +203 -0
  30. data/lib/rubylisp/prim_equivalence.rb +93 -0
  31. data/lib/rubylisp/prim_frame.rb +166 -0
  32. data/lib/rubylisp/prim_io.rb +266 -0
  33. data/lib/rubylisp/prim_list_support.rb +496 -0
  34. data/lib/rubylisp/{logical.rb → prim_logical.rb} +9 -14
  35. data/lib/rubylisp/prim_math.rb +397 -0
  36. data/lib/rubylisp/prim_native_object.rb +21 -0
  37. data/lib/rubylisp/prim_relational.rb +42 -0
  38. data/lib/rubylisp/{special_forms.rb → prim_special_forms.rb} +98 -85
  39. data/lib/rubylisp/prim_string.rb +792 -0
  40. data/lib/rubylisp/prim_system.rb +55 -0
  41. data/lib/rubylisp/prim_type_checks.rb +58 -0
  42. data/lib/rubylisp/prim_vector.rb +497 -0
  43. data/lib/rubylisp/primitive.rb +51 -6
  44. data/lib/rubylisp/string.rb +4 -803
  45. data/lib/rubylisp/symbol.rb +0 -1
  46. data/lib/rubylisp/tokenizer.rb +161 -137
  47. data/lib/rubylisp/vector.rb +10 -31
  48. data/lib/rubylisp.rb +1 -0
  49. metadata +46 -17
  50. data/lib/rubylisp/alist.rb +0 -230
  51. data/lib/rubylisp/assignment.rb +0 -65
  52. data/lib/rubylisp/equivalence.rb +0 -118
  53. data/lib/rubylisp/io.rb +0 -74
  54. data/lib/rubylisp/list_support.rb +0 -526
  55. data/lib/rubylisp/math.rb +0 -405
  56. data/lib/rubylisp/relational.rb +0 -46
  57. data/lib/rubylisp/system.rb +0 -20
  58. data/lib/rubylisp/testing.rb +0 -136
  59. data/lib/rubylisp/type_checks.rb +0 -60
@@ -3,41 +3,86 @@ module Lisp
3
3
  class Primitive < Atom
4
4
 
5
5
  attr_reader :doc, :name
6
+
6
7
 
7
- def self.register(name, doc="", special=false, env=Lisp::EnvironmentFrame.global, &implementation)
8
- instance = self.new(name, doc, special, &implementation)
8
+ def self.register(name, arity, doc="", special=false, env=Lisp::EnvironmentFrame.global, &implementation)
9
+ instance = self.new(name, arity, doc, special, &implementation)
9
10
  env.bind(Symbol.named(name), instance)
10
11
  end
11
12
 
12
- def initialize(name, doc, special, &implementation)
13
+
14
+ def initialize(name, arity, doc, special, &implementation)
13
15
  @name = name
16
+ @arity = arity
14
17
  @doc = doc
15
18
  @special = special
16
19
  @implementation = implementation
17
20
  end
18
21
 
22
+
23
+ def check_arity(args)
24
+ return true if @arity == "*"
25
+
26
+ number_of_args = args.length
27
+
28
+ @arity.split("|").map do |term|
29
+ m = /^(\d+)$/.match(term)
30
+ return true if m && number_of_args == m[1].to_i
31
+
32
+ m = /^>=(\d+)$/.match(term)
33
+ return true if m && number_of_args >= m[1].to_i
34
+
35
+ m = /^\((\d+),(\d+)\)$/.match(term)
36
+ return true if m && number_of_args >= m[1].to_i && number_of_args <= m[2].to_i
37
+ end
38
+
39
+ false
40
+ end
41
+
42
+
19
43
  def apply_to(args, env)
20
- @implementation.call(args, env)
44
+ return Lisp::Debug.process_error("Wrong number of arguments to #{@name}. Expected #{@arity} but got #{args.length}.", env) unless check_arity(args)
45
+
46
+ cooked_args = if @special
47
+ args
48
+ else
49
+ Lisp::ConsCell.array_to_list(args.to_a.map {|i| i.evaluate(env)})
50
+ end
51
+ @implementation.call(cooked_args, env)
21
52
  end
22
53
 
54
+
23
55
  def apply_to_without_evaluating(args, env)
56
+ return Lisp::Debug.process_error("Wrong number of arguments to #{@name}. Expected #{@arity} but got #{args.length}.", env) unless check_arity(args)
24
57
  @implementation.call(args, env)
25
58
  end
26
59
 
60
+
27
61
  def to_s
28
- "<prim: #{@name}>"
62
+ if @special
63
+ "<specialform: #{@name}>"
64
+ else
65
+ "<primitive: #{@name}>"
66
+ end
29
67
  end
30
68
 
69
+
31
70
  def primitive?
32
71
  true
33
72
  end
73
+
34
74
 
35
75
  def special?
36
76
  @special
37
77
  end
38
78
 
79
+
39
80
  def type
40
- :primitive
81
+ if @special
82
+ :specialform
83
+ else
84
+ :primitive
85
+ end
41
86
  end
42
87
 
43
88
  end