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
|
# File 'lib/nil/macro.rb', line 9
def compile(code)
code.gsub!(/\s/, '')
mode = 'ascii'
code.match /\.mode\((ascii|num)\)/i do |m|
$1 == 'num' ? mode = 'num' : nil
end
code.gsub!(/\.mode\((ascii|num)\)/i, '')
included_code = ""
files = code.scan(/\.include\(([^\)]+)\)/).flatten
files.each do |f|
included_code << File.open(f, 'r').read.strip
end
code.gsub!(/\.include\(([^\)]+)\)/, '')
code = included_code + code
code.gsub!(/;(.+);/, '')
subroutines = {}
sub_def_regex = Regexp.new ':(?<sub-name>[a-zA-Z0-9_]+)\{(?<sub-code>[\[\]><\-\+.,A-Za-z0-9:]+)\}'
sub_call_regex = Regexp.new '([a-zA-Z0-9_]+):'
code.scan(sub_def_regex).map do |sub|
subroutines[sub[0]] = sub[1]
end
subroutines.each do |s, c|
if c =~ sub_call_regex
raise SyntaxError, "Error: Recursive subroutine."
end
end
code.gsub!(sub_call_regex) do |m|
subroutines[$1]
end
code.gsub!(sub_def_regex, '')
code.gsub!(/([\+-<>])(\d+)/) do |m|
$1 * $2.to_i
end
Nil::NilCommands.new(code, mode)
end
|