This repository has been archived by the owner on Jan 23, 2018. It is now read-only.
/
bus_scheme.rb
89 lines (78 loc) · 2.46 KB
/
bus_scheme.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
#!/usr/bin/env ruby
$LOAD_PATH << File.dirname(__FILE__)
require 'readline'
require 'object_extensions'
require 'array_extensions'
require 'parser'
require 'eval'
require 'cons'
require 'lambda'
require 'stack_frame'
require 'primitives'
begin
require 'web'
require 'xml'
rescue LoadError
puts "Could not load web functionality."
end
module BusScheme
VERSION = "0.7.7"
PROMPT = '> '
INCOMPLETE_PROMPT = ' ... '
BusScheme['load-path'.sym] = Cons.new("#{File.dirname(__FILE__)}/scheme/",
Cons.new(File.expand_path('.'), nil))
class BusSchemeError < StandardError; end
class ParseError < BusSchemeError; end
class EvalError < BusSchemeError; end
class LoadError < BusSchemeError; end
class IncompleteError < BusSchemeError; end
class ArgumentError < BusSchemeError; end
class AssertionFailed < BusSchemeError; end
# Read-Eval-Print-Loop
def self.repl
loop do
puts begin
input = Readline.readline(PROMPT)
exit if input.nil? # only Ctrl-D produces nil here it seems
begin # allow for multiline input
result = BusScheme.eval_string(input).inspect
rescue IncompleteError
input += "\n" + Readline.readline(INCOMPLETE_PROMPT)
retry
end
Readline::HISTORY.push(input)
result
rescue Interrupt
'Type "(quit)" or press Ctrl-D to leave Bus Scheme.'
rescue BusSchemeError => e
"Error: #{e}"
rescue StandardError => e
"You found a bug in Bus Scheme!\n" +
"#{e.class}: #{e}\n#{e.backtrace.join("\n")}"
end
end
end
# Load a file if on the load path or absolute
def self.load(filename)
begin
loaded_files.push filename
eval_string File.read(add_load_path(filename))
loaded_files.pop
rescue
loaded_files.pop
raise
end
end
def self.add_load_path(filename, load_path = BusScheme['load-path'.sym])
return filename if filename.match(/^\//) or File.exist? filename
raise LoadError, "File not found: #{filename}" if load_path.empty?
return load_path.car + '/' + filename if File.exist? load_path.car + '/' + filename
return add_load_path(filename, load_path.cdr)
end
# For stack traces
def self.loaded_files
(@loaded_files ||= ["(eval)"])
end
['core.scm', 'test.scm', 'list.scm', 'predicates.scm'
].each { |f| load(f) }
end