|
1 | 1 | # frozen_string_literal: true |
2 | 2 |
|
3 | 3 | require_relative "compiler/generator" |
| 4 | +require_relative "compiler/assembler" |
| 5 | +require_relative "compiler/linker" |
4 | 6 |
|
5 | | -module Vaporware |
6 | | - # Your code goes here... |
7 | | - class Compiler |
8 | | - def self.compile(source, compiler: "gcc", dest: "tmp", debug: false, compiler_options: ["-O0"], shared: false) |
9 | | - _precompile = "#{dest}.s" |
10 | | - s = new(source, _precompile: _precompile, debug:, shared:) |
11 | | - s.compile(compiler:, compiler_options:) |
12 | | - end |
| 7 | +class Vaporware::Compiler |
| 8 | + attr_reader *%i(generator assembler linker) |
13 | 9 |
|
14 | | - def initialize(source, _precompile: "tmp.s", debug: false, shared: false) |
15 | | - @generator = Vaporware::Compiler::Generator.new(source, precompile: _precompile, debug:, shared:) |
16 | | - end |
17 | | - |
18 | | - def compile(compiler: "gcc", compiler_options: ["-O0"]) |
19 | | - @generator.register_var_and_method(@generator.ast) |
| 10 | + def self.compile(source, assembler: "as", linker: "ld", dest: "tmp", debug: false, compiler_options: ["-O0"], shared: false) |
| 11 | + compiler = new(input: source, output: dest, debug:, shared:, linker:, assembler:) |
| 12 | + compiler.compile(compiler_options:) |
| 13 | + compiler.assemble(input: dest.to_s + ".s", assembler:, debug:) |
| 14 | + compiler.link |
| 15 | + end |
20 | 16 |
|
21 | | - output = File.open(@generator.precompile, "w") |
22 | | - # prologue |
23 | | - output.puts ".intel_syntax noprefix" |
24 | | - if @generator.defined_methods.empty? |
25 | | - @generator.main = true |
26 | | - output.puts ".globl main" |
27 | | - output.puts "main:" |
28 | | - output.puts " push rbp" |
29 | | - output.puts " mov rbp, rsp" |
30 | | - output.puts " sub rsp, #{@generator.defined_variables.size * 8}" |
31 | | - @generator.to_asm(@generator.ast, output) |
32 | | - # epilogue |
33 | | - @generator.epilogue(output) |
34 | | - else |
35 | | - @generator.prologue_methods(output) |
36 | | - output.puts ".globl main" unless @generator.shared |
37 | | - @generator.to_asm(@generator.ast, output) |
38 | | - # epilogue |
39 | | - @generator.epilogue(output) |
40 | | - end |
41 | | - output.close |
42 | | - compiler_options += @generator.compile_shared_option if @generator.shared |
43 | | - @generator.call_compiler(compiler:, compiler_options:) |
44 | | - end |
| 17 | + def initialize(input:, output: File.basename(input, ".*"), linker: "ld", assembler: "as", debug: false, shared: false) |
| 18 | + @generator = Vaporware::Compiler::Generator.new(input:, output: output + ".s", debug:, shared:) |
| 19 | + @assembler = Vaporware::Compiler::Assembler.new(input: @generator.precompile, output: output + ".o", assembler:, debug:) |
| 20 | + @linker = Vaporware::Compiler::Linker.new(input: @assembler.obj_file, output:, linker:, debug:, shared:) |
45 | 21 | end |
| 22 | + |
| 23 | + def assemble(input:, output: File.basename(input, ".*") + ".o", assembler: "as", assembler_options: [], debug: false) = @assembler.assemble(input:, output:, assembler:, assembler_options:, debug:) |
| 24 | + def link = @linker.link |
| 25 | + def compile(compiler_options: ["-O0"]) = @generator.compile |
46 | 26 | end |
0 commit comments