Skip to content

Commit

Permalink
Automatic cast of numbers to other numbers, and symbols to enums (#6074)
Browse files Browse the repository at this point in the history
  • Loading branch information
asterite authored and RX14 committed May 8, 2018
1 parent da46016 commit 5d3e16d
Show file tree
Hide file tree
Showing 26 changed files with 1,022 additions and 91 deletions.
218 changes: 218 additions & 0 deletions spec/compiler/codegen/automatic_cast.cr
@@ -0,0 +1,218 @@
require "../../spec_helper"

describe "Code gen: automatic cast" do
it "casts literal integer (Int32 -> Int64)" do
run(%(
def foo(x : Int64)
x
end
foo(12345)
)).to_i.should eq(12345)
end

it "casts literal integer (Int64 -> Int32, ok)" do
run(%(
def foo(x : Int32)
x
end
foo(2147483647_i64)
)).to_i.should eq(2147483647)
end

it "casts literal integer (Int32 -> Float32)" do
run(%(
def foo(x : Float32)
x
end
foo(12345).to_i
)).to_i.should eq(12345)
end

it "casts literal integer (Int32 -> Float64)" do
run(%(
def foo(x : Float64)
x
end
foo(12345).to_i
)).to_i.should eq(12345)
end

it "casts literal float (Float32 -> Float64)" do
run(%(
def foo(x : Float64)
x
end
foo(12345.0_f32).to_i
)).to_i.should eq(12345)
end

it "casts literal float (Float64 -> Float32)" do
run(%(
def foo(x : Float32)
x
end
foo(12345.0).to_i
)).to_i.should eq(12345)
end

it "casts symbol literal to enum" do
run(%(
:four
enum Foo
One
Two
Three
end
def foo(x : Foo)
x
end
foo(:three)
)).to_i.should eq(2)
end

it "casts Int32 to Int64 in ivar assignment" do
run(%(
class Foo
@x : Int64
def initialize
@x = 10
end
def x
@x
end
end
Foo.new.x
)).to_i.should eq(10)
end

it "casts Symbol to Enum in ivar assignment" do
run(%(
enum E
One
Two
Three
end
class Foo
@x : E
def initialize
@x = :three
end
def x
@x
end
end
Foo.new.x
)).to_i.should eq(2)
end

it "casts Int32 to Int64 in cvar assignment" do
run(%(
class Foo
@@x : Int64 = 0_i64
def self.x
@@x = 10
@@x
end
end
Foo.x
)).to_i.should eq(10)
end

it "casts Int32 to Int64 in lvar assignment" do
run(%(
x : Int64
x = 123
x
)).to_i.should eq(123)
end

it "casts Int32 to Int64 in ivar type declaration" do
run(%(
class Foo
@x : Int64 = 10
def x
@x
end
end
Foo.new.x
)).to_i.should eq(10)
end

it "casts Symbol to Enum in ivar type declaration" do
run(%(
enum Color
Red
Green
Blue
end
class Foo
@x : Color = :blue
def x
@x
end
end
Foo.new.x
)).to_i.should eq(2)
end

it "casts Int32 to Int64 in cvar type declaration" do
run(%(
class Foo
@@x : Int64 = 10
def self.x
@@x
end
end
Foo.x
)).to_i.should eq(10)
end

it "casts Int32 -> Int64 in arg restriction" do
run(%(
def foo(x : Int64 = 123)
x
end
foo
)).to_i.should eq(123)
end

it "casts Int32 to Int64 in ivar type declaration in generic" do
run(%(
class Foo(T)
@x : T = 10
def x
@x
end
end
Foo(Int64).new.x
)).to_i.should eq(10)
end
end
12 changes: 9 additions & 3 deletions spec/compiler/normalize/def_spec.cr
Expand Up @@ -33,16 +33,22 @@ describe "Normalize: def" do
a_def = parse("def foo(x, y : Int32 = 1, z : Int64 = 2i64); x + y + z; end").as(Def)
actual = a_def.expand_default_arguments(Program.new, 1)
expected = parse("def foo(x); y = 1; z = 2i64; x + y + z; end").as(Def)
expected.body.as(Expressions).expressions.insert 1, TypeRestriction.new Var.new("y"), Path.new(["Int32"])
expected.body.as(Expressions).expressions.insert 3, TypeRestriction.new Var.new("z"), Path.new(["Int64"])

exps = expected.body.as(Expressions).expressions
exps[0] = AssignWithRestriction.new(exps[0].as(Assign), Path.new("Int32"))
exps[1] = AssignWithRestriction.new(exps[1].as(Assign), Path.new("Int64"))

actual.should eq(expected)
end

it "expands a def on request with default arguments and type restrictions (2)" do
a_def = parse("def foo(x, y : Int32 = 1, z : Int64 = 2i64); x + y + z; end").as(Def)
actual = a_def.expand_default_arguments(Program.new, 2)
expected = parse("def foo(x, y : Int32); z = 2i64; x + y + z; end").as(Def)
expected.body.as(Expressions).expressions.insert 1, TypeRestriction.new Var.new("z"), Path.new(["Int64"])

exps = expected.body.as(Expressions).expressions
exps[0] = AssignWithRestriction.new(exps[0].as(Assign), Path.new("Int64"))

actual.should eq(expected)
end

Expand Down

0 comments on commit 5d3e16d

Please sign in to comment.