From 0c01804b7b9c7ba19467f97bf0e3e1225abcb4ca Mon Sep 17 00:00:00 2001 From: rhysd Date: Wed, 10 Jun 2015 07:37:49 +0900 Subject: [PATCH] Crisp::Type -> Crisp::Expr --- spec/crisp/interpreter_spec.cr | 4 ++-- src/crisp/core.cr | 16 ++++++++-------- src/crisp/env.cr | 8 ++++---- src/crisp/evaluator.cr | 24 ++++++++++++------------ src/crisp/interpreter.cr | 12 ++++++------ src/crisp/printer.cr | 6 +++--- src/crisp/reader.cr | 12 ++++++------ src/crisp/types.cr | 28 ++++++++++++++-------------- 8 files changed, 55 insertions(+), 55 deletions(-) diff --git a/spec/crisp/interpreter_spec.cr b/spec/crisp/interpreter_spec.cr index 1407bc7..eba2fec 100644 --- a/spec/crisp/interpreter_spec.cr +++ b/spec/crisp/interpreter_spec.cr @@ -5,7 +5,7 @@ describe "Crisp::Interpreter" do it "takes arguments as string value" do i = Crisp::Interpreter.new %w(foo bar baz) result = i.eval_string("*ARGV*") - result.should be_a(Crisp::Type) + result.should be_a(Crisp::Expr) unwrapped = result.unwrap unwrapped.should be_a(Crisp::List) if unwrapped.is_a? Crisp::List @@ -27,7 +27,7 @@ describe "Crisp::Interpreter" do it "evaluates string of Crisp expression" do i = Crisp::Interpreter.new result = i.eval_string "(+ 1 2)" - result.should be_a(Crisp::Type) + result.should be_a(Crisp::Expr) unwrapped = result.unwrap unwrapped.should be_a(Int32) unwrapped.should eq(3) diff --git a/src/crisp/core.cr b/src/crisp/core.cr index b1845ca..747b65b 100644 --- a/src/crisp/core.cr +++ b/src/crisp/core.cr @@ -10,10 +10,10 @@ module Crisp extend self macro calc_op(op) - -> (args : Array(Crisp::Type)) { + -> (args : Array(Crisp::Expr)) { x, y = args[0].unwrap, args[1].unwrap Crisp.eval_error "invalid arguments for binary operator {{op.id}}" unless x.is_a?(Int32) && y.is_a?(Int32) - Crisp::Type.new(x {{op.id}} y) + Crisp::Expr.new(x {{op.id}} y) } end @@ -77,7 +77,7 @@ module Crisp end def cons(args) - head, tail = args[0] as Crisp::Type, args[1].unwrap + head, tail = args[0] as Crisp::Expr, args[1].unwrap Crisp.eval_error "2nd arg of cons must be list" unless tail.is_a? Array ([head] + tail).to_crisp_value end @@ -245,7 +245,7 @@ module Crisp return nil unless a0.is_a? Crisp::HashMap Crisp.eval_error "2nd argument of get must be string" unless a1.is_a? String - # a0[a1]? isn't available because type ofa0[a1] is infered NoReturn + # a0[a1]? isn't available because type of a0[a1] is inferred NoReturn a0.has_key?(a1) ? a0[a1] : nil end @@ -259,7 +259,7 @@ module Crisp def keys(args) head = args.first.unwrap Crisp.eval_error "1st argument of assoc must be hashmap" unless head.is_a? Crisp::HashMap - head.keys.each_with_object(Crisp::List.new){|e,l| l << Crisp::Type.new(e)} + head.keys.each_with_object(Crisp::List.new){|e,l| l << Crisp::Expr.new(e)} end def vals(args) @@ -345,11 +345,11 @@ module Crisp # Note: # Simply using ->self.some_func doesn't work macro func(name) - -> (args : Array(Crisp::Type)) { Crisp::Type.new self.{{name.id}}(args) } + -> (args : Array(Crisp::Expr)) { Crisp::Expr.new self.{{name.id}}(args) } end macro rel_op(op) - -> (args : Array(Crisp::Type)) { Crisp::Type.new (args[0] {{op.id}} args[1]) } + -> (args : Array(Crisp::Expr)) { Crisp::Expr.new (args[0] {{op.id}} args[1]) } end NameSpace = { @@ -377,7 +377,7 @@ module Crisp "nth" => func(:nth) "first" => func(:first) "rest" => func(:rest) - "throw" => -> (args : Array(Crisp::Type)) { raise Crisp::RuntimeException.new args[0] } + "throw" => -> (args : Array(Crisp::Expr)) { raise Crisp::RuntimeException.new args[0] } "apply" => func(:apply) "map" => func(:map) "nil?" => func(:nil?) diff --git a/src/crisp/env.cr b/src/crisp/env.cr index 244c48c..26f50a9 100644 --- a/src/crisp/env.cr +++ b/src/crisp/env.cr @@ -7,11 +7,11 @@ module Crisp property data def initialize(@outer = nil) - @data = {} of String => Crisp::Type + @data = {} of String => Crisp::Expr end - def initialize(@outer, binds, exprs : Array(Crisp::Type)) - @data = {} of String => Crisp::Type + def initialize(@outer, binds, exprs : Array(Crisp::Expr)) + @data = {} of String => Crisp::Expr Crisp.eval_error "binds must be list or vector" unless binds.is_a? Array @@ -27,7 +27,7 @@ module Crisp Crisp.eval_error "bind name must be symbol" unless next_param.is_a? Crisp::Symbol var_args = Crisp::List.new exprs[idx..-1].each{|e| var_args << e} if idx < exprs.size - @data[next_param.str] = Crisp::Type.new var_args + @data[next_param.str] = Crisp::Expr.new var_args break end diff --git a/src/crisp/evaluator.cr b/src/crisp/evaluator.cr index 3ec131b..4fa189f 100644 --- a/src/crisp/evaluator.cr +++ b/src/crisp/evaluator.cr @@ -12,18 +12,18 @@ module Crisp class Evaluator def func_of(env, binds, body) - -> (args : Array(Crisp::Type)) { + -> (args : Array(Crisp::Expr)) { new_env = Crisp::Env.new(env, binds, args) eval(body, new_env) } as Crisp::Func end def eval_ast(ast, env) - return ast.map{|n| eval(n, env) as Crisp::Type} if ast.is_a? Array + return ast.map{|n| eval(n, env) as Crisp::Expr} if ast.is_a? Array val = ast.unwrap - Crisp::Type.new case val + Crisp::Expr.new case val when Crisp::Symbol if e = env.get(val.str) e @@ -51,7 +51,7 @@ module Crisp list = ast.unwrap unless pair?(list) - return Crisp::Type.new( + return Crisp::Expr.new( Crisp::List.new << gen_type(Crisp::Symbol, "quote") << ast ) end @@ -64,13 +64,13 @@ module Crisp list[1] # (("splice-unquote" ...) ...) when pair?(head) && (arg0 = head.first.unwrap).is_a?(Crisp::Symbol) && arg0.str == "splice-unquote" - tail = Crisp::Type.new list[1..-1].to_crisp_value - Crisp::Type.new( + tail = Crisp::Expr.new list[1..-1].to_crisp_value + Crisp::Expr.new( Crisp::List.new << gen_type(Crisp::Symbol, "concat") << head[1] << quasiquote(tail) ) else - tail = Crisp::Type.new list[1..-1].to_crisp_value - Crisp::Type.new( + tail = Crisp::Expr.new list[1..-1].to_crisp_value + Crisp::Expr.new( Crisp::List.new << gen_type(Crisp::Symbol, "cons") << quasiquote(list.first) << quasiquote(tail) ) end @@ -148,7 +148,7 @@ module Crisp return invoke_list(list, env) unless head.is_a? Crisp::Symbol - return Crisp::Type.new case head.str + return Crisp::Expr.new case head.str when "def!" Crisp.eval_error "wrong number of argument for 'def!'" unless list.size == 3 a1 = list[1].unwrap @@ -173,7 +173,7 @@ module Crisp next # TCO when "do" if list.empty? - ast = Crisp::Type.new nil + ast = Crisp::Expr.new nil next end @@ -182,7 +182,7 @@ module Crisp next # TCO when "if" ast = unless eval(list[1], env).unwrap - list.size >= 4 ? list[3] : Crisp::Type.new(nil) + list.size >= 4 ? list[3] : Crisp::Expr.new(nil) else list[2] end @@ -219,7 +219,7 @@ module Crisp new_env = Crisp::Env.new(env, [catch_list[1]], [e.thrown]) eval(catch_list[2], new_env) rescue e - new_env = Crisp::Env.new(env, [catch_list[1]], [Crisp::Type.new e.message]) + new_env = Crisp::Env.new(env, [catch_list[1]], [Crisp::Expr.new e.message]) eval(catch_list[2], new_env) end else diff --git a/src/crisp/interpreter.cr b/src/crisp/interpreter.cr index a77a7e5..489fae0 100644 --- a/src/crisp/interpreter.cr +++ b/src/crisp/interpreter.cr @@ -17,8 +17,8 @@ module Crisp @evaluator = Evaluator.new @env = Crisp::Env.new - Crisp::NameSpace.each{|k,v| @env.set(k, Crisp::Type.new(v))} - @env.set("eval", Crisp::Type.new -> (args: Array(Crisp::Type)){ @evaluator.eval(args[0], @env) }) + 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) \")\")))))" @@ -30,11 +30,11 @@ module Crisp if args args.each do |a| - argv << Crisp::Type.new a + argv << Crisp::Expr.new a end end - @env.set("*ARGV*", Crisp::Type.new argv) + @env.set("*ARGV*", Crisp::Expr.new argv) end def read(str) @@ -49,12 +49,12 @@ module Crisp @evaluator.eval(read(str), @env) end - def eval(t : Crisp::Type) + def eval(t : Crisp::Expr) @evaluator.eval(t, @env) end def eval(val) - @evaluator.eval(Crisp::Type.new val, @env) + @evaluator.eval(Crisp::Expr.new val, @env) end def run(filename = nil) diff --git a/src/crisp/printer.cr b/src/crisp/printer.cr index 20fe031..4072751 100644 --- a/src/crisp/printer.cr +++ b/src/crisp/printer.cr @@ -29,12 +29,12 @@ module Crisp when Crisp::Atom "(atom #{print(value.val)})" else - raise "invalid CrispType: #{value.to_s}" + raise "invalid CrispExpr: #{value.to_s}" end end - def print(t : Crisp::Type) - print(t.unwrap) + (t.macro? ? " (macro)" : "") + def print(e : Crisp::Expr) + print(e.unwrap) + (e.macro? ? " (macro)" : "") end end end diff --git a/src/crisp/reader.cr b/src/crisp/reader.cr index 4fc5ef0..ddbcde9 100644 --- a/src/crisp/reader.cr +++ b/src/crisp/reader.cr @@ -49,15 +49,15 @@ module Crisp end def read_list - Crisp::Type.new read_sequence(Crisp::List.new, '(', ')') + Crisp::Expr.new read_sequence(Crisp::List.new, '(', ')') end def read_vector - Crisp::Type.new read_sequence(Crisp::Vector.new, '[', ']') + Crisp::Expr.new read_sequence(Crisp::Vector.new, '[', ']') end def read_hashmap - types = read_sequence([] of Crisp::Type, '{', '}') + types = read_sequence([] of Crisp::Expr, '{', '}') Crisp.parse_error "odd number of elements for hash-map: #{types.size}" if types.size.odd? map = Crisp::HashMap.new @@ -72,14 +72,14 @@ module Crisp end end - Crisp::Type.new map + Crisp::Expr.new map end def read_atom token = self.next Crisp.parse_error "expected Atom but got EOF" unless token - Crisp::Type.new case + Crisp::Expr.new case when token =~ /^-?\d+$/ then token.to_i when token == "true" then true when token == "false" then false @@ -100,7 +100,7 @@ module Crisp Crisp.parse_error "unexpected EOF" unless token Crisp.parse_error "unexpected comment" if token[0] == ';' - Crisp::Type.new case token + Crisp::Expr.new case token when "(" then read_list when ")" then Crisp.parse_error "unexpected ')'" when "[" then read_vector diff --git a/src/crisp/types.cr b/src/crisp/types.cr index 632fae6..fb2898a 100644 --- a/src/crisp/types.cr +++ b/src/crisp/types.cr @@ -13,13 +13,13 @@ module Crisp end end - class List < Array(Type) + class List < Array(Expr) end - class Vector < Array(Type) + class Vector < Array(Expr) end - class HashMap < Hash(String, Type) + class HashMap < Hash(String, Expr) end class Atom @@ -38,21 +38,21 @@ module Crisp end end - class Type - alias Func = (Array(Type) -> Type) - alias ValueType = Nil | Bool | Int32 | String | Symbol | List | Vector | HashMap | Func | Closure | Atom + class Expr + alias Func = (Array(Expr) -> Expr) + alias ValueExpr = Nil | Bool | Int32 | String | Symbol | List | Vector | HashMap | Func | Closure | Atom is_macro :: Bool - meta :: Type + meta :: Expr property :is_macro, :meta - def initialize(@val : ValueType) + def initialize(@val : ValueExpr) @is_macro = false @meta = nil end - def initialize(other : Type) + def initialize(other : Expr) @val = other.unwrap @is_macro = other.is_macro @meta = other.meta @@ -71,19 +71,19 @@ module Crisp end def dup - Type.new(@val).tap do |t| + Expr.new(@val).tap do |t| t.is_macro = @is_macro t.meta = @meta end end - def ==(other : Type) + def ==(other : Expr) @val == other.unwrap end macro rel_op(*ops) {% for op in ops %} - def {{op.id}}(other : Crisp::Type) + def {{op.id}}(other : Crisp::Expr) l, r = @val, other.unwrap {% for t in [Int32, String] %} if l.is_a?({{t}}) && r.is_a?({{t}}) @@ -101,11 +101,11 @@ module Crisp rel_op :<, :>, :<=, :>= end - alias Func = Type::Func + alias Func = Expr::Func end macro gen_type(t, *args) - Crisp::Type.new {{t.id}}.new({{*args}}) + Crisp::Expr.new {{t.id}}.new({{*args}}) end class Array