~tim/scheme-vm

8a35000c38241888bd2e9adcd1550bf66b521ea4 — Tim Morgan 4 years ago 85060b1
Build Char from stack value
7 files changed, 38 insertions(+), 21 deletions(-)

M compiler.rb
M spec/compiler_spec.rb
M spec/lib/char-spec.scm
M spec/vm_spec.rb
M vm.rb
M vm/char.rb
M vm/operations.rb
M compiler.rb => compiler.rb +7 -3
@@ 163,11 163,15 @@ class Compiler
  end

  def compile_character(name, options)
    char = {
    code = {
      'space'   => ' ',
      'newline' => "\n"
    }.fetch(name, name[0])
    [VM::PUSH_CHAR, char, pop_maybe(options)]
    }.fetch(name, name[0]).ord
    [
      VM::PUSH_NUM, code,
      VM::PUSH_CHAR,
      pop_maybe(options)
    ]
  end

  def compile_string(string, options)

M spec/compiler_spec.rb => spec/compiler_spec.rb +10 -5
@@ 110,11 110,14 @@ describe Compiler do

      it 'compiles into vm instructions' do
        expect(d(@result)).to eq([
          'VM::PUSH_CHAR', 'c',
          'VM::PUSH_NUM', 99,
          'VM::PUSH_CHAR',
          'VM::POP',
          'VM::PUSH_CHAR', ' ',
          'VM::PUSH_NUM', 32,
          'VM::PUSH_CHAR',
          'VM::POP',
          'VM::PUSH_CHAR', "\n",
          'VM::PUSH_NUM', 10,
          'VM::PUSH_CHAR',
          'VM::POP',
          'VM::HALT'
        ])


@@ 130,8 133,10 @@ describe Compiler do

      it 'compiles into vm instructions' do
        expect(d(@result)).to eq([
          'VM::PUSH_CHAR', 'a',
          'VM::PUSH_CHAR', 'b',
          'VM::PUSH_NUM', 97,
          'VM::PUSH_CHAR',
          'VM::PUSH_NUM', 98,
          'VM::PUSH_CHAR',
          'VM::PUSH_NUM', 2,
          'VM::PUSH_LIST',
          'VM::LIST_TO_STR',

M spec/lib/char-spec.scm => spec/lib/char-spec.scm +1 -0
@@ 4,3 4,4 @@
(assert (= 48 (char->integer #\0)))

(assert (= #\0 (integer->char 48)))
(assert (not (= #\1 (integer->char 48))))

M spec/vm_spec.rb => spec/vm_spec.rb +8 -5
@@ 132,7 132,7 @@ describe VM do

    it 'allocates memory, stores the character, and pushes address onto the stack' do
      expect(subject.stack_values).to eq([
        VM::Char.new('o')
        VM::Char.from_string('o')
      ])
    end
  end


@@ 156,8 156,10 @@ describe VM do
  describe 'LIST_TO_STR' do
    before do
      subject.execute([
        VM::PUSH_CHAR, 'a',
        VM::PUSH_CHAR, 'b',
        VM::PUSH_NUM, 97,
        VM::PUSH_CHAR,
        VM::PUSH_NUM, 98,
        VM::PUSH_CHAR,
        VM::PUSH_NUM, 2,
        VM::PUSH_LIST,
        VM::LIST_TO_STR,


@@ 197,14 199,15 @@ describe VM do
  describe 'PUSH_CHAR' do
    before do
      subject.execute([
        VM::PUSH_CHAR, 'c',
        VM::PUSH_NUM, 99,
        VM::PUSH_CHAR,
        VM::HALT
      ])
    end

    it 'allocates memory, stores the character, and pushes address onto the stack' do
      expect(subject.stack_values).to eq([
        VM::Char.new('c')
        VM::Char.from_string('c')
      ])
    end
  end

M vm.rb => vm.rb +1 -1
@@ 27,7 27,7 @@ class VM
    ['PUSH_ATOM',     1],
    ['PUSH_NUM',      1],
    ['PUSH_STR',      1],
    ['PUSH_CHAR',     1],
    ['PUSH_CHAR',     0],
    ['PUSH_TRUE',     0],
    ['PUSH_FALSE',    0],
    ['PUSH_TYPE',     0],

M vm/char.rb => vm/char.rb +9 -5
@@ 1,11 1,15 @@
class VM
  class Char
    def initialize(char)
      @byte = char.ord
    def initialize(code)
      @code = code
    end

    def self.from_string(str)
      new(str.ord)
    end

    def raw
      @byte
      @code
    end

    def ==(other)


@@ 16,11 20,11 @@ class VM
    alias eq? ==

    def to_s
      @byte.chr
      @code.chr
    end

    def to_ruby
      @byte.chr
      @code.chr
    end
  end
end

M vm/operations.rb => vm/operations.rb +2 -2
@@ 16,8 16,8 @@ class VM
    end

    def do_push_char
      char = fetch
      push_val(Char.new(char))
      code = pop_raw
      push_val(Char.new(code))
    end

    def do_push_true