heist 0.3.2 → 0.3.3
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +12 -0
- data/{README.txt → README.rdoc} +131 -148
- data/bin/heist +35 -10
- data/lib/heist.rb +3 -3
- data/lib/heist/builtin/compiled_library.rb +1 -0
- data/lib/heist/builtin/lib/character.scm +74 -0
- data/lib/heist/builtin/lib/list.scm +149 -0
- data/lib/heist/builtin/lib/logic.scm +17 -0
- data/lib/heist/builtin/lib/numeric.scm +184 -0
- data/lib/heist/builtin/lib/string.scm +117 -0
- data/lib/heist/builtin/lib/util.scm +18 -0
- data/lib/heist/builtin/lib/vector.scm +27 -0
- data/lib/{builtin → heist/builtin}/primitives.rb +0 -0
- data/lib/{builtin → heist/builtin}/syntax.scm +52 -52
- data/lib/{parser → heist/parser}/nodes.rb +0 -0
- data/lib/{parser → heist/parser}/ruby.rb +0 -0
- data/lib/{parser → heist/parser}/scheme.rb +0 -0
- data/lib/{parser → heist/parser}/scheme.tt +0 -0
- data/lib/{repl.rb → heist/repl.rb} +0 -0
- data/lib/{runtime → heist/runtime}/binding.rb +5 -0
- data/lib/{runtime → heist/runtime}/callable/continuation.rb +6 -1
- data/lib/{runtime → heist/runtime}/callable/function.rb +0 -0
- data/lib/{runtime → heist/runtime}/callable/macro.rb +1 -1
- data/lib/{runtime → heist/runtime}/callable/macro/expansion.rb +0 -0
- data/lib/{runtime → heist/runtime}/callable/macro/matches.rb +0 -0
- data/lib/{runtime → heist/runtime}/callable/macro/tree.rb +0 -0
- data/lib/{runtime → heist/runtime}/callable/syntax.rb +0 -0
- data/lib/{runtime → heist/runtime}/data/character.rb +0 -0
- data/lib/{runtime → heist/runtime}/data/cons.rb +0 -0
- data/lib/{runtime → heist/runtime}/data/expression.rb +0 -0
- data/lib/{runtime → heist/runtime}/data/identifier.rb +0 -0
- data/lib/heist/runtime/data/value.rb +14 -0
- data/lib/{runtime → heist/runtime}/data/vector.rb +0 -0
- data/lib/{runtime → heist/runtime}/frame.rb +3 -0
- data/lib/{runtime → heist/runtime}/runtime.rb +2 -2
- data/lib/{runtime → heist/runtime}/scope.rb +0 -0
- data/lib/{runtime → heist/runtime}/stack.rb +0 -0
- data/lib/{runtime → heist/runtime}/stackless.rb +0 -0
- data/lib/{stdlib → heist/stdlib}/benchmark.scm +0 -0
- data/lib/{stdlib → heist/stdlib}/birdhouse.scm +0 -0
- data/lib/{trie.rb → heist/trie.rb} +0 -0
- data/spec/heist_spec.rb +88 -0
- data/{test → spec}/helpers/lib.scm +0 -0
- data/{test → spec}/helpers/macro-helpers.scm +0 -0
- data/{test → spec}/helpers/vars.scm +0 -0
- data/{test → spec}/plt-macros.txt +0 -0
- data/{test → spec}/scheme_tests/arithmetic.scm +0 -0
- data/{test → spec}/scheme_tests/benchmarks.scm +0 -0
- data/{test → spec}/scheme_tests/booleans.scm +0 -0
- data/{test → spec}/scheme_tests/closures.scm +0 -0
- data/{test → spec}/scheme_tests/conditionals.scm +0 -0
- data/{test → spec}/scheme_tests/continuations.scm +14 -1
- data/{test → spec}/scheme_tests/define_functions.scm +0 -0
- data/{test → spec}/scheme_tests/define_values.scm +0 -0
- data/{test → spec}/scheme_tests/delay.scm +0 -0
- data/{test → spec}/scheme_tests/equivalence.scm +0 -0
- data/{test → spec}/scheme_tests/file_loading.scm +0 -0
- data/{test → spec}/scheme_tests/functional.scm +3 -0
- data/{test → spec}/scheme_tests/hygienic.scm +0 -0
- data/{test → spec}/scheme_tests/let.scm +0 -0
- data/{test → spec}/scheme_tests/lists.scm +0 -0
- data/{test → spec}/scheme_tests/macros.scm +0 -0
- data/{test → spec}/scheme_tests/numbers.scm +0 -0
- data/{test → spec}/scheme_tests/protection.scm +0 -0
- data/spec/scheme_tests/quoting.scm +14 -0
- data/{test → spec}/scheme_tests/strings.scm +0 -0
- data/{test → spec}/scheme_tests/unhygienic.scm +0 -0
- data/{test → spec}/scheme_tests/vectors.scm +0 -0
- data/spec/spec_helper.rb +4 -0
- metadata +98 -113
- data/Manifest.txt +0 -64
- data/Rakefile +0 -43
- data/lib/bin_spec.rb +0 -25
- data/lib/builtin/library.rb +0 -1
- data/lib/builtin/library.scm +0 -605
- data/test/test_heist.rb +0 -148
data/Manifest.txt
DELETED
@@ -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('<', '<').
|
33
|
-
gsub('>', '>') }
|
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
|
data/lib/bin_spec.rb
DELETED
@@ -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
|
-
|
data/lib/builtin/library.rb
DELETED
@@ -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]]]]
|
data/lib/builtin/library.scm
DELETED
@@ -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
|
-
|