From 8457c1dd58ec1aad2e3d5beb0cc90f77d89673d2 Mon Sep 17 00:00:00 2001
From: Ary Borenszweig <aborenszweig@manas.com.ar>
Date: Wed, 5 Nov 2014 16:02:14 -0300
Subject: [PATCH] Some refactors

---
 src/array.cr                            | 16 ++-----------
 src/base64.cr                           | 18 +++++++-------
 src/compiler/crystal/codegen/codegen.cr |  2 +-
 src/compiler/crystal/macros/macros.cr   |  5 +---
 src/compiler/crystal/macros/methods.cr  | 31 +++++++++----------------
 src/compiler/crystal/syntax/ast.cr      |  4 ++++
 6 files changed, 28 insertions(+), 48 deletions(-)

diff --git a/src/array.cr b/src/array.cr
index f607292173..f49fe2b46e 100644
--- a/src/array.cr
+++ b/src/array.cr
@@ -138,12 +138,7 @@ class Array(T)
   end
 
   def clone
-    ary = Array(T).new(length)
-    ary.length = length
-    each_with_index do |e, i|
-      ary.buffer[i] = e.clone
-    end
-    ary
+    Array.new(length) { |i| @buffer[i].clone as T }
   end
 
   def compact
@@ -445,14 +440,7 @@ class Array(T)
   end
 
   def reverse
-    ary = Array(T).new(length)
-    ary.length = length
-    i = 0
-    reverse_each do |obj|
-      ary.buffer[i] = obj
-      i += 1
-    end
-    ary
+    Array.new(length) { |i| @buffer[length - i - 1] }
   end
 
   def reverse!
diff --git a/src/base64.cr b/src/base64.cr
index f710af6960..1cc1634d14 100644
--- a/src/base64.cr
+++ b/src/base64.cr
@@ -140,16 +140,16 @@ module Base64
     end
   end
 
-  DECODE_TABLE = Array.new(256) do |i|
+  DECODE_TABLE = Array(Int8).new(256) do |i|
     case i.chr
-    when 'A'..'Z'   then i - 0x41
-    when 'a'..'z'   then i - 0x47
-    when '0'..'9'   then i + 0x04
-    when '+', '-'   then 0x3E
-    when '/', '_'   then 0x3F
-    when '\n', '\r' then -2
-    when '='        then -3
-    else                 -1
+    when 'A'..'Z'   then (i - 0x41).to_i8
+    when 'a'..'z'   then (i - 0x47).to_i8
+    when '0'..'9'   then (i + 0x04).to_i8
+    when '+', '-'   then 0x3E_i8
+    when '/', '_'   then 0x3F_i8
+    when '\n', '\r' then -2_i8
+    when '='        then -3_i8
+    else                 -1_i8
     end
   end
 end
diff --git a/src/compiler/crystal/codegen/codegen.cr b/src/compiler/crystal/codegen/codegen.cr
index 3e8db79d06..003b699c80 100644
--- a/src/compiler/crystal/codegen/codegen.cr
+++ b/src/compiler/crystal/codegen/codegen.cr
@@ -1335,7 +1335,7 @@ module Crystal
       end
 
       # Reuse this call for each dispatch branch
-      call = Call.new(node_obj ? Var.new("%self") : nil, node.name, Array(ASTNode).new(node.args.length) { |i| Var.new("%arg#{i}") }, node.block)
+      call = Call.new(node_obj ? Var.new("%self") : nil, node.name, node.args.map_with_index { |arg, i| Var.new("%arg#{i}") as ASTNode }, node.block)
       call.scope = node.scope
       call.location = node.location
 
diff --git a/src/compiler/crystal/macros/macros.cr b/src/compiler/crystal/macros/macros.cr
index 978cb0b641..f024ee9a5c 100644
--- a/src/compiler/crystal/macros/macros.cr
+++ b/src/compiler/crystal/macros/macros.cr
@@ -614,10 +614,7 @@ module Crystal
         when "@enum_members"
           scope = @scope.try &.instance_type
           if scope.is_a?(EnumType)
-            names = Array(ASTNode).new(scope.types.length)
-            scope.types.each_key do |name|
-              names << MacroId.new(name)
-            end
+            names = scope.types.map { |name, type| MacroId.new(name) as ASTNode }
             return @last = ArrayLiteral.new names
           end
         when "@enum_flags"
diff --git a/src/compiler/crystal/macros/methods.cr b/src/compiler/crystal/macros/methods.cr
index 8f765849d9..5a9a672f7b 100644
--- a/src/compiler/crystal/macros/methods.cr
+++ b/src/compiler/crystal/macros/methods.cr
@@ -156,7 +156,7 @@ module Crystal
       when "capitalize"
         interpret_argless_method(method, args) { StringLiteral.new(@value.capitalize) }
       when "chars"
-        interpret_argless_method(method, args) { create_array_literal_from_values(@value.chars) { |value| CharLiteral.new(value) } }
+        interpret_argless_method(method, args) { ArrayLiteral.map(@value.chars) { |value| CharLiteral.new(value) } }
       when "chomp"
         interpret_argless_method(method, args) { StringLiteral.new(@value.chomp) }
       when "downcase"
@@ -180,11 +180,11 @@ module Crystal
       when "length"
         interpret_argless_method(method, args) { NumberLiteral.new(@value.length) }
       when "lines"
-        interpret_argless_method(method, args) { create_array_literal_from_values(@value.lines) { |value| StringLiteral.new(value) } }
+        interpret_argless_method(method, args) { ArrayLiteral.map(@value.lines) { |value| StringLiteral.new(value) } }
       when "split"
         case args.length
         when 0
-          create_array_literal_from_values(@value.split) { |value| StringLiteral.new(value) }
+          ArrayLiteral.map(@value.split) { |value| StringLiteral.new(value) }
         when 1
           first_arg = args.first
           case first_arg
@@ -196,7 +196,7 @@ module Crystal
             splitter = first_arg.to_s
           end
 
-          create_array_literal_from_values(@value.split(splitter)) { |value| StringLiteral.new(value) }
+          ArrayLiteral.map(@value.split(splitter)) { |value| StringLiteral.new(value) }
         else
           raise "wrong number of arguments for split (#{args.length} for 0, 1)"
         end
@@ -221,10 +221,6 @@ module Crystal
       end
     end
 
-    def create_array_literal_from_values(values)
-      ArrayLiteral.new(Array(ASTNode).new(values.length) { |i| yield values[i] })
-    end
-
     def to_macro_id
       @value
     end
@@ -292,14 +288,11 @@ module Crystal
 
           block_arg = block.args.first?
 
-          mapped_elements = Array(ASTNode).new(elements.length)
-          elements.each do |elem|
+          ArrayLiteral.map(elements) do |elem|
             block_value = interpreter.accept elem.to_macro_var
             interpreter.define_var(block_arg.name, block_value) if block_arg
-            mapped_elements << interpreter.accept block.body
+            interpreter.accept block.body
           end
-
-          ArrayLiteral.new(mapped_elements)
         end
       when "select"
         interpret_argless_method(method, args) do
@@ -343,15 +336,15 @@ module Crystal
       when "empty?"
         interpret_argless_method(method, args) { BoolLiteral.new(entries.empty?) }
       when "keys"
-        interpret_argless_method(method, args) { ArrayLiteral.new(entries.map &.key) }
+        interpret_argless_method(method, args) { ArrayLiteral.map entries, &.key }
       when "length"
         interpret_argless_method(method, args) { NumberLiteral.new(entries.length) }
       when "to_a"
         interpret_argless_method(method, args) do
-          ArrayLiteral.new(Array(ASTNode).new(entries.length) { |i| TupleLiteral.new([entries[i].key, entries[i].value] of ASTNode) })
+          ArrayLiteral.map(entries) { |entry| TupleLiteral.new([entry.key, entry.value] of ASTNode) }
         end
       when "values"
-        interpret_argless_method(method, args) { ArrayLiteral.new(entries.map &.value) }
+        interpret_argless_method(method, args) { ArrayLiteral.map entries, &.value }
       when "[]"
         case args.length
         when 1
@@ -444,8 +437,7 @@ module Crystal
         interpret_argless_method(method, args) { @body || Nop.new }
       when "args"
         interpret_argless_method(method, args) do
-          vars = @args.map { |arg| MacroId.new(arg.name) as ASTNode }
-          ArrayLiteral.new(vars)
+          ArrayLiteral.map(@args) { |arg| MacroId.new(arg.name) }
         end
       else
         super
@@ -478,8 +470,7 @@ module Crystal
       when "body"
         body
       when "args"
-        def_args = Array(ASTNode).new(self.args.length) { |i| self.args[i] }
-        ArrayLiteral.new(def_args)
+        ArrayLiteral.map(self.args) { |arg| arg }
       when "receiver"
         receiver || Nop.new
       else
diff --git a/src/compiler/crystal/syntax/ast.cr b/src/compiler/crystal/syntax/ast.cr
index 3100fe2bc8..b275da7b0b 100644
--- a/src/compiler/crystal/syntax/ast.cr
+++ b/src/compiler/crystal/syntax/ast.cr
@@ -238,6 +238,10 @@ module Crystal
     def initialize(@elements = [] of ASTNode, @of = nil, @name = nil)
     end
 
+    def self.map(values)
+      new(values.map { |value| (yield value) as ASTNode })
+    end
+
     def accept_children(visitor)
       @name.try &.accept visitor
       elements.each &.accept visitor
-- 
GitLab