Class: MiniRuby::BytecodeFunction

Inherits:
Object
  • Object
show all
Extended by:
T::Sig
Defined in:
lib/miniruby/bytecode_function.rb

Overview

A chunk of bytecode produced by the compiler. Can be executed by the Virtual Machine.

Constant Summary collapse

ZERO =

: BytecodeFunction

new(name: 'zero')
MAX_VALUE_ID =
255

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(name: '<main>', filename: '<main>', instructions: String.new.b, value_pool: [], span: Span::ZERO) ⇒ BytecodeFunction

: (?name: String, ?filename: String, ?instructions: String, ?value_pool: Array, ?span: Span) -> void



48
49
50
51
52
53
54
# File 'lib/miniruby/bytecode_function.rb', line 48

def initialize(name: '<main>', filename: '<main>', instructions: String.new.b, value_pool: [], span: Span::ZERO)
  @name = name
  @filename = filename
  @instructions = instructions
  @value_pool = value_pool
  @span = span
end

Instance Attribute Details

#filenameObject (readonly)

: String



35
36
37
# File 'lib/miniruby/bytecode_function.rb', line 35

def filename
  @filename
end

#instructionsObject

A byte-buffer containing instructions : String



45
46
47
# File 'lib/miniruby/bytecode_function.rb', line 45

def instructions
  @instructions
end

#nameObject (readonly)

: String



32
33
34
# File 'lib/miniruby/bytecode_function.rb', line 32

def name
  @name
end

#spanObject (readonly)

: Span



38
39
40
# File 'lib/miniruby/bytecode_function.rb', line 38

def span
  @span
end

#value_poolObject (readonly)

: Array



41
42
43
# File 'lib/miniruby/bytecode_function.rb', line 41

def value_pool
  @value_pool
end

Class Method Details

.pack_instructions(*bytes) ⇒ Object

: (*Integer bytes) -> String



21
22
23
# File 'lib/miniruby/bytecode_function.rb', line 21

def pack_instructions(*bytes)
  pack_instructions!(bytes)
end

.pack_instructions!(bytes) ⇒ Object

: (Array bytes) -> String



16
17
18
# File 'lib/miniruby/bytecode_function.rb', line 16

def pack_instructions!(bytes)
  bytes.pack('c*')
end

.unpack_instructions(instructions) ⇒ Object

: (String instructions) -> Array



26
27
28
# File 'lib/miniruby/bytecode_function.rb', line 26

def unpack_instructions(instructions)
  instructions.unpack('c*') #: as untyped
end

Instance Method Details

#==(other) ⇒ Object

: (Object other) -> bool



121
122
123
124
125
126
127
128
# File 'lib/miniruby/bytecode_function.rb', line 121

def ==(other)
  return false unless other.is_a?(BytecodeFunction)

  @name == other.name &&
    @filename == other.filename &&
    @instructions == other.instructions &&
    @value_pool == other.value_pool
end

#add_bytes(*bytes) ⇒ Object

: (*Integer bytes) -> void



66
67
68
# File 'lib/miniruby/bytecode_function.rb', line 66

def add_bytes(*bytes)
  add_bytes!(bytes)
end

#add_bytes!(bytes) ⇒ Object

: (Array bytes) -> void



59
60
61
62
63
# File 'lib/miniruby/bytecode_function.rb', line 59

def add_bytes!(bytes)
  bytes.each do |byte|
    @instructions << byte.chr
  end
end

#add_value(value) ⇒ Object

Adds a value to the value pool and returns its index. Throws when the index is larger than 255. : (Object value) -> Integer



75
76
77
78
79
80
81
82
83
84
85
86
# File 'lib/miniruby/bytecode_function.rb', line 75

def add_value(value)
  id = @value_pool.find_index { _1 == value }
  return id if id

  id = @value_pool.length
  if id > MAX_VALUE_ID
    throw ArgumentError, "could not add value to the pool, exceeded #{MAX_VALUE_ID + 1} elements"
  end

  @value_pool << value
  id
end

#disassemble(out) ⇒ Object

: (IO out) -> void



102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
# File 'lib/miniruby/bytecode_function.rb', line 102

def disassemble(out)
  out.puts "== BytecodeFunction #{@name} at: #{@filename} =="
  return if @instructions.length == 0

  offset = 0
  while true
    offset = disassemble_instruction(out, offset)
    break if offset >= @instructions.length
  end

  @value_pool.each do |value|
    next unless value.is_a?(BytecodeFunction)

    out.puts
    value.disassemble(out)
  end
end

#disassemble_stdoutObject

: -> void



89
90
91
# File 'lib/miniruby/bytecode_function.rb', line 89

def disassemble_stdout
  disassemble($stdout)
end

#disassemble_stringObject

: -> String



94
95
96
97
98
99
# File 'lib/miniruby/bytecode_function.rb', line 94

def disassemble_string
  buff = StringIO.new
  disassemble(buff)

  buff.string
end

#inspectObject

: -> String



131
132
133
# File 'lib/miniruby/bytecode_function.rb', line 131

def inspect
  disassemble_string
end