heist 0.3.2 → 0.3.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (76) hide show
  1. data/History.txt +12 -0
  2. data/{README.txt → README.rdoc} +131 -148
  3. data/bin/heist +35 -10
  4. data/lib/heist.rb +3 -3
  5. data/lib/heist/builtin/compiled_library.rb +1 -0
  6. data/lib/heist/builtin/lib/character.scm +74 -0
  7. data/lib/heist/builtin/lib/list.scm +149 -0
  8. data/lib/heist/builtin/lib/logic.scm +17 -0
  9. data/lib/heist/builtin/lib/numeric.scm +184 -0
  10. data/lib/heist/builtin/lib/string.scm +117 -0
  11. data/lib/heist/builtin/lib/util.scm +18 -0
  12. data/lib/heist/builtin/lib/vector.scm +27 -0
  13. data/lib/{builtin → heist/builtin}/primitives.rb +0 -0
  14. data/lib/{builtin → heist/builtin}/syntax.scm +52 -52
  15. data/lib/{parser → heist/parser}/nodes.rb +0 -0
  16. data/lib/{parser → heist/parser}/ruby.rb +0 -0
  17. data/lib/{parser → heist/parser}/scheme.rb +0 -0
  18. data/lib/{parser → heist/parser}/scheme.tt +0 -0
  19. data/lib/{repl.rb → heist/repl.rb} +0 -0
  20. data/lib/{runtime → heist/runtime}/binding.rb +5 -0
  21. data/lib/{runtime → heist/runtime}/callable/continuation.rb +6 -1
  22. data/lib/{runtime → heist/runtime}/callable/function.rb +0 -0
  23. data/lib/{runtime → heist/runtime}/callable/macro.rb +1 -1
  24. data/lib/{runtime → heist/runtime}/callable/macro/expansion.rb +0 -0
  25. data/lib/{runtime → heist/runtime}/callable/macro/matches.rb +0 -0
  26. data/lib/{runtime → heist/runtime}/callable/macro/tree.rb +0 -0
  27. data/lib/{runtime → heist/runtime}/callable/syntax.rb +0 -0
  28. data/lib/{runtime → heist/runtime}/data/character.rb +0 -0
  29. data/lib/{runtime → heist/runtime}/data/cons.rb +0 -0
  30. data/lib/{runtime → heist/runtime}/data/expression.rb +0 -0
  31. data/lib/{runtime → heist/runtime}/data/identifier.rb +0 -0
  32. data/lib/heist/runtime/data/value.rb +14 -0
  33. data/lib/{runtime → heist/runtime}/data/vector.rb +0 -0
  34. data/lib/{runtime → heist/runtime}/frame.rb +3 -0
  35. data/lib/{runtime → heist/runtime}/runtime.rb +2 -2
  36. data/lib/{runtime → heist/runtime}/scope.rb +0 -0
  37. data/lib/{runtime → heist/runtime}/stack.rb +0 -0
  38. data/lib/{runtime → heist/runtime}/stackless.rb +0 -0
  39. data/lib/{stdlib → heist/stdlib}/benchmark.scm +0 -0
  40. data/lib/{stdlib → heist/stdlib}/birdhouse.scm +0 -0
  41. data/lib/{trie.rb → heist/trie.rb} +0 -0
  42. data/spec/heist_spec.rb +88 -0
  43. data/{test → spec}/helpers/lib.scm +0 -0
  44. data/{test → spec}/helpers/macro-helpers.scm +0 -0
  45. data/{test → spec}/helpers/vars.scm +0 -0
  46. data/{test → spec}/plt-macros.txt +0 -0
  47. data/{test → spec}/scheme_tests/arithmetic.scm +0 -0
  48. data/{test → spec}/scheme_tests/benchmarks.scm +0 -0
  49. data/{test → spec}/scheme_tests/booleans.scm +0 -0
  50. data/{test → spec}/scheme_tests/closures.scm +0 -0
  51. data/{test → spec}/scheme_tests/conditionals.scm +0 -0
  52. data/{test → spec}/scheme_tests/continuations.scm +14 -1
  53. data/{test → spec}/scheme_tests/define_functions.scm +0 -0
  54. data/{test → spec}/scheme_tests/define_values.scm +0 -0
  55. data/{test → spec}/scheme_tests/delay.scm +0 -0
  56. data/{test → spec}/scheme_tests/equivalence.scm +0 -0
  57. data/{test → spec}/scheme_tests/file_loading.scm +0 -0
  58. data/{test → spec}/scheme_tests/functional.scm +3 -0
  59. data/{test → spec}/scheme_tests/hygienic.scm +0 -0
  60. data/{test → spec}/scheme_tests/let.scm +0 -0
  61. data/{test → spec}/scheme_tests/lists.scm +0 -0
  62. data/{test → spec}/scheme_tests/macros.scm +0 -0
  63. data/{test → spec}/scheme_tests/numbers.scm +0 -0
  64. data/{test → spec}/scheme_tests/protection.scm +0 -0
  65. data/spec/scheme_tests/quoting.scm +14 -0
  66. data/{test → spec}/scheme_tests/strings.scm +0 -0
  67. data/{test → spec}/scheme_tests/unhygienic.scm +0 -0
  68. data/{test → spec}/scheme_tests/vectors.scm +0 -0
  69. data/spec/spec_helper.rb +4 -0
  70. metadata +98 -113
  71. data/Manifest.txt +0 -64
  72. data/Rakefile +0 -43
  73. data/lib/bin_spec.rb +0 -25
  74. data/lib/builtin/library.rb +0 -1
  75. data/lib/builtin/library.scm +0 -605
  76. data/test/test_heist.rb +0 -148
@@ -0,0 +1,117 @@
1
+ ; (string char ...)
2
+ ; Returns a new string formed by combining the given characters
3
+ (define (string . chars) (list->string chars))
4
+
5
+ (define (string-compare string1 string2 char-less? char-greater?)
6
+ (if (or (not (string? string1))
7
+ (not (string? string2)))
8
+ (error "Expected two strings as arguments")
9
+ (do ((pair1 (string->list string1) (cdr pair1))
10
+ (pair2 (string->list string2) (cdr pair2))
11
+ (diff '()))
12
+ ((integer? diff) diff)
13
+ (set! diff (cond ((null? pair1) (if (null? pair2) 0 -1))
14
+ ((null? pair2) 1)
15
+ (else (let ((char1 (car pair1))
16
+ (char2 (car pair2)))
17
+ (cond ((char-less? char1 char2) -1)
18
+ ((char-greater? char1 char2) 1)
19
+ (else '())))))))))
20
+
21
+ ; (string=? string1 string2)
22
+ ; Returns true iff string1 and string2 are equal strings
23
+ (define (string=? string1 string2)
24
+ (zero? (string-compare string1 string2 char<? char>?)))
25
+
26
+ ; (string-ci=? string1 string2)
27
+ ; Returns true iff string1 and string2 are equal strings, ignoring case
28
+ (define (string-ci=? string1 string2)
29
+ (zero? (string-compare string1 string2 char-ci<? char-ci>?)))
30
+
31
+ ; (string<? string1 string2)
32
+ ; Returns true iff string1 is lexicographically less than string2
33
+ (define (string<? string1 string2)
34
+ (= (string-compare string1 string2 char<? char>?) -1))
35
+
36
+ ; (string>? string1 string2)
37
+ ; Returns true iff string1 is lexicographically greater than string2
38
+ (define (string>? string1 string2)
39
+ (= (string-compare string1 string2 char<? char>?) 1))
40
+
41
+ ; (string<=? string1 string2)
42
+ ; Returns true iff string1 is lexicographically less than or equal
43
+ ; to string2
44
+ (define (string<=? string1 string2)
45
+ (not (string>? string1 string2)))
46
+
47
+ ; (string>=? string1 string2)
48
+ ; Returns true iff string1 is lexicographically greater than or equal
49
+ ; to string2
50
+ (define (string>=? string1 string2)
51
+ (not (string<? string1 string2)))
52
+
53
+ ; (string-ci<? string1 string2)
54
+ ; Returns true iff string1 is lexicographically less than string2,
55
+ ; ignoring differences in case
56
+ (define (string-ci<? string1 string2)
57
+ (= (string-compare string1 string2 char-ci<? char-ci>?) -1))
58
+
59
+ ; (string-ci>? string1 string2)
60
+ ; Returns true iff string1 is lexicographically greater than string2,
61
+ ; ignoring differences in case
62
+ (define (string-ci>? string1 string2)
63
+ (= (string-compare string1 string2 char-ci<? char-ci>?) 1))
64
+
65
+ ; (string-ci<=? string1 string2)
66
+ ; Returns true iff string1 is lexicographically less than or equal
67
+ ; to string2, ignoring differences in case
68
+ (define (string-ci<=? string1 string2)
69
+ (not (string-ci>? string1 string2)))
70
+
71
+ ; (string-ci>=? string1 string2)
72
+ ; Returns true iff string1 is lexicographically greater than or equal
73
+ ; to string2, ignoring differences in case
74
+ (define (string-ci>=? string1 string2)
75
+ (not (string-ci<? string1 string2)))
76
+
77
+ ; (substring string start end)
78
+ ; Returns a string composed of the characters from start (inclusive)
79
+ ; to end (exclusive) in string
80
+ (define (substring string start end)
81
+ (list->string (sublist (string->list string) start end)))
82
+
83
+ ; (list->string chars)
84
+ ; Returns a new string formed by combining the list
85
+ (define (list->string chars)
86
+ (let* ((size (length chars))
87
+ (str (make-string size)))
88
+ (do ((list chars (cdr list))
89
+ (i 0 (+ i 1)))
90
+ ((= i size) str)
91
+ (string-set! str i (car list)))))
92
+
93
+ ; (string->list string)
94
+ ; Returns a newly allocated list of the characters in the string
95
+ (define (string->list string)
96
+ (let ((size (string-length string)))
97
+ (do ((i size (- i 1))
98
+ (list '() (cons (string-ref string (- i 1)) list)))
99
+ ((zero? i) list))))
100
+
101
+ ; (string-copy string)
102
+ ; Returns a newly allocated copy of the string
103
+ (define (string-copy string)
104
+ (list->string (string->list string)))
105
+
106
+ ; (string-fill! string char)
107
+ ; Replaces every character of string with char
108
+ (define (string-fill! string char)
109
+ (let ((size (string-length string)))
110
+ (do ((i size (- i 1)))
111
+ ((zero? i) string)
112
+ (string-set! string (- i 1) char))))
113
+
114
+ ; (string-append string ...)
115
+ ; Returns a new string formed by concatenating the arguments
116
+ (define (string-append . strings)
117
+ (list->string (apply append (map string->list strings))))
@@ -0,0 +1,18 @@
1
+ ; Any built-in functions that we can implement directly
2
+ ; in Scheme should go here. If at all possible, write
3
+ ; builtins in Scheme rather than Ruby.
4
+
5
+ (define quit exit)
6
+
7
+ ; (newline)
8
+ ; prints a new-line character
9
+ (define (newline)
10
+ (display "\n"))
11
+
12
+ ; (force)
13
+ ; Extracts the value of a promise created using (delay)
14
+ (define (force promise) (promise))
15
+
16
+ ; (call/cc)
17
+ ; Alias for (call-with-current-continuation)
18
+ (define call/cc call-with-current-continuation)
@@ -0,0 +1,27 @@
1
+ ; (vector object ...)
2
+ ; Returns a newly allocated vector from its arguments
3
+ (define (vector . args) (list->vector args))
4
+
5
+ ; (list->vector list)
6
+ ; Returns a newly allocated vector from a list
7
+ (define (list->vector list)
8
+ (let* ((size (length list))
9
+ (new-vector (make-vector size)))
10
+ (do ((i 0 (+ i 1))
11
+ (pair list (cdr pair)))
12
+ ((= i size) new-vector)
13
+ (vector-set! new-vector i (car pair)))))
14
+
15
+ ; (vector->list vector)
16
+ ; Returns a newly allocated proper list from a vector
17
+ (define (vector->list vector)
18
+ (do ((i (vector-length vector) (- i 1))
19
+ (pair '() (cons (vector-ref vector (- i 1)) pair)))
20
+ ((zero? i) pair)))
21
+
22
+ ; (vector-fill! vector fill)
23
+ ; Sets every element of vector to fill
24
+ (define (vector-fill! vector fill)
25
+ (do ((i (vector-length vector) (- i 1)))
26
+ ((zero? i) vector)
27
+ (vector-set! vector (- i 1) fill)))
@@ -5,18 +5,18 @@
5
5
  ; found, its consequent is tail-called and no further
6
6
  ; preconditions are evaluated.
7
7
  (define-syntax cond (syntax-rules (else =>)
8
- [(cond) #f]
9
- [(cond (else expr1 expr2 ...))
10
- (begin expr1 expr2 ...)]
11
- [(cond (test => function) clause ...)
12
- (let ([temp test])
8
+ ((cond) #f)
9
+ ((cond (else expr1 expr2 ...))
10
+ (begin expr1 expr2 ...))
11
+ ((cond (test => function) clause ...)
12
+ (let ((temp test))
13
13
  (if temp
14
14
  (function temp)
15
- (cond clause ...)))]
16
- [(cond (test expression ...) clause ...)
15
+ (cond clause ...))))
16
+ ((cond (test expression ...) clause ...)
17
17
  (if test
18
18
  (begin expression ...)
19
- (cond clause ...))]))
19
+ (cond clause ...)))))
20
20
 
21
21
  ; (case) acts like Ruby's case statement. The value of the
22
22
  ; given expression is compared against a series of lists;
@@ -24,17 +24,17 @@
24
24
  ; following the list are evaluated and no further lists
25
25
  ; are tested.
26
26
  (define-syntax case (syntax-rules (else)
27
- [(case key) #f]
28
- [(case key (else expr1 expr2 ...))
29
- (begin expr1 expr2 ...)]
30
- [(case key
27
+ ((case key) #f)
28
+ ((case key (else expr1 expr2 ...))
29
+ (begin expr1 expr2 ...))
30
+ ((case key
31
31
  ((cell ...) expr1 expr2 ...)
32
32
  clause ...)
33
- (let ([temp key])
33
+ (let ((temp key))
34
34
  (if (member temp '(cell ...))
35
35
  (begin expr1 expr2 ...)
36
36
  (case temp
37
- clause ...)))]))
37
+ clause ...))))))
38
38
 
39
39
  ;----------------------------------------------------------------
40
40
 
@@ -47,33 +47,33 @@
47
47
  ; (let) evaluates values in the enclosing scope, so lambdas will
48
48
  ; not be able to refer to other values assigned using the (let).
49
49
  (define-syntax let (syntax-rules ()
50
- [(let ([variable init] ...) body ...)
50
+ ((let ((variable init) ...) body ...)
51
51
  ((lambda (variable ...)
52
52
  body ...)
53
- init ...)]
54
- [(let name ([variable init] ...) body ...)
55
- (letrec ([name (lambda (variable ...)
56
- body ...)])
57
- (name init ...))]))
53
+ init ...))
54
+ ((let name ((variable init) ...) body ...)
55
+ (letrec ((name (lambda (variable ...)
56
+ body ...)))
57
+ (name init ...)))))
58
58
 
59
59
  ; (let*) creates a new scope for each variable and evaluates
60
60
  ; each expression in its enclosing scope. Basically a shorthand
61
61
  ; for several nested (let)s. Variables may refer to those that
62
62
  ; preceed them but not vice versa.
63
63
  (define-syntax let* (syntax-rules ()
64
- [(let* ([n1 e1] [n2 e2] [n3 e3] ...) body ...) ; 2 or more bindings
65
- (let ([n1 e1])
66
- (let* ([n2 e2] [n3 e3] ...) body ...))]
67
- [(let* ([name expression] ...) body ...) ; 0 or 1 binding
68
- (let ([name expression] ...) body ...)]))
64
+ ((let* ((n1 e1) (n2 e2) (n3 e3) ...) body ...) ; 2 or more bindings
65
+ (let ((n1 e1))
66
+ (let* ((n2 e2) (n3 e3) ...) body ...)))
67
+ ((let* ((name expression) ...) body ...) ; 0 or 1 binding
68
+ (let ((name expression) ...) body ...))))
69
69
 
70
70
  ; (letrec) evaluates values in the inner scope, so lambdas are
71
71
  ; able to refer to other values assigned using the (letrec).
72
72
  (define-syntax letrec (syntax-rules ()
73
- [(letrec ([variable init] ...) body ...)
73
+ ((letrec ((variable init) ...) body ...)
74
74
  ((lambda ()
75
75
  (define variable init) ...
76
- body ...))]))
76
+ body ...)))))
77
77
 
78
78
  (define let-syntax let)
79
79
  (define letrec-syntax letrec)
@@ -89,19 +89,19 @@
89
89
  ; loop is halted and the value of the expression following
90
90
  ; the test is returned.
91
91
  (define-syntax do (syntax-rules ()
92
- [(do ([variable init step ...] ...) ; Allow 0 or 1 step
92
+ ((do ((variable init step ...) ...) ; Allow 0 or 1 step
93
93
  (test expression ...)
94
94
  command ...)
95
- (let loop ([variable init] ...)
95
+ (let loop ((variable init) ...)
96
96
  (if test
97
97
  (begin expression ...)
98
98
  (begin
99
99
  command ...
100
- (loop (do "step" variable step ...) ...))))]
101
- [(do "step" variable)
102
- variable]
103
- [(do "step" variable step)
104
- step]))
100
+ (loop (do "step" variable step ...) ...)))))
101
+ ((do "step" variable)
102
+ variable)
103
+ ((do "step" variable step)
104
+ step)))
105
105
 
106
106
  ;----------------------------------------------------------------
107
107
 
@@ -111,23 +111,23 @@
111
111
  ; of expressions, or returns the value of the last expression
112
112
  ; if all values are truthy.
113
113
  (define-syntax and (syntax-rules ()
114
- [(and test) test]
115
- [(and test1 test2 ...)
116
- (let ([temp test1])
114
+ ((and test) test)
115
+ ((and test1 test2 ...)
116
+ (let ((temp test1))
117
117
  (if (not temp)
118
118
  temp
119
- (and test2 ...)))]))
119
+ (and test2 ...))))))
120
120
 
121
121
  ; (or) returns the first truthy value returned by the list
122
122
  ; of expressions, or returns the value of the last expression
123
123
  ; if all values are falsey.
124
124
  (define-syntax or (syntax-rules ()
125
- [(or test) test]
126
- [(or test1 test2 ...)
127
- (let ([temp test1])
125
+ ((or test) test)
126
+ ((or test1 test2 ...)
127
+ (let ((temp test1))
128
128
  (if temp
129
129
  temp
130
- (or test2 ...)))]))
130
+ (or test2 ...))))))
131
131
 
132
132
  ;----------------------------------------------------------------
133
133
 
@@ -139,16 +139,16 @@
139
139
  ; ever evaluated once, so a promise can be implemented as a
140
140
  ; memoized closure.
141
141
  (define-syntax delay (syntax-rules ()
142
- [(delay expression)
143
- (let ([forced #f]
144
- [memo #f])
142
+ ((delay expression)
143
+ (let ((forced #f)
144
+ (memo #f))
145
145
  (lambda ()
146
146
  (if forced
147
147
  memo
148
148
  (begin
149
149
  (set! memo expression)
150
150
  (set! forced #t)
151
- memo))))]))
151
+ memo)))))))
152
152
 
153
153
  ;----------------------------------------------------------------
154
154
 
@@ -159,10 +159,10 @@
159
159
  ; it will evaluate it and insert the result into the
160
160
  ; surrounding quoted list.
161
161
  (define-syntax quasiquote (syntax-rules (unquote unquote-splicing)
162
- [`,expr expr]
163
- [`(,@first . rest) (append first `rest)]
164
- [`(first . rest) (cons `first `rest)]
165
- [`#(,@first rest ...) (list->vector `(,@first rest ...))]
166
- [`#(expr ...) (list->vector `(expr ...))]
167
- [`expr 'expr]))
162
+ (`,expr expr)
163
+ (`(,@first . rest) (append first `rest))
164
+ (`(first . rest) (cons `first `rest))
165
+ (`#(,@first rest ...) (list->vector `(,@first rest ...)))
166
+ (`#(expr ...) (list->vector `(expr ...)))
167
+ (`expr 'expr)))
168
168
 
File without changes
File without changes
File without changes
File without changes
File without changes
@@ -52,6 +52,11 @@ module Heist
52
52
  def innermost_binding(identifier)
53
53
  @scope
54
54
  end
55
+
56
+ # Returns a Rubyish representation of the binding's expression.
57
+ def to_ruby
58
+ @expression.respond_to?(:to_ruby) ? @expression.to_ruby : @expression
59
+ end
55
60
 
56
61
  # Returns a string representation of the binding's +Expression+.
57
62
  def to_s
@@ -28,8 +28,13 @@ module Heist
28
28
  # replace it with the stack returned by this method before continuing
29
29
  # execution.
30
30
  def call(scope, cells)
31
+ apply(cells.to_a)
32
+ end
33
+
34
+ # TODO support call-with-values
35
+ def apply(params)
31
36
  stack = @stack.copy
32
- stack.fill!(@target, cells.car)
37
+ stack.fill!(@target, Value.new(params.first))
33
38
  stack
34
39
  end
35
40
 
@@ -62,7 +62,7 @@ module Heist
62
62
  rule, matches = *rule_for(cells, scope)
63
63
  return Expansion.new(@scope, scope, rule.cdr.car, matches) if rule
64
64
  raise SyntaxError.new(
65
- "Bad syntax: no macro expansion found for #{Cons.new(@name, cells)}")
65
+ "Bad syntax: no macro expansion found for #{Cons.new(Identifier.new(@name), cells)}")
66
66
  end
67
67
 
68
68
  # Returns a string placeholder for the +Macro+, containing its
@@ -0,0 +1,14 @@
1
+ module Heist
2
+ class Runtime
3
+
4
+ class Value
5
+ attr_reader :value
6
+
7
+ def initialize(value)
8
+ @value = value
9
+ end
10
+ end
11
+
12
+ end
13
+ end
14
+
@@ -95,6 +95,9 @@ module Heist
95
95
  # +value+. When a hole is filled, the <tt>@current</tt> pointer is moved
96
96
  # to the next subexpression that needs evaluating.
97
97
  def fill!(subexpr, value)
98
+ value = value.value if Value === value and @values and
99
+ not (Syntax === @values.car)
100
+
98
101
  epair, vpair = @expression, @values
99
102
  while Cons === epair and not epair.null?
100
103
  if epair.car.equal?(subexpr)