Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Almost complete with combinators

* Still need to handle subst substituting bound variables
    * changed <S>'s params to get around it
* Changed <COND> to a regular LambdaFunction
* Raised the Symbol case in Interpreter2
* Added a lot of tracing output
* Copied in Cons equals method and added append
  • Loading branch information...
commit 4a349d56e81d99e1418f47c0637c5e17adc6a94c 1 parent 6d390c7
Mark Watts authored
View
7 crono/prelude.lisp
@@ -37,7 +37,7 @@
(define <K> (\ (x y) x))
%General application combinator
-(define <S> (\ (f g x) (f x (g x))))
+(define <S> (\ (f g p) (f p (g p))))
%Function composition combinator
(define <B> (\ (f g x) (f (g x))))
@@ -56,5 +56,8 @@
(define <Y> (\ (f)
(\ (x) (f (x x))) (\ (x) (f (x x))) ))
+(define pred (\ (x) (- x 1)))
+(define my_cond (\ (p f g x) (if (p x) (f x) (g x))))
+(define fapp (\ (x y) ((<S> (<K> (<S> <I>)) <K>) x y)))
+(define pradd (\ (x z) (<Z> (<B> (my_cond ((=) 0) (<K> z)) (<B> (<S> (<B> (+) (<K> 1)) ) (<C> <B> pred))) x)))
-(define <COND> (\ (p f g x) (if (p x) (f x) (g x))))
View
133 crono/src/crono/Interpreter2.java
@@ -16,6 +16,60 @@ public Interpreter2()
env_stack = new Stack<Environment>();
reset();
}
+ private CronoType coerceCombinator (CronoType val)
+ {
+ if (val == null)
+ {
+ throw new InterpreterException("attempting coerce on null");
+ }
+ System.out.println("coercing " + val + " to combinator");
+ CronoType result = null;
+ if (val instanceof Symbol && ((Symbol) val).isCombinator())
+ {
+ /* If the value is a combinator symbol,
+ * return true
+ */
+ result = val;
+ }
+ else if (val instanceof Cons)
+ {
+ /* If it's a cons and the head is a combinator
+ * reduce it and keep doing so until we
+ * reach a fixed point or the head isn't a combinator.
+ */
+ Cons c = (Cons) val;
+ CronoType head = c.car();
+ if (head instanceof Symbol)
+ {
+ Symbol maybe_comb = (Symbol) head;
+ if (maybe_comb.isCombinator())
+ {
+ System.out.println("Our head is a combinator symbol...");
+ CombinatorApplication ca = new CombinatorApplication(c);
+ CronoType r = ca.reduce(this);
+ System.out.println("c = " + c + " r = " + r );
+ /* Reduces to itself; fixed point */
+ if (r.equals(c))
+ {
+ result = r;
+ }
+ else if (r == null)
+ {
+ System.out.println("HERE at r == null");
+ }
+ else
+ {
+ /* If the result is still a combinator then we continue
+ * otherwise set result to null
+ */
+ result = coerceCombinator(r);
+ }
+ }
+ }
+ }
+ System.out.println("Result of coercion: " + result);
+ return result;
+ }
public CronoType visit (CronoType o)
{
@@ -25,6 +79,11 @@ public CronoType visit (CronoType o)
{
result = o;
}
+ else if (o instanceof Symbol)
+ {
+ Symbol s = (Symbol) o;
+ result = getEnv().get(s);
+ }
else if (o instanceof Cons)
{
/* Here we do two steps at once, both a translation
@@ -39,63 +98,47 @@ else if (o instanceof Cons)
*/
Cons c = (Cons) o;
CronoType head = c.car();
- if (head instanceof Symbol)
+ CronoType maybe_comb;
+ if ((maybe_comb = coerceCombinator(head)) != null)
{
- Symbol s = (Symbol) head;
- /* If the head position is occupied by a
- * "special" then we pass the whole cons to
- * a SpecialApplication.
- *
- * We don't evaluate the symbol, just look it
- * up, since we don't want to visit the head
- * twice
- */
- if (s.isCombinator())
+ c = new Cons(maybe_comb, c.cdr());
+ CombinatorApplication ca = new CombinatorApplication(c);
+ result = ca.reduce(this);
+ }
+ else
+ {
+ head = head.accept(this);
+ if (head instanceof Special)
{
- CombinatorApplication ca = new CombinatorApplication(c);
- result = ca.reduce(this);
+ 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);
}
- else
+ else if (head instanceof Function)
{
- 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);
- }
+ /*
+ * We assume function application by default
+ * Note that this assumption is relied on architecturally:
+ * Specials *are* Functions, Specials must always be checked
+ * before this case if they are to be matched...specifically
+ */
+ FunctionApplication fa = new FunctionApplication(c);
+ /* If we wanted only to create an AST,
+ * we would stop here.
+ */
+ result = fa.apply(this);
}
}
-
- if (result == null)
- {
- /*
- * We assume function application by default
- * Note that this assumption is relied on architecturally:
- * Specials *are* Functions, Specials must always be checked
- * before this case if they are to be matched...specifically
- */
- FunctionApplication fa = new FunctionApplication(c);
- /* If we wanted only to create an AST,
- * we would stop here.
- */
- result = fa.apply(this);
- }
}
else if (o instanceof Quote)
{
Quote q = (Quote) o;
result = q.node;
}
- else if (o instanceof Symbol)
- {
- Symbol s = (Symbol) o;
- result = getEnv().get(s);
- }
else
{
result = o;
View
43 crono/src/crono/type/CombinatorApplication.java
@@ -27,6 +27,7 @@
*/
public CombinatorApplication (Cons c)
{
+ System.out.println("Reducing combinatory expression " + c);
function = c.car();
// Unchecked cdr assumed to be cons
args = ((Cons) c.cdr()).toList();
@@ -47,11 +48,12 @@ public CronoType reduce (Visitor v)
* This may be extended to a "callable"
* later
*/
- CronoType o = function.accept(v);
System.out.printf("Reducing combinatory expression...\n");
+ CronoType o = function.accept(v);
CronoType result = null;
if (o instanceof LambdaFunction)
{
+ System.out.println("Simple combinator...");
LambdaFunction f = (LambdaFunction) o;
/* The arguments are passed to the function
@@ -63,7 +65,12 @@ public CronoType reduce (Visitor v)
* arguments.
*/
- if (f.arity == args.size())
+ System.out.println(args);
+ if (args.size() == 0)
+ {
+ result = function;
+ }
+ else if (f.arity == args.size())
{
CronoType substituted_body = f.body[0];
int i = 0;
@@ -76,21 +83,51 @@ public CronoType reduce (Visitor v)
/* We have to keep evaluating this to reduce it to a value */
result = substituted_body.accept(v);
}
+ else if (f.arity < args.size())
+ {
+ /* we take as many as we need and leave the rest alone */
+ Cons usable_args = Cons.fromList(args.subList(0, f.arity));
+ Cons rest_of_args = Cons.fromList(args.subList(f.arity, args.size()));
+ /* We can use either the combinator or function application
+ /* We can use either the combinator or function application
+ * path for this
+ */
+ CronoType reduced = (new Cons(function, usable_args)).accept(v);
+ Cons new_expr = Nil.NIL;
+ if (reduced instanceof Cons)
+ {
+ new_expr = ((Cons) reduced).append(rest_of_args);
+ }
+ else
+ {
+ new_expr = new Cons(reduced, rest_of_args);
+ }
+ result = new_expr.accept(v);
+ }
else
{
+ System.out.println("Not enough arguments to combinator...");
result = new Cons(function, Cons.fromList(args));
}
}
+ else if (o instanceof Cons)
+ {
+ /* We have to append this to args */
+ System.out.println("Reducing parethesized combinator...");
+ Cons reduced = ((Cons) o).append(Cons.fromList(args));
+ result = reduced.accept(v);
+ }
else
{
throw new TypeException(this, Function.TYPEID, o);
}
+ System.out.println("Reduced expression: " + result);
return result;
}
public String toString ()
{
- return "(apply " + function.toString() + " " + args.toString() + ")";
+ return "(comb_apply " + function.toString() + " " + args.toString() + ")";
}
public TypeId typeId() {
return CombinatorApplication.TYPEID;
View
236 crono/src/crono/type/Cons.java
@@ -9,123 +9,123 @@
public class Cons extends CronoType implements Iterable<CronoType> {
public static final TypeId TYPEID = new TypeId(":cons", Cons.class,
- CronoType.TYPEID);
+ 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) {
- cell = (Cons)(cell.cdr);
- }else {
- more = false;
- }
- return ret;
- }
-
- CronoType ret = cell.cdr;
- cell = null;
- return ret;
- }
-
- public void remove() {
- throw new UnsupportedOperationException();
- }
+ 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) {
+ cell = (Cons)(cell.cdr);
+ }else {
+ more = false;
+ }
+ 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();
- curr.car = iter.next();
- while(iter.hasNext()) {
- curr.cdr = new Cons();
- curr = (Cons)curr.cdr;
- curr.car = iter.next();
- }
- curr.cdr = Nil.NIL;
- return head;
+ if(args.size() <= 0) {
+ return Nil.NIL;
+ }
+
+ Cons head = new Cons();
+ Cons curr = head;
+ Iterator<CronoType> iter = args.iterator();
+ curr.car = iter.next();
+ while(iter.hasNext()) {
+ curr.cdr = new Cons();
+ curr = (Cons)curr.cdr;
+ curr.car = iter.next();
+ }
+ curr.cdr = Nil.NIL;
+ return head;
}
protected CronoType car, cdr;
protected Cons() {
- this.car = null;
- this.cdr = null;
+ this.car = null;
+ this.cdr = null;
}
public Cons(CronoType car, CronoType cdr) {
- this.car = car;
- this.cdr = cdr;
+ this.car = car;
+ this.cdr = cdr;
}
public Cons cons(CronoType car) {
- return new Cons(car, this);
+ return new Cons(car, this);
}
public CronoType car() {
- return (car == null) ? Nil.NIL : car;
+ return (car == null) ? Nil.NIL : car;
}
public CronoType cdr() {
- return (cdr == null) ? Nil.NIL : cdr;
+ return (cdr == null) ? Nil.NIL : cdr;
}
public Iterator<CronoType> iterator() {
- return new ConsIterator(this);
+ return new ConsIterator(this);
}
public CronoType accept(Visitor v) {
- return v.visit(this);
+ return v.visit(this);
}
public TypeId typeId() {
- return TYPEID;
+ return TYPEID;
}
public String toString() {
- StringBuilder builder = new StringBuilder();
- builder.append("(");
-
- Cons next = this;
- while(next != null) {
- builder.append(next.car);
- if(next.cdr instanceof Cons) {
- if(next.cdr == Nil.NIL) {
- next = null;
- }else {
- builder.append(" ");
- next = (Cons)(next.cdr);
- }
- }else {
- builder.append(" . ");
- builder.append(next.cdr);
- next = null;
- }
- }
-
- builder.append(")");
- return builder.toString();
+ StringBuilder builder = new StringBuilder();
+ builder.append("(");
+
+ Cons next = this;
+ while(next != null) {
+ builder.append(next.car);
+ if(next.cdr instanceof Cons) {
+ if(next.cdr == Nil.NIL) {
+ next = null;
+ }else {
+ builder.append(" ");
+ next = (Cons)(next.cdr);
+ }
+ }else {
+ builder.append(" . ");
+ builder.append(next.cdr);
+ next = null;
+ }
+ }
+
+ builder.append(")");
+ return builder.toString();
}
public static CronoType subst (CronoType expr, Symbol name, CronoType val)
@@ -144,28 +144,62 @@ else if (expr.equals(Nil.NIL))
else if (expr instanceof Cons)
{
Cons c = (Cons) expr;
+ //if (c.car().toString().equals(CronoSpecial.LAMBDA.toString()). )
+ //{
+ //o
+ //}
return new Cons(subst(c.car(), name, val), subst(c.cdr(), name, val));
}
return expr;
}
-
+ /* Appends other onto the end of this
+ */
+ public Cons append (Cons other)
+ {
+ if (!this.equals(Nil.NIL))
+ {
+ return new Cons(car, ((Cons) cdr).append(other));
+ }
+ else
+ {
+ return other;
+ }
+ }
public List<CronoType> toList() {
- List<CronoType> list = new LinkedList<CronoType>();
- Cons next = this;
- while(next != null) {
- list.add(next.car);
- if(next.cdr instanceof Cons) {
- if(next.cdr == Nil.NIL) {
- next = null;
- }else {
- next = (Cons)(next.cdr);
- }
- }else {
- list.add(next.cdr);
- next = null;
- }
- }
- return list;
+ List<CronoType> list = new LinkedList<CronoType>();
+ if (this == Nil.NIL)
+ {
+ return list;
+ }
+ Cons next = this;
+ while(next != null) {
+ list.add(next.car);
+ if(next.cdr instanceof Cons) {
+ if(next.cdr == Nil.NIL) {
+ next = null;
+ }else {
+ next = (Cons)(next.cdr);
+ }
+ }else {
+ list.add(next.cdr);
+ next = null;
+ }
+ }
+ return list;
+ }
+ public boolean equals(Object o) {
+ if(!(o instanceof Cons)) {
+ return false;
+ }
+ if(o instanceof Nil) {
+ return (this instanceof Nil);
+ }
+ if(o instanceof TruthValue) {
+ return (this instanceof TruthValue);
+ }
+
+ Cons lhs = (Cons)o, rhs = this;
+ return (lhs.car().equals(rhs.car()) && lhs.cdr().equals(rhs.cdr()));
}
}
Please sign in to comment.
Something went wrong with that request. Please try again.