Permalink
Browse files

Combinators working again.

  • Loading branch information...
1 parent c47bdef commit ac671cad3b040c929087805a23559b206699e46e Mark Watts committed Nov 28, 2012
@@ -13,10 +13,10 @@
LAMBDA(new Special(new TypeId[]{Cons.TYPEID, CronoType.TYPEID},
Function.TYPEID, 2, true, EvalType.NONE)
{
- private static final String _bad_type =
- "\\: expected :cons :any, got %s, %s";
- private static final String _bad_arg =
- "\\: arguments must be :symbol, got %s";
+ private static final String _bad_type =
+ "\\: expected :cons :any, got %s, %s";
+ private static final String _bad_arg =
+ "\\: arguments must be :symbol, got %s";
public CronoType run(Visitor v, List<CronoType> args) {
if(!(args.get(0) instanceof Cons)) {
throw new InterpreterException(_bad_type,
@@ -48,25 +48,25 @@ public CronoType run(Visitor v, List<CronoType> args) {
public String toString() {
return "\\";
}
- });
- //DEFINE(new Function(new TypeId[]{Symbol.TYPEID, CronoType.TYPEID},
- //CronoType.TYPEID, 2, EvalType.NONE)
- //{
- //private static final String _bad_type =
- //"DEFINE: expected :symbol, got %s";
+ }),
+ DEFINE(new Special(new TypeId[]{Symbol.TYPEID, CronoType.TYPEID},
+ CronoType.TYPEID, 2, EvalType.NONE)
+ {
+ private static final String _bad_type =
+ "DEFINE: expected :symbol, got %s";
- //public CronoType run(Visitor v, CronoType[]args) {
- //if(!(args[0] instanceof Symbol)) {
- //throw new InterpreterException(_bad_type, args[0].typeId());
- //}
- //CronoType value = args[1].accept(v);
- //v.getEnv().put(((Symbol)args[0]), value);
- //return value;
- //}
- //public String toString() {
- //return "define";
- //}
- //}),
+ public CronoType run(Visitor v, List<CronoType> args) {
+ if(!(args.get(0) instanceof Symbol)) {
+ throw new InterpreterException(_bad_type, args.get(0).typeId());
+ }
+ CronoType value = args.get(1).accept(v);
+ v.getEnv().put(((Symbol)args.get(0)), value);
+ return value;
+ }
+ public String toString() {
+ return "define";
+ }
+ }),
//UNDEFINE(new Function(new TypeId[]{Symbol.TYPEID}, Nil.TYPEID, 1,
//EvalType.NONE)
//{
@@ -168,6 +168,7 @@ public String toString() {
//return "if";
//}
//}),
+ ;
public final Special special;
private CronoSpecial(Special spec) {
this.special = spec;
@@ -50,25 +50,28 @@ else if (o instanceof Cons)
* up, since we don't want to visit the head
* twice
*/
- CronoType t = getEnv().get(s);
- if (t instanceof Special)
+ if (s.isCombinator())
{
- SpecialForm sf = new SpecialForm(c);
- /* If we wanted only to create an AST,
- * we would stop here.
- * However, we create the nodes and
- * evaluate on the fly
- */
- result = sf.reduce(this);
+ CombinatorApplication ca = new CombinatorApplication(c);
+ result = ca.reduce(this);
}
else
{
- FunctionApplication fa = new FunctionApplication(c);
- result = fa.apply(this);
+ CronoType t = getEnv().get(s);
+ if (t instanceof Special)
+ {
+ SpecialForm sf = new SpecialForm(c);
+ /* If we wanted only to create an AST,
+ * we would stop here.
+ * However, we create the nodes and
+ * evaluate on the fly
+ */
+ result = sf.reduce(this);
+ }
}
- /* TODO: add a combinator case */
}
- else
+
+ if (result == null)
{
/*
* We assume function application by default
@@ -5,9 +5,9 @@
public abstract class Atom extends CronoType {
public static final TypeId TYPEID = new TypeId(":atom", Atom.class,
- CronoType.TYPEID);
-
+ CronoType.TYPEID);
+
public CronoType accept(Visitor v) {
- return v.visit(this);
+ return v.visit(this);
}
-}
+}
@@ -10,26 +10,26 @@
public class Cons extends CronoType implements Iterable<CronoType> {
public static final TypeId TYPEID = new TypeId(":cons", Cons.class,
CronoType.TYPEID);
-
+
private class ConsIterator implements Iterator<CronoType> {
private Cons cell;
private boolean more;
-
+
public ConsIterator(Cons cell) {
this.more = (cell.cdr instanceof Cons);
this.cell = cell;
}
-
+
public boolean hasNext() {
return (cell != null) && ((more && cell.car != null) ||
cell.cdr != null);
}
-
+
public CronoType next() {
if(cell == null) {
throw new NoSuchElementException();
}
-
+
if(more) {
CronoType ret = cell.car;
if(cell.cdr instanceof Cons) {
@@ -39,22 +39,22 @@ public CronoType next() {
}
return ret;
}
-
+
CronoType ret = cell.cdr;
cell = null;
return ret;
}
-
+
public void remove() {
throw new UnsupportedOperationException();
}
}
-
+
public static Cons fromList(List<CronoType> args) {
if(args.size() <= 0) {
return Nil.NIL;
}
-
+
Cons head = new Cons();
Cons curr = head;
Iterator<CronoType> iter = args.iterator();
@@ -67,46 +67,46 @@ public static Cons fromList(List<CronoType> args) {
curr.cdr = Nil.NIL;
return head;
}
-
+
protected CronoType car, cdr;
-
+
protected Cons() {
this.car = null;
this.cdr = null;
}
-
+
public Cons(CronoType car, CronoType cdr) {
this.car = car;
this.cdr = cdr;
}
-
+
public Cons cons(CronoType car) {
return new Cons(car, this);
}
-
+
public CronoType car() {
return (car == null) ? Nil.NIL : car;
}
public CronoType cdr() {
return (cdr == null) ? Nil.NIL : cdr;
}
-
+
public Iterator<CronoType> iterator() {
return new ConsIterator(this);
}
-
+
public CronoType accept(Visitor v) {
return v.visit(this);
}
-
+
public TypeId typeId() {
return TYPEID;
}
-
+
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append("(");
-
+
Cons next = this;
while(next != null) {
builder.append(next.car);
@@ -123,11 +123,33 @@ public String toString() {
next = null;
}
}
-
+
builder.append(")");
return builder.toString();
}
-
+
+ public static CronoType subst (CronoType expr, Symbol name, CronoType val)
+ {
+ if (expr instanceof Symbol)
+ {
+ if (name.equals(expr))
+ {
+ return val;
+ }
+ }
+ else if (expr.equals(Nil.NIL))
+ {
+ return Nil.NIL;
+ }
+ else if (expr instanceof Cons)
+ {
+ Cons c = (Cons) expr;
+ return new Cons(subst(c.car(), name, val), subst(c.cdr(), name, val));
+ }
+
+ return expr;
+ }
+
public List<CronoType> toList() {
List<CronoType> list = new LinkedList<CronoType>();
Cons next = this;
@@ -124,7 +124,7 @@ else if (result instanceof FunctionApplication)
* i.e. fa.accept rather than fa.apply?
* leaving it accept for now
*/
- return fa.accept(v);
+ return fa.apply(v);
}
else
{
@@ -2,22 +2,27 @@
public class Symbol extends Atom {
public static final TypeId TYPEID = new TypeId(":symbol", Symbol.class,
- Atom.TYPEID);
-
+ Atom.TYPEID);
+
private final String name;
-
+
public Symbol(String name) {
- this.name = name;
+ this.name = name;
}
-
+
public TypeId typeId() {
- return Symbol.TYPEID;
+ return Symbol.TYPEID;
}
public String toString() {
- return this.name;
+ return this.name;
+ }
+ public boolean isCombinator()
+ {
+ /* All of our combinators thus far have this form */
+ return this.name.matches("<.*>");
+
}
-
public boolean equals(Object o) {
- return ((o instanceof Symbol) && ((Symbol)o).name.equals(name));
+ return ((o instanceof Symbol) && ((Symbol)o).name.equals(name));
}
}

0 comments on commit ac671ca

Please sign in to comment.