Added top-level Makefile and src/Makefile.
[voodoo-lang.git] / src / compiler.rb
blob8899dcf6e806ce38e8ac2acd8bee74f583f5e397
1 class Compiler
2   def initialize parser, code_generator, output
3     @parser = parser
4     @generator = code_generator
5     @output = output
6   end
8   def compile
9     # Map for magic words whose code generator method has
10     # a name different from the magic word
11     names_map = {
12       'else' => :ifelse,
13       'if' => :ifnonzero,
14       'return' => :ret,
15       'tail-call' => :tail_call,
16     }
18     while true
19       words = @parser.parse_line
20       break if words == nil
21       next if words.empty?
22   
23       # Process labels
24       while words[0] =~ /^\w+:$/
25         label = words[0][0..-2]
26         @generator.label label
27         words = words[1..-1]
28       end
29       next if words.empty?
31       # Process code
32       action, args = words[0], words[1..-1]
33       case action
34       when 'else'
35         if words.length == 1
36           @generator.ifelse
37         else
38           if words[1] == 'if'
39             @generator.ifelse
40             @generator.ifnonzero words[2..-1]
41           else
42             raise "Invalid action: #{action} #{words[1]}"
43           end
44         end
45       when 'end'
46         case words[1]
47         when 'function'
48           @generator.end_function
49         when 'if'
50           @generator.end_if
51         else
52           raise "Unknown action: #{action} #{words[1]}"
53         end
54       else
55         if names_map.has_key? action
56           @generator.send names_map[action], *args
57         else
58           sym = nil
59           begin
60             sym = action.to_sym
61           rescue ArgumentError
62             # Not a valid symbol
63           end
65           if sym != nil && @generator.respond_to?(action.to_sym)
66             @generator.send action.to_sym, *args
67           else
68             raise "Unknown action: #{words[0]}"
69           end
70         end
71       end
72     end
74     @generator.write @output
75   end
76 end