~tim/scheme-vm

37eb0a8130330fdca5be6c2798ef9c33ef2c2c21 — Tim Morgan 5 years ago d7925c6
Fix bug with macro expansion
7 files changed, 21 insertions(+), 24 deletions(-)

M compiler.rb
M lib/logic.scm
M program.rb
M spec/lib/logic-spec.scm
M spec/lib_spec.rb
M spec/macro_spec.rb
M vm.rb
M compiler.rb => compiler.rb +1 -1
@@ 314,7 314,7 @@ class Compiler
        if part.to_s == '...' && prev
          expand_template("#{prev}...", values)
        else
          [expand_template(part, values)]
          [expand_template(part, values)].compact
        end
      end
    end

M lib/logic.scm => lib/logic.scm +7 -17
@@ 5,23 5,13 @@
    ((and test1 test2 ...)
     (if test1 (and test2 ...) #f))))

(define or
  (lambda conditions
    (if (= 0 (length conditions))
        #f
        (if (= 1 (length conditions))
            (car conditions)
            (if (car conditions)
                (car conditions)
                (apply or (cdr conditions)))))))

;(define-syntax or
;  (syntax-rules ()
;    ((or) #f)
;    ((or test) test)
;    ((or test1 test2 ...)
;     (let ((x test1))
;       (if x x (or test2 ...))))))
(define-syntax or
 (syntax-rules ()
   ((or) #f)
   ((or test) test)
   ((or test1 test2 ...)
    (let ((x test1))
      (if x x (or test2 ...))))))

(define not
  (lambda (condition)

M program.rb => program.rb +1 -1
@@ 26,7 26,7 @@ class Program
  def run(debug: 0)
    @compiler.pretty_print(@instr) if debug >= 2
    vm.execute(@instr, debug: debug)
  rescue => e
  rescue VM::VariableUndefined => e
    print_error_message(e)
  end


M spec/lib/logic-spec.scm => spec/lib/logic-spec.scm +6 -1
@@ 5,4 5,9 @@
(assert-eq 1 (and 1))
(assert-eq 2 (and 1 2))
(assert-eq #f (and #f 2))
(assert-eq 2 (and 1 2))

(assert-eq #f (or))
(assert-eq #t (or #t))
(assert-eq 1 (or 1))
(assert-eq 1 (or 1 2))
(assert-eq 2 (or #f 2))

M spec/lib_spec.rb => spec/lib_spec.rb +4 -1
@@ 5,14 5,17 @@ describe 'Libs' do
  let(:out) { StringIO.new }

  it 'passes all tests' do
    failed = false
    Dir[File.expand_path('../lib/**/*.scm', __FILE__)].each do |path|
      Program.new(File.read(path), filename: File.split(path).last, stdout: out).run
      out.rewind
      result = out.read
      if result != ''
        puts
        puts result
        fail 'spec failed'
        failed = true
      end
    end
    fail 'spec failed' if failed
  end
end

M spec/macro_spec.rb => spec/macro_spec.rb +0 -1
@@ 91,7 91,6 @@ describe Compiler do
          'VM::PUSH_LOCAL', 'z',
          'VM::PUSH_NUM', 3,
          'VM::PUSH_LIST',
          'VM::POP',
          'VM::RETURN',
          'VM::ENDF',
          'VM::CALL',

M vm.rb => vm.rb +2 -2
@@ 270,10 270,10 @@ class VM
        case name
        when 'SET_ARGS'
          print 'args:   '
          p @call_args.each_with_object({}) { |a, h| h[a] = resolve(a) }
          p @call_args.each_with_object({}) { |a, h| h[a] = resolve(a) rescue nil }
        when 'SET_LOCAL'
          print 'locals: '
          p locals.each_with_object({}) { |(n, a), h| h[n] = resolve(a) }
          p locals.each_with_object({}) { |(n, a), h| h[n] = resolve(a) rescue nil }
        when /^JUMP/
          print 'ip:     '
          p @ip