Skip to content
This repository was archived by the owner on Nov 10, 2017. It is now read-only.

Commit 0dea657

Browse files
author
Ary Borenszweig
committed
Replace new with alloc and initialize
1 parent a8571a1 commit 0dea657

File tree

7 files changed

+29
-15
lines changed

7 files changed

+29
-15
lines changed

bin/icr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ def count_openings(string)
1717
when :IDENT
1818
case token.value
1919
when :begin, :class, :def, :if, :If, :unless, :Unless, :while
20-
openings += 1 if last_token.nil? || last_token == :';' || last_token == :NEWLINE
20+
openings += 1
2121
when :do
2222
openings += 1
2323
when :end, :End

lib/crystal/ast.rb

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -122,10 +122,6 @@ def accept(visitor)
122122
visitor.end_visit_class self
123123
end
124124

125-
def ==(other)
126-
other.is_a?(Class) && other.name == name
127-
end
128-
129125
def to_s
130126
@name
131127
end
@@ -873,10 +869,10 @@ def returns?
873869
end
874870
end
875871

876-
class NewClass < Expression
872+
class Alloc < Expression
877873
def accept(visitor)
878-
visitor.visit_new_class self
879-
visitor.end_visit_new_class self
874+
visitor.visit_alloc self
875+
visitor.end_visit_alloc self
880876
end
881877
end
882878
end

lib/crystal/builtin.rb

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,13 @@ def define_builtin_classes
2828

2929
def define_object_class
3030
@object_class = define_class Class.new("Object")
31+
@object_class.define_method Def.new('initialize', [], nil)
3132
end
3233

3334
def define_class_class
3435
@class_class = define_class Class.new("Class", @object_class)
35-
@class_class.define_method Def.new('new', [], NewClass.new)
36+
@class_class.define_method Def.new('new', [], nil)
37+
@class_class.define_method Def.new('alloc', [], Alloc.new)
3638
@object_class.class_class = @class_class
3739
end
3840

lib/crystal/codegen.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -665,7 +665,7 @@ def codegen(mod)
665665
end
666666
end
667667

668-
class NewClass
668+
class Alloc
669669
def codegen(mod)
670670
malloc = mod.builder.call mod.malloc, LLVM::Int(0)
671671
mod.builder.bit_cast malloc, resolved_type.llvm_type(mod)

lib/crystal/resolve.rb

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -206,9 +206,9 @@ def visit_call(node)
206206
method = node.obj.resolved_type.find_method(node.name)
207207

208208
if method
209-
#if method.obj == @scope.class_class && method.name == 'new'
210-
211-
#end
209+
if method.is_a?(Def) && method.obj == @scope.class_class && method.name == 'new'
210+
return replace_new_with_alloc_and_initialize node
211+
end
212212
else
213213
# Special case: rewrite a != b as !(a == b)
214214
return rewrite_not_equals node if node.name == :'!='
@@ -298,6 +298,21 @@ def visit_call(node)
298298
false
299299
end
300300

301+
def replace_new_with_alloc_and_initialize(node)
302+
@@temp_name_index ||= 0
303+
@@temp_name_index += 1
304+
temp_name = "*temp#{@@temp_name_index}"
305+
306+
exps = Expressions.new
307+
exps.expressions << Assign.new(Ref.new(temp_name), Call.new(node.obj, "alloc"))
308+
exps.expressions << Call.new(Ref.new(temp_name), "initialize", node.args)
309+
exps.expressions << Ref.new(temp_name)
310+
exps.accept self
311+
312+
node.parent.replace node, exps
313+
return false
314+
end
315+
301316
def rewrite_not_equals(node)
302317
node.name = :'=='
303318
node.resolved_type = nil
@@ -446,7 +461,7 @@ def visit_static_array_get(node)
446461
false
447462
end
448463

449-
def visit_new_class(node)
464+
def visit_alloc(node)
450465
node.resolved_type = @scope.def.args[0].resolved_type.real_class
451466
false
452467
end

lib/crystal/visitor.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ class Visitor
4242
'new_static_array',
4343
'static_array_set',
4444
'static_array_get',
45-
'new_class',
45+
'alloc',
4646
].each do |name|
4747
class_eval %Q(
4848
def visit_#{name}(node)

spec/eval_spec.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,7 @@ def self.it_evals_class(string, expected_value, options = {})
131131
it_evals "def Int.bar; 1; end; def StaticArray.foo; T; end; StaticArray(Int).foo.bar", 1.int
132132
it_evals "class Number; def foo; If self.class == Int; 1; Else; 2; End; end; end; 1.foo + 1.0.foo", 3.int
133133
it_evals "def Number.foo; If self == Int; 1; Else; 2; End; end; Int.foo + Float.foo", 3.int
134+
it_evals "class Foo; def bar; 1; end; end; foo = Foo.alloc; foo.bar", 1.int
134135
it_evals "class Foo; def bar; 1; end; end; foo = Foo.new; foo.bar", 1.int
135136
it_evals "class Foo; def initialize(x); end; def bar; 1; end; end; foo = Foo.new(1); foo.bar", 1.int
136137
end

0 commit comments

Comments
 (0)