Permalink
Browse files

Work on rewriting, matching building binding etc.

  • Loading branch information...
1 parent 256b135 commit 66840c7ea86fe528ddff3c5d80bd3e553234770d @zefhemel committed Mar 19, 2009
Showing with 141 additions and 30 deletions.
  1. +42 −9 ast.pil
  2. +54 −18 gelly.pil
  3. +15 −3 parser.pil
  4. +18 −0 rewrite.pil
  5. +12 −0 utils.pil
View
51 ast.pil
@@ -65,6 +65,29 @@ class gel::ConsTerm extends gel::Term {
return s.as<String>;
}
+ Bool ==(Object o) {
+ if(o == null) {
+ return false;
+ }
+ if(o instanceof ConsTerm) {
+ var t = o.as<ConsTerm>;
+ if(t.constructor != constructor) {
+ return false;
+ }
+ if(t.children.length != children.length) {
+ return false;
+ }
+ for(Int i = 0; i < children.length; i++) {
+ if(t.children[i] != children[i]) {
+ return false;
+ }
+ }
+ return true;
+ } else {
+ return false;
+ }
+ }
+
Bool match(Term t, Map<String, Term> bindings) {
if(t instanceof ConsTerm) {
var t2 = t.as<ConsTerm>;
@@ -77,16 +100,17 @@ class gel::ConsTerm extends gel::Term {
return false;
}
}
+ if(children.length != t2.children.length) {
+ return false;
+ }
for(Int i = 0; i < children.length; i++) {
- if(i < t2.children.length) {
- if(children[i] instanceof MatchVarTerm) {
- if(!children[i].match(t2.children[i], bindings)) {
- return false;
- }
- } else {
- if(!children[i].match(t2.children[i], bindings)) {
- return false;
- }
+ if(children[i] instanceof MatchVarTerm) {
+ if(!children[i].match(t2.children[i], bindings)) {
+ return false;
+ }
+ } else {
+ if(!children[i].match(t2.children[i], bindings)) {
+ return false;
}
}
}
@@ -105,6 +129,15 @@ class gel::ConsTerm extends gel::Term {
return nt;
}
+ ConsTerm clone() {
+ var nc = new Array<Term>(children.length);
+ for(Int i = 0; i < children.length; i++) {
+ nc[i] = children[i];
+ }
+ var n = new ConsTerm(type, constructor, nc);
+ return n;
+ }
+
as<String> {
var s = new MutableString("(");
s.append(constructor.as<String>);
View
@@ -1,31 +1,65 @@
import "ast.pil"
import "parser.pil"
//import "evaluator.pil"
+import "rewrite.pil"
import gel
+import gelly::rewrite
class gel::Interpreter {
- Term buildPattern = new Parser("build(?t)").acceptExp();
- Term rulePattern = new Parser("?rn : [ ?lh ] -> [ ?rh ]").acceptExp();
- Term applyPattern = new Parser("apply(?t)").acceptExp();
+ Term buildPattern = replaceMatchVar(new Parser("![ m_t ]").acceptExp(), "m_");
+ Term matchPattern = replaceMatchVar(new Parser("?[ m_t ]").acceptExp(), "m_");
+ Term rulePattern = replaceMatchVar(new Parser("m_rn : [ m_lh ] -> [ m_rh ]").acceptExp(), "m_");
+ Term showBindingsPattern = new Parser(":bindings").acceptExp();
+ Term showCurrentTermPattern = new Parser(":show").acceptExp();
Map<String, Term> ruleDefs = new Map<String, Term>();
Term currentTerm = null;
+ Map<String, Term> bindings = new Map<String, Term>();
void handleBuild(Term t) {
var m = new Map<String, Term>();
if(buildPattern.match(t, m)) {
- currentTerm = m["t"];
+ currentTerm = m["m_t"];
println("Current term set");
}
}
+ void handleMatch(Term t) {
+ var m = new Map<String, Term>();
+ if(matchPattern.match(t, m)) {
+ print("Match: ");
+ var t2 = replaceMatchVar(m["m_t"], "m_");
+ println(t2);
+ if(t2.match(currentTerm, bindings)) {
+ println(currentTerm);
+ println("Current bindings: " + bindings.as<String>);
+ } else {
+ println("Match failed.");
+ }
+ }
+ }
+
void handleRuleDef(Term t) {
var m = new Map<String, Term>();
if(rulePattern.match(t, m)) {
println("Defining rule!");
- ruleDefs[m["rn"].as<SymbolTerm>.symbol] = t;
println(m);
+ ruleDefs[m["m_rn"].as<SymbolTerm>.symbol] = t;
+ }
+ }
+
+ void handleShowBindings(Term t) {
+ var m = new Map<String, Term>();
+ if(showBindingsPattern.match(t, m)) {
+ println(bindings);
+ }
+ }
+
+ void handleShowCurrentTerm(Term t) {
+ var m = new Map<String, Term>();
+ if(showCurrentTermPattern.match(t, m)) {
+ println(currentTerm);
}
}
@@ -35,8 +69,8 @@ class gel::Interpreter {
var m = new Map<String, Term>();
rulePattern.match(rule, m);
var m2 = new Map<String, Term>();
- if(m["lh"].match(t, m2)) {
- currentTerm = m["rh"].construct(m2);
+ if(m["m_lh"].match(t, m2)) {
+ currentTerm = m["m_rh"].construct(m2);
return currentTerm;
} else {
throw new Exception("Could not apply!");
@@ -48,8 +82,8 @@ class gel::Interpreter {
void handleApply(Term t) {
var m = new Map<String, Term>();
- if(applyPattern.match(t, m)) {
- var ruleName = m["t"].as<SymbolTerm>.symbol;
+ if(t instanceof SymbolTerm) {
+ var ruleName = t.as<SymbolTerm>.symbol;
try {
println(apply(ruleName, currentTerm));
} catch(Exception e) {
@@ -61,17 +95,22 @@ class gel::Interpreter {
void handle(String input) {
var p = new Parser(input);
var t = p.acceptExp();
- println(t.toIndentedString(0));
- handleBuild(t);
- handleRuleDef(t);
- handleApply(t);
+ if(t != null) {
+ //println(t.toIndentedString(0));
+ handleBuild(t);
+ handleMatch(t);
+ handleRuleDef(t);
+ handleApply(t);
+ handleShowBindings(t);
+ handleShowCurrentTerm(t);
+ }
}
}
void main(Array<String> args) {
//evalInit();
String input = null;
- println("Welcome to zisp, type :q to quit.");
+ println("Welcome to gelly, type :q to quit.");
var interp = new Interpreter();
while(input != ":q") {
print("> ");
@@ -80,10 +119,7 @@ void main(Array<String> args) {
interp.handle(input);
}
}
- /*
- println(new Parser("3 * 8").acceptExp().toIndentedString(0));
- println(new Parser("rule : [ 10 ] -> [ 20 ]").acceptExp().toIndentedString(0));
- */
+ //println(replaceMatchVar(new Parser("3 * 8 + m_bla").acceptExp(), "m_").toIndentedString(0));
/*
var m = new Map<String, Term>();
println(t.match(matchTerm, m));
View
@@ -38,7 +38,7 @@ class gel::Parser {
);
List<String> noWhitespaceOps = new List<String>(";", ",", ".");
- Array<String> prefixOps = new Array<String>("++", "+", "--", "-", "*", "<", ">");
+ Array<String> prefixOps = new Array<String>("++", "+", "--", "-", "*", "<", ">", "?", "!", ":");
new(String text) {
@@ -99,10 +99,12 @@ class gel::Parser {
if(s != null) {
return new StringTerm(s);
}
+ /*
var mv = acceptMatchVar();
if(mv != null) {
return new MatchVarTerm(mv);
}
+ */
var pe = acceptPrefixExp();
if(pe != null) {
return pe;
@@ -348,10 +350,20 @@ class gel::Parser {
if(i == text.length) {
return null;
}
- if(!accept('?')) {
+ var oldI = i;
+ if(!accept('@')) {
+ return null;
+ }
+ var idn = acceptIdn();
+ if(idn == null) {
+ i = oldI;
+ return null;
+ }
+ if(!accept('@')) {
+ i = oldI;
return null;
}
- return acceptIdn();
+ return idn;
}
String acceptIdn() {
View
@@ -1,10 +1,28 @@
import "ast.pil"
+import "utils.pil"
import gel
+import gelly::utils
+import gelly::rewrite
class gelly::rewrite::FailException extends Exception {
}
+Term gelly::rewrite::replaceMatchVar(Term t, String idnPrefix) {
+ if(t instanceof SymbolTerm && stringStartsWith(t.as<SymbolTerm>.symbol, idnPrefix)) {
+ return new MatchVarTerm(t.as<SymbolTerm>.symbol);
+ } else if(t instanceof ConsTerm) {
+ var t2 = t.as<ConsTerm>;
+ var ct = t2.clone();
+ ct.constructor = replaceMatchVar(ct.constructor, idnPrefix);
+ for(Int i = 0; i < ct.children.length; i++) {
+ ct.children[i] = replaceMatchVar(ct.children[i], idnPrefix);
+ }
+ return ct;
+ }
+ return t;
+}
+
Term gelly::rewrite::apply(Function1<Term, Term> str, Term t) {
return str(t);
}
View
@@ -0,0 +1,12 @@
+
+Bool gelly::utils::stringStartsWith(String str, String prefix) {
+ if(prefix.length > str.length) {
+ return false;
+ }
+ for(Int i = 0; i < prefix.length; i++) {
+ if(prefix[i] != str[i]) {
+ return false;
+ }
+ }
+ return true;
+}

0 comments on commit 66840c7

Please sign in to comment.