heist 0.3.2 → 0.3.3

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 (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)