Skip to content

Commit

Permalink
Add some each and each_with_index macro methods
Browse files Browse the repository at this point in the history
  • Loading branch information
asterite authored and Blacksmoke16 committed Apr 15, 2020
1 parent bd28420 commit 690fa75
Showing 1 changed file with 69 additions and 0 deletions.
69 changes: 69 additions & 0 deletions src/compiler/crystal/macros/methods.cr
Original file line number Diff line number Diff line change
Expand Up @@ -897,6 +897,21 @@ module Crystal
end
when "values"
interpret_argless_method(method, args) { ArrayLiteral.map entries, &.value }
when "each"
interpret_argless_method(method, args) do
raise "each expects a block" unless block

block_arg_key = block.args[0]?
block_arg_value = block.args[1]?

entries.each do |entry|
interpreter.define_var(block_arg_key.name, entry.key) if block_arg_key
interpreter.define_var(block_arg_value.name, entry.value) if block_arg_value
interpreter.accept block.body
end

NilLiteral.new
end
when "map"
interpret_argless_method(method, args) do
raise "map expects a block" unless block
Expand Down Expand Up @@ -991,6 +1006,21 @@ module Crystal
end
when "values"
interpret_argless_method(method, args) { ArrayLiteral.map entries, &.value }
when "each"
interpret_argless_method(method, args) do
raise "each expects a block" unless block

block_arg_key = block.args[0]?
block_arg_value = block.args[1]?

entries.each do |entry|
interpreter.define_var(block_arg_key.name, MacroId.new(entry.key)) if block_arg_key
interpreter.define_var(block_arg_value.name, entry.value) if block_arg_value
interpreter.accept block.body
end

NilLiteral.new
end
when "map"
interpret_argless_method(method, args) do
raise "map expects a block" unless block
Expand Down Expand Up @@ -1102,6 +1132,17 @@ module Crystal
interpret_argless_method(method, args) { self.to }
when "excludes_end?"
interpret_argless_method(method, args) { BoolLiteral.new(self.exclusive?) }
when "each"
raise "each expects a block" unless block

block_arg = block.args.first?

interpret_to_range(interpreter).each do |num|
interpreter.define_var(block_arg.name, NumberLiteral.new(num)) if block_arg
interpreter.accept block.body
end

NilLiteral.new
when "map"
raise "map expects a block" unless block

Expand Down Expand Up @@ -2348,6 +2389,34 @@ private def interpret_array_or_tuple_method(object, klass, method, args, block,
object.interpret_argless_method(method, args) { object.elements.last? || Crystal::NilLiteral.new }
when "size"
object.interpret_argless_method(method, args) { Crystal::NumberLiteral.new(object.elements.size) }
when "each"
object.interpret_argless_method(method, args) do
raise "each expects a block" unless block

block_arg = block.args.first?

object.elements.each do |elem|
interpreter.define_var(block_arg.name, elem) if block_arg
interpreter.accept block.body
end

Crystal::NilLiteral.new
end
when "each_with_index"
object.interpret_argless_method(method, args) do
raise "each_with_index expects a block" unless block

block_arg = block.args[0]?
index_arg = block.args[1]?

object.elements.each_with_index do |elem, idx|
interpreter.define_var(block_arg.name, elem) if block_arg
interpreter.define_var(index_arg.name, Crystal::NumberLiteral.new idx) if index_arg
interpreter.accept block.body
end

Crystal::NilLiteral.new
end
when "map"
object.interpret_argless_method(method, args) do
raise "map expects a block" unless block
Expand Down

0 comments on commit 690fa75

Please sign in to comment.