The following macro and macro call cause a segmentation fault in the compiler.
(Also available here: https://play.opendylan.org/shared/e3ade7dbb9f0d071)
define traced macro enum-definer
{ define enum ?enum-name:name () ?clauses:* end }
=> { ?@defconst{ 1 ; ?clauses }
define constant "$" ## ?enum-name ## "-names" = vector(?@pretty-names{ ?clauses });
define constant "$" ## ?enum-name ## "-values" = vector(?@constant-names{ ?clauses }); }
defconst:
{ ?default:expression } => { }
// Rewrite foo; => foo = default ("foo");
{ ?default:expression ; ?:name ; ?more:* }
=> { ?@defconst{ ?default ; ?name = ?default (?"name") ; ?more } }
// Rewrite foo = 1; => foo = 1 ("foo");
{ ?default:expression ; ?:name = ?value:expression ; ?more:* }
=> { ?@defconst{ ?default ; ?name = ?value (?"name") ; ?more } }
// Rewrite foo ("Foo"); => foo = default ("Foo");
{ ?default:expression ; ?:name (?pretty-name:expression) ; ?more:* }
=> { ?@defconst{ ?default ; ?name = ?default (?pretty-name) ; ?more } }
// Fully specified case
{ ?default:expression ; ?:name = ?value:expression (?pretty-name:expression) ; ?more:* }
=> { define constant ?name :: <int> = ?value;
?@defconst{ ?default ; ?more } }
constant-names:
{ } => {}
{ ?:name ?junk:* ; ...} => { ?name , ... }
pretty-names:
{ ?:name = ?:expression { ?pretty-name:expression } ; ... } => { ?pretty-name , ... }
{ ?:name { ?pretty-name:expression } ; ... } => { ?pretty-name , ... }
{ ?:name = ?:expression ; ... } => { ?"name" , ... }
{ ?:name ; ... } => { ?"name" , ... }
{} => {}
end macro;
define enum color ()
$color-red; // defines $color-red :: <int> = 1 with name "red"
$color-green = 20; // defines $color-green :: <int> = 20 with name "green"
$color-blue {"Blue"}; // defines $color-blue :: <int> = 21 with name "Blue"
$color-cyan = 30 {"Cyan"}; // defines $color-cyan :: <int> = 30 with name "Cyan"
end;
The sharp eye will notice that I hadn't fixed all the template rules to use { } around the color name yet. Finishing that work (as is done here) prevents the crash.
I'm sure this isn't a minimal test case. I'll try to whittle it down a bit when I get a chance.
I don't yet understand why { } work and ( ) don't, but I did note that when using ( ) in the pretty-names aux rule set the clause $color-cyan = 30 ("Cyan"); was matching { ?:name = ?:expression ; ... } for some reason. I assume that's the same reason for the infinite recursion in the defconst rules as well.
Backtrace from segfault:
dylan-bt
frame #14 list 0x000001089cd433 libdylan.dylib at list.dylan:37
frame #15 append-sequence 0x0000010a20c7b9 libdfmc-reader.dylib at parser-support.dylan:13
frame #16 call-parser-action 0x0000010943916a libparser-run-time.dylib at dispatch.dylan:305
frame #17 run-parser 0x00000109439108 libparser-run-time.dylib at dispatch.dylan:395
frame #18 re-read-fragments 0x0000010a20eb9f libdfmc-reader.dylib at interface.dylan:65
frame #19 parse-constraint 0x0000010a36f144 libdfmc-macro-expander.dylib at constraint-parsing.dylan:55
frame #20 match-expression-constraint 0x0000010a37354c libdfmc-macro-expander.dylib at pattern-back-end.dylan:333
frame #21 Kanonymous_of_generate_functionF225I 0x0000010a38b8ed libdfmc-macro-expander.dylib at pattern-to-function.dylan:415
frame #22 Kanonymous_of_generate_pattern_element_functionF308I 0x0000010a38be1b libdfmc-macro-expander.dylib at pattern-to-function.dylan:228
frame #23 Kanonymous_of_generate_pattern_element_functionF308I 0x0000010a38be82 libdfmc-macro-expander.dylib at pattern-to-function.dylan:229
frame #24 Kanonymous_of_generate_pattern_element_functionF308I 0x0000010a38be82 libdfmc-macro-expander.dylib at pattern-to-function.dylan:229
frame #25 Kanonymous_of_generate_structure_parts_functionF322I 0x0000010a38bfba libdfmc-macro-expander.dylib at pattern-to-function.dylan:207
frame #26 Kanonymous_of_generate_structure_parts_functionF322I 0x0000010a38bfea libdfmc-macro-expander.dylib at pattern-to-function.dylan:209
frame #27 Kanonymous_of_generate_rule_functionF323I 0x0000010a38a09d libdfmc-macro-expander.dylib at pattern-to-function.dylan:105
frame #28 call-list-with-collecting 0x0000010a389b0c libdfmc-macro-expander.dylib at pattern-to-function.dylan:570
frame #29 Kanonymous_of_generate_template_functionF60I 0x0000010a3894a5 libdfmc-macro-expander.dylib at template-function.dylan:24
frame #30 call-list-with-collecting 0x0000010a389b0c libdfmc-macro-expander.dylib at pattern-to-function.dylan:570
frame #31 Kanonymous_of_generate_template_functionF60I 0x0000010a3894a5 libdfmc-macro-expander.dylib at template-function.dylan:24
frame #32 call-list-with-collecting 0x0000010a389b0c libdfmc-macro-expander.dylib at pattern-to-function.dylan:570
frame #33 Kanonymous_of_generate_template_functionF60I 0x0000010a3894a5 libdfmc-macro-expander.dylib at template-function.dylan:24
frame #34 call-list-with-collecting 0x0000010a389b0c libdfmc-macro-expander.dylib at pattern-to-function.dylan:570
...etc...
[edit: fixed dead playground links]
The following macro and macro call cause a segmentation fault in the compiler.
(Also available here: https://play.opendylan.org/shared/e3ade7dbb9f0d071)
The sharp eye will notice that I hadn't fixed all the template rules to use { } around the color name yet. Finishing that work (as is done here) prevents the crash.
I'm sure this isn't a minimal test case. I'll try to whittle it down a bit when I get a chance.
I don't yet understand why { } work and ( ) don't, but I did note that when using ( ) in the pretty-names aux rule set the clause
$color-cyan = 30 ("Cyan");was matching{ ?:name = ?:expression ; ... }for some reason. I assume that's the same reason for the infinite recursion in thedefconstrules as well.Backtrace from segfault:
[edit: fixed dead playground links]