Class: Nil::MacroParser

Inherits:
Object
  • Object
show all
Defined in:
lib/nil/macro.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeMacroParser

Returns a new instance of MacroParser.



5
6
# File 'lib/nil/macro.rb', line 5

def initialize
end

Instance Attribute Details

#compiled_codeObject

Returns the value of attribute compiled_code.



3
4
5
# File 'lib/nil/macro.rb', line 3

def compiled_code
  @compiled_code
end

#modeObject

Returns the value of attribute mode.



3
4
5
# File 'lib/nil/macro.rb', line 3

def mode
  @mode
end

#original_codeObject

Returns the value of attribute original_code.



3
4
5
# File 'lib/nil/macro.rb', line 3

def original_code
  @original_code
end

Instance Method Details

#compile_subroutines(code) ⇒ Object



8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# File 'lib/nil/macro.rb', line 8

def compile_subroutines(code)
  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, '')
end

#expand_included_files(code) ⇒ Object



36
37
38
39
40
41
42
43
44
45
46
47
# File 'lib/nil/macro.rb', line 36

def expand_included_files(code)
  c = code
  include_regex = Regexp.new '\.include\(([^\)]+)\)'
  included_code = ""
  files = c.scan(include_regex).flatten
  files.each do |f|
    included_code << File.open(f, 'r').read.strip
  end
  c.gsub!(include_regex, '')
  c = included_code + c
  c
end

#interpret_mode_definition(code) ⇒ Object



29
30
31
32
33
34
# File 'lib/nil/macro.rb', line 29

def interpret_mode_definition(code)
  code.match /\.mode\((ascii|num)\)/i do |m|
    $1 == 'num' ? Nil::Interpreter.mode = 'num' : Nil::Interpreter.mode = 'ascii'
  end
  code.gsub(/\.mode\((ascii|num)\)/i, '')
end

#parse(code) ⇒ Object



53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
# File 'lib/nil/macro.rb', line 53

def parse(code)
  @original_code = code

  compiled_code = @original_code

  compiled_code.gsub!(/\s/, '')

  compiled_code = interpret_mode_definition(compiled_code)

  compiled_code = expand_included_files(compiled_code)

  compiled_code = strip_comments(compiled_code)

  compiled_code.gsub!(/([\+-<>])(\d+)/) do |m| # Parse the numerical commands.
    $1 * $2.to_i
  end

  compiled_code = compile_subroutines(compiled_code)
  compiled_code
end

#strip_comments(code) ⇒ Object



49
50
51
# File 'lib/nil/macro.rb', line 49

def strip_comments(code)
  code.gsub(/;(.+);/, '')
end