digitalmars.D.learn - Create mixins from a list of strings
- "Casper =?UTF-8?B?RsOmcmdlbWFuZCI=?= <shorttail hotmail.com> (11/11) Jan 10 2014 Have:
- Jakob Ovrum (13/24) Jan 10 2014 You can use template argument lists for indexable compile-time
- "Casper =?UTF-8?B?RsOmcmdlbWFuZCI=?= <shorttail hotmail.com> (10/13) Jan 11 2014 enum semanticArray = ["test"];
- Philippe Sigaud (17/17) Jan 11 2014 Maybe you could use just one name and put the dispatching code inside it...
- "Casper =?UTF-8?B?RsOmcmdlbWFuZCI=?= <shorttail hotmail.com> (9/19) Jan 11 2014 I can't do this since there will be multiple rules with the same
- Philippe Sigaud (41/56) Jan 11 2014 OK, fair enough.
- "Casper =?UTF-8?B?RsOmcmdlbWFuZCI=?= <shorttail hotmail.com> (8/22) Jan 11 2014 Yes, and I would not be able to argue this is the definite way to
- Philippe Sigaud (29/39) Jan 11 2014 Duh, instead of closures, you can use opCall-ed structs:
- Timon Gehr (7/19) Jan 11 2014 import std.string, std.algorithm;
Have: enum (or is immutable array better?) array = ["derp", "lala"]; Want: mixin("some syntax" ~ array[0]); mixin("some syntax" ~ array[1]); Basically, to specify a number of similar functions based on a list of strings. Why? Pegged's semantic actions allows only calling a function by name, not specifying parameters. I could probably ask for an extension, but if there's a cool template or whatever way to do this, it would be a lot nicer. :3
Jan 10 2014
On Saturday, 11 January 2014 at 07:45:31 UTC, Casper Færgemand wrote:Have: enum (or is immutable array better?) array = ["derp", "lala"]; Want: mixin("some syntax" ~ array[0]); mixin("some syntax" ~ array[1]);You can use template argument lists for indexable compile-time lists: --- import std.typetuple : TypeTuple; alias array = TypeTuple!("derp", "lala"); mixin("some syntax" ~ array[0]); mixin("some syntax" ~ array[1]); ---Basically, to specify a number of similar functions based on a list of strings. Why? Pegged's semantic actions allows only calling a function by name, not specifying parameters. I could probably ask for an extension, but if there's a cool template or whatever way to do this, it would be a lot nicer. :3Your problem is probably better solved without string mixins, but we'd probably need to see some code or more elaboration to accurately suggest a solution.
Jan 10 2014
On Saturday, 11 January 2014 at 07:50:51 UTC, Jakob Ovrum wrote:Your problem is probably better solved without string mixins, but we'd probably need to see some code or more elaboration to accurately suggest a solution.enum semanticArray = ["test"]; mixin(`T ` ~ semanticArray[0] ~ `(T)(T t) { t.name ~= "` ~ semanticArray[0] ~ `"; return t; }`); This will mixin a single templated function named "test", which changes an AST node's name to whatever it was concatenated with "test". I want this to happen automatically for any length of semanticArray.
Jan 11 2014
Maybe you could use just one name and put the dispatching code inside it? T actor(T)(T t) { switch (t.name) { case "Gramm.Expr": return foo(t); case "Gramm.FunctionCall": return foo(t); case "Gramm.Declaration": return foo(t); default: throw new Exception("..."); } } or do it with a template, holding function names as aliases: alias actor = dispatcher!(foo, bar, baz);
Jan 11 2014
On Saturday, 11 January 2014 at 09:17:34 UTC, Philippe Sigaud wrote:case "Gramm.Expr": return foo(t); case "Gramm.FunctionCall": return foo(t); case "Gramm.Declaration": return foo(t); default: throw new Exception("...");I can't do this since there will be multiple rules with the same name that require different treatment. The reason I want to use semantic actions is that I don't want to push an already heavy grammar into double or triple size just to name specific rules in a certain way. Semantic actions take up very little space and fit nicely into the syntax.or do it with a template, holding function names as aliases: alias actor = dispatcher!(foo, bar, baz);I have no idea what you mean. :D
Jan 11 2014
On Sat, Jan 11, 2014 at 2:34 PM, <"Casper Færgemand\" <shorttail hotmail.com>" puremagic.com> wrote:On Saturday, 11 January 2014 at 09:17:34 UTC, Philippe Sigaud wrote:OK, fair enough. I'm a bit leery of putting D call syntax into semantic actions, because it'll also explode the Pegged grammar size (I'm fairly sure I'd have to pull in a big part of D if I want to get function calls right). That's one feature I wanted at one time, but I'm not sure it's a good idea. OTOH, you can define a templated semantic action: template foo(string s, int i) { T foo(T)(T t) { writeln("Calling foo"); t.name ~= s ~ to!string(i); return t; } } And then invoke it with a parameter: mixin(grammar(` Test: A <- B { foo!("abc",1) } C { foo!("def",2) } B <- 'b' C <- 'c' `)); I did not test it thoroughly, so I'm not sure every template parameter combination is OK. It's probably better not to have curly braces inside the arg list. Pegged also authorize anonymous functions as semantic actions: https://github.com/PhilippeSigaud/Pegged/wiki/Semantic-Actions#anonymous-functions-as-actions Maybe that could be another solution. Something like B { p => foo(arg1, p) } Note that closures are not (yet) supported in CTFE, because else another solution would be a function-returning function: auto bar(string s, int i) { return (ParseTree p) { p.name ~= s ~ to!string(i); return p; }; }case "Gramm.Expr": return foo(t); case "Gramm.FunctionCall": return foo(t); case "Gramm.Declaration": return foo(t); default: throw new Exception("...");I can't do this since there will be multiple rules with the same name that require different treatment. The reason I want to use semantic actions is that I don't want to push an already heavy grammar into double or triple size just to name specific rules in a certain way. Semantic actions take up very little space and fit nicely into the syntax.
Jan 11 2014
On Saturday, 11 January 2014 at 16:07:30 UTC, Philippe Sigaud wrote:I'm a bit leery of putting D call syntax into semantic actions, because it'll also explode the Pegged grammar size (I'm fairly sure I'd have to pull in a big part of D if I want to get function calls right). That's one feature I wanted at one time, but I'm not sure it's a good idea.Yes, and I would not be able to argue this is the definite way to handle things anyway. It's a try at type checking with little regard to efficiency. I'm just happy it works with Timon Gehr's extremely simple solution. :3 On Saturday, 11 January 2014 at 20:52:15 UTC, Timon Gehr wrote:import std.string, std.algorithm; enum semanticArray = ["derp", "lala"]; mixin(semanticArray.map!(a=>`T `~a~`(T)(T t) { t.name ~= "`~a~`"; return t; }`).join());Here, have a heart. <3
Jan 11 2014
Note that closures are not (yet) supported in CTFE, because else another solution would be a function-returning function: auto bar(string s, int i) { return (ParseTree p) { p.name ~= s ~ to!string(i); return p; }; }Duh, instead of closures, you can use opCall-ed structs: import pegged.grammar; auto foo(string s, int i) { return Foo(s,i); } struct Foo { string s; int i; this(string s, int i) { this.s = s; this.i = i;} ParseTree opCall(ParseTree p) { p.name ~= s ~ to!string(i); return p; } } mixin(grammar(` Test: A <- B { foo("abc",1) } C { foo("def",2) } B <- 'b' C <- 'c' `)); void main() { enum result = Test("bc"); // Compile-time parsing is still possible pragma(msg, result); writeln(result); }
Jan 11 2014
On 01/11/2014 09:35 AM, "Casper Færgemand" <shorttail hotmail.com>" wrote:On Saturday, 11 January 2014 at 07:50:51 UTC, Jakob Ovrum wrote:import std.string, std.algorithm; enum semanticArray = ["derp", "lala"]; mixin(semanticArray.map!(a=>`T `~a~`(T)(T t) { t.name ~= "`~a~`"; return t; }`).join());Your problem is probably better solved without string mixins, but we'd probably need to see some code or more elaboration to accurately suggest a solution.enum semanticArray = ["test"]; mixin(`T ` ~ semanticArray[0] ~ `(T)(T t) { t.name ~= "` ~ semanticArray[0] ~ `"; return t; }`); This will mixin a single templated function named "test", which changes an AST node's name to whatever it was concatenated with "test". I want this to happen automatically for any length of semanticArray.
Jan 11 2014