forked from DJMcMayhem/Brain-Flak
-
Notifications
You must be signed in to change notification settings - Fork 0
/
brain_flak.rb
141 lines (120 loc) · 3.49 KB
/
brain_flak.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
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
require_relative './stack.rb'
require_relative './Interpreter.rb'
require 'optparse'
debug = false
ascii_in = false
ascii_out = false
reverse = false
utf8 = false
arg_path = ""
parser = OptionParser.new do |opts|
opts.banner = "\nBrain-Flak Ruby Interpreter\n"\
"Usage:\n"\
"\tbrain_flak [options] source_file args...\n\n"
opts.on("-d", "--debug", "Enables parsing of debug commands") do
debug = true
end
opts.on("-f", "--file=FILE", "Reads input for the brain-flak program from FILE, rather than from the command line.") do |file|
arg_path = file
end
opts.on("-a", "--ascii-in", "Take input in ASCII code points and output in decimal. This overrides previous -A and -c flags.") do
ascii_in = true
ascii_out = false
end
opts.on("-A", "--ascii-out", "Take input in decimal and output in ASCII code points. This overrides previous -a and -c flags.") do
ascii_in = false
ascii_out = true
end
opts.on("-c", "--ascii", "Take input and output in ASCII code points, rather than in decimal. This overrides previous -a and -A flags.") do
ascii_in = true
ascii_out = true
end
opts.on("-r", "--reverse", "Reverses the order that arguments are pushed onto the stack AND that values are printed at the end.") do
reverse = true
end
opts.on("-u", "--utf8", "Enables handling of UTF-8 characters in input and output") do
utf8 = true
end
opts.on("-h", "--help", "Prints info on the command line usage of Brain-Flak and then exits") do
STDERR.puts opts
exit
end
opts.on("-v", "--version", "Prints the version of the Brain-Flak interpreter and then exits") do
STDERR.puts "Brain-Flak Ruby Interpreter v1.0.0"
exit
end
end
begin
parser.order!
rescue OptionParser::ParseError => e
STDERR.puts e
STDERR.puts "\n"
STDERR.puts parser
exit
end
if ARGV.length < 1 then
STDERR.puts parser
exit
end
source_path = ARGV[0]
if arg_path != "" then
input_file = File.open(arg_path, 'r')
if !ascii_in
numbers = input_file.read.gsub(/\s+/m, ' ').strip.split(" ")
else
numbers = input_file.read.split("")
end
else
if ascii_in
numbers = ARGV[1..-1].join(" ").split("")
else
numbers = ARGV[1..-1]
end
end
if debug then
STDERR.puts "Debug mode... ENGAGED!"
end
source_file = File.open(source_path, 'r')
source = source_file.read
source_length = source.length
begin
if !ascii_in
numbers.each do |a|
raise BrainFlakError.new("Invalid integer in input: \"%s\"" % [a], 0) if !(a =~ /^-?\d+$/)
end
numbers.map!(&:to_i)
else
numbers.map!(&:ord)
if !utf8 then
numbers.each do |a|
raise BrainFlakError.new("Invalid character in input: \"%s\"" % [a.chr(Encoding::UTF_8)], 0) if a > 255
end
end
end
numbers.reverse! if !reverse
interpreter = BrainFlakInterpreter.new(source, numbers, [], debug)
while interpreter.step
end
if interpreter.main_stack.length > 0
unmatched_brak = interpreter.main_stack[0]
raise BrainFlakError.new("Unclosed '%s' character." % unmatched_brak[0], unmatched_brak[2])
end
interpreter.active_stack.print_stack(ascii_out,reverse,utf8)
rescue BrainFlakError => e
STDERR.puts e.message
rescue Interrupt
STDERR.puts "\nKeyboard Interrupt"
STDERR.puts interpreter.inspect
if debug then
STDERR.puts interpreter.debug_info
end
rescue RuntimeError => e
if e.to_s == "Second Interrupt"
STDERR.puts interpreter.inspect
if debug then
STDERR.puts interpreter.debug_info
end
else
raise e
end
end