Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

source "https://rubygems.org"

# Specify your gem's dependencies in vaporware.gemspec
# Specify your gem's dependencies in caotral.gemspec
gemspec

gem "rake", "~> 13.0"
8 changes: 6 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# Vaporware
# Caotral

it's the vaporware.
Caotral is a project to build a toolchain that compiles Ruby to native binaries.

## Future
- Compile Ruby code to native binaries on all PCs.
- Learn compilers, cssemblers, and linkers by implementing the pipeline end to end.
2 changes: 1 addition & 1 deletion Rakefile
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ require "steep/cli"
task default: %i[test]

Rake::TestTask.new do |t|
t.test_files = FileList['test/test*.rb', 'test/**/test*.rb', 'test/**/*_test.rb']
t.test_files = FileList['test/**/*_test.rb']
end

namespace :steep do
Expand Down
2 changes: 1 addition & 1 deletion bin/console
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# frozen_string_literal: true

require "bundler/setup"
require "vaporware"
require "caotral"

# You can add fixtures and/or initialization code here to make experimenting
# with your gem easier. You can also use a different console, if you like.
Expand Down
12 changes: 6 additions & 6 deletions vaporware.gemspec → caotral.gemspec
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
# frozen_string_literal: true

require_relative "lib/vaporware/version"
require_relative "lib/caotral/version"

Gem::Specification.new do |spec|
spec.name = "vaporware-compiler"
spec.version = Vaporware::VERSION
spec.name = "caotral"
spec.version = Caotral::VERSION
spec.authors = ["MATSUMOTO, Katsuyoshi"]
spec.email = ["github@katsyoshi.org"]

spec.summary = "Vaporware is the vaporware."
spec.description = "Vaporware is the vaporware."
spec.summary = "Caotral is the ruby native compiler."
spec.description = "Caotral is the caotral."
spec.license = "MIT"
spec.required_ruby_version = ">= 3.2.0"
spec.homepage = "https://github.com/katsyoshi/vaporware"
spec.homepage = "https://github.com/katsyoshi/caotral"

# Specify which files should be added to the gem when it is released.
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
Expand Down
8 changes: 4 additions & 4 deletions exe/vaporware → exe/caotral
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#!/usr/bin/env ruby

require "vaporware"
require "caotral"
require "optparse"
opt = OptionParser.new
options = {
Expand Down Expand Up @@ -70,17 +70,17 @@ basename = File.expand_path(File.basename(input, ".*"))
extname = File.extname(output) == ".so"

output = basename + ".s"
Vaporware.compile(input:, output:, debug:) if options[:compile]
Caotral.compile(input:, output:, debug:) if options[:compile]
input, output = output, basename + ".o"
if options[:assemble]
input = ARGV.first unless options[:compile]
Vaporware.assemble(input:, output:, assembler:, debug:)
Caotral.assemble(input:, output:, assembler:, debug:)
File.delete(input) if File.exist?(input) && !debug && File.extname(input) != ".s"
end
if options[:link]
input, output = output, basename
output = options[:output] || output
output += ".so" if options[:shared] && !extname
Vaporware.link(input:, output:, debug:, shared:, linker:) if options[:link]
Caotral.link(input:, output:, debug:, shared:, linker:) if options[:link]
File.delete(input) if File.exist?(input) && !debug && File.extname(input) != ".o"
end
16 changes: 8 additions & 8 deletions lib/vaporware.rb → lib/caotral.rb
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
# frozen_string_literal: true

require_relative "vaporware/version"
require_relative "caotral/version"

require_relative "vaporware/assembler"
require_relative "vaporware/compiler"
require_relative "vaporware/linker"
require_relative "caotral/assembler"
require_relative "caotral/compiler"
require_relative "caotral/linker"

module Vaporware
module Caotral
module_function
def compile!(input:, assembler: "as", linker: "ld", output: "tmp", debug: false, compiler_options: ["-O0"], shared: false)
d = File.expand_path(output)
Expand All @@ -17,12 +17,12 @@ def compile!(input:, assembler: "as", linker: "ld", output: "tmp", debug: false,
link(input: basename+".o", output: execf, linker:, debug:, shared:)
end
def compile(input:, output: "tmp.s", debug: false, shared: false)
Vaporware::Compiler.compile!(input:, output:, debug:)
Caotral::Compiler.compile!(input:, output:, debug:)
end
def assemble(input:, output: "tmp.o", debug: false, shared: false, assembler: "as")
Vaporware::Assembler.assemble!(input:, output:, debug:, assembler:, shared:)
Caotral::Assembler.assemble!(input:, output:, debug:, assembler:, shared:)
end
def link(input:, output: "tmp", linker: "ld", debug: false, shared: false)
Vaporware::Linker.link!(input:, output:, linker:, debug:, shared:)
Caotral::Linker.link!(input:, output:, linker:, debug:, shared:)
end
end
2 changes: 1 addition & 1 deletion lib/vaporware/assembler.rb → lib/caotral/assembler.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
require_relative "assembler/elf/sections"
require_relative "assembler/elf/section_header"

class Vaporware::Assembler
class Caotral::Assembler
GCC_ASSEMBLERS = ["gcc", "as"].freeze
CLANG_ASSEMBLERS = ["clang", "llvm"].freeze
ASSEMBLERS = (GCC_ASSEMBLERS + CLANG_ASSEMBLERS).freeze
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
class Vaporware::Assembler
class Caotral::Assembler
class ELF
class Error < StandardError; end
class Section; end
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
require_relative "../elf"

class Vaporware::Assembler::ELF::Header
include Vaporware::Assembler::ELF::Utils
class Caotral::Assembler::ELF::Header
include Caotral::Assembler::ELF::Utils
IDENT = [0x7f, 0x45, 0x4c, 0x46, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00].freeze
ELF_FILE_TYPE = { NONE: 0, REL: 1, EXEC: 2, DYN: 3, CORE: 4 }.freeze

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,15 @@
require_relative "section/shstrtab"
require_relative "section_header"

class Vaporware::Assembler::ELF::Section
class Caotral::Assembler::ELF::Section
attr_reader :header, :body, :name, :section_name
def initialize(type:, options: {})
type_string = type.to_s.capitalize
type_string = type_string.upcase if type_string == "Bss"
@section_name = type_string.downcase
@name = section_name == "null" ? "" : "\0.#{section_name}"
@header = Vaporware::Assembler::ELF::SectionHeader.new.send("#{@section_name}!")
@body = Module.const_get("Vaporware::Assembler::ELF::Section::#{type_string}").new(**options)
@header = Caotral::Assembler::ELF::SectionHeader.new.send("#{@section_name}!")
@body = Module.const_get("Caotral::Assembler::ELF::Section::#{type_string}").new(**options)
end

def name=(name)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
class Vaporware::Assembler::ELF::Section::BSS
include Vaporware::Assembler::ELF::Utils
class Caotral::Assembler::ELF::Section::BSS
include Caotral::Assembler::ELF::Utils
def initialize(**opts) = nil
def build = bytes.flatten.pack("C*")
def set! = self
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
class Vaporware::Assembler::ELF::Section::Data
include Vaporware::Assembler::ELF::Utils
class Caotral::Assembler::ELF::Section::Data
include Caotral::Assembler::ELF::Utils
def initialize(**opts) = nil
def build = bytes.flatten.pack("C*")
def set! = self
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
class Vaporware::Assembler::ELF::Section::Note
include Vaporware::Assembler::ELF::Utils
class Caotral::Assembler::ELF::Section::Note
include Caotral::Assembler::ELF::Utils

def self.gnu_property = new.gnu_property!.build
def self.null = new.null!.build
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
class Vaporware::Assembler::ELF::Section::Null
include Vaporware::Assembler::ELF::Utils
class Caotral::Assembler::ELF::Section::Null
include Caotral::Assembler::ELF::Utils
def initialize(**opts) = nil
def build = bytes.flatten.pack("C*")
def set! = self
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
class Vaporware::Assembler::ELF::Section::Shstrtab
include Vaporware::Assembler::ELF::Utils
class Caotral::Assembler::ELF::Section::Shstrtab
include Caotral::Assembler::ELF::Utils
def initialize(**opts) = @name = []
def build = bytes.flatten.pack("C*")
def set!(name:) = (@name << name!(name); self)
Expand All @@ -11,12 +11,12 @@ def name!(name)
when String
(name.match(/\A\0\..+\z/) ? name : "\0.#{name}").bytes
when Array
raise Vaporware::Assembler::ELF::Error, "unaccepted type in Array" unless name.all? { |elem| elem.is_a?(Integer) }
raise Caotral::Assembler::ELF::Error, "unaccepted type in Array" unless name.all? { |elem| elem.is_a?(Integer) }
n = name
n.unshift(0) && n.push(0) unless n.first == 0 && n.last == 0
n
else
raise Vaporware::Assembler::ELF::Error, "unsupported type"
raise Caotral::Assembler::ELF::Error, "unsupported type"
end
end
end
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
class Vaporware::Assembler::ELF::Section::Strtab
include Vaporware::Assembler::ELF::Utils
class Caotral::Assembler::ELF::Section::Strtab
include Caotral::Assembler::ELF::Utils
def initialize(names = "\0main\0", **opts) = @names = names
def build = @names.bytes.pack("C*")
end
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
class Vaporware::Assembler::ELF::Section::Symtab
include Vaporware::Assembler::ELF::Utils
class Caotral::Assembler::ELF::Section::Symtab
include Caotral::Assembler::ELF::Utils
def initialize(**opts)
@entsize = []
@name = num2bytes(0, 4)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
class Vaporware::Assembler::ELF::Section::Text
class Caotral::Assembler::ELF::Section::Text
PREFIX = {
REX_W: 0x48,
}.freeze
Expand Down Expand Up @@ -115,14 +115,14 @@ def opecode(op, offset, *operands)
when "ret"
[0xc3]
else
raise Vaporware::Assembler::ELF::Error, "yet implemented operations: #{op}"
raise Caotral::Assembler::ELF::Error, "yet implemented operations: #{op}"
end
end

def jump(op, offset, *operands)
label = operands.first
target = @label_positions.fetch(label) do
raise Vaporware::Compiler::Assembler::ELF::Error, "unknown label: #{label}"
raise Caotral::Compiler::Assembler::ELF::Error, "unknown label: #{label}"
end
size = instruction_size(op, label)
rel = target - (offset + size)
Expand Down Expand Up @@ -253,7 +253,7 @@ def reg(r)
when /\d+/
r.to_i(16)
else
raise Vaporware::Assembler::ELF::Error, "yet implemented operand address: #{r}"
raise Caotral::Assembler::ELF::Error, "yet implemented operand address: #{r}"
end
end
def immediate(operand) = [operand.to_i(16)].pack("L").unpack("C*")
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
class Vaporware::Assembler::ELF::SectionHeader
include Vaporware::Assembler::ELF::Utils
class Caotral::Assembler::ELF::SectionHeader
include Caotral::Assembler::ELF::Utils
def initialize
@name = nil
@type = nil
Expand Down
19 changes: 19 additions & 0 deletions lib/caotral/assembler/elf/sections.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
require_relative "section"

class Caotral::Assembler::ELF::Sections
ATTRIBUTES = %i|null text data bss note symtab strtab shstrtab|
attr_reader *ATTRIBUTES

def initialize
@null = Caotral::Assembler::ELF::Section.new(type: :null)
@text = Caotral::Assembler::ELF::Section.new(type: :text)
@data = Caotral::Assembler::ELF::Section.new(type: :data)
@bss = Caotral::Assembler::ELF::Section.new(type: :bss)
@note = Caotral::Assembler::ELF::Section.new(type: :note, options: {type: :gnu})
@symtab = Caotral::Assembler::ELF::Section.new(type: :symtab)
@strtab = Caotral::Assembler::ELF::Section.new(type: :strtab)
@shstrtab = Caotral::Assembler::ELF::Section.new(type: :shstrtab)
end

def each(&block) = ATTRIBUTES.each { |t| yield send(t) }
end
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
module Vaporware::Assembler::ELF::Utils
module Caotral::Assembler::ELF::Utils
def build = (build_errors; bytes.flatten.pack("C*"))
def size = build.bytesize
def set! = (raise Vaporware::Assembler::ELF::Error, "should be implementing #{self.class}")
def set! = (raise Caotral::Assembler::ELF::Error, "should be implementing #{self.class}")
def empties = must_be_filled_section_fields

private
def align(val, bytes)
val << 0 until val.size % bytes == 0
val
end
def bytes = (raise Vaporware::Assembler::ELF::Error, "should be implementing #{self.class}")
def bytes = (raise Caotral::Assembler::ELF::Error, "should be implementing #{self.class}")
def must_be_filled_section_fields = instance_variables.reject { |i| instance_variable_get(i) }
def num2bytes(val, bytes) = hexas(val, bytes).reverse
def check(val, bytes) = ((val.is_a?(Array) && val.all? { |v| v.is_a?(Integer) } && val.size == bytes) || (val.is_a?(Integer) && (hexas(val, bytes).size == bytes)))
Expand All @@ -18,6 +18,6 @@ def build_errors
return unless bytes.any?(&:nil?)
errors = []
bytes.each_with_index { |v, idx| errors << instance_variables[idx] if v.nil? }
raise Vaporware::Assembler::ELF::Error, "unaccepted types: #{errors.join(",")}"
raise Caotral::Assembler::ELF::Error, "unaccepted types: #{errors.join(",")}"
end
end
4 changes: 2 additions & 2 deletions lib/vaporware/compiler.rb → lib/caotral/compiler.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

require_relative "compiler/generator"

class Vaporware::Compiler
class Caotral::Compiler
attr_reader *%i(generator assembler linker)

def self.compile!(input:, output: "tmp.s", debug: false, compiler_options: ["-O0"], shared: false)
Expand All @@ -11,7 +11,7 @@ def self.compile!(input:, output: "tmp.s", debug: false, compiler_options: ["-O0
end

def initialize(input:, output:, debug: false, shared: false)
@generator = Vaporware::Compiler::Generator.new(input:, output:, debug:, shared:)
@generator = Caotral::Compiler::Generator.new(input:, output:, debug:, shared:)
end
def compile(compiler_options: ["-O0"]) = @generator.compile
end
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# frozen_string_literal: true

module Vaporware
module Caotral
class Compiler
class Generator
REGISTER = %w(rdi rsi rdx rcx r8 r9)
Expand Down
2 changes: 1 addition & 1 deletion lib/vaporware/error.rb → lib/caotral/error.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# frozen_string_literal: true

module Vaporware
module Caotral
class Error < StandardError; end
end
2 changes: 1 addition & 1 deletion lib/vaporware/linker.rb → lib/caotral/linker.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# frozen_string_literal: true
class Vaporware::Linker
class Caotral::Linker
def self.link!(input:, output: "a.out", linker: "mold", debug: false, shared: false) = new(input:, output:, linker:, debug:, shared:).link

def initialize(input:, output: "a.out", linker: "mold", linker_options: [], shared: false, debug: false)
Expand Down
2 changes: 1 addition & 1 deletion lib/vaporware/version.rb → lib/caotral/version.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# frozen_string_literal: true

module Vaporware
module Caotral
VERSION = "0.2.0"
end
19 changes: 0 additions & 19 deletions lib/vaporware/assembler/elf/sections.rb

This file was deleted.

Loading