cat.cr
· 1.5 KiB · Crystal
Bruto
Playground
macro concat(*values)
{% top = -1 %}
{% for value, i in values %}
{% if value.is_a? ProcLiteral %}
{% new_top = top - value.args.size + 1 %}
%var{new_top} = {{value}}.call({% for arg, j in value.args %}
%var{top - (value.args.size - j - 1)},
{% end %})
{% top = new_top %}
{% elsif value.is_a? Call %}
{% new_top = top - value.args.size + 1 %}
%var{new_top} = {{value}}({% for arg, j in value.args %}
%var{top - (value.args.size - j - 1)},
{% end %})
{% top = new_top %}
{% elsif value.is_a? SymbolLiteral && value == :put_stack %}
{% for i in (0..top) %}
puts(%var{i})
{% end %}
puts("---------")
{% elsif value.is_a? SymbolLiteral && value == :swap %}
%var{top}, %var{top - 1} = %var{top - 1}, %var{top}
{% elsif value.is_a? SymbolLiteral && value == :dup %}
{% top += 1 %}
%var{top} = %var{top - 1}
{% elsif value.is_a? SymbolLiteral && value == :over %}
{% top += 1 %}
%var{top} = %var{top - 2}
{% elsif value.is_a? SymbolLiteral && value == :drop %}
{% top -= 1 %}
{% else %}
{% top += 1 %}
%var{top} = {{value}}
{% end %}
{% end %}
end
three = concat(
1, 2, :over, :over,
->(x : Int32, y : Int32){ x - y },
:dup, ->(x : Int32, y : Int32){ x + y },
:drop, ->(x : Int32, y : Int32){ x / y }
)
| 1 | macro concat(*values) |
| 2 | {% top = -1 %} |
| 3 | {% for value, i in values %} |
| 4 | {% if value.is_a? ProcLiteral %} |
| 5 | {% new_top = top - value.args.size + 1 %} |
| 6 | %var{new_top} = {{value}}.call({% for arg, j in value.args %} |
| 7 | %var{top - (value.args.size - j - 1)}, |
| 8 | {% end %}) |
| 9 | {% top = new_top %} |
| 10 | {% elsif value.is_a? Call %} |
| 11 | {% new_top = top - value.args.size + 1 %} |
| 12 | %var{new_top} = {{value}}({% for arg, j in value.args %} |
| 13 | %var{top - (value.args.size - j - 1)}, |
| 14 | {% end %}) |
| 15 | {% top = new_top %} |
| 16 | {% elsif value.is_a? SymbolLiteral && value == :put_stack %} |
| 17 | {% for i in (0..top) %} |
| 18 | puts(%var{i}) |
| 19 | {% end %} |
| 20 | puts("---------") |
| 21 | {% elsif value.is_a? SymbolLiteral && value == :swap %} |
| 22 | %var{top}, %var{top - 1} = %var{top - 1}, %var{top} |
| 23 | {% elsif value.is_a? SymbolLiteral && value == :dup %} |
| 24 | {% top += 1 %} |
| 25 | %var{top} = %var{top - 1} |
| 26 | {% elsif value.is_a? SymbolLiteral && value == :over %} |
| 27 | {% top += 1 %} |
| 28 | %var{top} = %var{top - 2} |
| 29 | {% elsif value.is_a? SymbolLiteral && value == :drop %} |
| 30 | {% top -= 1 %} |
| 31 | {% else %} |
| 32 | {% top += 1 %} |
| 33 | %var{top} = {{value}} |
| 34 | {% end %} |
| 35 | {% end %} |
| 36 | end |
| 37 | |
| 38 | three = concat( |
| 39 | 1, 2, :over, :over, |
| 40 | ->(x : Int32, y : Int32){ x - y }, |
| 41 | :dup, ->(x : Int32, y : Int32){ x + y }, |
| 42 | :drop, ->(x : Int32, y : Int32){ x / y } |
| 43 | ) |