Sha256: 355e8a73e7632867f67ea0862420df67fd49b58cbe2c816d8a6abe811809f97f

Contents?: true

Size: 1.11 KB

Versions: 1

Compression:

Stored size: 1.11 KB

Contents

require "minilisp/version"

module Minilisp
  class Interpreter

    def initialize
      @env = { 
        :label => lambda { |(name,val), _| @env[name] = val },
        :quote => lambda { |sexpr, _| sexpr[0] },
        :car   => lambda { |(list), _| list[0] },
        :cdr   => lambda { |(list), _| list.drop 1 },
        :cons  => lambda { |(e,cell), _| [e] + cell },
        :eq    => lambda { |(l,r), _| l == r },
        :if    => lambda { |(cond, thn, els), ctx| eval(cond, ctx) ? eval(thn, ctx) : eval(els, ctx) },
        :atom  => lambda { |(sexpr), _| (sexpr.is_a? Symbol) or (sexpr.is_a? Numeric) }
      }
    end
   
    def apply fn, args, ctx=@env
      return @env[fn].call(args, ctx) if @env[fn].respond_to? :call
   
      self.eval @env[fn][2], Hash[*(@env[fn][1].zip args).flatten(1)]
    end
   
    def eval sexpr, ctx=@env
      if @env[:atom].call [sexpr], ctx
        return ctx[sexpr] if ctx[sexpr]
        return sexpr
      end
   
      fn = sexpr[0]
      args = (sexpr.drop 1)
      args = args.map { |a| self.eval(a, ctx) } if not [:quote, :if].member? fn
      apply(fn, args, ctx)
    end

  end
end

Version data entries

1 entries across 1 versions & 1 rubygems

Version Path
minilisp-0.1.0 lib/minilisp.rb