Skip to content

Instantly share code, notes, and snippets.

@bcardiff
Created June 19, 2015 08:24
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 bcardiff/740e8c1f7c7fbc456bb0 to your computer and use it in GitHub Desktop.
Save bcardiff/740e8c1f7c7fbc456bb0 to your computer and use it in GitHub Desktop.
Autocode metaprogramming POC in Crystal

Compiling

crystal build main.cr

will change Settings declaration in main.cr from

class Settings
  auto
end

to

class Settings
  auto
  property baz
  property bar
  property foo
end

Yet the program needs to be compiled twice to get the property code expanded.

macro auto(file = __FILE__, line = __LINE__)
{% metadata_file = file + "." + @type.name.stringify + ".auto" %}
{{ run("./autoprepare", {{metadata_file}}) }}
macro method_missing(name, args, block)
\{{ run("./autowritter", {{file}}, {{line}}, @type.name, name, {{metadata_file}}) }}
nil
end
end
File.write(ARGV[0], "")
file, loc, type_name, prop, metadata_file = ARGV[0], ARGV[1].to_i, ARGV[2], ARGV[3], ARGV[4]
prop = prop[0..-2] if prop[-1] == '='
File.each_line(metadata_file) do |other_prop|
exit if other_prop.strip == prop
end
File.open(metadata_file, "a") do |metadata|
metadata.print("#{prop}\n")
end
content = File.read(file)
File.open(file, "w") do |f|
content.each_line do |line|
f.print(line)
if loc == 1
prefix = /^\s*/.match(line)
f.print("#{prefix.not_nil![0]}property #{prop}\n")
end
loc -= 1
end
end
require "./autocode"
class Settings
auto
end
s = Settings.new
s.foo = 1
s.bar
s.baz
puts s.foo
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment