diff --git a/spec/compiler/macro/macro_methods_spec.cr b/spec/compiler/macro/macro_methods_spec.cr index f18f9edb7aa5..525208770153 100644 --- a/spec/compiler/macro/macro_methods_spec.cr +++ b/spec/compiler/macro/macro_methods_spec.cr @@ -3137,6 +3137,15 @@ module Crystal end.should eq %(bar\n) end + it "print" do + String.build do |io| + assert_macro(%({% print foo %}), "") do |program| + program.stdout = io + {foo: "bar".string} + end + end.should eq %(bar) + end + it "p" do String.build do |io| assert_macro(%({% p foo %}), "") do |program| diff --git a/src/compiler/crystal/macros.cr b/src/compiler/crystal/macros.cr index 8b5c6845c0b2..6cce0815e0af 100644 --- a/src/compiler/crystal/macros.cr +++ b/src/compiler/crystal/macros.cr @@ -186,6 +186,10 @@ module Crystal::Macros def puts(*expressions) : Nop end + # Prints AST nodes at compile-time. Useful for debugging macros. + def print(*expressions) : Nop + end + # Same as `puts`. def p(*expressions) : Nop end diff --git a/src/compiler/crystal/macros/methods.cr b/src/compiler/crystal/macros/methods.cr index 6894d3d60c15..f5d4c89866e4 100644 --- a/src/compiler/crystal/macros/methods.cr +++ b/src/compiler/crystal/macros/methods.cr @@ -59,6 +59,8 @@ module Crystal interpret_parse_type(node) when "puts" interpret_puts(node) + when "print" + interpret_print(node) when "p", "pp" interpret_p(node) when "p!", "pp!" @@ -196,6 +198,18 @@ module Crystal @last = Nop.new end + def interpret_print(node) + node.args.each do |arg| + arg.accept self + last = @last + last = last.value if last.is_a?(StringLiteral) + + @program.stdout.print last + end + + @last = Nop.new + end + def interpret_p(node) node.args.each do |arg| arg.accept self