From 731844ee6d0f01fb8cff8601f29803a3f7bf8a1d Mon Sep 17 00:00:00 2001 From: "Brian J. Cardiff" Date: Mon, 26 Nov 2018 10:00:17 -0300 Subject: [PATCH 1/5] Compiler: Refactor Enum due to overflow If the last value was 1 << 31 an overflow would be thrown. This is not changing the current behavior. The Enum flags with UInt64 base type work only if the values are explicit. --- src/compiler/crystal/semantic/top_level_visitor.cr | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/compiler/crystal/semantic/top_level_visitor.cr b/src/compiler/crystal/semantic/top_level_visitor.cr index 45c39b1e65e2..6c563cd9c5ed 100644 --- a/src/compiler/crystal/semantic/top_level_visitor.cr +++ b/src/compiler/crystal/semantic/top_level_visitor.cr @@ -676,10 +676,10 @@ class Crystal::TopLevelVisitor < Crystal::SemanticVisitor if counter == 0 # In case the member is set to 0 1 else - counter * 2 + counter &* 2 end else - counter + 1 + counter &+ 1 end {new_counter, all_value} else From e85bb7e32996423b8008e24c7dffb0910b0f450b Mon Sep 17 00:00:00 2001 From: "Brian J. Cardiff" Date: Tue, 18 Dec 2018 17:42:33 -0300 Subject: [PATCH 2/5] Compiler: Use unchecked number conversions operations when calling libs --- spec/compiler/semantic/c_struct_spec.cr | 12 ++++++------ spec/compiler/semantic/lib_spec.cr | 12 ++++++------ src/compiler/crystal/semantic/conversions.cr | 2 +- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/spec/compiler/semantic/c_struct_spec.cr b/spec/compiler/semantic/c_struct_spec.cr index acb01cd722dd..0f3d15d47f9e 100644 --- a/spec/compiler/semantic/c_struct_spec.cr +++ b/spec/compiler/semantic/c_struct_spec.cr @@ -322,7 +322,7 @@ describe "Semantic: struct" do )) { int32 } end - it "errors if invoking to_i32 and got error in that call" do + it "errors if invoking to_i32! and got error in that call" do assert_error %( lib LibFoo struct Foo @@ -331,7 +331,7 @@ describe "Semantic: struct" do end class Foo - def to_i32 + def to_i32! 1 + 'a' end end @@ -339,10 +339,10 @@ describe "Semantic: struct" do foo = LibFoo::Foo.new foo.x = Foo.new ), - "converting from Foo to Int32 by invoking 'to_i32'" + "converting from Foo to Int32 by invoking 'to_i32!'" end - it "errors if invoking to_i32 and got wrong type" do + it "errors if invoking to_i32! and got wrong type" do assert_error %( lib LibFoo struct Foo @@ -351,7 +351,7 @@ describe "Semantic: struct" do end class Foo - def to_i32 + def to_i32! 'a' end end @@ -359,7 +359,7 @@ describe "Semantic: struct" do foo = LibFoo::Foo.new foo.x = Foo.new ), - "invoked 'to_i32' to convert from Foo to Int32, but got Char" + "invoked 'to_i32!' to convert from Foo to Int32, but got Char" end it "errors if invoking to_unsafe and got error in that call" do diff --git a/spec/compiler/semantic/lib_spec.cr b/spec/compiler/semantic/lib_spec.cr index 9fcbe9c97043..4b247bd3fd7e 100644 --- a/spec/compiler/semantic/lib_spec.cr +++ b/spec/compiler/semantic/lib_spec.cr @@ -608,38 +608,38 @@ describe "Semantic: lib" do )) { float64 } end - it "errors if invoking to_i32 and got error in that call" do + it "errors if invoking to_i32! and got error in that call" do assert_error %( lib LibFoo fun foo(x : Int32) : Float64 end class Foo - def to_i32 + def to_i32! 1 + 'a' end end LibFoo.foo Foo.new ), - "converting from Foo to Int32 by invoking 'to_i32'" + "converting from Foo to Int32 by invoking 'to_i32!'" end - it "errors if invoking to_i32 and got wrong type" do + it "errors if invoking to_i32! and got wrong type" do assert_error %( lib LibFoo fun foo(x : Int32) : Float64 end class Foo - def to_i32 + def to_i32! 'a' end end LibFoo.foo Foo.new ), - "invoked 'to_i32' to convert from Foo to Int32, but got Char" + "invoked 'to_i32!' to convert from Foo to Int32, but got Char" end it "defines lib funs before funs with body" do diff --git a/src/compiler/crystal/semantic/conversions.cr b/src/compiler/crystal/semantic/conversions.cr index 63161afd5200..e2998722ca98 100644 --- a/src/compiler/crystal/semantic/conversions.cr +++ b/src/compiler/crystal/semantic/conversions.cr @@ -1,6 +1,6 @@ module Crystal::Conversions def self.numeric_argument(node, var, visitor, unaliased_type, expected_type, actual_type) - convert_call_name = "to_#{unaliased_type.kind}" + convert_call_name = "to_#{unaliased_type.kind}!" convert_call = Call.new(var, convert_call_name).at(node) begin From 9253525feb8f89d3ed9a020735f8659dd33e0d85 Mon Sep 17 00:00:00 2001 From: "Brian J. Cardiff" Date: Tue, 4 Dec 2018 01:00:32 -0300 Subject: [PATCH 3/5] Compiler: Refactor due to overflow --- src/compiler/crystal/semantic/lib.cr | 20 ++++++++++---------- src/llvm/generic_value.cr | 2 +- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/compiler/crystal/semantic/lib.cr b/src/compiler/crystal/semantic/lib.cr index 99b6c3bd25ea..e781c61983c8 100644 --- a/src/compiler/crystal/semantic/lib.cr +++ b/src/compiler/crystal/semantic/lib.cr @@ -244,16 +244,16 @@ class Crystal::Call self_arg.value = case unaliased_type - when program.uint8 ; num.to_u8.to_s - when program.uint16 ; num.to_u16.to_s - when program.uint32 ; num.to_u32.to_s - when program.uint64 ; num.to_u64.to_s - when program.int8 ; num.to_i8.to_s - when program.int16 ; num.to_i16.to_s - when program.int32 ; num.to_i32.to_s - when program.int64 ; num.to_i64.to_s - when program.float32; num.to_f32.to_s - else num.to_f64.to_s + when program.uint8 ; num.to_u8!.to_s + when program.uint16 ; num.to_u16!.to_s + when program.uint32 ; num.to_u32!.to_s + when program.uint64 ; num.to_u64!.to_s + when program.int8 ; num.to_i8!.to_s + when program.int16 ; num.to_i16!.to_s + when program.int32 ; num.to_i32!.to_s + when program.int64 ; num.to_i64!.to_s + when program.float32; num.to_f32!.to_s + else num.to_f64!.to_s end self_arg.kind = unaliased_type.kind self_arg.type = unaliased_type diff --git a/src/llvm/generic_value.cr b/src/llvm/generic_value.cr index e054e38dffd4..15f9d378c75e 100644 --- a/src/llvm/generic_value.cr +++ b/src/llvm/generic_value.cr @@ -3,7 +3,7 @@ class LLVM::GenericValue end def to_i : Int32 - to_i64.to_i32 + to_i64.to_i32! end def to_i64 : Int64 From d6904bfecd5073f0c95447e6280b74a2238eac11 Mon Sep 17 00:00:00 2001 From: "Brian J. Cardiff" Date: Sun, 2 Dec 2018 19:11:42 -0300 Subject: [PATCH 4/5] Compiler: Handle Int128 UInt128 in IntegerType#range --- src/compiler/crystal/types.cr | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/compiler/crystal/types.cr b/src/compiler/crystal/types.cr index 4dcdb04ef33c..c8ab4ff00c99 100644 --- a/src/compiler/crystal/types.cr +++ b/src/compiler/crystal/types.cr @@ -1282,6 +1282,8 @@ module Crystal {Int32::MIN, Int32::MAX} when :i64 {Int64::MIN, Int64::MAX} + when :i128 + {Int128::MIN, Int128::MAX} when :u8 {UInt8::MIN, UInt8::MAX} when :u16 @@ -1290,6 +1292,8 @@ module Crystal {UInt32::MIN, UInt32::MAX} when :u64 {UInt64::MIN, UInt64::MAX} + when :u128 + {UInt128::MIN, UInt128::MAX} else raise "Bug: called 'range' for non-integer literal" end From ff030b224be08a31d76f5d86591e5c827d9c732c Mon Sep 17 00:00:00 2001 From: "Brian J. Cardiff" Date: Wed, 27 Jun 2018 10:49:02 +0200 Subject: [PATCH 5/5] Refactor Specs: Avoid using overflowing operators in codegen specs Otherwise OverflowError and raise method will need to be defined --- spec/compiler/codegen/alias_spec.cr | 2 +- spec/compiler/codegen/array_literal_spec.cr | 16 ++--- spec/compiler/codegen/block_spec.cr | 48 ++++++++------- spec/compiler/codegen/c_struct_spec.cr | 2 +- spec/compiler/codegen/class_spec.cr | 2 +- spec/compiler/codegen/class_var_spec.cr | 14 ++--- spec/compiler/codegen/closure_spec.cr | 40 ++++++------- spec/compiler/codegen/const_spec.cr | 2 +- spec/compiler/codegen/def_spec.cr | 18 +++--- spec/compiler/codegen/double_splat_spec.cr | 20 +++---- spec/compiler/codegen/enum_spec.cr | 4 +- spec/compiler/codegen/extern_spec.cr | 34 +++++------ spec/compiler/codegen/generic_class_spec.cr | 6 +- spec/compiler/codegen/hash_literal_spec.cr | 42 +++++++------- spec/compiler/codegen/hooks_spec.cr | 4 +- spec/compiler/codegen/is_a_spec.cr | 16 ++--- spec/compiler/codegen/macro_spec.cr | 58 ++++++++++--------- spec/compiler/codegen/magic_constants_spec.cr | 4 +- spec/compiler/codegen/method_missing_spec.cr | 14 ++--- spec/compiler/codegen/module_spec.cr | 4 +- spec/compiler/codegen/named_args_spec.cr | 38 +++++++----- spec/compiler/codegen/named_tuple_spec.cr | 2 +- spec/compiler/codegen/new_spec.cr | 16 ++--- spec/compiler/codegen/next_spec.cr | 26 ++++----- spec/compiler/codegen/op_assign_spec.cr | 10 ++-- spec/compiler/codegen/pointer_spec.cr | 4 +- spec/compiler/codegen/previous_def_spec.cr | 6 +- spec/compiler/codegen/primitives_spec.cr | 8 +-- spec/compiler/codegen/proc_spec.cr | 14 +++-- spec/compiler/codegen/splat_spec.cr | 16 ++--- spec/compiler/codegen/ssa_spec.cr | 4 +- spec/compiler/codegen/super_spec.cr | 8 +-- spec/compiler/codegen/tuple_spec.cr | 4 +- spec/compiler/codegen/uninitialized_spec.cr | 2 +- spec/compiler/codegen/union_type_spec.cr | 14 ++++- spec/compiler/codegen/until_spec.cr | 2 +- spec/compiler/codegen/var_spec.cr | 4 +- spec/compiler/codegen/virtual_spec.cr | 2 +- spec/compiler/codegen/while_spec.cr | 10 ++-- .../compiler/codegen/yield_with_scope_spec.cr | 6 +- 40 files changed, 290 insertions(+), 256 deletions(-) diff --git a/spec/compiler/codegen/alias_spec.cr b/spec/compiler/codegen/alias_spec.cr index 3f595a4568ba..95048dcd9f6d 100644 --- a/spec/compiler/codegen/alias_spec.cr +++ b/spec/compiler/codegen/alias_spec.cr @@ -66,7 +66,7 @@ describe "Code gen: alias" do if n == 0 1 else - foo(n - 1).as(Foo) + foo(n &- 1).as(Foo) end end diff --git a/spec/compiler/codegen/array_literal_spec.cr b/spec/compiler/codegen/array_literal_spec.cr index a24fbc06d00e..e840a27d7b5b 100644 --- a/spec/compiler/codegen/array_literal_spec.cr +++ b/spec/compiler/codegen/array_literal_spec.cr @@ -9,7 +9,7 @@ describe "Code gen: array literal spec" do end def <<(element) - @value += element + @value &+= element end def value @@ -30,7 +30,7 @@ describe "Code gen: array literal spec" do end def <<(element : T) - @value += element + @value &+= element end def value @@ -51,7 +51,7 @@ describe "Code gen: array literal spec" do end def <<(element : T) - @value += element + @value &+= element end def value @@ -72,7 +72,7 @@ describe "Code gen: array literal spec" do end def <<(element : T) - @value += element + @value &+= element end def value @@ -95,7 +95,7 @@ describe "Code gen: array literal spec" do end def <<(element : T) - @value += element + @value &+= element end def value @@ -118,7 +118,7 @@ describe "Code gen: array literal spec" do end def <<(element) - @value += element + @value &+= element end def value @@ -140,7 +140,7 @@ describe "Code gen: array literal spec" do end def <<(element) - @value += element + @value &+= element end def value @@ -163,7 +163,7 @@ describe "Code gen: array literal spec" do end def <<(element : T) - @value += element + @value &+= element end def value diff --git a/spec/compiler/codegen/block_spec.cr b/spec/compiler/codegen/block_spec.cr index eb3e88cf25df..e82c3fb5b616 100644 --- a/spec/compiler/codegen/block_spec.cr +++ b/spec/compiler/codegen/block_spec.cr @@ -20,7 +20,7 @@ describe "Code gen: block" do end foo do |x| - x + 1 + x &+ 1 end ").to_i.should eq(2) end @@ -32,7 +32,7 @@ describe "Code gen: block" do end foo(3) do |x| - x + 1 + x &+ 1 end ").to_i.should eq(4) end @@ -46,7 +46,7 @@ describe "Code gen: block" do end 3.foo do |x| - x + 1 + x &+ 1 end ").to_i.should eq(4) end @@ -60,7 +60,7 @@ describe "Code gen: block" do end 3.foo(2) do |x, i| - x + i + x &+ i end ").to_i.should eq(5) end @@ -73,7 +73,7 @@ describe "Code gen: block" do x = 1 foo do - x + 1 + x &+ 1 end ").to_i.should eq(2) end @@ -90,7 +90,7 @@ describe "Code gen: block" do end Foo.new.foo do |x| - x + 1 + x &+ 1 end ").to_i.should eq(2) end @@ -127,7 +127,7 @@ describe "Code gen: block" do end end - Foo.new.foo { |x| x + 1 } + Foo.new.foo { |x| x &+ 1 } ").to_i.should eq(2) end @@ -320,6 +320,8 @@ describe "Code gen: block" do it "call block from dispatch and use local vars" do run(" + require \"prelude\" + def bar(y) yield y end @@ -377,7 +379,7 @@ describe "Code gen: block" do end a = 0 - foo { a += 1; break } + foo { a &+= 1; break } a ").to_i.should eq(1) end @@ -445,7 +447,7 @@ describe "Code gen: block" do require \"nil\" def foo - 1 + yield + 1 &+ yield end foo { break 2 }.to_i @@ -494,7 +496,7 @@ describe "Code gen: block" do end def foo - bar { 1 + yield } + bar { 1 &+ yield } end foo { break 3 } @@ -906,6 +908,8 @@ describe "Code gen: block" do it "codegens dispatch with block and break (1)" do run(" + require \"prelude\" + class Foo(T) def initialize(@x : T) end @@ -1021,7 +1025,7 @@ describe "Code gen: block" do end foo = Foo.new do |a| - a + 1 + a &+ 1 end foo.x )).to_i.should eq(2) @@ -1135,7 +1139,7 @@ describe "Code gen: block" do foo do |key| if 1 == 1 extra = 1 - extra + key + extra &+ key end end @@ -1201,7 +1205,7 @@ describe "Code gen: block" do a = 0 foo do |x| - a += x + a &+= x next if true break end @@ -1219,7 +1223,7 @@ describe "Code gen: block" do a = 0 foo do |x| - a += x + a &+= x next if 1 == 1 break end @@ -1358,7 +1362,7 @@ describe "Code gen: block" do a = 0 foo do |x| - a += x + a &+= x end a )).to_i.should eq(4) @@ -1372,7 +1376,7 @@ describe "Code gen: block" do end foo do |x, y, z| - x + y + z + x &+ y &+ z end )).to_i.should eq(6) end @@ -1396,7 +1400,7 @@ describe "Code gen: block" do end foo do |*args| - args[0] + args[1] + args[2] + args[0] &+ args[1] &+ args[2] end )).to_i.should eq(6) end @@ -1408,7 +1412,7 @@ describe "Code gen: block" do end foo do |x, y, *z, w| - ((((x + y) * z[0]) - z[1]) * z[2]) - w + ((((x &+ y) &* z[0]) &- z[1]) &* z[2]) &- w end )).to_i.should eq(((((1 + 2) * 3) - 4) * 5) - 6) end @@ -1422,7 +1426,7 @@ describe "Code gen: block" do total = 0 foo do |*args| - total += args[0].to_i + total &+= args[0].to_i end total )).to_i.should eq(3) @@ -1436,7 +1440,7 @@ describe "Code gen: block" do end foo do |x, y, z| - (x + y) * z + (x &+ y) &* z end )).to_i.should eq((1 + 2) * 4) end @@ -1453,7 +1457,7 @@ describe "Code gen: block" do w = 4 foo do |(x, y), (z, w)| end - x + y + z + w + x &+ y &+ z &+ w )).to_i.should eq(10) end @@ -1506,7 +1510,7 @@ describe "Code gen: block" do a = fn(1 || 'a') { 2 } b = fn('a' || 1) { 2 } - a + b + a &+ b )).to_i.should eq(3) end diff --git a/spec/compiler/codegen/c_struct_spec.cr b/spec/compiler/codegen/c_struct_spec.cr index 626bbc235fff..4d93e967b3f5 100644 --- a/spec/compiler/codegen/c_struct_spec.cr +++ b/spec/compiler/codegen/c_struct_spec.cr @@ -261,7 +261,7 @@ describe "Code gen: struct" do end point = LibC::Point.new x: 1, y: 2 - point.x + point.y + point.x &+ point.y )).to_i.should eq(3) end diff --git a/spec/compiler/codegen/class_spec.cr b/spec/compiler/codegen/class_spec.cr index da7ff1e7dcd5..b8504543f1e5 100644 --- a/spec/compiler/codegen/class_spec.cr +++ b/spec/compiler/codegen/class_spec.cr @@ -29,7 +29,7 @@ describe "Code gen: class" do f = Foo.new(2) g = Foo.new(40) - f.coco + g.coco + f.coco &+ g.coco ").to_i.should eq(42) end diff --git a/spec/compiler/codegen/class_var_spec.cr b/spec/compiler/codegen/class_var_spec.cr index 14be91036460..ae610e357070 100644 --- a/spec/compiler/codegen/class_var_spec.cr +++ b/spec/compiler/codegen/class_var_spec.cr @@ -110,7 +110,7 @@ describe "Codegen: class var" do @@var : Int32 @@var = begin a = class_method - a + 3 + a &+ 3 end def self.var @@ -118,7 +118,7 @@ describe "Codegen: class var" do end def self.class_method - 1 + 2 + 1 &+ 2 end end @@ -130,7 +130,7 @@ describe "Codegen: class var" do run(%( class Foo @@var2 : Int32 - @@var2 = @@var + 1 + @@var2 = @@var &+ 1 @@var = 41 @@ -199,7 +199,7 @@ describe "Codegen: class var" do def foo a = 1 b = 2 - a + b + a &+ b end CONST = foo() @@ -256,7 +256,7 @@ describe "Codegen: class var" do @@foo = begin a = 1 b = 2 - a + b + a &+ b end def self.foo @@ -274,7 +274,7 @@ describe "Codegen: class var" do @@foo : Int32 = begin a = 1 b = 2 - a + b + a &+ b end def self.foo @@ -548,7 +548,7 @@ describe "Codegen: class var" do c = f2.bar f2.bar = 20 d = f1.bar - a + b + c + d + a &+ b &+ c &+ d )).to_i.should eq(1 + 1 + 10 + 20) end end diff --git a/spec/compiler/codegen/closure_spec.cr b/spec/compiler/codegen/closure_spec.cr index 557f0054f161..b69c59ed75fe 100644 --- a/spec/compiler/codegen/closure_spec.cr +++ b/spec/compiler/codegen/closure_spec.cr @@ -54,7 +54,7 @@ describe "Code gen: closure" do a = 1 f = foo do b = 2 - -> { a + b } + -> { a &+ b } end f.call ").to_i.should eq(3) @@ -70,7 +70,7 @@ describe "Code gen: closure" do a = 1 f = foo do |x| - -> { a + x } + -> { a &+ x } end f.call ").to_i.should eq(4) @@ -85,7 +85,7 @@ describe "Code gen: closure" do f = foo do |x| a = 2 - -> { a + x } + -> { a &+ x } end f.call ").to_i.should eq(3) @@ -118,7 +118,7 @@ describe "Code gen: closure" do b = 1 foo do |y| c = 1 - -> { a + b + c + x + y } + -> { a &+ b &+ c &+ x &+ y } end end f.call @@ -153,7 +153,7 @@ describe "Code gen: closure" do f = foo do b = 1 bar do - -> { a + b } + -> { a &+ b } end end f.call @@ -175,7 +175,7 @@ describe "Code gen: closure" do b = 1 bar do |x| x - -> { a + b } + -> { a &+ b } end end f.call @@ -210,7 +210,7 @@ describe "Code gen: closure" do def foo a = 2 - ->{ self.x + a } + ->{ self.x &+ a } end def x @@ -230,7 +230,7 @@ describe "Code gen: closure" do def foo a = 2 - ->{ x + a } + ->{ x &+ a } end def x @@ -250,7 +250,7 @@ describe "Code gen: closure" do def foo a = 2 - ->{ @x + a } + ->{ @x &+ a } end end @@ -286,7 +286,7 @@ describe "Code gen: closure" do def foo bar do a = 2 - ->{ @x + a } + ->{ @x &+ a } end end end @@ -392,7 +392,7 @@ describe "Code gen: closure" do a = 1 ->{ b = 2 - ->{ a + b } + ->{ a &+ b } }.call.call )).to_i.should eq(3) end @@ -412,7 +412,7 @@ describe "Code gen: closure" do c = 3 foo do |d| -> { - a + b + c + d + a &+ b &+ c &+ d } end } @@ -453,7 +453,7 @@ describe "Code gen: closure" do a = 1 f = ->(foo : Foo) { - foo.x + a + foo.x &+ a } obj = Foo.new(2) @@ -468,7 +468,7 @@ describe "Code gen: closure" do end def foo(x) - @x + x + @x &+ x end def bar @@ -500,7 +500,7 @@ describe "Code gen: closure" do a = 1 foo do |x| - x + a + x &+ a end ").to_i.should eq(2) end @@ -512,7 +512,7 @@ describe "Code gen: closure" do end a = 1 - g = foo { |x| x + a } + g = foo { |x| x &+ a } h = foo { |x| x.to_f + a } (g.call(3) + h.call(5)).to_i ").to_i.should eq(10) @@ -557,7 +557,7 @@ describe "Code gen: closure" do end a = 1 - f = ->(x : Int32) { x + a } + f = ->(x : Int32) { x &+ a } foo &f ").to_i.should eq(2) end @@ -570,7 +570,7 @@ describe "Code gen: closure" do end a = 0 - foo { |x| a += x } + foo { |x| a &+= x } a )).to_i.should eq(3) end @@ -670,7 +670,7 @@ describe "Code gen: closure" do # Here 'local' isn't to be confused with # the outer closured 'local' local = 1 - local + arg + local &+ arg } arg = 2 @@ -678,7 +678,7 @@ describe "Code gen: closure" do local = 4_i64 f2 = ->{ local.to_i } - f1.call + f2.call + f1.call &+ f2.call )) end end diff --git a/spec/compiler/codegen/const_spec.cr b/spec/compiler/codegen/const_spec.cr index e94e7af3aa41..8cf2b86a9b3f 100644 --- a/spec/compiler/codegen/const_spec.cr +++ b/spec/compiler/codegen/const_spec.cr @@ -288,7 +288,7 @@ describe "Codegen: const" do def foo a = 1 b = 2 - a + b + a &+ b end x diff --git a/spec/compiler/codegen/def_spec.cr b/spec/compiler/codegen/def_spec.cr index 2c2420fd8d73..c5ae5e5f0032 100644 --- a/spec/compiler/codegen/def_spec.cr +++ b/spec/compiler/codegen/def_spec.cr @@ -27,7 +27,7 @@ describe "Code gen: def" do end it "uses self" do - run("struct Int; def foo; self + 1; end; end; 3.foo").to_i.should eq(4) + run("struct Int; def foo; self &+ 1; end; end; 3.foo").to_i.should eq(4) end it "uses var after external" do @@ -167,20 +167,20 @@ describe "Code gen: def" do it "codegens with and witout default arguments" do run(" def foo(x = 1) - x + 1 + x &+ 1 end - foo(2) + foo + foo(2) &+ foo ").to_i.should eq(5) end it "codegens with and witout many default arguments" do run(" def foo(x = 1, y = 2, z = 3) - x + y + z + x &+ y &+ z end - foo + foo(9) + foo(3, 4) + foo(6, 3, 1) + foo &+ foo(9) &+ foo(3, 4) &+ foo(6, 3, 1) ").to_i.should eq(40) end @@ -188,7 +188,7 @@ describe "Code gen: def" do run(" class Foo def foo(x = self.bar) - x + 1 + x &+ 1 end def bar @@ -198,7 +198,7 @@ describe "Code gen: def" do f = Foo.new - f.foo(2) + f.foo + f.foo(2) &+ f.foo ").to_i.should eq(5) end @@ -512,8 +512,8 @@ describe "Code gen: def" do it "uses previous argument in default value (#1062)" do run(%( - def foo(x = 123, y = x + 456) - x + y + def foo(x = 123, y = x &+ 456) + x &+ y end foo diff --git a/spec/compiler/codegen/double_splat_spec.cr b/spec/compiler/codegen/double_splat_spec.cr index 7dcc3a338a74..f7ffcf5d81f4 100644 --- a/spec/compiler/codegen/double_splat_spec.cr +++ b/spec/compiler/codegen/double_splat_spec.cr @@ -4,7 +4,7 @@ describe "Codegen: double splat" do it "double splats named argument into arguments (1)" do run(%( def foo(x, y) - x - y + x &- y end tup = {x: 32, y: 10} @@ -15,7 +15,7 @@ describe "Codegen: double splat" do it "double splats named argument into arguments (2)" do run(%( def foo(x, y) - x - y + x &- y end tup = {y: 10, x: 32} @@ -26,7 +26,7 @@ describe "Codegen: double splat" do it "double splats named argument with positional arguments" do run(%( def foo(x, y, z) - x - y*z + x &- y &* z end tup = {y: 20, z: 30} @@ -37,7 +37,7 @@ describe "Codegen: double splat" do it "double splats named argument with named args (1)" do run(%( def foo(x, y, z) - x - y*z + x &- y &* z end tup = {x: 1000, z: 30} @@ -48,7 +48,7 @@ describe "Codegen: double splat" do it "double splats named argument with named args (2)" do run(%( def foo(x, y, z) - x - y*z + x &- y &* z end tup = {z: 30} @@ -59,7 +59,7 @@ describe "Codegen: double splat" do it "double splats twice " do run(%( def foo(x, y, z, w) - (x - y*z) * w + (x &- y &* z) &* w end tup1 = {x: 1000, z: 30} @@ -71,7 +71,7 @@ describe "Codegen: double splat" do it "matches double splat on method with named args" do run(%( def foo(**options) - options[:x] - options[:y] + options[:x] &- options[:y] end foo x: 10, y: 3 @@ -81,7 +81,7 @@ describe "Codegen: double splat" do it "matches double splat on method with named args and regular args" do run(%( def foo(x, **args) - x - args[:y]*args[:z] + x &- args[:y] &* args[:z] end foo y: 20, z: 30, x: 1000 @@ -91,7 +91,7 @@ describe "Codegen: double splat" do it "matches double splat with regular splat" do run(%( def foo(*args, **options) - (args[0] - args[1]*options[:z]) * options[:w] + (args[0] &- args[1] &* options[:z]) &* options[:w] end foo 1000, 20, z: 30, w: 40 @@ -112,7 +112,7 @@ describe "Codegen: double splat" do end def data - Global.x += 1 + Global.x &+= 1 {x: Global.x, y: Global.x, z: Global.x} end diff --git a/spec/compiler/codegen/enum_spec.cr b/spec/compiler/codegen/enum_spec.cr index 95d77a416ace..97d8dc778381 100644 --- a/spec/compiler/codegen/enum_spec.cr +++ b/spec/compiler/codegen/enum_spec.cr @@ -317,8 +317,8 @@ describe "Code gen: enum" do end x = 0 - x += 1 if Foo::None.none? - x += 2 if Foo::A.none? + x &+= 1 if Foo::None.none? + x &+= 2 if Foo::A.none? x )).to_i.should eq(1) end diff --git a/spec/compiler/codegen/extern_spec.cr b/spec/compiler/codegen/extern_spec.cr index 15dfc8640b9b..535358943e37 100644 --- a/spec/compiler/codegen/extern_spec.cr +++ b/spec/compiler/codegen/extern_spec.cr @@ -160,7 +160,7 @@ describe "Codegen: extern struct" do x = f.call(Data.new(1)) y = f.call(Data.new(2)) - x + y + x &+ y )).to_i.should eq(3) end @@ -219,7 +219,7 @@ describe "Codegen: extern struct" do Global.y = s.y }) - Global.x + Global.y + Global.x &+ Global.y ), &.to_i.should eq(3)) end @@ -270,11 +270,11 @@ describe "Codegen: extern struct" do end LibMylib.foo(->(x, s, y) { - Global.x = s.x + x - Global.y = s.y + y + Global.x = s.x &+ x + Global.y = s.y &+ y }) - Global.x + Global.y + Global.x &+ Global.y ), &.to_i.should eq(33)) end @@ -330,7 +330,7 @@ describe "Codegen: extern struct" do nil }) - Global.x + Global.y + Global.x &+ Global.y ), &.to_i.should eq(3)) end @@ -388,7 +388,7 @@ describe "Codegen: extern struct" do s }) - Global.x + Global.y + s2.x + s2.y + Global.x &+ Global.y &+ s2.x &+ s2.y ), &.to_i.should eq(303)) end @@ -423,7 +423,7 @@ describe "Codegen: extern struct" do s }) - s2.x + s2.y + s2.x &+ s2.y ), &.to_i.should eq(30)) end @@ -469,15 +469,15 @@ describe "Codegen: extern struct" do end s2 = LibMylib.foo(->(s) { - Global.x += s.x - Global.x += s.y - Global.x += s.z + Global.x &+= s.x + Global.x &+= s.y + Global.x &+= s.z s }) - Global.x += s2.x - Global.x += s2.y - Global.x += s2.z + Global.x &+= s2.x + Global.x &+= s2.y + Global.x &+= s2.z Global.x.to_i32 ), &.to_i.should eq(12)) end @@ -523,8 +523,8 @@ describe "Codegen: extern struct" do end f = ->(s : LibMylib::Struct) { - Global.x += s.x - Global.x += s.y + Global.x &+= s.x + Global.x &+= s.y } s = LibMylib::Struct.new @@ -559,7 +559,7 @@ describe "Codegen: extern struct" do } s = f.call - s.x + s.y + s.z + s.w + s.a + s.x &+ s.y &+ s.z &+ s.w &+ s.a )).to_i.should eq(15) end {% end %} diff --git a/spec/compiler/codegen/generic_class_spec.cr b/spec/compiler/codegen/generic_class_spec.cr index f2afa7d0b7e1..7b68090379c3 100644 --- a/spec/compiler/codegen/generic_class_spec.cr +++ b/spec/compiler/codegen/generic_class_spec.cr @@ -8,7 +8,7 @@ describe "Code gen: generic class type" do end def x - @x + 1 + @x &+ 1 end end @@ -30,7 +30,7 @@ describe "Code gen: generic class type" do end end - Foo(Int32).new.x + 1 + Foo(Int32).new.x &+ 1 )).to_i.should eq(2) end @@ -150,7 +150,7 @@ describe "Code gen: generic class type" do end baz = Baz.new - baz.x + baz.y + baz.x &+ baz.y )).to_i.should eq(42) end diff --git a/spec/compiler/codegen/hash_literal_spec.cr b/spec/compiler/codegen/hash_literal_spec.cr index 34c8b664aa4d..b9e78077e551 100644 --- a/spec/compiler/codegen/hash_literal_spec.cr +++ b/spec/compiler/codegen/hash_literal_spec.cr @@ -10,8 +10,8 @@ describe "Code gen: hash literal spec" do end def []=(key, value) - @keys += key - @values += value + @keys &+= key + @values &+= value end def keys @@ -24,7 +24,7 @@ describe "Code gen: hash literal spec" do end custom = Custom {1 => 10, 2 => 20} - custom.keys * custom.values + custom.keys &* custom.values )).to_i.should eq(90) end @@ -37,8 +37,8 @@ describe "Code gen: hash literal spec" do end def []=(key, value) - @keys += key - @values += value + @keys &+= key + @values &+= value end def keys @@ -51,7 +51,7 @@ describe "Code gen: hash literal spec" do end custom = Custom {1 => 10, 2 => 20} - custom.keys * custom.values + custom.keys &* custom.values )).to_i.should eq(90) end @@ -64,8 +64,8 @@ describe "Code gen: hash literal spec" do end def []=(key, value) - @keys += key - @values += value + @keys &+= key + @values &+= value end def keys @@ -78,7 +78,7 @@ describe "Code gen: hash literal spec" do end custom = Custom(Int32, Int32) {1 => 10, 2 => 20} - custom.keys * custom.values + custom.keys &* custom.values )).to_i.should eq(90) end @@ -91,8 +91,8 @@ describe "Code gen: hash literal spec" do end def []=(key, value) - @keys += key - @values += value + @keys &+= key + @values &+= value end def keys @@ -107,7 +107,7 @@ describe "Code gen: hash literal spec" do alias MyCustom = Custom custom = MyCustom {1 => 10, 2 => 20} - custom.keys * custom.values + custom.keys &* custom.values )).to_i.should eq(90) end @@ -120,8 +120,8 @@ describe "Code gen: hash literal spec" do end def []=(key, value) - @keys += key - @values += value + @keys &+= key + @values &+= value end def keys @@ -136,7 +136,7 @@ describe "Code gen: hash literal spec" do alias MyCustom = Custom(Int32, Int32) custom = MyCustom {1 => 10, 2 => 20} - custom.keys * custom.values + custom.keys &* custom.values )).to_i.should eq(90) end @@ -163,8 +163,8 @@ describe "Code gen: hash literal spec" do end def []=(key, value) - @keys += key - @values += value + @keys &+= key + @values &+= value end def keys @@ -178,7 +178,7 @@ describe "Code gen: hash literal spec" do end custom = Moo::Custom {1 => 10, 2 => 20} - custom.keys * custom.values + custom.keys &* custom.values )).to_i.should eq(90) end @@ -192,8 +192,8 @@ describe "Code gen: hash literal spec" do end def []=(key, value) - @keys += key - @values += value + @keys &+= key + @values &+= value end def keys @@ -207,7 +207,7 @@ describe "Code gen: hash literal spec" do end custom = Moo::Custom {1 => 10, 2 => 20} - custom.keys * custom.values + custom.keys &* custom.values )).to_i.should eq(90) end end diff --git a/spec/compiler/codegen/hooks_spec.cr b/spec/compiler/codegen/hooks_spec.cr index 7b480167962b..eb745bb5d320 100644 --- a/spec/compiler/codegen/hooks_spec.cr +++ b/spec/compiler/codegen/hooks_spec.cr @@ -100,7 +100,7 @@ describe "Code gen: hooks" do class Foo macro inherited - Global.x += 1 + Global.x &+= 1 end end @@ -138,7 +138,7 @@ describe "Code gen: hooks" do end class Bar < Foo - Global.x += 1 + Global.x &+= 1 end Bar.y diff --git a/spec/compiler/codegen/is_a_spec.cr b/spec/compiler/codegen/is_a_spec.cr index d07b1f7ccbbf..346567d5402b 100644 --- a/spec/compiler/codegen/is_a_spec.cr +++ b/spec/compiler/codegen/is_a_spec.cr @@ -243,7 +243,7 @@ describe "Codegen: is_a?" do run(" a = 1 if a.is_a?(Int32 | Char) - a + 1 + a &+ 1 else 0 end @@ -253,7 +253,7 @@ describe "Codegen: is_a?" do it "restricts union with union" do run(" struct Char - def +(other : Int32) + def &+(other : Int32) other end end @@ -266,7 +266,7 @@ describe "Codegen: is_a?" do a = 1 || 'a' || false if a.is_a?(Int32 | Char) - a + 2 + a &+ 2 else a.foo end @@ -433,7 +433,7 @@ describe "Codegen: is_a?" do foo = Foo.new(1) x = foo.x if x.is_a?(Int32) - z = x + 1 + z = x &+ 1 else z = x.foo_bar end @@ -513,7 +513,7 @@ describe "Codegen: is_a?" do run(%( a = 123 if (b = a).is_a?(Int32) - b + 1 + b &+ 1 else a end @@ -524,7 +524,7 @@ describe "Codegen: is_a?" do run(%( a = 123 if (b = a).is_a?(Int32) - a + 2 + a &+ 2 else b end @@ -537,7 +537,7 @@ describe "Codegen: is_a?" do if (b = a).is_a?(Char) b else - b + 1 + b &+ 1 end )).to_i.should eq(124) end @@ -550,7 +550,7 @@ describe "Codegen: is_a?" do else a end - b ? b + 1 : 0 + b ? b &+ 1 : 0 )).to_i.should eq(124) end diff --git a/spec/compiler/codegen/macro_spec.cr b/spec/compiler/codegen/macro_spec.cr index 5ed9184b9184..c6b22b1af023 100644 --- a/spec/compiler/codegen/macro_spec.cr +++ b/spec/compiler/codegen/macro_spec.cr @@ -2,13 +2,13 @@ require "../../spec_helper" describe "Code gen: macro" do it "expands macro" do - run("macro foo; 1 + 2; end; foo").to_i.should eq(3) + run("macro foo; 1 &+ 2; end; foo").to_i.should eq(3) end it "expands macro with arguments" do run(%( macro foo(n) - {{n}} + 2 + {{n}} &+ 2 end foo(1) @@ -19,7 +19,7 @@ describe "Code gen: macro" do run(%( macro foo def x - 1 + 2 + 1 &+ 2 end end @@ -79,7 +79,7 @@ describe "Code gen: macro" do run(%( a = 0 {% for i in [1, 2, 3] %} - a += {{i}} + a &+= {{i}} {% end %} a )).to_i.should eq(6) @@ -89,7 +89,7 @@ describe "Code gen: macro" do run(%( a = 0 {% if 1 == 1 %} - a += 1 + a &+= 1 {% end %} a )).to_i.should eq(1) @@ -99,7 +99,7 @@ describe "Code gen: macro" do run(%( a = 0 {% if 1 == 2 %} - a += 1 + a &+= 1 {% end %} a )).to_i.should eq(0) @@ -109,7 +109,7 @@ describe "Code gen: macro" do run(%( class Foo macro foo - 1 + 2 + 1 &+ 2 end def bar @@ -323,7 +323,7 @@ describe "Code gen: macro" do end macro foo(x, y = :bar) - {{x}} + {{y.id}} + {{x}} &+ {{y.id}} end foo(1) @@ -425,9 +425,15 @@ describe "Code gen: macro" do it "doesn't reuse macro nodes (bug)" do run(%( + struct Float + def &+(other) + self + other + end + end + def foo(x) {% for y in [1, 2] %} - x + 1 + x &+ 1 {% end %} end @@ -490,7 +496,7 @@ describe "Code gen: macro" do a = 0 foo do |x| - a += x + a &+= x end a )).to_i.should eq(3) @@ -617,7 +623,7 @@ describe "Code gen: macro" do end foo do |x| - x + 1 + x &+ 1 end )).to_i.should eq(2) end @@ -625,7 +631,7 @@ describe "Code gen: macro" do it "executes with named arguments" do run(%( macro foo(x = 1) - {{x}} + 1 + {{x}} &+ 1 end foo x: 2 @@ -735,7 +741,7 @@ describe "Code gen: macro" do end end - Color.red.value + Color.green.value + Color.blue.value + Color.red.value &+ Color.green.value &+ Color.blue.value )).to_i.should eq(0 + 1 + 2) end @@ -927,14 +933,14 @@ describe "Code gen: macro" do it "doesn't override local variable when using macro variable (2)" do run(%( macro foo(x) - %a = {{x}} + 10 + %a = {{x}} &+ 10 %a end a = 1 z = foo(2) w = foo(3) - a + z + w + a &+ z &+ w )).to_i.should eq(26) end @@ -947,14 +953,14 @@ describe "Code gen: macro" do %total = 0 {% for elem, i in elems %} - %total += %var{i} + %total &+= %var{i} {% end %} %total end z = 0 - z += foo 4, 5, 6 - z += foo 40, 50, 60 + z &+= foo 4, 5, 6 + z &+= foo 40, 50, 60 z )).to_i.should eq(4 + 5 + 6 + 40 + 50 + 60) end @@ -968,7 +974,7 @@ describe "Code gen: macro" do %total = 0 {% for elem, i in elems %} - %total += %var{elem, i} + %total &+= %var{elem, i} {% end %} %total end @@ -983,7 +989,7 @@ describe "Code gen: macro" do class Foo def bar(*args) : Int32 {{ @type }} - args[0] + args[1] + args[2] + args[0] &+ args[1] &+ args[2] end end @@ -996,7 +1002,7 @@ describe "Code gen: macro" do class Foo def bar(foo = 1) : Int32 {{ @type }} - foo + 2 + foo &+ 2 end end @@ -1302,7 +1308,7 @@ describe "Code gen: macro" do it "executes with named arguments for positional arg (1)" do run(%( macro foo(x) - {{x}} + 1 + {{x}} &+ 1 end foo x: 2 @@ -1312,7 +1318,7 @@ describe "Code gen: macro" do it "executes with named arguments for positional arg (2)" do run(%( macro foo(x, y) - {{x}} + {{y}} + 1 + {{x}} &+ {{y}} &+ 1 end foo x: 2, y: 3 @@ -1328,7 +1334,7 @@ describe "Code gen: macro" do end macro foo(x, y) - {{x}} + {{y}}.bytesize + 1 + {{x}} &+ {{y}}.bytesize &+ 1 end foo y: "foo", x: 2 @@ -1789,8 +1795,8 @@ describe "Code gen: macro" do x, y = Foo.new(2).defaults a = 0 - a += 1 if x - a += 2 if y + a &+= 1 if x + a &+= 2 if y a )).to_i.should eq(1) end diff --git a/spec/compiler/codegen/magic_constants_spec.cr b/spec/compiler/codegen/magic_constants_spec.cr index 35b8885df6c1..edf1d9d9aeff 100644 --- a/spec/compiler/codegen/magic_constants_spec.cr +++ b/spec/compiler/codegen/magic_constants_spec.cr @@ -61,7 +61,7 @@ describe "Code gen: magic constants" do require "primitives" def foo(x, z = 10, line = __LINE__) - z + line + z &+ line end foo 1, 20 @@ -73,7 +73,7 @@ describe "Code gen: magic constants" do require "primitives" def foo(x, line = __LINE__, z = 1) - z + line + z &+ line end foo 1, z: 20 diff --git a/spec/compiler/codegen/method_missing_spec.cr b/spec/compiler/codegen/method_missing_spec.cr index 00a6c4a53f67..d2cb16a0b34c 100644 --- a/spec/compiler/codegen/method_missing_spec.cr +++ b/spec/compiler/codegen/method_missing_spec.cr @@ -21,7 +21,7 @@ describe "Code gen: method_missing" do run(%( class Foo macro method_missing(call) - {{call.args.join(" + ").id}} + {{call.args.join(" &+ ").id}} end end @@ -45,7 +45,7 @@ describe "Code gen: method_missing" do a = 0 Foo.new.foo do |x| - a += x + a &+= x end a )).to_i.should eq(6) @@ -55,7 +55,7 @@ describe "Code gen: method_missing" do run(%( class Foo def foo_something - 1 + 2 + 1 &+ 2 end macro method_missing(call) @@ -339,7 +339,7 @@ describe "Code gen: method_missing" do run(%( class Foo macro method_missing(call) - {{call.args.join(" + ").id}} + {{call.args.join(" &+ ").id}} end end @@ -351,7 +351,7 @@ describe "Code gen: method_missing" do run(%( class Wrapped def foo(x, y, z) - x + y + z + x &+ y &+ z end end @@ -386,7 +386,7 @@ describe "Code gen: method_missing" do run(%( class A macro method_missing(call) - x + y + x &+ y end end @@ -399,7 +399,7 @@ describe "Code gen: method_missing" do run(%( class A macro method_missing(call) - {{call.named_args[0].name}} + + {{call.named_args[0].name}} &+ {{call.named_args[1].name}} end end diff --git a/spec/compiler/codegen/module_spec.cr b/spec/compiler/codegen/module_spec.cr index 49946f8ac8c6..36f8d72b1684 100644 --- a/spec/compiler/codegen/module_spec.cr +++ b/spec/compiler/codegen/module_spec.cr @@ -488,7 +488,7 @@ describe "Code gen: module" do mooer = Mooer.new(Bar.new) y = mooer.moo - x + y + x &+ y )).to_i.should eq(3) end @@ -527,7 +527,7 @@ describe "Code gen: module" do mooer = Mooer.new(Bar(Int32).new) y = mooer.moo - x + y + x &+ y )).to_i.should eq(3) end diff --git a/spec/compiler/codegen/named_args_spec.cr b/spec/compiler/codegen/named_args_spec.cr index 2ef815f6e968..87f8424464cd 100644 --- a/spec/compiler/codegen/named_args_spec.cr +++ b/spec/compiler/codegen/named_args_spec.cr @@ -14,7 +14,7 @@ describe "Code gen: named args" do it "calls with named arg and other args" do run(%( def foo(x, y = 2, z = 3) - x + y + z + x &+ y &+ z end foo 1, z: 10 @@ -25,7 +25,7 @@ describe "Code gen: named args" do run(%( class Foo def foo(x, y = 2, z = 3) - x + y + z + x &+ y &+ z end end @@ -35,13 +35,19 @@ describe "Code gen: named args" do it "calls twice with different types" do run(%( + struct Int32 + def &+(other : Float) + self + other + end + end + def add(x, y = 1) - x + y + x &+ y end value = 0 - value += add(1, y: 2) - value += add(1, y: 1.3) + value &+= add(1, y: 2) + value &+= add(1, y: 1.3) value.to_i )).to_i.should eq(5) end @@ -52,7 +58,7 @@ describe "Code gen: named args" do @value : Int32 def initialize(x, y = 2, z = 3) - @value = x + y + z + @value = x &+ y &+ z end def value @@ -68,13 +74,13 @@ describe "Code gen: named args" do run(%( class Foo def foo(x, z = 2) - x + z + 1 + x &+ z &+ 1 end end class Bar def foo(x, z = 2) - x + z + x &+ z end end @@ -96,7 +102,7 @@ describe "Code gen: named args" do it "sends two regular arguments as named arguments" do run(%( def foo(x, y) - x + y + x &+ y end foo x: 10, y: 32 @@ -126,32 +132,32 @@ describe "Code gen: named args" do it "overloads based on required named args" do run(%( def foo(x, *, y) - x + y + x &+ y end def foo(x, *, z) - x * z + x &* z end a = foo(10, y: 20) b = foo(30, z: 40) - a + b + a &+ b )).to_i.should eq(10 + 20 + 30*40) end it "overloads based on required named args, with restrictions" do run(%( def foo(x, *, z : Int32) - x + z + x &+ z end def foo(x, *, z : Float64) - x * z.to_i + x &* z.to_i end a = foo(10, z: 20) b = foo(30, z: 40.0) - a + b + a &+ b )).to_i.should eq(10 + 20 + 30*40) end @@ -169,7 +175,7 @@ describe "Code gen: named args" do v1 = Foo.new.y v2 = Foo.new(y: 20).y - v1 + v2 + v1 &+ v2 )).to_i.should eq(42) end end diff --git a/spec/compiler/codegen/named_tuple_spec.cr b/spec/compiler/codegen/named_tuple_spec.cr index b581e70bfe7b..18a7d5f2d902 100644 --- a/spec/compiler/codegen/named_tuple_spec.cr +++ b/spec/compiler/codegen/named_tuple_spec.cr @@ -273,7 +273,7 @@ describe "Code gen: named tuple" do if v.is_a?(Float64) 10 else - v[0].to_i + v[1].to_i + v[0].to_i &+ v[1].to_i end )).to_i.should eq(42) end diff --git a/spec/compiler/codegen/new_spec.cr b/spec/compiler/codegen/new_spec.cr index 5185fbba07f3..bb04c5cbb80f 100644 --- a/spec/compiler/codegen/new_spec.cr +++ b/spec/compiler/codegen/new_spec.cr @@ -133,7 +133,7 @@ describe "Code gen: new" do class Bar < Foo def self.new(foo : Int32) : self - Global.x = foo + 1 + Global.x = foo &+ 1 super end end @@ -162,7 +162,7 @@ describe "Code gen: new" do end def self.new(foo : Int32) : self - Global.x = foo + 1 + Global.x = foo &+ 1 previous_def end end @@ -179,7 +179,7 @@ describe "Code gen: new" do @x : Int32 def initialize(x : Int32) - @x = x + 1 + @x = x &+ 1 end def x @@ -325,7 +325,7 @@ describe "Code gen: new" do end foo = Foo.new(y: 22) - foo.x + foo.y + foo.x &+ foo.y )).to_i.should eq(42) end @@ -349,10 +349,10 @@ describe "Code gen: new" do total = 0 foo = Foo.new do |a, b| - total += a - total += b + total &+= a + total &+= b end - total += foo.x + total &+= foo.x total )).to_i.should eq(42) end @@ -381,7 +381,7 @@ describe "Code gen: new" do foo = Foo.new do 20 end - foo.x + foo.block.call + foo.x &+ foo.block.call )).to_i.should eq(42) end end diff --git a/spec/compiler/codegen/next_spec.cr b/spec/compiler/codegen/next_spec.cr index 55c9153d2539..bcb397996f12 100644 --- a/spec/compiler/codegen/next_spec.cr +++ b/spec/compiler/codegen/next_spec.cr @@ -25,7 +25,7 @@ describe "Code gen: next" do a = 0 foo do |i| next if i.unsafe_mod(2) == 0 - a += i + a &+= i end a ").to_i.should eq(4) @@ -35,10 +35,10 @@ describe "Code gen: next" do run(" def foo x = 0 - x += yield 1 - x += yield 2 - x += yield 3 - x += yield 4 + x &+= yield 1 + x &+= yield 2 + x &+= yield 3 + x &+= yield 4 x end @@ -75,8 +75,8 @@ describe "Code gen: next" do run(" def foo a = 0 - a += yield 1 - a += yield 2 + a &+= yield 1 + a &+= yield 2 a end @@ -95,8 +95,8 @@ describe "Code gen: next" do run(" def foo a = 0 - a += yield 1 - a += yield 2 + a &+= yield 1 + a &+= yield 2 a end @@ -115,8 +115,8 @@ describe "Code gen: next" do run(" def foo a = 0 - a += yield 4 - a += yield 5 + a &+= yield 4 + a &+= yield 5 a end @@ -124,9 +124,9 @@ describe "Code gen: next" do a = 0 b = 0 while a < 4 - a += 1 + a &+= 1 next if a.unsafe_mod(2) == 0 - b += a + b &+= a end if b == i next 10 diff --git a/spec/compiler/codegen/op_assign_spec.cr b/spec/compiler/codegen/op_assign_spec.cr index 0d3983aeba8c..5a6127efaa4f 100644 --- a/spec/compiler/codegen/op_assign_spec.cr +++ b/spec/compiler/codegen/op_assign_spec.cr @@ -24,11 +24,11 @@ describe "Code gen: op assign" do end def foo - Global.value += 1 + Global.value &+= 1 Foo.new end - foo.bar += 2 + foo.bar &+= 2 Global.value )).to_i.should eq(1) @@ -57,16 +57,16 @@ describe "Code gen: op assign" do end def foo - Global.value += 1 + Global.value &+= 1 Foo.new end def bar - Global.value += 10 + Global.value &+= 10 0 end - foo[bar] += 2 + foo[bar] &+= 2 Global.value )).to_i.should eq(11) diff --git a/spec/compiler/codegen/pointer_spec.cr b/spec/compiler/codegen/pointer_spec.cr index 2162bef09149..1c398324f177 100644 --- a/spec/compiler/codegen/pointer_spec.cr +++ b/spec/compiler/codegen/pointer_spec.cr @@ -53,11 +53,11 @@ describe "Code gen: pointer" do end it "codegens malloc" do - run("p = Pointer(Int32).malloc(10_u64); p.value = 1; p.value + 1_i64").to_i.should eq(2) + run("p = Pointer(Int32).malloc(10_u64); p.value = 1; p.value &+ 1_i64").to_i.should eq(2) end it "codegens realloc" do - run("p = Pointer(Int32).malloc(10_u64); p.value = 1; x = p.realloc(20_u64); x.value + 1_i64").to_i.should eq(2) + run("p = Pointer(Int32).malloc(10_u64); p.value = 1; x = p.realloc(20_u64); x.value &+ 1_i64").to_i.should eq(2) end it "codegens pointer cast" do diff --git a/spec/compiler/codegen/previous_def_spec.cr b/spec/compiler/codegen/previous_def_spec.cr index 9981cff28254..444a1b30f42a 100644 --- a/spec/compiler/codegen/previous_def_spec.cr +++ b/spec/compiler/codegen/previous_def_spec.cr @@ -8,7 +8,7 @@ describe "codegen: previous_def" do end def foo - previous_def + 1 + previous_def &+ 1 end foo @@ -18,11 +18,11 @@ describe "codegen: previous_def" do it "codeges previous def when inside fun and forwards args" do run(%( def foo(z) - z + 1 + z &+ 1 end def foo(z) - ->(x : Int32) { x + previous_def } + ->(x : Int32) { x &+ previous_def } end x = foo(2) diff --git a/spec/compiler/codegen/primitives_spec.cr b/spec/compiler/codegen/primitives_spec.cr index 21cbca7b7fdf..ccb96c55acea 100644 --- a/spec/compiler/codegen/primitives_spec.cr +++ b/spec/compiler/codegen/primitives_spec.cr @@ -55,7 +55,7 @@ describe "Code gen: primitives" do end it "codegens 1 + 2" do - run(%(1 + 2)).to_i.should eq(3) + run(%(require "prelude"; 1 + 2)).to_i.should eq(3) end it "codegens 1 &+ 2" do @@ -63,7 +63,7 @@ describe "Code gen: primitives" do end it "codegens 1 - 2" do - run(%(1 - 2)).to_i.should eq(-1) + run(%(require "prelude"; 1 - 2)).to_i.should eq(-1) end it "codegens 1 &- 2" do @@ -71,7 +71,7 @@ describe "Code gen: primitives" do end it "codegens 2 * 3" do - run(%(2 * 3)).to_i.should eq(6) + run(%(require "prelude"; 2 * 3)).to_i.should eq(6) end it "codegens 2 &* 3" do @@ -178,7 +178,7 @@ describe "Code gen: primitives" do fun foo : K end - Test.foo + 1 + Test.foo &+ 1 )) end diff --git a/spec/compiler/codegen/proc_spec.cr b/spec/compiler/codegen/proc_spec.cr index 784f05ab2bee..f513e9b97649 100644 --- a/spec/compiler/codegen/proc_spec.cr +++ b/spec/compiler/codegen/proc_spec.cr @@ -6,7 +6,7 @@ describe "Code gen: proc" do end it "call proc literal with arguments" do - run("f = ->(x : Int32) { x + 1 }; f.call(41)").to_i.should eq(42) + run("f = ->(x : Int32) { x &+ 1 }; f.call(41)").to_i.should eq(42) end it "call proc pointer" do @@ -16,7 +16,7 @@ describe "Code gen: proc" do it "call proc pointer with args" do run(" def foo(x, y) - x + y + x &+ y end f = ->foo(Int32, Int32) @@ -87,7 +87,13 @@ describe "Code gen: proc" do it "codegens proc that accepts a union and is called with a single type" do run(" - f = ->(x : Int32 | Float64) { x + 1 } + struct Float + def &+(other) + self + other + end + end + + f = ->(x : Int32 | Float64) { x &+ 1 } f.call(1).to_i ").to_i.should eq(2) end @@ -390,7 +396,7 @@ describe "Code gen: proc" do alias Func = Int32 -> Int32 a = 2 - f = Func.new { |x| x + a } + f = Func.new { |x| x &+ a } f.call(1) ").to_i.should eq(3) end diff --git a/spec/compiler/codegen/splat_spec.cr b/spec/compiler/codegen/splat_spec.cr index 0d149a73fa69..8ac1f3955d5e 100644 --- a/spec/compiler/codegen/splat_spec.cr +++ b/spec/compiler/codegen/splat_spec.cr @@ -22,7 +22,7 @@ describe "Code gen: splat" do end def foo(x, *args) - x + args.size + x &+ args.size end foo 10, 1, 1 @@ -32,7 +32,7 @@ describe "Code gen: splat" do it "splats on call" do run(%( def foo(x, y) - x + y + x &+ y end tuple = {1, 2} @@ -61,7 +61,7 @@ describe "Code gen: splat" do end def foo(x = 100, *args) - x + args.size + x &+ args.size end foo @@ -75,7 +75,7 @@ describe "Code gen: splat" do end def foo(x, y = 100, *args) - x + y + args.size + x &+ y &+ args.size end foo 10 @@ -89,7 +89,7 @@ describe "Code gen: splat" do end def foo(x, y = 100, *args) - x + y + args.size + x &+ y &+ args.size end foo 10, 20, 30, 40 @@ -116,7 +116,7 @@ describe "Code gen: splat" do end foo = Foo.new 1, 2 - foo.x + foo.y + foo.x &+ foo.y )).to_i.should eq(3) end @@ -157,12 +157,12 @@ describe "Code gen: splat" do end def data - Global.x += 1 + Global.x &+= 1 {Global.x, Global.x, Global.x} end def test(x, y, z) - x + y + z + x &+ y &+ z end v = test(*data) diff --git a/spec/compiler/codegen/ssa_spec.cr b/spec/compiler/codegen/ssa_spec.cr index 829d9d893233..88f78c60e234 100644 --- a/spec/compiler/codegen/ssa_spec.cr +++ b/spec/compiler/codegen/ssa_spec.cr @@ -199,14 +199,14 @@ describe "Code gen: ssa" do i = 1 while i <= 3 yield i - i += 1 + i &+= 1 end end a = 0 foo do |x| coconio = x if x == 1 - a += coconio.to_i + a &+= coconio.to_i end a )).to_i.should eq(1) diff --git a/spec/compiler/codegen/super_spec.cr b/spec/compiler/codegen/super_spec.cr index d70d59a9f849..1b716ffe5ef8 100644 --- a/spec/compiler/codegen/super_spec.cr +++ b/spec/compiler/codegen/super_spec.cr @@ -6,7 +6,7 @@ describe "Codegen: super" do end it "codegens super without arguments but parent has arguments" do - run("class Foo; def foo(x); x + 1; end; end; class Bar < Foo; def foo(x); super; end; end; Bar.new.foo(1)").to_i.should eq(2) + run("class Foo; def foo(x); x &+ 1; end; end; class Bar < Foo; def foo(x); super; end; end; Bar.new.foo(1)").to_i.should eq(2) end it "codegens super without arguments and instance variable" do @@ -222,13 +222,13 @@ describe "Codegen: super" do end def foo(z) - z + @x + z &+ @x end end class Bar < Foo def foo(z) - ->(x : Int32) { x + super } + ->(x : Int32) { x &+ super } end end @@ -344,7 +344,7 @@ describe "Codegen: super" do class Bar(T) < Foo def initialize - Global.x += 1 + Global.x &+= 1 super end end diff --git a/spec/compiler/codegen/tuple_spec.cr b/spec/compiler/codegen/tuple_spec.cr index d2e49183d09b..bddd440ef23e 100644 --- a/spec/compiler/codegen/tuple_spec.cr +++ b/spec/compiler/codegen/tuple_spec.cr @@ -73,7 +73,7 @@ describe "Code gen: tuple" do end p = foo({1, 2}) - p.value[0] + p.value[1] + p.value[0] &+ p.value[1] ").to_i.should eq(3) end @@ -290,7 +290,7 @@ describe "Code gen: tuple" do if v.is_a?(Float64) 10 else - v[0].to_i + v[1].to_i + v[0].to_i &+ v[1].to_i end )).to_i.should eq(42) end diff --git a/spec/compiler/codegen/uninitialized_spec.cr b/spec/compiler/codegen/uninitialized_spec.cr index 8365854f09ed..137477099346 100644 --- a/spec/compiler/codegen/uninitialized_spec.cr +++ b/spec/compiler/codegen/uninitialized_spec.cr @@ -67,7 +67,7 @@ describe "Code gen: uninitialized" do end bar = Bar.new - bar.x + bar.y + bar.x &+ bar.y )).to_i.should eq(3) end diff --git a/spec/compiler/codegen/union_type_spec.cr b/spec/compiler/codegen/union_type_spec.cr index 196014c2b238..d09236429589 100644 --- a/spec/compiler/codegen/union_type_spec.cr +++ b/spec/compiler/codegen/union_type_spec.cr @@ -31,6 +31,18 @@ describe "Code gen: union type" do it "codegens union type for instance var" do run(" + struct Float + def &+(other) + self + other + end + end + + struct Int32 + def &+(other : Float) + self + other + end + end + class Foo @value : Int32 | Float32 @@ -43,7 +55,7 @@ describe "Code gen: union type" do f = Foo.new(1) f.value = 1.5_f32 - (f.value + f.value).to_f + (f.value &+ f.value).to_f ").to_f64.should eq(3) end diff --git a/spec/compiler/codegen/until_spec.cr b/spec/compiler/codegen/until_spec.cr index 5cbc7891d444..d004402c038a 100644 --- a/spec/compiler/codegen/until_spec.cr +++ b/spec/compiler/codegen/until_spec.cr @@ -5,7 +5,7 @@ describe "Codegen: until" do run(%( a = 1 until a == 10 - a = a + 1 + a = a &+ 1 end a )).to_i.should eq(10) diff --git a/spec/compiler/codegen/var_spec.cr b/spec/compiler/codegen/var_spec.cr index 5a50636a0fc1..92455ceb6679 100644 --- a/spec/compiler/codegen/var_spec.cr +++ b/spec/compiler/codegen/var_spec.cr @@ -30,9 +30,9 @@ describe "Code gen: var" do def foo if 1 == 2 - @angle += 1 + @angle &+= 1 else - @angle -= 1 + @angle &-= 1 end end end diff --git a/spec/compiler/codegen/virtual_spec.cr b/spec/compiler/codegen/virtual_spec.cr index 79af017fcd91..e4849c3cd3e5 100644 --- a/spec/compiler/codegen/virtual_spec.cr +++ b/spec/compiler/codegen/virtual_spec.cr @@ -110,7 +110,7 @@ describe "Code gen: virtual type" do class Bar < Foo def foo - @x + 1 + @x &+ 1 end end diff --git a/spec/compiler/codegen/while_spec.cr b/spec/compiler/codegen/while_spec.cr index ce05c540599d..f4467e62288a 100644 --- a/spec/compiler/codegen/while_spec.cr +++ b/spec/compiler/codegen/while_spec.cr @@ -10,15 +10,15 @@ describe "Codegen: while" do end it "codegens while with non-false condition" do - run("a = 1; while a < 10; a = a + 1; end; a").to_i.should eq(10) + run("a = 1; while a < 10; a = a &+ 1; end; a").to_i.should eq(10) end it "break without value" do - run("a = 0; while a < 10; a += 1; break; end; a").to_i.should eq(1) + run("a = 0; while a < 10; a &+= 1; break; end; a").to_i.should eq(1) end it "conditional break without value" do - run("a = 0; while a < 10; a += 1; break if a > 5; end; a").to_i.should eq(6) + run("a = 0; while a < 10; a &+= 1; break if a > 5; end; a").to_i.should eq(6) end it "codegens endless while" do @@ -73,9 +73,9 @@ describe "Codegen: while" do x = 0 while i < 10 - i += 1 + i &+= 1 next if i.unsafe_mod(2) == 0 - x += i + x &+= i end x ").to_i.should eq(25) diff --git a/spec/compiler/codegen/yield_with_scope_spec.cr b/spec/compiler/codegen/yield_with_scope_spec.cr index a0428dea88f9..dbef663cb82d 100644 --- a/spec/compiler/codegen/yield_with_scope_spec.cr +++ b/spec/compiler/codegen/yield_with_scope_spec.cr @@ -117,7 +117,7 @@ describe "Semantic: yield with scope" do def bar Foo.new.foo do - @x + 1 + @x &+ 1 end end end @@ -137,7 +137,7 @@ describe "Semantic: yield with scope" do class Bar def bar Foo.new.foo do - baz + 1 + baz &+ 1 end end @@ -162,7 +162,7 @@ describe "Semantic: yield with scope" do end def coco - @x + 1 + @x &+ 1 end end