Excellent overview. I'm having a disconnect on some things. What's the difference between the $ and the @? Does $ substitute and @ match? So your first match in there substitues in var, then parses it and then matches it filling in exp with a subtree?
How exactly to you match trees? Do you first compile the match expression into a tree and then compare the results? How do you distinguish between parents and children?
define deriv(expr, var) {
switch (expr) {
match e`$var ** @exp` ? (isConst(exp)) {
e`$exp * $var ** ($exp -1)`
}
match e`@a + @b` {
define da := deriv(a, var)
define db := deriv(b, var)
e`$da + $db`
I was also trying to think of when I would want to use a different kind of quasi-parser based on a grammar. For instance I wrote an ANTLR grammar for gcc, but I'm not sure what kinds of interesting things I could be doing with it inside of E. The most obvious is tree rewriting, but I can already do that in ANTLR itself, not sure what the advantage would be with quasi-parsing.
My mindset is dominated by having the parser driving the control of a program, so maybe I'm just not "getting it" or I'm trying to solve problems which aren't appropriate for quasi-parsers.
My attempt at an ANTLR translation:
derivExpr(expr, var): // by definition we're parsing the AST in the first
argument
#("**" var1:expr exp:constant) { #derivExpr = #(#[MULT, "*"], exp,
#(#[EXP,"**"], var, #[]) ) } //build the new tree
| #("+" e1:derivExpr(var) e2:derivExpr(var)) //tree automatically
built
;
OK, yours is much much easier to read as far as what is output. But you are matching trees against trees and not really parsing trees, I think. Why does that matter? Overhead, and generality. You have to generate a tree for every expression you match against.
Hmm, I have more thinking to do. Given a separate grammar you could enter it from a quasi-pattern...or you could specify grammar fragments in the quasi-pattern... but you don't want to parse a whole program, just a sub tree...
Sorry my thoughts are so fragmented. I'll return to it tomorrow.
Monty