# Feature request: macro to pass code to command

**URL:** <https://forum.crystal-lang.org/t/feature-request-macro-to-pass-code-to-command/1698>\
**Category:** Crystal Contrib\
**Created:** [February 12, 2020, 5:58am UTC](https://forum.crystal-lang.org/t/feature-request-macro-to-pass-code-to-command/1698 "2020-02-12T05:58:47Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![rogerdpack](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/rogerdpack/32/117_2.png) [@rogerdpack](https://forum.crystal-lang.org/u/rogerdpack)\
**Post date:** [February 12, 2020, 5:58am UTC](https://forum.crystal-lang.org/t/feature-request-macro-to-pass-code-to-command/1698/1 "2020-02-12T05:58:47Z")

</div>

I know there is a macro method to call out to a system command

[https://crystal-lang.org/api/0.32.1/Crystal/Macros.html#system(command):MacroId-instance-method](https://crystal-lang.org/api/0.32.1/Crystal/Macros.html#system(command):MacroId-instance-method)

It would be interesting to me, at least from an curiosity perspective, to be able to pass an AST or a “string block of code” to that command so it could return something and effectively rewrite existing crystal code. Just a thought/idea. Sorry I know I’ve requested it before LOL.

Cheers!

---

<div class="post-metadata">

**Author:** ![asterite](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/asterite/32/60_2.png) [@asterite](https://forum.crystal-lang.org/u/asterite)\
**Post date:** [February 12, 2020, 10:25am UTC](https://forum.crystal-lang.org/t/feature-request-macro-to-pass-code-to-command/1698/2 "2020-02-12T10:25:21Z")

</div>

You can already do that. Pass a string representation of the ast to the macro, let the macro parse it, transform it, return it, and then you paste the result into the program.

---

<div class="post-metadata">

**Author:** ![rogerdpack](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/rogerdpack/32/117_2.png) [@rogerdpack](https://forum.crystal-lang.org/u/rogerdpack)\
**Post date:** [February 12, 2020, 2:43pm UTC](https://forum.crystal-lang.org/t/feature-request-macro-to-pass-code-to-command/1698/3 "2020-02-12T14:43:31Z")

</div>

Nice. It’s possible to pass the string as a parameter to the system command? Examples would be wonderful, thanks, I’m not experienced with macros…

---

<div class="post-metadata">

**Author:** ![asterite](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/asterite/32/60_2.png) [@asterite](https://forum.crystal-lang.org/u/asterite)\
**Post date:** [February 12, 2020, 3:04pm UTC](https://forum.crystal-lang.org/t/feature-request-macro-to-pass-code-to-command/1698/4 "2020-02-12T15:04:29Z")

</div>

Sure!

```crystal
# foo.cr
macro foo(ast)
  {{ run "./bar", ast }}
  {% debug %}
end

foo def add(x, y)
  x + y
end

p add(2, 3)

```

```crystal
# bar.cr
require "compiler/crystal/syntax"

include Crystal

code = ARGV[0]
nodes = Parser.parse(code)

a_def = nodes.as(Def)
a_def.body = Call.new(Var.new("x"), "*", Var.new("y"))

puts a_def.to_s

```

So we pass a `def` to the macro, we get it on `bar` (as code), we parse it and then modify the body to do a multiplication instead of an addition.

If you want to modify code in a more generic way you probably want to use a `Crystal::Transformer`.

I don’t know what use cases this has, but it’s possible.

It’s a bit slow to compile the first time but subsequent times should be faster.

---

<div class="post-metadata">

**Author:** ![rogerdpack](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/rogerdpack/32/117_2.png) [@rogerdpack](https://forum.crystal-lang.org/u/rogerdpack)\
**Post date:** [February 13, 2020, 4:22am UTC](https://forum.crystal-lang.org/t/feature-request-macro-to-pass-code-to-command/1698/5 "2020-02-13T04:22:36Z")

</div>

Awesome, thanks!
