Skip to content

Instantly share code, notes, and snippets.

@bew
Last active May 25, 2018 20:50
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bew/9296a477ca60eb979af7d27dda1fb4d0 to your computer and use it in GitHub Desktop.
Save bew/9296a477ca60eb979af7d27dda1fb4d0 to your computer and use it in GitHub Desktop.
ArrayLiteral expansion using macros only
# Based on https://github.com/crystal-lang/crystal/blob/26635f1052b99ab5b52a8b051020a25435dba751/src/compiler/crystal/semantic/literal_expander.cr
macro expand_literal_ArrayLiteral_empty(node)
{% puts "--- expansion for: #{node}" %}
Array({{ node.of }}).new
{% debug %}
end
macro expand_literal_ArrayLiteral_filled(node)
{% puts "--- expansion for: #{node}" %}
{% if node_of = node.of %}
{% type_var = node_of %}
{% else %}
{% type_var = "typeof(#{node.splat})".id %}
{% end %}
Array({{ type_var }}).build({{ node.size }}) do |%buffer|
{% for elem, index in node %}
%buffer[{{ index }}] = {{ elem }}
{% end %}
{{ node.size }}
end
{% debug %}
end
macro expand_literal_ArrayLiteral_named_empty(node)
{% puts "--- expansion for: #{node}" %}
{{ node.type }}.new
{% debug %}
end
macro expand_literal_ArrayLiteral_named_filled(node)
{% puts "--- expansion for: #{node}" %}
%obj = {{ node.type }}(typeof({{ *node }})).new
{% for elem in node %}
%obj << {{ elem }}
{% end %}
%obj
{% debug %}
end
macro expand_literal_ArrayLiteral(node)
{% if node.of && node.size == 0 %}
expand_literal_ArrayLiteral_empty({{ node }})
{% elsif node.type && node.size == 0 %}
expand_literal_ArrayLiteral_named_empty({{ node }})
{% elsif node.type %}
expand_literal_ArrayLiteral_named_filled({{ node }})
{% else %}
expand_literal_ArrayLiteral_filled({{ node }})
{% end %}
end
macro expand_literal(node)
{% if node.is_a? ArrayLiteral %}
expand_literal_ArrayLiteral({{ node }})
{% else %}
{% puts "Can't expand literal of type #{node.class_name}" %}
{{ node }}
{% end %}
end
# expand_literal_ArrayLiteral_empty
expand_literal [] of Int32
expand_literal [1, true] of Int32 | Bool | String
expand_literal [1, true, "bew"]
expand_literal Set{1, true, "bew"}
"--- expansion for: [] of Int32"
Array(Int32).new
"--- expansion for: [1, true] of Int32 | Bool | String"
Array(Int32 | Bool | String).build(2) do |__temp_20|
__temp_20[0] = 1
__temp_20[1] = true
2
end
"--- expansion for: [1, true, \"bew\"]"
Array(typeof(1, true, "bew")).build(3) do |__temp_21|
__temp_21[0] = 1
__temp_21[1] = true
__temp_21[2] = "bew"
3
end
"--- expansion for: Set {1, true, \"bew\"}"
__temp_22 = Set(typeof(1, true, "bew")).new
__temp_22 << 1
__temp_22 << true
__temp_22 << "bew"
__temp_22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment