class Lignite::OpCompiler

Compiles methods for all the instructions in ev3.yml The methods return the {ByteString}s corresponding to the ops.

Constants

PRIMPAR_1_BYTE
PRIMPAR_2_BYTES
PRIMPAR_4_BYTES
PRIMPAR_ADDR
PRIMPAR_BYTES
PRIMPAR_CONST
PRIMPAR_CONST_SIGN
PRIMPAR_GLOBAL
PRIMPAR_HANDLE
PRIMPAR_INDEX
PRIMPAR_LABEL
PRIMPAR_LOCAL
PRIMPAR_LONG
PRIMPAR_SHORT
PRIMPAR_STRING
PRIMPAR_STRING_OLD
PRIMPAR_VALUE
PRIMPAR_VARIABEL

Public Class Methods

new(globals = nil, locals = nil) click to toggle source

@param globals [Variables,nil] @param locals [Variables,nil]

# File lib/lignite/op_compiler.rb, line 15
def initialize(globals = nil, locals = nil)
  @globals = globals
  @locals = locals
end

Private Instance Methods

make_v(n, local_or_global) click to toggle source

@return [ByteString]

# File lib/lignite/op_compiler.rb, line 81
def make_v(n, local_or_global)
  vartag = PRIMPAR_VARIABEL | local_or_global
  bytes = if (0..31).cover? n
    [vartag | (n & PRIMPAR_VALUE)]
  elsif (0..255).cover? n
    [vartag | PRIMPAR_LONG | PRIMPAR_1_BYTE, n & 0xff]
  elsif (0..65535).cover? n
    [vartag | PRIMPAR_LONG | PRIMPAR_2_BYTES, n & 0xff, (n >> 8) & 0xff]
  else
    [vartag | PRIMPAR_LONG | PRIMPAR_4_BYTES,
     n & 0xff, (n >> 8) & 0xff, (n >> 16) & 0xff, (n >> 24) & 0xff]
  end
  bytes.map(&:chr).join("")
end
make_var(sym) click to toggle source

Reference a variable. (For declaring, see {VariableDeclarer}.) @return [ByteString]

# File lib/lignite/op_compiler.rb, line 99
def make_var(sym)
  raise "No variables declared, cannot process symbols" if @locals.nil? && @globals.nil?
  if @locals.key?(sym)
    o = @locals.offset(sym)
    make_v(o, PRIMPAR_LOCAL)
  elsif @globals.key?(sym)
    o = @globals.offset(sym)
    make_v(o, PRIMPAR_GLOBAL)
  else
    raise "Variable #{sym} not found"
  end
end
numeric_literal(n, next_size = nil) click to toggle source

@param n [Integer] value to encode @param next_size [Integer] how many bytes follow the initial opcode @return [ByteString]

# File lib/lignite/op_compiler.rb, line 67
def numeric_literal(n, next_size = nil)
  next_size ||= if (-31..31).cover? n
    0
  elsif (-127..127).cover? n
    1
  elsif (-32767..32767).cover? n
    2
  else
    4
  end
  numeric_literal_with_size(n, next_size)
end
numeric_literal_with_size(n, next_size) click to toggle source

@param n [Integer] value to encode @param next_size [Integer] how many bytes follow the initial opcode @return [ByteString]

# File lib/lignite/op_compiler.rb, line 49
def numeric_literal_with_size(n, next_size)
  bytes = case next_size
          when 0
            [n & PRIMPAR_VALUE]
          when 1
            [PRIMPAR_LONG | PRIMPAR_1_BYTE, n & 0xff]
          when 2
            [PRIMPAR_LONG | PRIMPAR_2_BYTES, n & 0xff, (n >> 8) & 0xff]
          else
            [PRIMPAR_LONG | PRIMPAR_4_BYTES,
             n & 0xff, (n >> 8) & 0xff, (n >> 16) & 0xff, (n >> 24) & 0xff]
  end
  bytes.map(&:chr).join("")
end
param_multiple(*args) click to toggle source

@return [ByteString]

# File lib/lignite/op_compiler.rb, line 118
def param_multiple(*args)
  args.map { |a| param_simple(a) }.join("")
end
param_n_multiple(*args) click to toggle source

@return [ByteString]

# File lib/lignite/op_compiler.rb, line 113
def param_n_multiple(*args)
  u8(args.size) + param_multiple(*args)
end
param_simple(x) click to toggle source

@return [ByteString]

# File lib/lignite/op_compiler.rb, line 135
def param_simple(x)
  case x
  when Numeric
    param_simple_numeric(x)
  when JumpOffset
    numeric_literal(x.value, x.size)
  when String
    u8(0x80) + x + u8(0x00)
  when true
    param_simple(1)
  when false
    param_simple(0)
  when Symbol
    make_var(x)
  else
    raise ArgumentError, "Unexpected type: #{x.class}"
  end
end
param_simple_numeric(x) click to toggle source

@return [ByteString]

# File lib/lignite/op_compiler.rb, line 123
def param_simple_numeric(x)
  case x
  when Integer
    numeric_literal(x)
  when Float
    u8(0x83) + f32(x)
  else
    raise ArgumentError, "Unexpected type: #{x.class}"
  end
end