From 2efe9443780500c73cc08669ef4a2080f22b2352 Mon Sep 17 00:00:00 2001 From: Jon Date: Sat, 24 Feb 2018 13:43:44 -0500 Subject: [PATCH] [interpreter,spec] Rename `Value` to `MTValue`. In the past, collision between the Myst-level type `Value` and Crystal's native `Value` class has been cumbersome (requiring namespacing as `Myst::Value`). Renaming to `MTValue` clears that confusion, and makes it more obvious where we're talking about Myst values. --- spec/interpreter/invocation_spec.cr | 2 +- spec/interpreter/nodes/interpolation_spec.cr | 4 +- spec/interpreter/nodes/literals_spec.cr | 4 +- spec/interpreter/value_spec.cr | 32 +++++++-------- spec/support/breakpoints.cr | 4 +- spec/support/interpret.cr | 14 +++---- src/myst/interpreter.cr | 12 +++--- src/myst/interpreter/closure_scope.cr | 6 +-- src/myst/interpreter/exceptions.cr | 4 +- src/myst/interpreter/invocation.cr | 8 ++-- src/myst/interpreter/matcher.cr | 8 ++-- src/myst/interpreter/native_lib.cr | 14 +++---- src/myst/interpreter/native_lib/boolean.cr | 4 +- src/myst/interpreter/native_lib/float.cr | 22 +++++----- src/myst/interpreter/native_lib/integer.cr | 22 +++++----- src/myst/interpreter/native_lib/io.cr | 4 +- src/myst/interpreter/native_lib/list.cr | 6 +-- src/myst/interpreter/native_lib/map.cr | 8 ++-- src/myst/interpreter/native_lib/nil.cr | 4 +- src/myst/interpreter/native_lib/random.cr | 8 ++-- src/myst/interpreter/native_lib/string.cr | 12 +++--- src/myst/interpreter/native_lib/symbol.cr | 4 +- src/myst/interpreter/native_lib/time.cr | 8 ++-- src/myst/interpreter/native_lib/top_level.cr | 6 +-- src/myst/interpreter/nodes/call.cr | 6 +-- src/myst/interpreter/nodes/def.cr | 2 +- .../interpreter/nodes/exception_handler.cr | 2 +- src/myst/interpreter/nodes/literals.cr | 10 ++--- src/myst/interpreter/nodes/unary_ops.cr | 6 +-- src/myst/interpreter/scope.cr | 12 +++--- src/myst/interpreter/util.cr | 12 +++--- src/myst/interpreter/value.cr | 40 +++++++++---------- 32 files changed, 155 insertions(+), 155 deletions(-) diff --git a/spec/interpreter/invocation_spec.cr b/spec/interpreter/invocation_spec.cr index 6ba594f..0546ede 100644 --- a/spec/interpreter/invocation_spec.cr +++ b/spec/interpreter/invocation_spec.cr @@ -88,7 +88,7 @@ private def it_invokes(prelude, call, expected) # clarity in the tests, the stack is cleared of any existing values before # making any assertions. itr.stack.clear - it_interprets(call, [expected] of Myst::Value, itr) + it_interprets(call, [expected] of MTValue, itr) end describe "Interpreter - Invocation" do diff --git a/spec/interpreter/nodes/interpolation_spec.cr b/spec/interpreter/nodes/interpolation_spec.cr index 7fed289..1c715c1 100644 --- a/spec/interpreter/nodes/interpolation_spec.cr +++ b/spec/interpreter/nodes/interpolation_spec.cr @@ -17,11 +17,11 @@ describe "Interpreter - Interpolation" do it_interprets %q(<[1]>), [TList.new([val(1)])] it_interprets %q(<[1, 2, 3]>), [TList.new([val(1), val(2), val(3)])] it_interprets %q(<[nil, :hi]>), [TList.new([val(nil), val(:hi)])] - it_interprets %q(<[[1, 2], [3, 4]]>), [TList.new([TList.new([val(1), val(2)]), TList.new([val(3), val(4)])] of Myst::Value)] + it_interprets %q(<[[1, 2], [3, 4]]>), [TList.new([TList.new([val(1), val(2)]), TList.new([val(3), val(4)])] of MTValue)] it_interprets %q(<{a: 1 }>), [TMap.new({ val(:a) => val(1) })] it_interprets %q(<{<1>: "int", : :nil }>), [TMap.new({ val(1) => val("int"), val(nil) => val(:nil) })] - it_interprets %q(<{<{a: 1}>: {b: 2}}>), [TMap.new({ TMap.new({ val(:a) => val(1) }) => TMap.new({ val(:b) => val(2) }) } of Myst::Value => Myst::Value)] + it_interprets %q(<{<{a: 1}>: {b: 2}}>), [TMap.new({ TMap.new({ val(:a) => val(1) }) => TMap.new({ val(:b) => val(2) }) } of MTValue => MTValue)] it_interprets %q(<(true && true)>), [val(true)] it_interprets %q(<(false && true)>), [val(false)] diff --git a/spec/interpreter/nodes/literals_spec.cr b/spec/interpreter/nodes/literals_spec.cr index af7e31f..a7986e6 100644 --- a/spec/interpreter/nodes/literals_spec.cr +++ b/spec/interpreter/nodes/literals_spec.cr @@ -17,9 +17,9 @@ describe "Interpreter - Literals" do it_interprets %q([1]), [TList.new([val(1)])] it_interprets %q([1, 2, 3]), [TList.new([val(1), val(2), val(3)])] it_interprets %q([nil, :hi]), [TList.new([val(nil), val(:hi)])] - it_interprets %q([[1, 2], [3, 4]]), [TList.new([TList.new([val(1), val(2)]), TList.new([val(3), val(4)])] of Myst::Value)] + it_interprets %q([[1, 2], [3, 4]]), [TList.new([TList.new([val(1), val(2)]), TList.new([val(3), val(4)])] of MTValue)] it_interprets %q({a: 1}), [TMap.new({ val(:a) => val(1) })] it_interprets %q({<1>: "int", : :nil}), [TMap.new({ val(1) => val("int"), val(nil) => val(:nil) })] - it_interprets %q({<{a: 1}>: {b: 2}}), [TMap.new({ TMap.new({ val(:a) => val(1) }) => TMap.new({ val(:b) => val(2) }) } of Myst::Value => Myst::Value)] + it_interprets %q({<{a: 1}>: {b: 2}}), [TMap.new({ TMap.new({ val(:a) => val(1) }) => TMap.new({ val(:b) => val(2) }) } of MTValue => MTValue)] end diff --git a/spec/interpreter/value_spec.cr b/spec/interpreter/value_spec.cr index 1f46180..b7fb4d4 100644 --- a/spec/interpreter/value_spec.cr +++ b/spec/interpreter/value_spec.cr @@ -3,38 +3,38 @@ require "../spec_helper.cr" describe "Values" do describe "::from_literal" do it "maps NilLiteral to TNil" do - Myst::Value.from_literal(NilLiteral.new).should be_a(TNil) + MTValue.from_literal(NilLiteral.new).should be_a(TNil) end it "maps BooleanLiteral to TBoolean" do - Myst::Value.from_literal(BooleanLiteral.new(false)).should be_a(TBoolean) + MTValue.from_literal(BooleanLiteral.new(false)).should be_a(TBoolean) end it "maps IntegerLiteral to TInteger" do - Myst::Value.from_literal(IntegerLiteral.new("0")).should be_a(TInteger) + MTValue.from_literal(IntegerLiteral.new("0")).should be_a(TInteger) end it "maps FloatLiteral to TFloat" do - Myst::Value.from_literal(FloatLiteral.new("0.0")).should be_a(TFloat) + MTValue.from_literal(FloatLiteral.new("0.0")).should be_a(TFloat) end it "maps StringLiteral to TString" do - Myst::Value.from_literal(StringLiteral.new("hello")).should be_a(TString) + MTValue.from_literal(StringLiteral.new("hello")).should be_a(TString) end it "maps SymbolLiteral to TSymbol" do - Myst::Value.from_literal(SymbolLiteral.new("hi")).should be_a(TSymbol) + MTValue.from_literal(SymbolLiteral.new("hi")).should be_a(TSymbol) end # Container values like List and Map require some effort from the # interpreter to be generated. As such, Value::from_literal cannot generate # them automatically from a node. it "does not map ListLiterals" do - expect_raises(Exception) { Myst::Value.from_literal(ListLiteral.new).should be_a(TList) } + expect_raises(Exception) { MTValue.from_literal(ListLiteral.new).should be_a(TList) } end it "does not map MapLiterals" do - expect_raises(Exception) { Myst::Value.from_literal(MapLiteral.new).should be_a(TMap) } + expect_raises(Exception) { MTValue.from_literal(MapLiteral.new).should be_a(TMap) } end end @@ -239,7 +239,7 @@ hi end it "can be created with initial elements" do - TList.new([TNil.new, TNil.new] of Myst::Value) + TList.new([TNil.new, TNil.new] of MTValue) end it "can contain any mixture of Values" do @@ -247,7 +247,7 @@ hi end it "can contain other lists within itself" do - TList.new([TList.new, TList.new] of Myst::Value) + TList.new([TList.new, TList.new] of MTValue) end it "can dynamically adjust its size" do @@ -260,8 +260,8 @@ hi it "is always truthy" do TList.new.truthy?.should eq(true) - TList.new([TNil.new] of Myst::Value).truthy?.should eq(true) - TList.new([TBoolean.new(false)] of Myst::Value).truthy?.should eq(true) + TList.new([TNil.new] of MTValue).truthy?.should eq(true) + TList.new([TBoolean.new(false)] of MTValue).truthy?.should eq(true) TList.new([TInteger.new(1_i64), TNil.new]).truthy?.should eq(true) end end @@ -273,7 +273,7 @@ hi end it "can be created with initial elements" do - TMap.new({ TNil.new => TNil.new } of Myst::Value => Myst::Value) + TMap.new({ TNil.new => TNil.new } of MTValue => MTValue) end it "can contain any mixture of Values" do @@ -281,7 +281,7 @@ hi end it "can contain other maps within itself" do - TMap.new({ TMap.new => TMap.new } of Myst::Value => Myst::Value) + TMap.new({ TMap.new => TMap.new } of MTValue => MTValue) end it "can dynamically adjust its size" do @@ -294,8 +294,8 @@ hi it "is always truthy" do TMap.new.truthy?.should eq(true) - TMap.new({ TNil.new => TNil.new } of Myst::Value => Myst::Value).truthy?.should eq(true) - TMap.new({ TSymbol.new("") => TInteger.new(1_i64) } of Myst::Value => Myst::Value).truthy?.should eq(true) + TMap.new({ TNil.new => TNil.new } of MTValue => MTValue).truthy?.should eq(true) + TMap.new({ TSymbol.new("") => TInteger.new(1_i64) } of MTValue => MTValue).truthy?.should eq(true) end end end diff --git a/spec/support/breakpoints.cr b/spec/support/breakpoints.cr index b62325f..e7a3a37 100644 --- a/spec/support/breakpoints.cr +++ b/spec/support/breakpoints.cr @@ -28,12 +28,12 @@ require "../spec_helper.cr" # end # ), interpreter: itr macro add_breakpoint(itr, name) - %handler = ->(this : Myst::Value, __args : Array(Myst::Value), block : TFunctor?) do + %handler = ->(this : MTValue, __args : Array(MTValue), block : TFunctor?) do %result = begin {{ yield }} end - %result.is_a?(Myst::Value) ? %result : TNil.new.as(Myst::Value) + %result.is_a?(MTValue) ? %result : TNil.new.as(MTValue) end {{itr}}.kernel.scope[{{name}}] = TFunctor.new({{name}}, [%handler] of Callable) diff --git a/spec/support/interpret.cr b/spec/support/interpret.cr index 6dc0855..47614c8 100644 --- a/spec/support/interpret.cr +++ b/spec/support/interpret.cr @@ -1,7 +1,7 @@ require "../spec_helper.cr" require "./nodes.cr" -def it_interprets(node : String, expected_stack : Array(Myst::Value), itr=Interpreter.new, file=__FILE__, line=__LINE__, end_line=__END_LINE__) +def it_interprets(node : String, expected_stack : Array(MTValue), itr=Interpreter.new, file=__FILE__, line=__LINE__, end_line=__END_LINE__) it %Q(interprets #{node}), file, line, end_line do program = parse_program(node) itr.run(program) @@ -31,11 +31,11 @@ def it_interprets(node : String, file=__FILE__, line=__LINE__, end_line=__END_LI end def it_interprets(node : String, file=__FILE__, line=__LINE__, end_line=__END_LINE__) - it_interprets(node, [] of Myst::Value, Interpreter.new, file, line, end_line) + it_interprets(node, [] of MTValue, Interpreter.new, file, line, end_line) end -def it_interprets_with_assignments(node : String, assignments : Hash(String, Myst::Value), itr=Interpreter.new, file=__FILE__, line=__LINE__, end_line=__END_LINE__) +def it_interprets_with_assignments(node : String, assignments : Hash(String, MTValue), itr=Interpreter.new, file=__FILE__, line=__LINE__, end_line=__END_LINE__) it %Q(interprets #{node}), file, line, end_line do program = parse_program(node) itr.run(program) @@ -99,21 +99,21 @@ end # val(node) # -# Run `Value.from_literal` on the given node and return the result. If `node` +# Run `MTValue.from_literal` on the given node and return the result. If `node` # is not already a Node, it will be run through `l` first. def val(node : Node) - Myst::Value.from_literal(node).as(Myst::Value) + MTValue.from_literal(node).as(MTValue) end def val(node : Array(T)) forall T - TList.new(node.map{ |n| val(n) }).as(Myst::Value) + TList.new(node.map{ |n| val(n) }).as(MTValue) end def val(node : Hash(K, V)) forall K, V node.reduce(TMap.new) do |map, (k, v)| map.entries[val(k)] = val(v) map - end.as(Myst::Value) + end.as(MTValue) end def val(node); val(l(node)); end diff --git a/src/myst/interpreter.cr b/src/myst/interpreter.cr index 17a2e9a..2da3608 100644 --- a/src/myst/interpreter.cr +++ b/src/myst/interpreter.cr @@ -4,8 +4,8 @@ require "./interpreter/native_lib" module Myst class Interpreter - property stack : Array(Value) - property self_stack : Array(Value) + property stack : Array(MTValue) + property self_stack : Array(MTValue) property scope_stack : Array(Scope) property callstack : Callstack property kernel : TModule @@ -22,11 +22,11 @@ module Myst 2 => errput }) - @stack = [] of Value + @stack = [] of MTValue @scope_stack = [] of Scope @callstack = Callstack.new @kernel = create_kernel - @self_stack = [@kernel] of Value + @self_stack = [@kernel] of MTValue @warnings = 0 end @@ -85,7 +85,7 @@ module Myst self_stack.last end - def push_self(new_self : Value) + def push_self(new_self : MTValue) self_stack.push(new_self) end @@ -119,7 +119,7 @@ module Myst def put_error(error : RuntimeError) value_to_s = __scopeof(error.value)["to_s"].as(TFunctor) - result = Invocation.new(self, value_to_s, error.value, [] of Value, nil).invoke + result = Invocation.new(self, value_to_s, error.value, [] of MTValue, nil).invoke errput.puts("Uncaught Exception: " + result.as(TString).value) errput.puts(error.trace) end diff --git a/src/myst/interpreter/closure_scope.cr b/src/myst/interpreter/closure_scope.cr index acc162f..7f02fa8 100644 --- a/src/myst/interpreter/closure_scope.cr +++ b/src/myst/interpreter/closure_scope.cr @@ -9,7 +9,7 @@ module Myst property closed_scope : Scope def initialize(@closed_scope : Scope, @parent : Scope? = nil) - @values = {} of String => Value + @values = {} of String => MTValue end def []?(key : String) @@ -20,7 +20,7 @@ module Myst end end - def []=(key : String, value : Value) + def []=(key : String, value : MTValue) if closed_scope.has_key?(key) closed_scope.assign(key, value) else @@ -32,7 +32,7 @@ module Myst !!@values[key]? || closed_scope.has_key?(key) end - def assign(key : String, value : Value) + def assign(key : String, value : MTValue) if closed_scope.has_key?(key) closed_scope.assign(key, value) else diff --git a/src/myst/interpreter/exceptions.cr b/src/myst/interpreter/exceptions.cr index b7b7760..2b9aa34 100644 --- a/src/myst/interpreter/exceptions.cr +++ b/src/myst/interpreter/exceptions.cr @@ -14,10 +14,10 @@ module Myst # The containing error type for any error raised within the language. class RuntimeError < Exception - property value : Value + property value : MTValue property trace : Callstack - def initialize(@value : Value, @trace : Callstack) + def initialize(@value : MTValue, @trace : Callstack) end end diff --git a/src/myst/interpreter/invocation.cr b/src/myst/interpreter/invocation.cr index adefe05..5b9e08d 100644 --- a/src/myst/interpreter/invocation.cr +++ b/src/myst/interpreter/invocation.cr @@ -11,14 +11,14 @@ module Myst struct Invocation property itr : Interpreter property func : TFunctor - property! receiver : Value? - property args : Array(Value) + property! receiver : MTValue? + property args : Array(MTValue) property! block : TFunctor? @selfstack_size_at_entry : Int32 = -1 @scopestack_size_at_entry : Int32 = -1 @callstack_size_at_entry : Int32 = -1 - def initialize(@itr : Interpreter, @func : TFunctor, @receiver : Value?, @args : Array(Value), @block : TFunctor?) + def initialize(@itr : Interpreter, @func : TFunctor, @receiver : MTValue?, @args : Array(MTValue), @block : TFunctor?) end def invoke @@ -113,7 +113,7 @@ module Myst return @itr.stack.pop end - private def do_call(func : TNativeDef, receiver : Value, args : Array(Value), block : TFunctor?) + private def do_call(func : TNativeDef, receiver : MTValue, args : Array(MTValue), block : TFunctor?) func.call(receiver, args, block) end diff --git a/src/myst/interpreter/matcher.cr b/src/myst/interpreter/matcher.cr index 110b53c..4dcdf83 100644 --- a/src/myst/interpreter/matcher.cr +++ b/src/myst/interpreter/matcher.cr @@ -2,7 +2,7 @@ require "./exceptions.cr" module Myst class Interpreter - def match(pattern : Node, value : Value) + def match(pattern : Node, value : MTValue) case pattern when ListLiteral match_list(pattern, value) @@ -31,7 +31,7 @@ module Myst # For simplicity and efficiency, the equality of values according to a # match operation is determined by the native equality of the values, not # by any override of `==`. - private def match_value(pattern : Node, right : Value) + private def match_value(pattern : Node, right : MTValue) visit(pattern) left = stack.pop success = @@ -51,7 +51,7 @@ module Myst success || __raise_runtime_error(MatchError.new(callstack)) end - private def match_list(pattern : ListLiteral, value : Value) + private def match_list(pattern : ListLiteral, value : MTValue) __raise_runtime_error(MatchError.new(callstack)) unless value.is_a?(TList) left, splat, right = chunk_list_pattern(pattern) @@ -68,7 +68,7 @@ module Myst end end - private def match_map(pattern : MapLiteral, value : Value) + private def match_map(pattern : MapLiteral, value : MTValue) __raise_runtime_error(MatchError.new(callstack)) unless value.is_a?(TMap) pattern.entries.each do |entry| diff --git a/src/myst/interpreter/native_lib.cr b/src/myst/interpreter/native_lib.cr index 06506a6..3259820 100644 --- a/src/myst/interpreter/native_lib.cr +++ b/src/myst/interpreter/native_lib.cr @@ -6,19 +6,19 @@ module Myst # function. The function can be either a native function or a source-level # function. The results do not affect the stack, the result of calling the # function will be returned directly. - def call_func(itr, func : TFunctor, args : Array(Value), receiver : Value?=nil) + def call_func(itr, func : TFunctor, args : Array(MTValue), receiver : MTValue?=nil) Invocation.new(itr, func, receiver, args, nil).invoke end # Same as `call_func`, but the function to call is given as a name to # look up on the given receiver. - def call_func_by_name(itr, receiver : Value, name : String, args : Array(Value)) + def call_func_by_name(itr, receiver : MTValue, name : String, args : Array(MTValue)) func = itr.__scopeof(receiver)[name].as(TFunctor) Invocation.new(itr, func, receiver, args, nil).invoke end # Instantiate a given type and invoke its initializer - def instantiate(itr, type : TType, params : Array(Value)) : TInstance + def instantiate(itr, type : TType, params : Array(MTValue)) : TInstance instance = TInstance.new(type) if (initializer = instance.scope["initialize"]?) && initializer.is_a?(TFunctor) @@ -29,7 +29,7 @@ module Myst end macro method(name, this_type, *params, &block) - def {{name.id}}(this : Value, __args : Array(Value), block : TFunctor?) : Value + def {{name.id}}(this : MTValue, __args : Array(MTValue), block : TFunctor?) : MTValue this = this.as({{this_type}}) {% for type, index in params %} @@ -40,19 +40,19 @@ module Myst {{block.body}} end - %result.as(Value) + %result.as(MTValue) end end macro def_method(type, name, impl_name) {{type}}.scope["{{name.id}}"] = TFunctor.new("{{name.id}}", [ - ->{{impl_name.id}}(Value, Array(Value), TFunctor?).as(Callable) + ->{{impl_name.id}}(MTValue, Array(MTValue), TFunctor?).as(Callable) ] of Callable) end macro def_instance_method(type, name, impl_name) {{type}}.instance_scope["{{name.id}}"] = TFunctor.new("{{name.id}}", [ - ->{{impl_name.id}}(Value, Array(Value), TFunctor?).as(Callable) + ->{{impl_name.id}}(MTValue, Array(MTValue), TFunctor?).as(Callable) ] of Callable) end end diff --git a/src/myst/interpreter/native_lib/boolean.cr b/src/myst/interpreter/native_lib/boolean.cr index ce3eefb..6613059 100644 --- a/src/myst/interpreter/native_lib/boolean.cr +++ b/src/myst/interpreter/native_lib/boolean.cr @@ -4,7 +4,7 @@ module Myst TString.new(this.value ? "true" : "false") end - NativeLib.method :bool_eq, TBoolean, other : Value do + NativeLib.method :bool_eq, TBoolean, other : MTValue do case other when TBoolean TBoolean.new(this.value == other.value) @@ -13,7 +13,7 @@ module Myst end end - NativeLib.method :bool_not_eq, TBoolean, other : Value do + NativeLib.method :bool_not_eq, TBoolean, other : MTValue do case other when TBoolean TBoolean.new(this.value != other.value) diff --git a/src/myst/interpreter/native_lib/float.cr b/src/myst/interpreter/native_lib/float.cr index 52455ce..1d499db 100644 --- a/src/myst/interpreter/native_lib/float.cr +++ b/src/myst/interpreter/native_lib/float.cr @@ -1,6 +1,6 @@ module Myst class Interpreter - NativeLib.method :float_add, TFloat, other : Value do + NativeLib.method :float_add, TFloat, other : MTValue do case other when TInteger, TFloat TFloat.new(this.value + other.value) @@ -9,7 +9,7 @@ module Myst end end - NativeLib.method :float_subtract, TFloat, other : Value do + NativeLib.method :float_subtract, TFloat, other : MTValue do case other when TInteger, TFloat TFloat.new(this.value - other.value) @@ -18,7 +18,7 @@ module Myst end end - NativeLib.method :float_multiply, TFloat, other : Value do + NativeLib.method :float_multiply, TFloat, other : MTValue do case other when TInteger, TFloat TFloat.new(this.value * other.value) @@ -27,7 +27,7 @@ module Myst end end - NativeLib.method :float_divide, TFloat, other : Value do + NativeLib.method :float_divide, TFloat, other : MTValue do case other when TInteger, TFloat __raise_runtime_error("Division by zero") if other.value == 0 @@ -37,7 +37,7 @@ module Myst end end - NativeLib.method :float_modulo, TFloat, other : Value do + NativeLib.method :float_modulo, TFloat, other : MTValue do case other when TInteger, TFloat __raise_runtime_error("Division by zero") if other.value == 0 @@ -51,7 +51,7 @@ module Myst TString.new(this.value.to_s) end - NativeLib.method :float_eq, TFloat, other : Value do + NativeLib.method :float_eq, TFloat, other : MTValue do case other when TFloat, TInteger TBoolean.new(this.value == other.value) @@ -60,7 +60,7 @@ module Myst end end - NativeLib.method :float_not_eq, TFloat, other : Value do + NativeLib.method :float_not_eq, TFloat, other : MTValue do case other when TFloat, TInteger TBoolean.new(this.value != other.value) @@ -73,7 +73,7 @@ module Myst TFloat.new(-this.value) end - NativeLib.method :float_lt, TFloat, other : Value do + NativeLib.method :float_lt, TFloat, other : MTValue do case other when TInteger, TFloat TBoolean.new(this.value < other.value) @@ -82,7 +82,7 @@ module Myst end end - NativeLib.method :float_lte, TFloat, other : Value do + NativeLib.method :float_lte, TFloat, other : MTValue do case other when TInteger, TFloat TBoolean.new(this.value <= other.value) @@ -91,7 +91,7 @@ module Myst end end - NativeLib.method :float_gt, TFloat, other : Value do + NativeLib.method :float_gt, TFloat, other : MTValue do case other when TInteger, TFloat TBoolean.new(this.value > other.value) @@ -100,7 +100,7 @@ module Myst end end - NativeLib.method :float_gte, TFloat, other : Value do + NativeLib.method :float_gte, TFloat, other : MTValue do case other when TInteger, TFloat TBoolean.new(this.value >= other.value) diff --git a/src/myst/interpreter/native_lib/integer.cr b/src/myst/interpreter/native_lib/integer.cr index d29cec4..4b7eef3 100644 --- a/src/myst/interpreter/native_lib/integer.cr +++ b/src/myst/interpreter/native_lib/integer.cr @@ -1,6 +1,6 @@ module Myst class Interpreter - NativeLib.method :int_add, TInteger, other : Value do + NativeLib.method :int_add, TInteger, other : MTValue do case other when TInteger TInteger.new(this.value + other.value) @@ -11,7 +11,7 @@ module Myst end end - NativeLib.method :int_subtract, TInteger, other : Value do + NativeLib.method :int_subtract, TInteger, other : MTValue do case other when TInteger TInteger.new(this.value - other.value) @@ -22,7 +22,7 @@ module Myst end end - NativeLib.method :int_multiply, TInteger, other : Value do + NativeLib.method :int_multiply, TInteger, other : MTValue do case other when TInteger TInteger.new(this.value * other.value) @@ -33,7 +33,7 @@ module Myst end end - NativeLib.method :int_divide, TInteger, other : Value do + NativeLib.method :int_divide, TInteger, other : MTValue do case other when TInteger __raise_runtime_error("Division by zero") if other.value == 0 @@ -46,7 +46,7 @@ module Myst end end - NativeLib.method :int_modulo, TInteger, other : Value do + NativeLib.method :int_modulo, TInteger, other : MTValue do case other when TInteger __raise_runtime_error("Division by zero") if other.value == 0 @@ -63,7 +63,7 @@ module Myst TString.new(this.value.to_s) end - NativeLib.method :int_eq, TInteger, other : Value do + NativeLib.method :int_eq, TInteger, other : MTValue do case other when TInteger, TFloat TBoolean.new(this.value == other.value) @@ -72,7 +72,7 @@ module Myst end end - NativeLib.method :int_not_eq, TInteger, other : Value do + NativeLib.method :int_not_eq, TInteger, other : MTValue do case other when TInteger, TFloat TBoolean.new(this.value != other.value) @@ -85,7 +85,7 @@ module Myst TInteger.new(-this.value) end - NativeLib.method :int_lt, TInteger, other : Value do + NativeLib.method :int_lt, TInteger, other : MTValue do case other when TInteger, TFloat TBoolean.new(this.value < other.value) @@ -94,7 +94,7 @@ module Myst end end - NativeLib.method :int_lte, TInteger, other : Value do + NativeLib.method :int_lte, TInteger, other : MTValue do case other when TInteger, TFloat TBoolean.new(this.value <= other.value) @@ -103,7 +103,7 @@ module Myst end end - NativeLib.method :int_gt, TInteger, other : Value do + NativeLib.method :int_gt, TInteger, other : MTValue do case other when TInteger, TFloat TBoolean.new(this.value > other.value) @@ -112,7 +112,7 @@ module Myst end end - NativeLib.method :int_gte, TInteger, other : Value do + NativeLib.method :int_gte, TInteger, other : MTValue do case other when TInteger, TFloat TBoolean.new(this.value >= other.value) diff --git a/src/myst/interpreter/native_lib/io.cr b/src/myst/interpreter/native_lib/io.cr index ad13901..c63be3f 100644 --- a/src/myst/interpreter/native_lib/io.cr +++ b/src/myst/interpreter/native_lib/io.cr @@ -1,10 +1,10 @@ module Myst class Interpreter - NativeLib.method :io_read, Value, size : TInteger do + NativeLib.method :io_read, MTValue, size : TInteger do __raise_runtime_error("`IO#read` must be implemented by inheriting types.") end - NativeLib.method :io_write, Value, content : Value do + NativeLib.method :io_write, MTValue, content : MTValue do __raise_runtime_error("`IO#write` must be implemented by inheriting types.") end diff --git a/src/myst/interpreter/native_lib/list.cr b/src/myst/interpreter/native_lib/list.cr index beca4f7..1571895 100644 --- a/src/myst/interpreter/native_lib/list.cr +++ b/src/myst/interpreter/native_lib/list.cr @@ -18,7 +18,7 @@ module Myst this end - NativeLib.method :list_eq, TList, other : Value do + NativeLib.method :list_eq, TList, other : MTValue do return TBoolean.new(false) unless other.is_a?(TList) return TBoolean.new(true) if this == other return TBoolean.new(false) if this.elements.size != other.elements.size @@ -30,7 +30,7 @@ module Myst TBoolean.new(true) end - NativeLib.method :list_not_eq, TList, other : Value do + NativeLib.method :list_not_eq, TList, other : MTValue do return TBoolean.new(true) unless other.is_a?(TList) return TBoolean.new(false) if this == other return TBoolean.new(true) if this.elements.size != other.elements.size @@ -54,7 +54,7 @@ module Myst end end - NativeLib.method :list_access_assign, TList, index : TInteger, value : Value do + NativeLib.method :list_access_assign, TList, index : TInteger, value : MTValue do this.ensure_capacity(index.value + 1) this.elements[index.value] = value end diff --git a/src/myst/interpreter/native_lib/map.cr b/src/myst/interpreter/native_lib/map.cr index db794a6..6246594 100644 --- a/src/myst/interpreter/native_lib/map.cr +++ b/src/myst/interpreter/native_lib/map.cr @@ -18,7 +18,7 @@ module Myst TMap.new(this.entries.merge(other.entries)) end - NativeLib.method :map_eq, TMap, other : Value do + NativeLib.method :map_eq, TMap, other : MTValue do return TBoolean.new(false) unless other.is_a?(TMap) return TBoolean.new(true) if this == other return TBoolean.new(false) if this.entries.size != other.entries.size @@ -35,7 +35,7 @@ module Myst TBoolean.new(true) end - NativeLib.method :map_not_eq, TMap, other : Value do + NativeLib.method :map_not_eq, TMap, other : MTValue do return TBoolean.new(true) unless other.is_a?(TMap) return TBoolean.new(false) if this == other return TBoolean.new(true) if this.entries.size != other.entries.size @@ -52,11 +52,11 @@ module Myst TBoolean.new(true) end - NativeLib.method :map_access, TMap, index : Value do + NativeLib.method :map_access, TMap, index : MTValue do this.entries[index]? || TNil.new end - NativeLib.method :map_access_assign, TMap, index : Value, value : Value do + NativeLib.method :map_access_assign, TMap, index : MTValue, value : MTValue do this.entries[index] = value end diff --git a/src/myst/interpreter/native_lib/nil.cr b/src/myst/interpreter/native_lib/nil.cr index bdf3bdf..0f9b244 100644 --- a/src/myst/interpreter/native_lib/nil.cr +++ b/src/myst/interpreter/native_lib/nil.cr @@ -4,7 +4,7 @@ module Myst TString.new("") end - NativeLib.method :nil_eq, TNil, other : Value do + NativeLib.method :nil_eq, TNil, other : MTValue do case other when TNil TBoolean.new(true) @@ -13,7 +13,7 @@ module Myst end end - NativeLib.method :nil_not_eq, TNil, other : Value do + NativeLib.method :nil_not_eq, TNil, other : MTValue do case other when TNil TBoolean.new(false) diff --git a/src/myst/interpreter/native_lib/random.cr b/src/myst/interpreter/native_lib/random.cr index 699f528..e718384 100644 --- a/src/myst/interpreter/native_lib/random.cr +++ b/src/myst/interpreter/native_lib/random.cr @@ -1,7 +1,7 @@ module Myst - class Interpreter - NativeLib.method :random_rand, TModule, max : Value? = nil do - if max.is_a? TInteger + class Interpreter + NativeLib.method :random_rand, TModule, max : MTValue? = nil do + if max.is_a? TInteger TInteger.new(rand(max.value)) elsif max.is_a? TFloat TFloat.new(rand(max.value)) @@ -13,7 +13,7 @@ module Myst def init_random(kernel : TModule) random_module = TModule.new("Random", kernel.scope) - NativeLib.def_method(random_module, :rand, :random_rand) + NativeLib.def_method(random_module, :rand, :random_rand) random_module end diff --git a/src/myst/interpreter/native_lib/string.cr b/src/myst/interpreter/native_lib/string.cr index 58f314d..7174b75 100644 --- a/src/myst/interpreter/native_lib/string.cr +++ b/src/myst/interpreter/native_lib/string.cr @@ -1,6 +1,6 @@ module Myst class Interpreter - NativeLib.method :string_add, TString, other : Value do + NativeLib.method :string_add, TString, other : MTValue do case other when TString TString.new(this.value + other.value) @@ -9,7 +9,7 @@ module Myst end end - NativeLib.method :string_multiply, TString, other : Value do + NativeLib.method :string_multiply, TString, other : MTValue do case other when TInteger # String multiplication repeats `this` `arg` times. @@ -23,7 +23,7 @@ module Myst this.as(TString) end - NativeLib.method :string_eq, TString, other : Value do + NativeLib.method :string_eq, TString, other : MTValue do case other when TString TBoolean.new(this.value == other.value) @@ -32,7 +32,7 @@ module Myst end end - NativeLib.method :string_not_eq, TString, other : Value do + NativeLib.method :string_not_eq, TString, other : MTValue do case other when TString TBoolean.new(this.value != other.value) @@ -50,7 +50,7 @@ module Myst delim_arg.value end - TList.new(this.value.split(delimiter).map{ |s| TString.new(s).as(Value) }) + TList.new(this.value.split(delimiter).map{ |s| TString.new(s).as(MTValue) }) end NativeLib.method :string_size, TString do @@ -58,7 +58,7 @@ module Myst end NativeLib.method :string_chars, TString do - TList.new(this.value.chars.map { |c| TString.new(c.to_s).as Value }) + TList.new(this.value.chars.map { |c| TString.new(c.to_s).as MTValue }) end NativeLib.method :string_downcase, TString do diff --git a/src/myst/interpreter/native_lib/symbol.cr b/src/myst/interpreter/native_lib/symbol.cr index aa9c07e..4904c09 100644 --- a/src/myst/interpreter/native_lib/symbol.cr +++ b/src/myst/interpreter/native_lib/symbol.cr @@ -4,7 +4,7 @@ module Myst TString.new(this.name) end - NativeLib.method :symbol_eq, TSymbol, other : Value do + NativeLib.method :symbol_eq, TSymbol, other : MTValue do case other when TSymbol TBoolean.new(this.value == other.value) @@ -13,7 +13,7 @@ module Myst end end - NativeLib.method :symbol_not_eq, TSymbol, other : Value do + NativeLib.method :symbol_not_eq, TSymbol, other : MTValue do case other when TSymbol TBoolean.new(this.value != other.value) diff --git a/src/myst/interpreter/native_lib/time.cr b/src/myst/interpreter/native_lib/time.cr index c2663c1..466696b 100644 --- a/src/myst/interpreter/native_lib/time.cr +++ b/src/myst/interpreter/native_lib/time.cr @@ -1,13 +1,13 @@ module Myst class Interpreter - NativeLib.method :static_time_now, Value do + NativeLib.method :static_time_now, MTValue do seconds, nanoseconds = Crystal::System::Time.compute_utc_seconds_and_nanoseconds offset = Crystal::System::Time.compute_utc_offset(seconds) - + instance = NativeLib.instantiate(self, this.as(TType), [ - TInteger.new(seconds + offset), + TInteger.new(seconds + offset), TInteger.new(nanoseconds.to_i64) - ] of Value) + ] of MTValue) instance end diff --git a/src/myst/interpreter/native_lib/top_level.cr b/src/myst/interpreter/native_lib/top_level.cr index 2f6188e..7f37c4b 100644 --- a/src/myst/interpreter/native_lib/top_level.cr +++ b/src/myst/interpreter/native_lib/top_level.cr @@ -1,6 +1,6 @@ module Myst class Interpreter - NativeLib.method :mt_exit, Value, status : TInteger? do + NativeLib.method :mt_exit, MTValue, status : TInteger? do real_status = if status.is_a?(TInteger) status.value @@ -11,8 +11,8 @@ module Myst exit(real_status.to_i32) end - NativeLib.method :mt_sleep, Value, time : TInteger | TFloat? = nil do - + NativeLib.method :mt_sleep, MTValue, time : TInteger | TFloat? = nil do + if time.is_a? TInteger || time.is_a? TFloat sleep(time.value) else diff --git a/src/myst/interpreter/nodes/call.cr b/src/myst/interpreter/nodes/call.cr index 300f1a4..a85fc97 100644 --- a/src/myst/interpreter/nodes/call.cr +++ b/src/myst/interpreter/nodes/call.cr @@ -16,7 +16,7 @@ module Myst end - private def lookup_call(node : Call) : Tuple(Value, Value?) + private def lookup_call(node : Call) : Tuple(MTValue, MTValue?) # If the Call has a receiver, lookup the Call on that receiver, otherwise # search the current scope. receiver, check_current = @@ -49,7 +49,7 @@ module Myst private def visit_call(node, receiver, func : TFunctor) - args = [] of Value + args = [] of MTValue node.args.each do |elem| elem.accept(self) @@ -78,7 +78,7 @@ module Myst stack.push(result) end - private def visit_call(_node, _receiver, value : Value) + private def visit_call(_node, _receiver, value : MTValue) stack.push(value) end end diff --git a/src/myst/interpreter/nodes/def.cr b/src/myst/interpreter/nodes/def.cr index f2e9fba..06bce39 100644 --- a/src/myst/interpreter/nodes/def.cr +++ b/src/myst/interpreter/nodes/def.cr @@ -7,7 +7,7 @@ module Myst type.scope when {TType, false} type.instance_scope - when {Value, true} + when {MTValue, true} # Any other kind of value is not allowed to define static methods. __raise_runtime_error("Cannot define static method on #{__typeof(current_self).name}") else diff --git a/src/myst/interpreter/nodes/exception_handler.cr b/src/myst/interpreter/nodes/exception_handler.cr index 525bdf7..d5553e3 100644 --- a/src/myst/interpreter/nodes/exception_handler.cr +++ b/src/myst/interpreter/nodes/exception_handler.cr @@ -48,7 +48,7 @@ module Myst end end - private def rescue_matches?(param : Param, arg : Value) + private def rescue_matches?(param : Param, arg : MTValue) self.match(param.pattern, arg) if param.pattern? self.match(Var.new(param.name), arg) if param.name? self.match(param.restriction, arg) if param.restriction? diff --git a/src/myst/interpreter/nodes/literals.cr b/src/myst/interpreter/nodes/literals.cr index 1640e5e..e6056a9 100644 --- a/src/myst/interpreter/nodes/literals.cr +++ b/src/myst/interpreter/nodes/literals.cr @@ -1,7 +1,7 @@ module Myst class Interpreter def visit(node : ListLiteral) - elements = [] of Value + elements = [] of MTValue node.elements.each do |elem| elem.accept(self) @@ -22,7 +22,7 @@ module Myst end def visit(node : MapLiteral) - entries = node.entries.reduce(Hash(Value, Value).new) do |map, entry| + entries = node.entries.reduce(Hash(MTValue, MTValue).new) do |map, entry| entry.key.accept(self) key = stack.pop entry.value.accept(self) @@ -38,7 +38,7 @@ module Myst strs = node.components.map do |piece| case piece when StringLiteral - Value.from_literal(piece).as(TString) + MTValue.from_literal(piece).as(TString) else visit(piece) expr_result = stack.pop @@ -47,7 +47,7 @@ module Myst self, value_to_s, expr_result, - [] of Value, + [] of MTValue, nil ).invoke.as(TString) end @@ -58,7 +58,7 @@ module Myst end def visit(node : Literal) - stack.push(Value.from_literal(node)) + stack.push(MTValue.from_literal(node)) end end end diff --git a/src/myst/interpreter/nodes/unary_ops.cr b/src/myst/interpreter/nodes/unary_ops.cr index e1711a2..111ddf4 100644 --- a/src/myst/interpreter/nodes/unary_ops.cr +++ b/src/myst/interpreter/nodes/unary_ops.cr @@ -4,7 +4,7 @@ module Myst visit(node.value) value = stack.pop() negate = self.__scopeof(value)["negate"].as(TFunctor) - result = Invocation.new(self, negate, value, [] of Value, nil).invoke + result = Invocation.new(self, negate, value, [] of MTValue, nil).invoke stack.push(result) end @@ -15,7 +15,7 @@ module Myst result = if not_method = self.__scopeof(value)["!"]? not_method = not_method.as(TFunctor) - Invocation.new(self, not_method, value, [] of Value , nil).invoke + Invocation.new(self, not_method, value, [] of MTValue , nil).invoke else TBoolean.new(!value.truthy?) end @@ -29,7 +29,7 @@ module Myst if splat_method = recursive_lookup(value, "*").as?(TFunctor) splat_method = splat_method.as(TFunctor) - result = Invocation.new(self, splat_method, value, [] of Value, nil).invoke + result = Invocation.new(self, splat_method, value, [] of MTValue, nil).invoke else __raise_not_found("* (splat)", value) end diff --git a/src/myst/interpreter/scope.cr b/src/myst/interpreter/scope.cr index 4d393f9..0ca786f 100644 --- a/src/myst/interpreter/scope.cr +++ b/src/myst/interpreter/scope.cr @@ -3,17 +3,17 @@ require "./value.cr" module Myst class Scope property parent : Scope? - property values : Hash(String, Value) + property values : Hash(String, MTValue) def initialize(@parent : Scope? = nil) - @values = {} of String => Value + @values = {} of String => MTValue end # The shorthand access notations (`[]?`, `[]`, `[]=`) will all fall back to # the parent scope if the value does not exist in this scope. # # The longhand `has_key?` and `assign` only operate on this scope. - def []?(key : String) : Value? + def []?(key : String) : MTValue? @values[key]? || @parent.try(&.[key]?) end @@ -21,11 +21,11 @@ module Myst # it is not considered a "public" exception (it is not meant to be # reachable by userland code). Any instance where the exception propogates # outside of the interpreter should be considered a bug. - def [](key : String) : Value + def [](key : String) : MTValue self[key]? || raise IndexError.new("Interpeter Bug: Unmanaged, failed attempt to access `#{key}` from scope: #{self.inspect}") end - def []=(key : String, value : Value) : Value + def []=(key : String, value : MTValue) : MTValue scope = self while scope if scope.has_key?(key) @@ -43,7 +43,7 @@ module Myst !!@values[key]? end - def assign(key : String, value : Value) + def assign(key : String, value : MTValue) @values[key] = value end diff --git a/src/myst/interpreter/util.cr b/src/myst/interpreter/util.cr index b4aa95e..00cf016 100644 --- a/src/myst/interpreter/util.cr +++ b/src/myst/interpreter/util.cr @@ -4,13 +4,13 @@ module Myst # types, these are _always_ looked up in the Kernel. For Instances, the # type is looked up from the type reference on the instance itself. For # Types and Modules, the value itself is returned. - def __typeof(value : Value) + def __typeof(value : MTValue) case value when ContainerType value when TInstance value.type - when Value + when MTValue @kernel.scope[value.type_name].as(TType) else __raise_runtime_error("Can't resolve type of #{value}") @@ -20,7 +20,7 @@ module Myst # Resolve the Scope for `value`. For primitives, this returns the instance # scope of the Type for that value. For Instances, Types, and Modules, this # just returns `.scope` for that value. - def __scopeof(value : Value, prefer_instance_scope = false) : Scope + def __scopeof(value : MTValue, prefer_instance_scope = false) : Scope case value when TInstance value.scope @@ -83,12 +83,12 @@ module Myst end - def __raise_not_found(name, value : Value?) + def __raise_not_found(name, value : MTValue?) type_name = __typeof(value).name error_message = "No variable or method `#{name}` for #{type_name}" if value_to_s = __scopeof(value)["to_s"]? - value_str = NativeLib.call_func_by_name(self, value, "to_s", [] of Value).as(TString).value + value_str = NativeLib.call_func_by_name(self, value, "to_s", [] of MTValue).as(TString).value error_message = "No variable or method `#{name}` for #{value_str}:#{type_name}" end @@ -105,7 +105,7 @@ module Myst raise RuntimeError.new(TString.new(message), callstack) end - def __raise_runtime_error(value : Value) + def __raise_runtime_error(value : MTValue) raise RuntimeError.new(value, callstack) end diff --git a/src/myst/interpreter/value.cr b/src/myst/interpreter/value.cr index 821bf8f..28131e5 100644 --- a/src/myst/interpreter/value.cr +++ b/src/myst/interpreter/value.cr @@ -1,6 +1,6 @@ module Myst - abstract class Value - def Value.from_literal(literal : Node) + abstract class MTValue + def MTValue.from_literal(literal : Node) case literal when IntegerLiteral TInteger.new(literal.value.to_i64) @@ -15,7 +15,7 @@ module Myst when NilLiteral TNil.new else - raise "Interpreter Bug: Attempting to create a Value from a #{literal.class}, which is not a valid Literal type." + raise "Interpreter Bug: Attempting to create an MTValue from a #{literal.class}, which is not a valid Literal type." end end @@ -35,7 +35,7 @@ module Myst end end - abstract class ContainerType < Value + abstract class ContainerType < MTValue property name : String = "" # Ancestors are the modules that have been included inside of a Type. For # example, if a module includes Enumerable, then the ancestors for that @@ -82,11 +82,11 @@ module Myst # TODO: revist this when base object for TType is in place # Currently this prevents to_s from being overriden on Types @scope["to_s"] = TFunctor.new("to_s", [ - ->ttype_to_s(Value, Array(Value), TFunctor?)] of Callable) + ->ttype_to_s(MTValue, Array(MTValue), TFunctor?)] of Callable) end def ttype_to_s(_a, _b, _c) - TString.new(@name).as(Value) + TString.new(@name).as(MTValue) end def type_name @@ -128,7 +128,7 @@ module Myst def_equals_and_hash name, scope, instance_scope end - class TInstance < Value + class TInstance < MTValue property type : TType property scope : Scope @@ -149,7 +149,7 @@ module Myst # Primitives are immutable objects - abstract class TPrimitive(T) < Value + abstract class TPrimitive(T) < MTValue property value : T def initialize(@value : T); end @@ -161,7 +161,7 @@ module Myst def_equals_and_hash value end - class TNil < Value + class TNil < MTValue # All instances of Nil in a program refer to the same object. NIL_OBJECT = TNil.allocate @@ -255,10 +255,10 @@ module Myst end - class TList < Value - property elements : Array(Value) + class TList < MTValue + property elements : Array(MTValue) - def initialize(@elements=[] of Value) + def initialize(@elements=[] of MTValue) end def ensure_capacity(size : Int) @@ -273,10 +273,10 @@ module Myst def_equals_and_hash elements end - class TMap < Value - property entries : Hash(Value, Value) + class TMap < MTValue + property entries : Hash(MTValue, MTValue) - def initialize(@entries={} of Value => Value) + def initialize(@entries={} of MTValue => MTValue) end def type_name @@ -287,7 +287,7 @@ module Myst end - class TFunctorDef < Value + class TFunctorDef < MTValue property definition : Def delegate params, block_param, block_param?, body, splat_index?, splat_index, to: definition @@ -298,20 +298,20 @@ module Myst def_equals_and_hash definition end - alias TNativeDef = Value, Array(Value), TFunctor? -> Value + alias TNativeDef = MTValue, Array(MTValue), TFunctor? -> MTValue alias Callable = TFunctorDef | TNativeDef # A Functor is a container for multiple functor definitions, which can either # be language-level or native. - class TFunctor < Value + class TFunctor < MTValue property name : String property clauses : Array(Callable) property lexical_scope : Scope property? closure : Bool - property! closed_self : Value? + property! closed_self : MTValue? - def initialize(@name : String, @clauses=[] of Callable, @lexical_scope : Scope=Scope.new, @closure : Bool=false, @closed_self : Value?=nil) + def initialize(@name : String, @clauses=[] of Callable, @lexical_scope : Scope=Scope.new, @closure : Bool=false, @closed_self : MTValue?=nil) end def add_clause(definition : Callable)