A fork of Crisp for HARP
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.
 

76 lignes
1.9 KiB

require "colorize"
require "readline"
require "./reader"
require "./printer"
require "./types"
require "./env"
require "./core"
require "./error"
require "./evaluator"
module Crisp
class Interpreter
def initialize(args = nil)
@printer = Printer.new
@evaluator = Evaluator.new
@env = Crisp::Env.new
Crisp::NameSpace.each{|k,v| @env.set(k, Crisp::Expr.new(v))}
@env.set("eval", Crisp::Expr.new -> (args: Array(Crisp::Expr)){ @evaluator.eval(args[0], @env) })
eval_string "(def! not (fn* (a) (if a false true)))"
eval_string "(def! load-file (fn* (f) (eval (read-string (str \"(do \" (slurp f) \")\")))))"
eval_string "(defmacro! cond (fn* (& xs) (if (> (count xs) 0) (list 'if (first xs) (if (> (count xs) 1) (nth xs 1) (throw \"odd number of forms to cond\")) (cons 'cond (rest (rest xs)))))))"
eval_string "(defmacro! or (fn* (& xs) (if (empty? xs) nil (if (= 1 (count xs)) (first xs) `(let* (or_FIXME ~(first xs)) (if or_FIXME or_FIXME (or ~@(rest xs))))))))"
eval_string "(def! *host-language* \"crystal\")"
argv = Crisp::List.new
if args
args.each do |a|
argv << Crisp::Expr.new a
end
end
@env.set("*ARGV*", Crisp::Expr.new argv)
end
def read(str)
Crisp.read_str str
end
def print(result)
@printer.print(result)
end
def eval_string(str)
@evaluator.eval(read(str), @env)
end
def eval(t : Crisp::Expr)
@evaluator.eval(t, @env)
end
def eval(val)
@evaluator.eval(Crisp::Expr.new val, @env)
end
def run(filename = nil)
if filename
eval_string "(load-file \"#{filename}\")"
return
end
while line = Readline.readline("Crisp> ", true)
begin
puts self.print(eval_string(line))
rescue e
puts e.message
end
end
end
end
end