Skip to content

Commit

Permalink
crystal: prevent defmacro! from mutating its argument
Browse files Browse the repository at this point in the history
  • Loading branch information
asarhaddon committed Oct 9, 2024
1 parent 29ac2df commit bfcbe98
Show file tree
Hide file tree
Showing 3 changed files with 9 additions and 3 deletions.
4 changes: 3 additions & 1 deletion impls/crystal/step8_macros.cr
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,9 @@ module Mal
eval_error "wrong number of argument for 'defmacro!'" unless list.size == 3
a1 = list[1].unwrap
eval_error "1st argument of 'defmacro!' must be symbol: #{a1}" unless a1.is_a? Mal::Symbol
return Mal::Type.new env.set(a1.str, eval(list[2], env).tap { |n| n.is_macro = true })
mac = eval(list[2], env).dup
mac.is_macro = true
return Mal::Type.new env.set(a1.str, mac)
else
evaluated_first = eval(list.first, env)
f = evaluated_first.unwrap
Expand Down
4 changes: 3 additions & 1 deletion impls/crystal/step9_try.cr
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,9 @@ module Mal
eval_error "wrong number of argument for 'defmacro!'" unless list.size == 3
a1 = list[1].unwrap
eval_error "1st argument of 'defmacro!' must be symbol: #{a1}" unless a1.is_a? Mal::Symbol
return Mal::Type.new env.set(a1.str, eval(list[2], env).tap { |n| n.is_macro = true })
mac = eval(list[2], env).dup
mac.is_macro = true
return Mal::Type.new env.set(a1.str, mac)
when "try*"
catch_list = list.size >= 3 ? list[2].unwrap : Mal::Type.new(nil)
return eval(list[1], env) unless catch_list.is_a? Mal::List
Expand Down
4 changes: 3 additions & 1 deletion impls/crystal/stepA_mal.cr
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,9 @@ module Mal
eval_error "wrong number of argument for 'defmacro!'" unless list.size == 3
a1 = list[1].unwrap
eval_error "1st argument of 'defmacro!' must be symbol: #{a1}" unless a1.is_a? Mal::Symbol
return Mal::Type.new env.set(a1.str, eval(list[2], env).tap { |n| n.is_macro = true })
mac = eval(list[2], env).dup
mac.is_macro = true
return Mal::Type.new env.set(a1.str, mac)
when "try*"
catch_list = list.size >= 3 ? list[2].unwrap : Mal::Type.new(nil)
return eval(list[1], env) unless catch_list.is_a? Mal::List
Expand Down

0 comments on commit bfcbe98

Please sign in to comment.