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
@@ -1,64 +0,0 @@
1
- History.txt
2
- Manifest.txt
3
- Rakefile
4
- README.txt
5
- bin/heist
6
- lib/bin_spec.rb
7
- lib/heist.rb
8
- lib/repl.rb
9
- lib/trie.rb
10
- lib/builtin/library.scm
11
- lib/builtin/library.rb
12
- lib/builtin/primitives.rb
13
- lib/builtin/syntax.scm
14
- lib/parser/nodes.rb
15
- lib/parser/ruby.rb
16
- lib/parser/scheme.rb
17
- lib/parser/scheme.tt
18
- lib/runtime/callable/continuation.rb
19
- lib/runtime/callable/function.rb
20
- lib/runtime/callable/syntax.rb
21
- lib/runtime/callable/macro.rb
22
- lib/runtime/callable/macro/matches.rb
23
- lib/runtime/callable/macro/tree.rb
24
- lib/runtime/callable/macro/expansion.rb
25
- lib/runtime/data/character.rb
26
- lib/runtime/data/cons.rb
27
- lib/runtime/data/expression.rb
28
- lib/runtime/data/identifier.rb
29
- lib/runtime/data/vector.rb
30
- lib/runtime/binding.rb
31
- lib/runtime/frame.rb
32
- lib/runtime/runtime.rb
33
- lib/runtime/scope.rb
34
- lib/runtime/stack.rb
35
- lib/runtime/stackless.rb
36
- lib/stdlib/benchmark.scm
37
- lib/stdlib/birdhouse.scm
38
- test/helpers/lib.scm
39
- test/helpers/macro-helpers.scm
40
- test/helpers/vars.scm
41
- test/scheme_tests/arithmetic.scm
42
- test/scheme_tests/benchmarks.scm
43
- test/scheme_tests/booleans.scm
44
- test/scheme_tests/closures.scm
45
- test/scheme_tests/conditionals.scm
46
- test/scheme_tests/continuations.scm
47
- test/scheme_tests/define_functions.scm
48
- test/scheme_tests/define_values.scm
49
- test/scheme_tests/delay.scm
50
- test/scheme_tests/equivalence.scm
51
- test/scheme_tests/file_loading.scm
52
- test/scheme_tests/functional.scm
53
- test/scheme_tests/hygienic.scm
54
- test/scheme_tests/let.scm
55
- test/scheme_tests/lists.scm
56
- test/scheme_tests/macros.scm
57
- test/scheme_tests/numbers.scm
58
- test/scheme_tests/protection.scm
59
- test/scheme_tests/strings.scm
60
- test/scheme_tests/unhygienic.scm
61
- test/scheme_tests/vectors.scm
62
- test/plt-macros.txt
63
- test/test_heist.rb
64
-
data/Rakefile DELETED
@@ -1,43 +0,0 @@
1
- # -*- ruby -*-
2
-
3
- require 'rubygems'
4
- require 'hoe'
5
- require './lib/heist.rb'
6
-
7
- Hoe.spec('heist') do |p|
8
- p.developer('James Coglan', 'jcoglan@googlemail.com')
9
- p.extra_deps = %w(oyster treetop)
10
- end
11
-
12
- file "lib/builtin/library.rb" => "lib/builtin/library.scm" do |t|
13
- program = Heist.parse(File.read t.prerequisites.first).convert!
14
- File.open(t.name, 'w') { |f| f.write 'program ' + program.to_ruby.inspect }
15
- end
16
-
17
- task :compile => "lib/builtin/library.rb"
18
-
19
- namespace :spec do
20
- task :r5rs do
21
- procedures = Dir['r5rs/*.html'].
22
- map { |f| File.read(f) }.
23
- join("\n").
24
- split(/\n+/).
25
- grep(/(syntax|procedure)\:/).
26
- map { |s| s.gsub(/<\/?[^>]+>/, '').
27
- scan(/\(([^\) ]+)/).
28
- flatten.
29
- first }.
30
- uniq.
31
- compact.
32
- map { |s| s.gsub('&lt;', '<').
33
- gsub('&gt;', '>') }
34
-
35
- scope = Heist::Runtime.new.top_level
36
- procedures.each do |proc|
37
- message = scope.defined?(proc) ? scope.exec(proc) : 'MISSING'
38
- puts " %-32s %-48s" % [proc, message]
39
- end
40
- end
41
- end
42
-
43
- # vim: syntax=Ruby
@@ -1,25 +0,0 @@
1
- require 'rubygems'
2
- require 'oyster'
3
-
4
- Heist::BIN_SPEC = Oyster.spec do
5
- name "heist -- Ruby-powered Scheme interpreter, v. #{Heist::VERSION}"
6
- author 'James Coglan <jcoglan@googlemail.com>'
7
-
8
- synopsis <<-EOS
9
- heist -i [OPTIONS]
10
- heist FILE_NAME [OPTIONS]
11
- EOS
12
-
13
- flag :interactive, :desc =>
14
- 'Start an interactive Scheme session'
15
-
16
- flag :lazy, :default => false, :desc =>
17
- 'Use lazy evaluation order'
18
-
19
- flag :continuations, :default => false, :desc =>
20
- 'Enable first-class continuations and (call/cc)'
21
-
22
- flag :unhygienic, :default => false, :desc =>
23
- 'Use Common Lisp-style unhygienic macros'
24
- end
25
-
@@ -1 +0,0 @@
1
- program [[:define, :quit, :exit], [:define, [:newline], [:display, "\n"]], [:define, [:force, :promise], [:promise]], [:define, :"call/cc", :"call-with-current-continuation"], [:define, :eq?, :eqv?], [:define, [:not, :x], [:if, :x, false, true]], [:define, :true, true], [:define, :false, false], [:define, [:boolean?, :x], [:or, [:eqv?, :x, true], [:eqv?, :x, false]]], [:define, :number?, :complex?], [:define, [:exact?, :x], [:or, [:rational?, :x], [:and, [:not, [:zero?, [:"imag-part", :x]]], [:exact?, [:"real-part", :x]], [:exact?, [:"imag-part", :x]]]]], [:define, [:inexact?, :x], [:not, [:exact?, :x]]], [:define, [:"=", :".", :args], [:define, [:iter, :x, :rest], [:if, [:null?, :rest], true, [:let, [[:y, [:car, :rest]]], [:if, [:or, [:not, [:number?, :x]], [:not, [:number?, :y]], [:not, [:equal?, :x, :y]]], false, [:iter, :x, [:cdr, :rest]]]]]], [:iter, [:car, :args], [:cdr, :args]]], [:define, [:zero?, :x], [:eqv?, :x, 0]], [:define, [:positive?, :x], [:>, :x, 0]], [:define, [:negative?, :x], [:<, :x, 0]], [:define, [:odd?, :x], [:"=", 1, [:remainder, :x, 2]]], [:define, [:even?, :x], [:zero?, [:remainder, :x, 2]]], [:define, [:max, :".", :values], [:foldr, [:lambda, [:a, :b], [:if, [:>=, :a, :b], :a, :b]], [:car, :values], [:cdr, :values]]], [:define, [:min, :".", :values], [:foldr, [:lambda, [:a, :b], [:if, [:<=, :a, :b], :a, :b]], [:car, :values], [:cdr, :values]]], [:define, [:abs, :x], [:if, [:negative?, :x], [:-, :x], :x]], [:define, [:quotient, :x, :y], [:let, [[:result, [:/, :x, :y]]], [[:if, [:positive?, :result], :floor, :ceiling], :result]]], [:define, [:remainder, :x, :y], [:-, [:round, :x], [:*, [:round, :y], [:quotient, :x, :y]]]], [:define, [:modulo, :x, :y], [:+, [:remainder, :x, :y], [:if, [:negative?, [:*, :x, :y]], [:round, :y], 0]]], [:define, [:gcd, :x, :y, :".", :rest], [:if, [:null?, :rest], [:if, [:zero?, :y], [:abs, :x], [:gcd, :y, [:remainder, :x, :y]]], [:apply, :gcd, [:cons, [:gcd, :x, :y], :rest]]]], [:define, [:lcm, :x, :y, :".", :rest], [:if, [:null?, :rest], [:/, [:abs, [:*, :x, :y]], [:gcd, :x, :y]], [:apply, :lcm, [:cons, [:lcm, :x, :y], :rest]]]], [:define, :ceiling, :ceil], [:define, [:rationalize, :x, :tolerance], [:cond, [[:rational?, :x], :x], [[:not, [:zero?, [:"imag-part", :x]]], [:"make-rectangular", [:rationalize, [:"real-part", :x], :tolerance], [:rationalize, [:"imag-part", :x], :tolerance]]], [:else, [:"let*", [[:t, [:abs, :tolerance]], [:a, [:-, :x, :t]], [:b, [:+, :x, :t]]], [:do, [[:i, 1, [:+, :i, 1]], [:z, false]], [[:number?, :z], :z], [:let, [[:p, [:ceiling, [:*, :a, :i]]], [:q, [:floor, [:*, :b, :i]]]], [:if, [:<=, :p, :q], [:set!, :z, [:/, [:if, [:positive?, :p], :p, :q], :i]]]]]]]]], [:define, [:"make-polar", :magnitude, :angle], [:let, [[:re, [:*, :magnitude, [:cos, :angle]]], [:im, [:*, :magnitude, [:sin, :angle]]]], [:"make-rectangular", :re, :im]]], [:define, [:magnitude, :z], [:let, [[:re, [:"real-part", :z]], [:im, [:"imag-part", :z]]], [:sqrt, [:+, [:*, :re, :re], [:*, :im, :im]]]]], [:define, [:angle, :z], [:let, [[:re, [:"real-part", :z]], [:im, [:"imag-part", :z]]], [:atan, :im, :re]]], [:define, [:factorial, :x], [:define, [:iter, :y, :acc], [:if, [:zero?, :y], :acc, [:iter, [:-, :y, 1], [:*, :y, :acc]]]], [:iter, :x, 1]], [:define, [:null?, :object], [:eqv?, [:quote, []], :object]], [:define, [:list?, :object], [:or, [:null?, :object], [:and, [:pair?, :object], [:list?, [:cdr, :object]]]]], [:define, [:list, :".", :args], :args], [:define, [:length, :object], [:define, [:iter, :list, :acc], [:if, [:null?, :list], :acc, [:iter, [:cdr, :list], [:+, 1, :acc]]]], [:iter, :object, 0]], [:define, [:append, :first, :".", :rest], [:cond, [[:null?, :rest], :first], [[:null?, :first], [:apply, :append, :rest]], [:else, [:cons, [:car, :first], [:append, [:cdr, :first], [:apply, :append, :rest]]]]]], [:define, [:reverse, :object], [:if, [:null?, :object], :object, [:append, [:reverse, [:cdr, :object]], [:list, [:car, :object]]]]], [:define, [:"list-tail", :list, :k], [:do, [[:pair, :list, [:cdr, :pair]], [:i, :k, [:-, :i, 1]]], [[:zero?, :i], :pair]]], [:define, [:"list-ref", :list, :k], [:car, [:"list-tail", :list, :k]]], [:define, [:"list-transform-search", :transform], [:lambda, [:predicate], [:lambda, [:object, :list], [:do, [[:pair, :list, [:cdr, :pair]]], [[:or, [:null?, :pair], [:predicate, [:car, [:transform, :pair]], :object]], [:if, [:null?, :pair], false, [:transform, :pair]]]]]]], [:define, :"list-search", [:"list-transform-search", [:lambda, [:x], :x]]], [:define, :memq, [:"list-search", :eq?]], [:define, :memv, [:"list-search", :eqv?]], [:define, :member, [:"list-search", :equal?]], [:define, :"assoc-list-search", [:"list-transform-search", :car]], [:define, :assq, [:"assoc-list-search", :eq?]], [:define, :assv, [:"assoc-list-search", :eqv?]], [:define, :assoc, [:"assoc-list-search", :equal?]], [:define, [:map, :proc, :list1, :".", :list2], [:if, [:null?, :list1], :list1, [:if, [:null?, :list2], [:cons, [:proc, [:car, :list1]], [:map, :proc, [:cdr, :list1]]], [:"let*", [[:all, [:cons, :list1, :list2]], [:args, [:map, :car, :all]], [:rest, [:map, :cdr, :all]]], [:cons, [:apply, :proc, :args], [:apply, :map, [:cons, :proc, :rest]]]]]]], [:define, [:"for-each", :proc, :list1, :".", :list2], [:do, [[:pair, :list1, [:cdr, :pair]], [:others, :list2, [:map, :cdr, :others]]], [[:null?, :pair], [:quote, []]], [:apply, :proc, [:cons, [:car, :pair], [:map, :car, :others]]]]], [:define, [:foldr, :proc, :value, :list], [:if, [:null?, :list], :value, [:proc, [:car, :list], [:foldr, :proc, :value, [:cdr, :list]]]]], [:define, [:sublist, :list, :start, :end], [:cond, [[:null?, :list], [:quote, []]], [[:>, :start, 0], [:sublist, [:cdr, :list], [:-, :start, 1], [:-, :end, 1]]], [[:<=, :end, 0], [:quote, []]], [:else, [:cons, [:car, :list], [:sublist, [:cdr, :list], 0, [:-, :end, 1]]]]]], [:define, [:char, :string], [:if, [:and, [:string?, :string], [:"=", [:"string-length", :string], 1]], [:"string-ref", :string, 0], [:quote, []]]], [:define, [:"char-upper-case?", :letter], [:and, [:char?, :letter], [:let, [[:code, [:"char->integer", :letter]]], [:and, [:>=, :code, 65], [:<=, :code, 90]]]]], [:define, [:"char-lower-case?", :letter], [:and, [:char?, :letter], [:let, [[:code, [:"char->integer", :letter]]], [:and, [:>=, :code, 97], [:<=, :code, 122]]]]], [:define, [:"char-alphabetic?", :char], [:or, [:"char-upper-case?", :char], [:"char-lower-case?", :char]]], [:define, [:"char-numeric?", :char], [:and, [:char?, :char], [:let, [[:code, [:"char->integer", :char]]], [:and, [:>=, :code, 48], [:<=, :code, 57]]]]], [:define, [:"char-whitespace?", :char], [:and, [:char?, :char], [:if, [:member, [:"char->integer", :char], [:quote, [9, 10, 32]]], true, false]]], [:define, [:"char-upcase", :char], [:let, [[:code, [:"char->integer", :char]]], [:if, [:and, [:>=, :code, 97], [:<=, :code, 122]], [:"integer->char", [:-, :code, 32]], [:"integer->char", :code]]]], [:define, [:"char-downcase", :char], [:let, [[:code, [:"char->integer", :char]]], [:if, [:and, [:>=, :code, 65], [:<=, :code, 90]], [:"integer->char", [:+, :code, 32]], [:"integer->char", :code]]]], [:define, [:"char-compare-ci", :operator], [:lambda, [:x, :y], [:operator, [:"char-downcase", :x], [:"char-downcase", :y]]]], [:define, :"char-ci=?", [:"char-compare-ci", :"char=?"]], [:define, :"char-ci<?", [:"char-compare-ci", :"char<?"]], [:define, :"char-ci>?", [:"char-compare-ci", :"char>?"]], [:define, :"char-ci<=?", [:"char-compare-ci", :"char<=?"]], [:define, :"char-ci>=?", [:"char-compare-ci", :"char>=?"]], [:define, [:string, :".", :chars], [:"list->string", :chars]], [:define, [:"string-compare", :string1, :string2, :"char-less?", :"char-greater?"], [:if, [:or, [:not, [:string?, :string1]], [:not, [:string?, :string2]]], [:error, "Expected two strings as arguments"], [:do, [[:pair1, [:"string->list", :string1], [:cdr, :pair1]], [:pair2, [:"string->list", :string2], [:cdr, :pair2]], [:diff, [:quote, []]]], [[:integer?, :diff], :diff], [:set!, :diff, [:cond, [[:null?, :pair1], [:if, [:null?, :pair2], 0, -1]], [[:null?, :pair2], 1], [:else, [:let, [[:char1, [:car, :pair1]], [:char2, [:car, :pair2]]], [:cond, [[:"char-less?", :char1, :char2], -1], [[:"char-greater?", :char1, :char2], 1], [:else, [:quote, []]]]]]]]]]], [:define, [:"string=?", :string1, :string2], [:zero?, [:"string-compare", :string1, :string2, :"char<?", :"char>?"]]], [:define, [:"string-ci=?", :string1, :string2], [:zero?, [:"string-compare", :string1, :string2, :"char-ci<?", :"char-ci>?"]]], [:define, [:"string<?", :string1, :string2], [:"=", [:"string-compare", :string1, :string2, :"char<?", :"char>?"], -1]], [:define, [:"string>?", :string1, :string2], [:"=", [:"string-compare", :string1, :string2, :"char<?", :"char>?"], 1]], [:define, [:"string<=?", :string1, :string2], [:not, [:"string>?", :string1, :string2]]], [:define, [:"string>=?", :string1, :string2], [:not, [:"string<?", :string1, :string2]]], [:define, [:"string-ci<?", :string1, :string2], [:"=", [:"string-compare", :string1, :string2, :"char-ci<?", :"char-ci>?"], -1]], [:define, [:"string-ci>?", :string1, :string2], [:"=", [:"string-compare", :string1, :string2, :"char-ci<?", :"char-ci>?"], 1]], [:define, [:"string-ci<=?", :string1, :string2], [:not, [:"string-ci>?", :string1, :string2]]], [:define, [:"string-ci>=?", :string1, :string2], [:not, [:"string-ci<?", :string1, :string2]]], [:define, [:substring, :string, :start, :end], [:"list->string", [:sublist, [:"string->list", :string], :start, :end]]], [:define, [:"list->string", :chars], [:"let*", [[:size, [:length, :chars]], [:str, [:"make-string", :size]]], [:do, [[:list, :chars, [:cdr, :list]], [:i, 0, [:+, :i, 1]]], [[:"=", :i, :size], :str], [:"string-set!", :str, :i, [:car, :list]]]]], [:define, [:"string->list", :string], [:let, [[:size, [:"string-length", :string]]], [:do, [[:i, :size, [:-, :i, 1]], [:list, [:quote, []], [:cons, [:"string-ref", :string, [:-, :i, 1]], :list]]], [[:zero?, :i], :list]]]], [:define, [:"string-copy", :string], [:"list->string", [:"string->list", :string]]], [:define, [:"string-fill!", :string, :char], [:let, [[:size, [:"string-length", :string]]], [:do, [[:i, :size, [:-, :i, 1]]], [[:zero?, :i], :string], [:"string-set!", :string, [:-, :i, 1], :char]]]], [:define, [:"string-append", :".", :strings], [:"list->string", [:apply, :append, [:map, :"string->list", :strings]]]], [:define, [:vector, :".", :args], [:"list->vector", :args]], [:define, [:"list->vector", :list], [:"let*", [[:size, [:length, :list]], [:"new-vector", [:"make-vector", :size]]], [:do, [[:i, 0, [:+, :i, 1]], [:pair, :list, [:cdr, :pair]]], [[:"=", :i, :size], :"new-vector"], [:"vector-set!", :"new-vector", :i, [:car, :pair]]]]], [:define, [:"vector->list", :vector], [:do, [[:i, [:"vector-length", :vector], [:-, :i, 1]], [:pair, [:quote, []], [:cons, [:"vector-ref", :vector, [:-, :i, 1]], :pair]]], [[:zero?, :i], :pair]]], [:define, [:"vector-fill!", :vector, :fill], [:do, [[:i, [:"vector-length", :vector], [:-, :i, 1]]], [[:zero?, :i], :vector], [:"vector-set!", :vector, [:-, :i, 1], :fill]]]]
@@ -1,605 +0,0 @@
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)
19
-
20
- ; (eq? x y)
21
- ; Currently an alias for (eqv? x y). TODO implement properly
22
- (define eq? eqv?)
23
-
24
- ; (not x)
25
- ; Boolean inverse of x
26
- (define (not x)
27
- (if x #f #t))
28
-
29
- ; Longhand aliases for boolean constants
30
- (define true #t)
31
- (define false #f)
32
-
33
- ; (boolean? x)
34
- ; Returns true iff x is a boolean value
35
- (define (boolean? x)
36
- (or (eqv? x #t) (eqv? x #f)))
37
-
38
- ;----------------------------------------------------------------
39
-
40
- ; Numerical functions
41
-
42
- ; (number? x)
43
- ; Returns true iff x is any type of number
44
- (define number? complex?)
45
-
46
- ; (exact? x)
47
- ; Returns true iff the given number is exact i.e. an integer, a
48
- ; rational, or a complex made of integers or rationals
49
- (define (exact? x)
50
- (or (rational? x)
51
- (and (not (zero? (imag-part x)))
52
- (exact? (real-part x))
53
- (exact? (imag-part x)))))
54
-
55
- ; (inexact? x)
56
- ; Returns true iff x is not an exact number
57
- (define (inexact? x)
58
- (not (exact? x)))
59
-
60
- ; Returns true iff all arguments are numerically equal
61
- (define (= . args)
62
- (define (iter x rest)
63
- (if (null? rest)
64
- #t
65
- (let ([y (car rest)])
66
- (if (or (not (number? x))
67
- (not (number? y))
68
- (not (equal? x y)))
69
- #f
70
- (iter x (cdr rest))))))
71
- (iter (car args) (cdr args)))
72
-
73
- ; (zero? x)
74
- ; Returns true iff x is zero
75
- (define (zero? x)
76
- (eqv? x 0))
77
-
78
- ; (positive? x)
79
- ; Returns true iff x > 0
80
- (define (positive? x)
81
- (> x 0))
82
-
83
- ; (negative? x)
84
- ; Returns true iff x < 0
85
- (define (negative? x)
86
- (< x 0))
87
-
88
- ; (odd? x)
89
- ; Returns true iff x is odd
90
- (define (odd? x)
91
- (= 1 (remainder x 2)))
92
-
93
- ; (even? x)
94
- ; Returns true iff x is even
95
- (define (even? x)
96
- (zero? (remainder x 2)))
97
-
98
- ; (max arg1 arg2 ...)
99
- ; Returns the maximum value in the list of arguments
100
- (define (max . values)
101
- (foldr (lambda (a b) (if (>= a b) a b))
102
- (car values)
103
- (cdr values)))
104
-
105
- ; (min arg1 arg2 ...)
106
- ; Returns the minimum value in the list of arguments
107
- (define (min . values)
108
- (foldr (lambda (a b) (if (<= a b) a b))
109
- (car values)
110
- (cdr values)))
111
-
112
- ; (abs x)
113
- ; Returns the absolute value of a number
114
- (define (abs x)
115
- (if (negative? x)
116
- (- x)
117
- x))
118
-
119
- ; (quotient) and (remainder) satisfy
120
- ;
121
- ; (= n1 (+ (* n2 (quotient n1 n2))
122
- ; (remainder n1 n2)))
123
-
124
- ; (quotient x y)
125
- ; Returns the quotient of two numbers, i.e. performs n1/n2
126
- ; and rounds toward zero.
127
- (define (quotient x y)
128
- (let ([result (/ x y)])
129
- ((if (positive? result)
130
- floor
131
- ceiling)
132
- result)))
133
-
134
- ; (remainder x y)
135
- ; Returns the remainder after dividing the first operand
136
- ; by the second
137
- (define (remainder x y)
138
- (- (round x)
139
- (* (round y)
140
- (quotient x y))))
141
-
142
- ; (modulo x y)
143
- ; Returns the first operand modulo the second
144
- (define (modulo x y)
145
- (+ (remainder x y)
146
- (if (negative? (* x y))
147
- (round y)
148
- 0)))
149
-
150
- ; (gcd x y)
151
- ; Returns the greatest common divisor of two numbers
152
- ; http://en.wikipedia.org/wiki/Euclidean_algorithm
153
- (define (gcd x y . rest)
154
- (if (null? rest)
155
- (if (zero? y)
156
- (abs x)
157
- (gcd y (remainder x y)))
158
- (apply gcd (cons (gcd x y) rest))))
159
-
160
- ; (lcm x y)
161
- ; Returns the lowest common multiple of two numbers
162
- ; http://en.wikipedia.org/wiki/Least_common_multiple
163
- (define (lcm x y . rest)
164
- (if (null? rest)
165
- (/ (abs (* x y))
166
- (gcd x y))
167
- (apply lcm (cons (lcm x y) rest))))
168
-
169
- (define ceiling ceil)
170
-
171
- ; (rationalize x tolerance)
172
- ; Returns the simplest rational number that differs from x by
173
- ; no more than tolerance. Here 'simplest' means the smallest
174
- ; possible denominator is found first, and with that set the
175
- ; smallest corresponding numerator is chosen.
176
- (define (rationalize x tolerance)
177
- (cond [(rational? x)
178
- x]
179
- [(not (zero? (imag-part x)))
180
- (make-rectangular (rationalize (real-part x) tolerance)
181
- (rationalize (imag-part x) tolerance))]
182
- [else
183
- (let* ([t (abs tolerance)]
184
- [a (- x t)]
185
- [b (+ x t)])
186
- (do ([i 1 (+ i 1)]
187
- [z #f])
188
- ((number? z) z)
189
- (let ([p (ceiling (* a i))]
190
- [q (floor (* b i))])
191
- (if (<= p q)
192
- (set! z (/ (if (positive? p) p q)
193
- i))))))]))
194
-
195
- ; (make-polar magnitude angle)
196
- ; Returns a new complex number with the given
197
- ; magnitude and angle
198
- (define (make-polar magnitude angle)
199
- (let ([re (* magnitude (cos angle))]
200
- [im (* magnitude (sin angle))])
201
- (make-rectangular re im)))
202
-
203
- ; (magnitude z)
204
- ; Returns the magnitude of a complex number
205
- (define (magnitude z)
206
- (let ([re (real-part z)]
207
- [im (imag-part z)])
208
- (sqrt (+ (* re re) (* im im)))))
209
-
210
- ; (angle z)
211
- ; Returns the angle a complex number makes with the
212
- ; real axis when plotted in the complex plane
213
- (define (angle z)
214
- (let ([re (real-part z)]
215
- [im (imag-part z)])
216
- (atan im re)))
217
-
218
- ; (factorial x)
219
- ; Returns factorial of x
220
- (define (factorial x)
221
- (define (iter y acc)
222
- (if (zero? y)
223
- acc
224
- (iter (- y 1) (* y acc))))
225
- (iter x 1))
226
-
227
- ;----------------------------------------------------------------
228
-
229
- ; List/pair functions
230
-
231
- ; (null? object)
232
- ; Returns true iff object is the empty list
233
- (define (null? object)
234
- (eqv? '() object))
235
-
236
- ; (list? object)
237
- ; Returns true iff object is a proper list
238
- (define (list? object)
239
- (or (null? object)
240
- (and (pair? object)
241
- (list? (cdr object)))))
242
-
243
- ; (list arg ...)
244
- ; Allocates and returns a new list from its arguments
245
- (define (list . args) args)
246
-
247
- ; (length object)
248
- ; Returns the length of a proper list
249
- (define (length object)
250
- (define (iter list acc)
251
- (if (null? list)
252
- acc
253
- (iter (cdr list) (+ 1 acc))))
254
- (iter object 0))
255
-
256
- ; (append list ...)
257
- ; Returns a new list formed by concatenating the arguments.
258
- ; The final argument is not copied and the return value of
259
- ; (append) shares structure with it.
260
- (define (append first . rest)
261
- (cond [(null? rest) first]
262
- [(null? first) (apply append rest)]
263
- [else
264
- (cons (car first)
265
- (append (cdr first)
266
- (apply append rest)))]))
267
-
268
- ; (reverse list)
269
- ; Returns a newly allocated list consisting of the
270
- ; elements of list in reverse order.
271
- (define (reverse object)
272
- (if (null? object)
273
- object
274
- (append (reverse (cdr object))
275
- (list (car object)))))
276
-
277
- ; (list-tail list k)
278
- ; Returns the sublist of list obtained by omitting the
279
- ; first k elements.
280
- (define (list-tail list k)
281
- (do ([pair list (cdr pair)]
282
- [i k (- i 1)])
283
- ((zero? i) pair)))
284
-
285
- ; (list-ref list k)
286
- ; Returns the kth element of list.
287
- (define (list-ref list k)
288
- (car (list-tail list k)))
289
-
290
- ; (memq obj list)
291
- ; (memv obj list)
292
- ; (member obj list)
293
- ; These procedures return the first sublist of list whose
294
- ; car is obj, where the sublists of list are the non-empty
295
- ; lists returned by (list-tail list k) for k less than the
296
- ; length of list. If obj does not occur in list, then #f
297
- ; (not the empty list) is returned. Memq uses eq? to compare
298
- ; obj with the elements of list, while memv uses eqv? and
299
- ; member uses equal?.
300
-
301
- (define (list-transform-search transform)
302
- (lambda (predicate)
303
- (lambda (object list)
304
- (do ([pair list (cdr pair)])
305
- ((or (null? pair)
306
- (predicate (car (transform pair)) object))
307
- (if (null? pair)
308
- #f
309
- (transform pair)))))))
310
-
311
- (define list-search (list-transform-search (lambda (x) x)))
312
- (define memq (list-search eq?))
313
- (define memv (list-search eqv?))
314
- (define member (list-search equal?))
315
-
316
- ; (assq obj alist)
317
- ; (assv obj alist)
318
- ; (assoc obj alist)
319
- ; Alist (for "association list") must be a list of pairs.
320
- ; These procedures find the first pair in alist whose car
321
- ; field is obj, and returns that pair. If no pair in alist
322
- ; has obj as its car, then #f (not the empty list) is
323
- ; returned. Assq uses eq? to compare obj with the car fields
324
- ; of the pairs in alist, while assv uses eqv? and assoc
325
- ; uses equal?.
326
-
327
- (define assoc-list-search (list-transform-search car))
328
- (define assq (assoc-list-search eq?))
329
- (define assv (assoc-list-search eqv?))
330
- (define assoc (assoc-list-search equal?))
331
-
332
- ; (map proc list1 list2 ...)
333
- ; Returns a new list formed by applying proc to each member
334
- ; (or set of members) of the given list(s).
335
- (define (map proc list1 . list2)
336
- (if (null? list1)
337
- list1
338
- (if (null? list2)
339
- (cons (proc (car list1))
340
- (map proc (cdr list1)))
341
- (let* ([all (cons list1 list2)]
342
- [args (map car all)]
343
- [rest (map cdr all)])
344
- (cons (apply proc args)
345
- (apply map (cons proc rest)))))))
346
-
347
- ; (for-each proc list1 list2 ...)
348
- ; Calls proc once for each member of list1, passing each
349
- ; member (or set of members if more than one list given)
350
- ; as arguments to proc.
351
- (define (for-each proc list1 . list2)
352
- (do ([pair list1 (cdr pair)]
353
- [others list2 (map cdr others)])
354
- ((null? pair) '())
355
- (apply proc (cons (car pair)
356
- (map car others)))))
357
-
358
- ; (foldr proc value list)
359
- (define (foldr proc value list)
360
- (if (null? list)
361
- value
362
- (proc (car list)
363
- (foldr proc value (cdr list)))))
364
-
365
- ; (sublist list start end)
366
- (define (sublist list start end)
367
- (cond [(null? list) '()]
368
- [(> start 0) (sublist (cdr list) (- start 1) (- end 1))]
369
- [(<= end 0) '()]
370
- [else (cons (car list)
371
- (sublist (cdr list) 0 (- end 1)))]))
372
-
373
- ;----------------------------------------------------------------
374
-
375
- ; Character functions
376
-
377
- ; (char string)
378
- ; Returns a character from a single-character string. Mostly
379
- ; useful for succinct representation of characters in hand-
380
- ; written Ruby code.
381
- (define (char string)
382
- (if (and (string? string) (= (string-length string) 1))
383
- (string-ref string 0)
384
- '()))
385
-
386
- ; (char-upper-case? letter)
387
- ; Returns true iff letter is an uppercase letter
388
- (define (char-upper-case? letter)
389
- (and (char? letter)
390
- (let ([code (char->integer letter)])
391
- (and (>= code 65)
392
- (<= code 90)))))
393
-
394
- ; (char-lower-case? letter)
395
- ; Returns true iff letter is a lowercase letter
396
- (define (char-lower-case? letter)
397
- (and (char? letter)
398
- (let ([code (char->integer letter)])
399
- (and (>= code 97)
400
- (<= code 122)))))
401
-
402
- ; (char-alphabetic? char)
403
- ; Returns true iff char is an alphabetic character
404
- (define (char-alphabetic? char)
405
- (or (char-upper-case? char)
406
- (char-lower-case? char)))
407
-
408
- ; (char-numeric? char)
409
- ; Returns true iff char is a numeric character
410
- (define (char-numeric? char)
411
- (and (char? char)
412
- (let ([code (char->integer char)])
413
- (and (>= code 48)
414
- (<= code 57)))))
415
-
416
- ; (char-whitespace? char)
417
- ; Returns true iff char is a whitespace character
418
- (define (char-whitespace? char)
419
- (and (char? char)
420
- (if (member (char->integer char)
421
- '(9 10 32))
422
- #t
423
- #f)))
424
-
425
- ; (char-upcase char)
426
- ; Returns an uppercase copy of char
427
- (define (char-upcase char)
428
- (let ([code (char->integer char)])
429
- (if (and (>= code 97) (<= code 122))
430
- (integer->char (- code 32))
431
- (integer->char code))))
432
-
433
- ; (char-downcase char)
434
- ; Returns a lowercase copy of char
435
- (define (char-downcase char)
436
- (let ([code (char->integer char)])
437
- (if (and (>= code 65) (<= code 90))
438
- (integer->char (+ code 32))
439
- (integer->char code))))
440
-
441
- (define (char-compare-ci operator)
442
- (lambda (x y)
443
- (operator (char-downcase x)
444
- (char-downcase y))))
445
-
446
- (define char-ci=? (char-compare-ci char=?))
447
- (define char-ci<? (char-compare-ci char<?))
448
- (define char-ci>? (char-compare-ci char>?))
449
- (define char-ci<=? (char-compare-ci char<=?))
450
- (define char-ci>=? (char-compare-ci char>=?))
451
-
452
- ;----------------------------------------------------------------
453
-
454
- ; String functions
455
-
456
- ; (string char ...)
457
- ; Returns a new string formed by combining the given characters
458
- (define (string . chars) (list->string chars))
459
-
460
- (define (string-compare string1 string2 char-less? char-greater?)
461
- (if (or (not (string? string1))
462
- (not (string? string2)))
463
- (error "Expected two strings as arguments")
464
- (do ([pair1 (string->list string1) (cdr pair1)]
465
- [pair2 (string->list string2) (cdr pair2)]
466
- [diff '()])
467
- ((integer? diff) diff)
468
- (set! diff (cond [(null? pair1) (if (null? pair2) 0 -1)]
469
- [(null? pair2) 1]
470
- [else (let ([char1 (car pair1)]
471
- [char2 (car pair2)])
472
- (cond [(char-less? char1 char2) -1]
473
- [(char-greater? char1 char2) 1]
474
- [else '()]))])))))
475
-
476
- ; (string=? string1 string2)
477
- ; Returns true iff string1 and string2 are equal strings
478
- (define (string=? string1 string2)
479
- (zero? (string-compare string1 string2 char<? char>?)))
480
-
481
- ; (string-ci=? string1 string2)
482
- ; Returns true iff string1 and string2 are equal strings, ignoring case
483
- (define (string-ci=? string1 string2)
484
- (zero? (string-compare string1 string2 char-ci<? char-ci>?)))
485
-
486
- ; (string<? string1 string2)
487
- ; Returns true iff string1 is lexicographically less than string2
488
- (define (string<? string1 string2)
489
- (= (string-compare string1 string2 char<? char>?) -1))
490
-
491
- ; (string>? string1 string2)
492
- ; Returns true iff string1 is lexicographically greater than string2
493
- (define (string>? string1 string2)
494
- (= (string-compare string1 string2 char<? char>?) 1))
495
-
496
- ; (string<=? string1 string2)
497
- ; Returns true iff string1 is lexicographically less than or equal
498
- ; to string2
499
- (define (string<=? string1 string2)
500
- (not (string>? string1 string2)))
501
-
502
- ; (string>=? string1 string2)
503
- ; Returns true iff string1 is lexicographically greater than or equal
504
- ; to string2
505
- (define (string>=? string1 string2)
506
- (not (string<? string1 string2)))
507
-
508
- ; (string-ci<? string1 string2)
509
- ; Returns true iff string1 is lexicographically less than string2,
510
- ; ignoring differences in case
511
- (define (string-ci<? string1 string2)
512
- (= (string-compare string1 string2 char-ci<? char-ci>?) -1))
513
-
514
- ; (string-ci>? string1 string2)
515
- ; Returns true iff string1 is lexicographically greater than string2,
516
- ; ignoring differences in case
517
- (define (string-ci>? string1 string2)
518
- (= (string-compare string1 string2 char-ci<? char-ci>?) 1))
519
-
520
- ; (string-ci<=? string1 string2)
521
- ; Returns true iff string1 is lexicographically less than or equal
522
- ; to string2, ignoring differences in case
523
- (define (string-ci<=? string1 string2)
524
- (not (string-ci>? string1 string2)))
525
-
526
- ; (string-ci>=? string1 string2)
527
- ; Returns true iff string1 is lexicographically greater than or equal
528
- ; to string2, ignoring differences in case
529
- (define (string-ci>=? string1 string2)
530
- (not (string-ci<? string1 string2)))
531
-
532
- ; (substring string start end)
533
- ; Returns a string composed of the characters from start (inclusive)
534
- ; to end (exclusive) in string
535
- (define (substring string start end)
536
- (list->string (sublist (string->list string) start end)))
537
-
538
- ; (list->string chars)
539
- ; Returns a new string formed by combining the list
540
- (define (list->string chars)
541
- (let* ([size (length chars)]
542
- [str (make-string size)])
543
- (do ([list chars (cdr list)]
544
- [i 0 (+ i 1)])
545
- ((= i size) str)
546
- (string-set! str i (car list)))))
547
-
548
- ; (string->list string)
549
- ; Returns a newly allocated list of the characters in the string
550
- (define (string->list string)
551
- (let ([size (string-length string)])
552
- (do ([i size (- i 1)]
553
- [list '() (cons (string-ref string (- i 1)) list)])
554
- ((zero? i) list))))
555
-
556
- ; (string-copy string)
557
- ; Returns a newly allocated copy of the string
558
- (define (string-copy string)
559
- (list->string (string->list string)))
560
-
561
- ; (string-fill! string char)
562
- ; Replaces every character of string with char
563
- (define (string-fill! string char)
564
- (let ([size (string-length string)])
565
- (do ([i size (- i 1)])
566
- ((zero? i) string)
567
- (string-set! string (- i 1) char))))
568
-
569
- ; (string-append string ...)
570
- ; Returns a new string formed by concatenating the arguments
571
- (define (string-append . strings)
572
- (list->string (apply append (map string->list strings))))
573
-
574
- ;----------------------------------------------------------------
575
-
576
- ; Vector functions
577
-
578
- ; (vector object ...)
579
- ; Returns a newly allocated vector from its arguments
580
- (define (vector . args) (list->vector args))
581
-
582
- ; (list->vector list)
583
- ; Returns a newly allocated vector from a list
584
- (define (list->vector list)
585
- (let* ([size (length list)]
586
- [new-vector (make-vector size)])
587
- (do ([i 0 (+ i 1)]
588
- [pair list (cdr pair)])
589
- ((= i size) new-vector)
590
- (vector-set! new-vector i (car pair)))))
591
-
592
- ; (vector->list vector)
593
- ; Returns a newly allocated proper list from a vector
594
- (define (vector->list vector)
595
- (do ([i (vector-length vector) (- i 1)]
596
- [pair '() (cons (vector-ref vector (- i 1)) pair)])
597
- ((zero? i) pair)))
598
-
599
- ; (vector-fill! vector fill)
600
- ; Sets every element of vector to fill
601
- (define (vector-fill! vector fill)
602
- (do ([i (vector-length vector) (- i 1)])
603
- ((zero? i) vector)
604
- (vector-set! vector (- i 1) fill)))
605
-