Class: Iode::Interpreter
- Inherits:
-
Object
- Object
- Iode::Interpreter
- Includes:
- BuiltIns
- Defined in:
- lib/iode/interpreter.rb
Overview
Iode interpreter, providing the central #eval function.
Instance Method Summary collapse
-
#apply(fn, args) ⇒ Object
Apply a function to its arguments.
-
#eval(sexp) ⇒ Object
Given an iode data structure, execute it.
-
#initialize(scope = Scope.new) ⇒ Interpreter
constructor
Create a new Interpreter with a given Scope.
-
#lambda(argnames, *sexps) ⇒ Proc
Create a new lambda for Iode.
-
#progn(*sexps) ⇒ Object
Create an explicit progn block.
Methods included from BuiltIns
#caddddr, #cadddr, #caddr, #cadr, #car, #cdddddr, #cddddr, #cdddr, #cddr, #cdr
Constructor Details
#initialize(scope = Scope.new) ⇒ Interpreter
Create a new Interpreter with a given Scope.
26 27 28 |
# File 'lib/iode/interpreter.rb', line 26 def initialize(scope = Scope.new) @env = scope end |
Instance Method Details
#apply(fn, args) ⇒ Object
Apply a function to its arguments.
74 75 76 77 78 79 80 |
# File 'lib/iode/interpreter.rb', line 74 def apply(fn, args) if fn.respond_to?(:call) fn.call(*args) else raise "Cannot apply non-function `#{fn}`" end end |
#eval(sexp) ⇒ Object
Given an iode data structure, execute it.
89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 |
# File 'lib/iode/interpreter.rb', line 89 def eval(sexp) case sexp when Array case car(sexp) when nil nil when :quote cadr(sexp) when :if if eval(cadr(sexp)) eval(caddr(sexp)) else eval(cadddr(sexp)) end when :progn progn(*cdr(sexp)) when :set! @env[cadr(sexp)] = eval(caddr(sexp)) when :lambda lambda(cadr(sexp), *cddr(sexp)) else apply(eval(car(sexp)), cdr(sexp).map(&method(:eval))) end when Symbol @env[sexp] else sexp end end |
#lambda(argnames, *sexps) ⇒ Proc
Create a new lambda for Iode.
These lambdas act as closures in their environment.
56 57 58 59 60 61 62 |
# File 'lib/iode/interpreter.rb', line 56 def lambda(argnames, *sexps) Proc.new do |*args| Interpreter.new( @env.push_scope(Hash[argnames.zip(args)]) ).progn(*sexps) end end |
#progn(*sexps) ⇒ Object
Create an explicit progn block.
A progn encapsulates a list of S-Expressions to be evaluated in sequence. The last evaluated S-Expression becomes the value of the progn.
40 41 42 |
# File 'lib/iode/interpreter.rb', line 40 def progn(*sexps) sexps.inject(nil){|_,s| eval(s)} end |