Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Merge branch 'master' of github.com:mwatts15/Crono

Conflicts:
	crono/prelude.lisp

* changed <COND> to my_cond
  • Loading branch information...
commit 9bb2aed7a4c8b80a13d00b770e15c6035575d8ba 2 parents 7eefb1c + 202adb4
Mark Watts authored
View
65 crono/prelude.lisp
@@ -1,3 +1,25 @@
+%%%%
+% Base Predicates
+%%%%
+(define nil? (= Nil))
+(define zero? (= 0))
+(define t? (= #t))
+
+(defun any? (value) (= (typeof value) :any))
+(defun array? (value) (= (typeof value) :array))
+(defun atom? (value) (= (typeof value) :atom))
+(defun char? (value) (= (typeof value) :char))
+(defun cons? (value) (= (typeof value) :cons))
+(defun float? (value) (= (typeof value) :float))
+(defun func? (value) (= (typeof value) :func))
+(defun int? (value) (= (typeof value) :int))
+(defun number? (value) (= (typeof value) :number))
+(defun primitive? (value) (= (typeof value) :primitive))
+(defun string? (value) (= (typeof value) :string))
+(defun struct? (value) (= (typeof value) :struct))
+(defun type? (value) (= (typeof value) :type))
+(defun vector? (value) (= (typeof value) :vector))
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% boolean functions
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -7,6 +29,11 @@
(define or (\ (a b) (if a #t b)))
+%%%%
+% Extra predicates
+%%%%
+(defun boolean? (value) (or (nil? value) (t? value)))
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% higher order functions
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -27,9 +54,13 @@
(defun mod (x y) (if (< x y) x (mod (- x y) y)))
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% combinators
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+(define pred (+ -1))
+(define succ (+ 1))
+
%identity combinator
(define <I> (\ (x) x))
@@ -37,27 +68,29 @@
(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))))
+% (define <B> (<S> (<K> <S>) <K>))
%
-(define <C> (\ (f x y) (f y x)))
-
-%(define <Y> (f)
-% (f (<Y> f)) )
-%Cannata's incorrect definition of Y combinator
+(define <C> (\ (f x y) ((f y) x)))
+% (define <C> (<S> (<S> (<K> (<S> (<K> <S>) <K>)) <S>) (<K> <K>)))
%Recursive function
-(define <Z> (\ (f)
- ((\ (x) (f (\ (v) ((x x) v))))
- (\ (x) (f (\ (v) ((x x) v)))))))
-
(define <Y> (\ (f)
- (\ (x) (f (x x))) (\ (x) (f (x x))) ))
-
-(define <COND> (\ (p f g x) (if (p x) (f x) (g x))))
-
-(define prFoldr (\ (fn z x)
- (<Y> (<B> (<COND> (= nil) (<K> z)) (<B> (<S> (<B> fn (car)) ) (<C> <B> cdr))) x)))
+ ((\ (x) (f (\ (v) ((x x) v))))
+ (\ (y) (f (\ (w) ((y y) w)))))))
+%(define <Y> (\ (f)
+% (\ (x) (f (x x))) (\ (x) (f (x x))) ))
+
+(define my_cond (\ (p f g x) (if (p x) (f x) (g x))))
+
+% (define prFoldr (\ (fn z x)
+% (<Y> (<B> (my_cond (= nil) (<K> z)) (<B> (<S> (<B> fn (car)) ) (<C> <B> cdr))) x)))
+(defun pradd1 (x z)
+ (<Y> (<B>
+ (my_cond (= 0) (<K> z))
+ (<B> (<S> (<B> + (<K> 1))) (<C> <B> pred)))
+ x))
View
154 crono/src/crono/Crono.java
@@ -18,6 +18,7 @@
new Option('e', "show-environment"),
new Option('h', "help"),
new Option('p', "print-ast"),
+ new Option('P', "no-prelude"),
new Option('q', "quiet"),
new Option('s', "static"),
new Option('t', "show-types"),
@@ -28,30 +29,29 @@
public static final String introstr =
"Crono++ by Mark Watts, Carlo Vidal, Troy Varney (c) 2012\n";
public static final String prompt = "> ";
+ public static final String prelude = "./prelude.lisp";
+ public static boolean showTypes = false;
+ public static boolean interactive = false;
+ public static boolean loadPrelude = true;
+ public static Visitor v = null;
+ public static List<String> files = new LinkedList<String>();
private static CronoType getStatement(Parser p) {
- /* This was supposed to loop the parser until it got a valid statement
- * or hit EOF, but I can't get it to work quite right */
- CronoType statement = null;
System.out.print(prompt);
try {
- statement = p.statement();
+ CronoType statement = p.statement();
+ if(!interactive) {
+ System.out.println((statement == null) ? "" : statement);
+ }
+ return statement;
}catch(ParseException pe) {
System.err.println(pe);
- statement = null;
}
-
- return statement;
+ return null;
}
- public static void main(String[] args) {
- boolean showTypes = false;
+ public static boolean parseOptions(Interpreter interp, String[] args) {
OptionParser optparse = new OptionParser(args);
- Interpreter interp = new Interpreter();
- Visitor v = interp;
- boolean interactive = (System.console() != null); /*< Java 6 feature */
- List<String> files = new LinkedList<String>();
-
int opt = optparse.getopt(options);
while(opt != -1) {
switch(opt) {
@@ -59,23 +59,25 @@ public static void main(String[] args) {
interp.dynamic(true);
break;
case 'D':
- interp.showEnv(true);
- interp.printAST(true);
- interp.trace(true);
+ interp.debug(true);
break;
case 'e':
interp.showEnv(true);
break;
case 'h':
System.err.println(helpstr);
- return;
+ return false;
case 'p':
interp.printAST(true);
break;
+ case 'P':
+ loadPrelude = false;
+ break;
case 'q':
interp.showEnv(false);
interp.printAST(false);
interp.trace(false);
+ interp.debug(false);
break;
case 's':
interp.dynamic(false);
@@ -92,7 +94,7 @@ public static void main(String[] args) {
System.err.printf("Invalid option: %s\n",
optparse.optchar);
System.err.println(helpstr);
- return;
+ return false;
}
opt = optparse.getopt(options);
}
@@ -100,8 +102,16 @@ public static void main(String[] args) {
for(int i = optparse.optind(); i < args.length; ++i) {
files.add(args[i]);
}
+ return true;
+ }
+
+ public static void main(String[] args) {
+ Interpreter interp = new Interpreter();
+ v = interp;
+ interactive = (System.console() != null); /*< Java 6 feature */
+
+ parseOptions(interp, args);
- Parser parser = null;
try {
File package_dir = new File("./packages/");
CronoPackage.initLoader(new URL[]{package_dir.toURI().toURL()});
@@ -109,55 +119,71 @@ public static void main(String[] args) {
System.err.printf("Crono: Could not open package directory!\n");
}
- if(interactive && files.size() == 0) {
- parser = new Parser(new InputStreamReader(System.in));
- System.out.println(introstr);
-
- boolean good = false;
- CronoType statement = getStatement(parser);
- while(statement != null) {
- try{
- statement = statement.accept(v);
- if(showTypes) {
- System.out.printf("Result: %s [%s]\n",statement.repr(),
- statement.typeId());
- }else {
- System.out.printf("Result: %s\n", statement.repr());
- }
- }catch(InterpreterException re) {
- String message = re.getMessage();
- if(message != null) {
- System.err.println(message);
- }else {
- System.err.println("Unknown Interpreter Error!");
- }
- }catch(RuntimeException re) {
- re.printStackTrace();
- }
- statement = getStatement(parser);
- }
-
- System.out.println();
+ if(files.size() == 0) {
+ interactive();
}else {
for(String fname : files) {
- try {
- parser = new Parser(new FileReader(fname));
- }catch(FileNotFoundException fnfe) {
- System.err.printf("Could not find %s:\n %s\n", fname,
- fnfe.toString());
- continue;
+ loadPrelude();
+ parseFile(fname);
+ v.reset(); /*< Reset the visitor for the next file */
+ }
+ }
+ }
+
+ public static void loadPrelude() {
+ if(loadPrelude) {
+ parseFile(prelude);
+ }
+ }
+
+ public static void interactive() {
+ System.out.println(introstr);
+ loadPrelude();
+
+ Parser parser = new Parser(new InputStreamReader(System.in));
+ CronoType statement = getStatement(parser);
+ while(statement != null) {
+ try{
+ statement = statement.accept(v);
+ if(showTypes) {
+ System.out.printf("Result: %s [%s]\n",statement.repr(),
+ statement.typeId());
+ }else {
+ System.out.printf("Result: %s\n", statement.repr());
}
-
- try {
- CronoType head = parser.program();
- head.accept(v);
- } catch(ParseException pe) {
- System.err.printf("Error parsing crono file: %s\n %s\n",
- fname, pe);
+ }catch(InterpreterException re) {
+ String message = re.getMessage();
+ if(message != null) {
+ System.err.println(message);
+ }else {
+ System.err.println("Unknown Interpreter Error!");
}
-
- v.reset(); /*< Reset the visitor for the next file */
+ }catch(RuntimeException re) {
+ re.printStackTrace();
}
+ statement = getStatement(parser);
+ }
+
+ System.out.println();
+ }
+
+
+ public static void parseFile(String fname) {
+ Parser parser = null;
+ try {
+ parser = new Parser(new FileReader(fname));
+ }catch(FileNotFoundException fnfe) {
+ System.err.printf("Could not find file %s:\n %s\n", fname, fnfe);
+ return;
+ }
+ try {
+ CronoType[] prog = parser.program();
+ for(int i = 0; i < prog.length; ++i) {
+ prog[i].accept(v);
+ }
+ }catch(ParseException pe) {
+ System.err.printf("Error parsing crono file: %s\n %s\n",fname,pe);
+ return;
}
}
}
View
1,513 crono/src/crono/CronoFunction.java
@@ -8,28 +8,10 @@
import java.util.List;
import java.util.Map;
-import crono.type.Cons;
-import crono.type.CronoArray;
-import crono.type.CronoCharacter;
-import crono.type.CronoFloat;
-import crono.type.CronoInteger;
-import crono.type.CronoNumber;
-import crono.type.CronoPrimitive;
-import crono.type.CronoString;
-import crono.type.CronoStruct;
-import crono.type.CronoType;
-import crono.type.Function;
-import crono.type.Function.EvalType;
-import crono.type.Nil;
-import crono.type.LambdaFunction;
-import crono.type.Symbol;
-import crono.type.TruthValue;
-import crono.type.TypeId;
-
import crono.inf.InfDatabase;
-import crono.inf.InfTriple;
-import crono.inf.InfClass;
-import crono.inf.InfStruct;
+
+import crono.type.*;
+import crono.type.Function.EvalType;
/**
* Define all builtins here. If the function is not variadic, don't define the
@@ -41,42 +23,42 @@
*/
public enum CronoFunction {
CONS(new Function(new TypeId[]{CronoType.TYPEID, CronoType.TYPEID},
- Cons.TYPEID, 2)
+ Cons.TYPEID, 2)
{
- public CronoType run(Visitor v, CronoType[] args) {
- return new Cons(args[0], args[1]);
- }
- public String toString() {
- return "cons";
- }
+ public CronoType run(Visitor v, CronoType[] args) {
+ return new Cons(args[0], args[1]);
+ }
+ public String toString() {
+ return "cons";
+ }
}),
CAR(new Function(new TypeId[]{Cons.TYPEID}, CronoType.TYPEID, 1)
{
- private static final String _not_cons = "%s is not a cons cell";
-
+ private static final String _not_cons = "%s is not a cons cell";
+
public CronoType run(Visitor v, CronoType[] args) {
- if(!(args[0] instanceof Cons)) {
- throw new InterpreterException(_not_cons, args[0]);
- }
- return ((Cons)args[0]).car();
- }
- public String toString() {
- return "car";
- }
+ if(!(args[0] instanceof Cons)) {
+ throw new InterpreterException(_not_cons, args[0]);
+ }
+ return ((Cons)args[0]).car();
+ }
+ public String toString() {
+ return "car";
+ }
}),
CDR(new Function(new TypeId[]{Cons.TYPEID}, CronoType.TYPEID, 1)
{
- private static final String _not_cons = "%s is not a cons cell";
-
- public CronoType run(Visitor v, CronoType[] args) {
- if(!(args[0] instanceof Cons)) {
- throw new InterpreterException(_not_cons, args[0]);
- }
- return ((Cons)args[0]).cdr();
- }
- public String toString() {
- return "cdr";
- }
+ private static final String _not_cons = "%s is not a cons cell";
+
+ public CronoType run(Visitor v, CronoType[] args) {
+ if(!(args[0] instanceof Cons)) {
+ throw new InterpreterException(_not_cons, args[0]);
+ }
+ return ((Cons)args[0]).cdr();
+ }
+ public String toString() {
+ return "cdr";
+ }
}),
SUBST(new Function(new TypeId[]{CronoType.TYPEID}, CronoType.TYPEID, 1,
EvalType.PARTIAL)
@@ -90,705 +72,896 @@ public String toString() {
}),
LIST(new Function(new TypeId[]{CronoType.TYPEID}, Cons.TYPEID, 1, true)
{
- public CronoType run(Visitor v, CronoType[] args) {
- Cons c = Nil.NIL;
- for(int i = 0; i < args.length; ++i) {
- c = new Cons(args[i], c);
- }
- return c;
- }
- public String toString() {
- return "list";
- }
+ public CronoType run(Visitor v, CronoType[] args) {
+ Cons c = Nil.NIL;
+ for(int i = 0; i < args.length; ++i) {
+ c = new Cons(args[i], c);
+ }
+ return c;
+ }
+ public String toString() {
+ return "list";
+ }
}),
GET(new Function(new TypeId[]{CronoArray.TYPEID, CronoInteger.TYPEID},
- CronoType.TYPEID, 2)
+ CronoType.TYPEID, 2)
{
- public CronoType run(Visitor v, CronoType[] args) {
- int index = (int)((CronoInteger)args[1]).value;
- ((CronoArray)args[0]).get(index);
- return args[0];
- }
- public String toString() {
- return "get";
- }
+ public CronoType run(Visitor v, CronoType[] args) {
+ int index = (int)((CronoInteger)args[1]).value;
+ ((CronoArray)args[0]).get(index);
+ return args[0];
+ }
+ public String toString() {
+ return "get";
+ }
}),
PUT(new Function(new TypeId[]{CronoArray.TYPEID, CronoInteger.TYPEID,
- CronoType.TYPEID},
- CronoType.TYPEID, 3)
- {
- public CronoType run(Visitor v, CronoType[] args) {
- int index = (int)((CronoInteger)args[1]).value;
- ((CronoArray)args[0]).put(index, args[2]);
- return args[0];
- }
- public String toString() {
- return "put";
- }
+ CronoType.TYPEID},
+ CronoType.TYPEID, 3)
+ {
+ public CronoType run(Visitor v, CronoType[] args) {
+ int index = (int)((CronoInteger)args[1]).value;
+ ((CronoArray)args[0]).put(index, args[2]);
+ return args[0];
+ }
+ public String toString() {
+ return "put";
+ }
}),
APPEND(new Function(new TypeId[]{CronoArray.TYPEID, CronoType.TYPEID},
- CronoType.TYPEID, 2)
+ CronoType.TYPEID, 2)
{
- public CronoType run(Visitor v, CronoType[] args) {
- ((CronoArray)args[0]).append(args[1]);
- return args[0];
- }
- public String toString() {
- return "append";
- }
+ public CronoType run(Visitor v, CronoType[] args) {
+ ((CronoArray)args[0]).append(args[1]);
+ return args[0];
+ }
+ public String toString() {
+ return "append";
+ }
+ }),
+ INSERT(new Function(new TypeId[]{CronoArray.TYPEID, CronoInteger.TYPEID,
+ CronoArray.TYPEID}, CronoArray.TYPEID, 3)
+ {
+ public CronoType run(Visitor v, CronoType[] args) {
+ CronoArray dest = (CronoArray)args[0], src = (CronoArray)args[2];
+ return dest.insert(src, (int)((CronoInteger)args[1]).value);
+ }
+ public String toString() {
+ return "insert";
+ }
+ }),
+ CONCAT(new Function(new TypeId[]{CronoArray.TYPEID, CronoArray.TYPEID},
+ CronoArray.TYPEID, 2)
+ {
+ public CronoType run(Visitor v, CronoType[] args) {
+ CronoArray dest = (CronoArray)args[0], src = (CronoArray)args[1];
+ return dest.concat(src);
+ }
+ public String toString() {
+ return "concat";
+ }
}),
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";
-
- 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";
- }
+ 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";
+ }
+ }),
+ DEFINED(new Function(new TypeId[]{Symbol.TYPEID}, Cons.TYPEID, 1,
+ EvalType.NONE)
+ {
+ public CronoType run(Visitor v, CronoType[] args) {
+ Symbol s = (Symbol)args[0];
+ return (v.getEnv().get(s) == null) ? Nil.NIL : TruthValue.T;
+ }
+ public String toString() {
+ return "defined";
+ }
+ }),
+ DEFUN(new Function(new TypeId[]{Symbol.TYPEID, Cons.TYPEID,
+ CronoType.TYPEID}, LambdaFunction.TYPEID,
+ 3, true, EvalType.NONE)
+ {
+ private static final String _bad_arg =
+ "defun: argument list must be symbols; got %s in argument list";
+ public CronoType run(Visitor v, CronoType[] args) {
+ List<CronoType> list = ((Cons)args[1]).toList();
+ for(CronoType item : list) {
+ if(!(item instanceof Symbol)) {
+ throw new InterpreterException(_bad_arg,item.typeId());
+ }
+ }
+
+ Symbol[] arglist = new Symbol[list.size()];
+ CronoType[] body;
+ List<CronoType> blist = new LinkedList<CronoType>();
+ for(int i = 2; i < args.length; ++i) {
+ blist.add(args[i]);
+ }
+ body = new CronoType[blist.size()];
+ body = blist.toArray(body);
+ LambdaFunction lfun = new LambdaFunction(list.toArray(arglist),
+ body, v.getEnv());
+ v.getEnv().put((Symbol)args[0], lfun);
+ lfun.environment.put((Symbol)args[0], lfun);
+ return lfun;
+ }
+ public String toString() {
+ return "defun";
+ }
}),
UNDEFINE(new Function(new TypeId[]{Symbol.TYPEID}, Nil.TYPEID, 1,
- EvalType.NONE)
- {
- private static final String _bad_type =
- "UNDEF: expected :symbol, got %s";
-
- public CronoType run(Visitor v, CronoType[] args) {
- StringBuilder builder = new StringBuilder();
- boolean errors = false;
- for(CronoType ct : args) {
- if(!(ct instanceof Symbol)) {
- builder.append(String.format(_bad_type, ct.typeId()));
- builder.append('\n');
- errors = true;
- continue;
- }
- v.getEnv().remove((Symbol)ct);
- }
-
- if(errors) {
- /* Remove last newline */
- builder.deleteCharAt(builder.length() - 1);
- throw new InterpreterException(builder.toString());
- }
- return Nil.NIL;
- }
- public String toString() {
- return "undef";
- }
+ EvalType.NONE)
+ {
+ private static final String _bad_type =
+ "UNDEF: expected :symbol, got %s";
+
+ public CronoType run(Visitor v, CronoType[] args) {
+ StringBuilder builder = new StringBuilder();
+ boolean errors = false;
+ for(CronoType ct : args) {
+ if(!(ct instanceof Symbol)) {
+ builder.append(String.format(_bad_type, ct.typeId()));
+ builder.append('\n');
+ errors = true;
+ continue;
+ }
+ v.getEnv().remove((Symbol)ct);
+ }
+
+ if(errors) {
+ /* Remove last newline */
+ builder.deleteCharAt(builder.length() - 1);
+ throw new InterpreterException(builder.toString());
+ }
+ return Nil.NIL;
+ }
+ public String toString() {
+ return "undef";
+ }
}),
LAMBDA(new Function(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";
-
- public CronoType run(Visitor v, CronoType[] args) {
- if(!(args[0] instanceof Cons)) {
- throw new InterpreterException(_bad_type,
- args[0].typeId(),
- args[1].typeId());
- }
-
- List<CronoType> list = ((Cons)args[0]).toList();
- for(CronoType item : list) {
- if(!(item instanceof Symbol)) {
- throw new InterpreterException(_bad_arg,item.typeId());
- }
- }
-
- Symbol[] arglist = new Symbol[list.size()];
- CronoType[] body;
- List<CronoType> blist = new LinkedList<CronoType>();
- for(int i = 1; i < args.length; ++i) {
- blist.add(args[i]);
- }
- body = new CronoType[blist.size()];
- body = blist.toArray(body);
- return new LambdaFunction(list.toArray(arglist), body,
- v.getEnv());
- }
- public String toString() {
- return "\\";
- }
+ 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";
+
+ public CronoType run(Visitor v, CronoType[] args) {
+ if(!(args[0] instanceof Cons)) {
+ throw new InterpreterException(_bad_type,
+ args[0].typeId(),
+ args[1].typeId());
+ }
+
+ List<CronoType> list = ((Cons)args[0]).toList();
+ for(CronoType item : list) {
+ if(!(item instanceof Symbol)) {
+ throw new InterpreterException(_bad_arg,item.typeId());
+ }
+ }
+
+ Symbol[] arglist = new Symbol[list.size()];
+ CronoType[] body;
+ List<CronoType> blist = new LinkedList<CronoType>();
+ for(int i = 1; i < args.length; ++i) {
+ blist.add(args[i]);
+ }
+ body = new CronoType[blist.size()];
+ body = blist.toArray(body);
+ return new LambdaFunction(list.toArray(arglist), body,
+ v.getEnv());
+ }
+ public String toString() {
+ return "\\";
+ }
}),
LET(new Function(new TypeId[]{Cons.TYPEID, CronoType.TYPEID},
- CronoType.TYPEID, 2, true, EvalType.NONE)
- {
- private static final String _subst_list_type =
- "LET: substitution list must be :cons, got %s";
- private static final String _subst_not_cons =
- "LET: expected :cons in substitution list, got %s";
- private static final String _subst_not_sym =
- "LET: argument names numst be :symbol, got %s";
-
- public CronoType run(Visitor v, CronoType[] args) {
- if(!(args[0] instanceof Cons)) {
- throw new InterpreterException(_subst_list_type,
- args[0].typeId());
- }
-
- List<Symbol> symlist = new LinkedList<Symbol>();
- List<CronoType> arglist = new LinkedList<CronoType>();
- for(CronoType ct : ((Cons)args[0])) {
- if(!(ct instanceof Cons)) {
- throw new InterpreterException(_subst_not_cons,
- ct.typeId());
- }
-
- CronoType car = ((Cons)ct).car();
- CronoType cdr = ((Cons)ct).cdr();
- if(!(car instanceof Symbol)) {
- throw new InterpreterException(_subst_not_sym,
- car.typeId());
- }
-
- cdr = cdr.accept(v);
- symlist.add((Symbol)car);
- arglist.add(cdr);
- }
-
- Symbol[] lsyms = new Symbol[symlist.size()];
- lsyms = symlist.toArray(lsyms);
-
- List<CronoType> bodylist = new LinkedList<CronoType>();
- for(int i = 1; i < args.length; ++i) {
- bodylist.add(args[i]);
- }
- CronoType[] body = new CronoType[bodylist.size()];
- body = bodylist.toArray(body);
-
- CronoType[] largs = new CronoType[arglist.size()];
- largs = arglist.toArray(largs);
-
- LambdaFunction lambda = new LambdaFunction(lsyms,body,v.getEnv());
- return lambda.run(v, largs); /*< -. - */
- }
- public String toString() {
- return "let";
- }
+ CronoType.TYPEID, 2, true, EvalType.NONE)
+ {
+ private static final String _subst_list_type =
+ "let: substitution list must be :cons, got %s";
+ private static final String _subst_not_cons =
+ "let: expected :cons in substitution list, got %s";
+ private static final String _subst_not_sym =
+ "let: argument names numst be :symbol, got %s";
+ private static final String _subst_not_pair =
+ "let: arguments expect pairs; got %s";
+ private String argString(CronoType[] args) {
+ StringBuilder builder = new StringBuilder("");
+ if(args.length > 0) {
+ builder.append(args[0]);
+ }
+ for(int i = 1; i < args.length; ++i) {
+ builder.append(" ");
+ builder.append(args[i]);
+ }
+ return builder.toString();
+ }
+
+ public CronoType run(Visitor v, CronoType[] args) {
+ if(!(args[0] instanceof Cons)) {
+ throw new InterpreterException(_subst_list_type,
+ args[0].typeId());
+ }
+
+ List<Symbol> symlist = new LinkedList<Symbol>();
+ List<CronoType> arglist = new LinkedList<CronoType>();
+ for(CronoType ct : ((Cons)args[0])) {
+ if(!(ct instanceof Cons)) {
+ throw new InterpreterException(_subst_not_cons,
+ ct.typeId());
+ }
+
+ CronoType car = ((Cons)ct).car();
+ CronoType cdr = ((Cons)ct).cdr();
+ if(!(car instanceof Symbol)) {
+ throw new InterpreterException(_subst_not_sym,
+ car.typeId());
+ }
+ if(cdr instanceof Cons) {
+ if(((Cons)cdr).cdr() != Nil.NIL) {
+ throw new InterpreterException(_subst_not_pair,
+ cdr);
+ }
+ cdr = ((Cons)cdr).car();
+ }
+ cdr = cdr.accept(v);
+ symlist.add((Symbol)car);
+ arglist.add(cdr);
+ }
+
+ Symbol[] lsyms = new Symbol[symlist.size()];
+ lsyms = symlist.toArray(lsyms);
+
+ List<CronoType> bodylist = new LinkedList<CronoType>();
+ for(int i = 1; i < args.length; ++i) {
+ bodylist.add(args[i]);
+ }
+ CronoType[] body = new CronoType[bodylist.size()];
+ body = bodylist.toArray(body);
+
+ CronoType[] largs = new CronoType[arglist.size()];
+ largs = arglist.toArray(largs);
+
+ LambdaFunction lambda = new LambdaFunction(lsyms,body,v.getEnv());
+ v.dprint("Converting let to lambda application: (%s %s)\n",
+ lambda, argString(largs));
+
+ return lambda.run(v, largs);
+ }
+ public String toString() {
+ return "let";
+ }
+ }),
+ LETREC(new Function(new TypeId[]{Cons.TYPEID, CronoType.TYPEID},
+ CronoType.TYPEID, 2, true, EvalType.NONE)
+ {
+ private static final String _subst_list_type =
+ "letrec: substitution list must be :cons, got %s";
+ private static final String _subst_not_cons =
+ "letrec: expected :cons in substitution list, got %s";
+ private static final String _subst_not_sym =
+ "letrec: argument names numst be :symbol, got %s";
+ private static final String _subst_not_pair =
+ "let: arguments expect pairs; got %s";
+
+ private String argString(CronoType[] args) {
+ StringBuilder builder = new StringBuilder("");
+ if(args.length > 0) {
+ builder.append(args[0]);
+ }
+ for(int i = 1; i < args.length; ++i) {
+ builder.append(" ");
+ builder.append(args[i]);
+ }
+ return builder.toString();
+ }
+
+ public CronoType run(Visitor v, CronoType[] args) {
+ if(!(args[0] instanceof Cons)) {
+ throw new InterpreterException(_subst_list_type,
+ args[0].typeId());
+ }
+
+ List<Symbol> symlist = new LinkedList<Symbol>();
+ List<CronoType> arglist = new LinkedList<CronoType>();
+ for(CronoType ct : ((Cons)args[0])) {
+ if(!(ct instanceof Cons)) {
+ throw new InterpreterException(_subst_not_cons,
+ ct.typeId());
+ }
+
+ CronoType car = ((Cons)ct).car();
+ CronoType cdr = ((Cons)ct).cdr();
+ if(!(car instanceof Symbol)) {
+ throw new InterpreterException(_subst_not_sym,
+ car.typeId());
+ }
+
+ if(cdr instanceof Cons) {
+ if(((Cons)cdr).cdr() != Nil.NIL) {
+ throw new InterpreterException(_subst_not_pair,
+ cdr);
+ }
+ cdr = ((Cons)cdr).car();
+ }
+ cdr = cdr.accept(v);
+ symlist.add((Symbol)car);
+ arglist.add(cdr);
+
+ if(cdr instanceof LambdaFunction) {
+ LambdaFunction lfun = ((LambdaFunction)cdr);
+ lfun.environment.put((Symbol)car, cdr);
+ }
+ }
+
+ Symbol[] lsyms = new Symbol[symlist.size()];
+ lsyms = symlist.toArray(lsyms);
+
+ List<CronoType> bodylist = new LinkedList<CronoType>();
+ for(int i = 1; i < args.length; ++i) {
+ bodylist.add(args[i]);
+ }
+ CronoType[] body = new CronoType[bodylist.size()];
+ body = bodylist.toArray(body);
+
+ CronoType[] largs = new CronoType[arglist.size()];
+ largs = arglist.toArray(largs);
+
+ LambdaFunction lambda = new LambdaFunction(lsyms,body,v.getEnv());
+ v.dprint("Converting letrec to lambda application: (%s %s)\n",
+ lambda, argString(largs));
+ return lambda.run(v, largs); /*< -. - */
+ }
+ public String toString() {
+ return "letrec";
+ }
+ }),
+ WHILE(new Function(new TypeId[]{CronoType.TYPEID, CronoType.TYPEID},
+ CronoType.TYPEID, 2, EvalType.NONE)
+ {
+ public CronoType run(Visitor v, CronoType[] args) {
+ CronoType result = Nil.NIL;
+ while((args[0].accept(v)) != Nil.NIL) {
+ result = args[1].accept(v);
+ }
+ return result;
+ }
+ public String toString() {
+ return "while";
+ }
}),
IF(new Function(new TypeId[]{CronoType.TYPEID, CronoType.TYPEID,
- CronoType.TYPEID},
- CronoType.TYPEID, 3, EvalType.NONE)
+ CronoType.TYPEID},
+ CronoType.TYPEID, 3, EvalType.NONE)
{
- public CronoType run(Visitor v, CronoType[] args) {
- CronoType check = args[0].accept(v);
- if(check != Nil.NIL) {
- return args[1].accept(v);
- }
- return args[2].accept(v);
- }
+ public CronoType run(Visitor v, CronoType[] args) {
+ CronoType check = args[0].accept(v);
+ if(check != Nil.NIL) {
+ return args[1].accept(v);
+ }
+ return args[2].accept(v);
+ }
public String toString() {
- return "if";
- }
+ return "if";
+ }
}),
EQ(new Function(new TypeId[]{CronoType.TYPEID, CronoType.TYPEID},
- Cons.TYPEID, 2)
+ Cons.TYPEID, 2)
{
- public CronoType run(Visitor v, CronoType[] args) {
- return (args[0].equals(args[1])) ?
- TruthValue.T : Nil.NIL;
- }
- public String toString() {
- return "=";
- }
+ public CronoType run(Visitor v, CronoType[] args) {
+ return (args[0].equals(args[1])) ?
+ TruthValue.T : Nil.NIL;
+ }
+ public String toString() {
+ return "=";
+ }
}),
LT(new Function(new TypeId[]{CronoPrimitive.TYPEID, CronoPrimitive.TYPEID},
- Cons.TYPEID, 2)
- {
- private static final String _bad_type =
- "<: expected :primitive :primitive, got %s %s";
-
- private Number resolve(CronoType type) {
- if(type instanceof CronoInteger) {
- return ((Long)((CronoInteger)type).value);
- }else if(type instanceof CronoFloat) {
- return ((Double)((CronoFloat)type).value);
- }else if(type instanceof CronoCharacter) {
- return ((Long)((long)((CronoCharacter)type).ch));
- }
- return null;
- }
- public CronoType run(Visitor v, CronoType[] args) {
- if(!(args[0] instanceof CronoPrimitive &&
- args[1] instanceof CronoPrimitive)) {
- throw new InterpreterException(_bad_type, args[0].typeId(),
- args[1].typeId());
- }
-
- Number lhs = resolve(args[0]);
- Number rhs = resolve(args[1]);
- if(lhs instanceof Double || rhs instanceof Double) {
- return (lhs.doubleValue() < rhs.doubleValue()) ?
- TruthValue.T : Nil.NIL;
- }
- return (lhs.longValue() < rhs.longValue()) ?
- TruthValue.T : Nil.NIL;
- }
- public String toString() {
- return "<";
- }
+ Cons.TYPEID, 2)
+ {
+ private static final String _bad_type =
+ "<: expected :primitive :primitive, got %s %s";
+
+ private Number resolve(CronoType type) {
+ if(type instanceof CronoInteger) {
+ return ((Long)((CronoInteger)type).value);
+ }else if(type instanceof CronoFloat) {
+ return ((Double)((CronoFloat)type).value);
+ }else if(type instanceof CronoCharacter) {
+ return ((Long)((long)((CronoCharacter)type).ch));
+ }
+ return null;
+ }
+ public CronoType run(Visitor v, CronoType[] args) {
+ if(!(args[0] instanceof CronoPrimitive &&
+ args[1] instanceof CronoPrimitive)) {
+ throw new InterpreterException(_bad_type, args[0].typeId(),
+ args[1].typeId());
+ }
+
+ Number lhs = resolve(args[0]);
+ Number rhs = resolve(args[1]);
+ if(lhs instanceof Double || rhs instanceof Double) {
+ return (lhs.doubleValue() < rhs.doubleValue()) ?
+ TruthValue.T : Nil.NIL;
+ }
+ return (lhs.longValue() < rhs.longValue()) ?
+ TruthValue.T : Nil.NIL;
+ }
+ public String toString() {
+ return "<";
+ }
}),
GT(new Function(new TypeId[]{CronoPrimitive.TYPEID, CronoPrimitive.TYPEID},
- Cons.TYPEID, 2)
- {
- private static final String _bad_type =
- ">: expected :primitive :primitive, got %s %s";
-
- private Number resolve(CronoType type) {
- if(type instanceof CronoInteger) {
- return ((Long)((CronoInteger)type).value);
- }else if(type instanceof CronoFloat) {
- return ((Double)((CronoFloat)type).value);
- }else if(type instanceof CronoCharacter) {
- return ((Long)((long)((CronoCharacter)type).ch));
- }
- return null;
- }
- public CronoType run(Visitor v, CronoType[] args) {
- if(!(args[0] instanceof CronoPrimitive &&
- args[1] instanceof CronoPrimitive)) {
- throw new InterpreterException(_bad_type, args[0].typeId(),
- args[1].typeId());
- }
-
- Number lhs = resolve(args[0]);
- Number rhs = resolve(args[1]);
- if(lhs instanceof Double || rhs instanceof Double) {
- return (lhs.doubleValue() > rhs.doubleValue()) ?
- TruthValue.T : Nil.NIL;
- }
- return (lhs.longValue() > rhs.longValue()) ?
- TruthValue.T : Nil.NIL;
- }
- public String toString() {
- return ">";
- }
+ Cons.TYPEID, 2)
+ {
+ private static final String _bad_type =
+ ">: expected :primitive :primitive, got %s %s";
+
+ private Number resolve(CronoType type) {
+ if(type instanceof CronoInteger) {
+ return ((Long)((CronoInteger)type).value);
+ }else if(type instanceof CronoFloat) {
+ return ((Double)((CronoFloat)type).value);
+ }else if(type instanceof CronoCharacter) {
+ return ((Long)((long)((CronoCharacter)type).ch));
+ }
+ return null;
+ }
+ public CronoType run(Visitor v, CronoType[] args) {
+ if(!(args[0] instanceof CronoPrimitive &&
+ args[1] instanceof CronoPrimitive)) {
+ throw new InterpreterException(_bad_type, args[0].typeId(),
+ args[1].typeId());
+ }
+
+ Number lhs = resolve(args[0]);
+ Number rhs = resolve(args[1]);
+ if(lhs instanceof Double || rhs instanceof Double) {
+ return (lhs.doubleValue() > rhs.doubleValue()) ?
+ TruthValue.T : Nil.NIL;
+ }
+ return (lhs.longValue() > rhs.longValue()) ?
+ TruthValue.T : Nil.NIL;
+ }
+ public String toString() {
+ return ">";
+ }
}),
ADD(new Function(new TypeId[]{CronoNumber.TYPEID, CronoNumber.TYPEID},
- CronoNumber.TYPEID, 2)
- {
- private static final String _bad_type =
- "+: expected types :number :number, got %s %s";
-
- public CronoType run(Visitor v, CronoType[] args) {
- CronoNumber lhs = null, rhs = null;
- if(!(args[0] instanceof CronoNumber &&
- args[1] instanceof CronoNumber)) {
- throw new InterpreterException(_bad_type, args[0].typeId(),
- args[0].typeId());
- }
-
- lhs = (CronoNumber)(args[0]);
- rhs = (CronoNumber)(args[1]);
-
- if(lhs instanceof CronoFloat) {
- double val1, val2;
- val1 = ((CronoFloat)lhs).value;
- if(rhs instanceof CronoFloat) {
- val2 = ((CronoFloat)rhs).value;
- }else {
- val2 = (double)(((CronoInteger)rhs).value);
- }
- return new CronoFloat(val1 + val2);
- }else {
- if(rhs instanceof CronoFloat) {
- double val1, val2;
- val1 = (double)(((CronoInteger)lhs).value);
- val2 = ((CronoFloat)rhs).value;
- return new CronoFloat(val1 + val2);
- }else {
- long val1, val2;
- val1 = ((CronoInteger)lhs).value;
- val2 = ((CronoInteger)rhs).value;
- return new CronoInteger(val1 + val2);
- }
- }
- }
- public String toString() {
- return "+";
- }
+ CronoNumber.TYPEID, 2)
+ {
+ private static final String _bad_type =
+ "+: expected types :number :number, got %s %s";
+
+ public CronoType run(Visitor v, CronoType[] args) {
+ CronoNumber lhs = null, rhs = null;
+ if(!(args[0] instanceof CronoNumber &&
+ args[1] instanceof CronoNumber)) {
+ throw new InterpreterException(_bad_type, args[0].typeId(),
+ args[0].typeId());
+ }
+
+ lhs = (CronoNumber)(args[0]);
+ rhs = (CronoNumber)(args[1]);
+
+ if(lhs instanceof CronoFloat) {
+ double val1, val2;
+ val1 = ((CronoFloat)lhs).value;
+ if(rhs instanceof CronoFloat) {
+ val2 = ((CronoFloat)rhs).value;
+ }else {
+ val2 = (double)(((CronoInteger)rhs).value);
+ }
+ return new CronoFloat(val1 + val2);
+ }else {
+ if(rhs instanceof CronoFloat) {
+ double val1, val2;
+ val1 = (double)(((CronoInteger)lhs).value);
+ val2 = ((CronoFloat)rhs).value;
+ return new CronoFloat(val1 + val2);
+ }else {
+ long val1, val2;
+ val1 = ((CronoInteger)lhs).value;
+ val2 = ((CronoInteger)rhs).value;
+ return new CronoInteger(val1 + val2);
+ }
+ }
+ }
+ public String toString() {
+ return "+";
+ }
}),
SUB(new Function(new TypeId[]{CronoNumber.TYPEID, CronoNumber.TYPEID},
- CronoNumber.TYPEID, 2)
- {
- private static final String _bad_type =
- "-: expected types :number :number, got %s %s";
-
- public CronoType run(Visitor v, CronoType[] args) {
- CronoNumber lhs = null, rhs = null;
- if(!(args[0] instanceof CronoNumber &&
- args[1] instanceof CronoNumber)) {
- throw new InterpreterException(_bad_type, args[0].typeId(),
- args[1].typeId());
- }
-
- lhs = (CronoNumber)(args[0]);
- rhs = (CronoNumber)(args[1]);
-
- if(lhs instanceof CronoFloat) {
- double val1, val2;
- val1 = ((CronoFloat)lhs).value;
- if(rhs instanceof CronoFloat) {
- val2 = ((CronoFloat)rhs).value;
- }else {
- val2 = (double)(((CronoInteger)rhs).value);
- }
- return new CronoFloat(val1 - val2);
- }else {
- if(rhs instanceof CronoFloat) {
- double val1, val2;
- val1 = (double)(((CronoInteger)lhs).value);
- val2 = ((CronoFloat)rhs).value;
- return new CronoFloat(val1 - val2);
- }else {
- long val1, val2;
- val1 = ((CronoInteger)lhs).value;
- val2 = ((CronoInteger)rhs).value;
- return new CronoInteger(val1 - val2);
- }
- }
- }
- public String toString() {
- return "-";
- }
+ CronoNumber.TYPEID, 2)
+ {
+ private static final String _bad_type =
+ "-: expected types :number :number, got %s %s";
+
+ public CronoType run(Visitor v, CronoType[] args) {
+ CronoNumber lhs = null, rhs = null;
+ if(!(args[0] instanceof CronoNumber &&
+ args[1] instanceof CronoNumber)) {
+ throw new InterpreterException(_bad_type, args[0].typeId(),
+ args[1].typeId());
+ }
+
+ lhs = (CronoNumber)(args[0]);
+ rhs = (CronoNumber)(args[1]);
+
+ if(lhs instanceof CronoFloat) {
+ double val1, val2;
+ val1 = ((CronoFloat)lhs).value;
+ if(rhs instanceof CronoFloat) {
+ val2 = ((CronoFloat)rhs).value;
+ }else {
+ val2 = (double)(((CronoInteger)rhs).value);
+ }
+ return new CronoFloat(val1 - val2);
+ }else {
+ if(rhs instanceof CronoFloat) {
+ double val1, val2;
+ val1 = (double)(((CronoInteger)lhs).value);
+ val2 = ((CronoFloat)rhs).value;
+ return new CronoFloat(val1 - val2);
+ }else {
+ long val1, val2;
+ val1 = ((CronoInteger)lhs).value;
+ val2 = ((CronoInteger)rhs).value;
+ return new CronoInteger(val1 - val2);
+ }
+ }
+ }
+ public String toString() {
+ return "-";
+ }
}),
MUL(new Function(new TypeId[]{CronoNumber.TYPEID, CronoNumber.TYPEID},
- CronoNumber.TYPEID, 2)
- {
- private static final String _bad_type =
- "*: expected types :number :number, got %s %s";
-
- public CronoType run(Visitor v, CronoType[] args) {
- CronoNumber lhs = null, rhs = null;
- if(!(args[0] instanceof CronoNumber &&
- args[1] instanceof CronoNumber)) {
- throw new InterpreterException(_bad_type, args[0].typeId(),
- args[1].typeId());
- }
-
- lhs = (CronoNumber)(args[0]);
- rhs = (CronoNumber)(args[1]);
-
- if(lhs instanceof CronoFloat) {
- double val1, val2;
- val1 = ((CronoFloat)lhs).value;
- if(rhs instanceof CronoFloat) {
- val2 = ((CronoFloat)rhs).value;
- }else {
- val2 = (double)(((CronoInteger)rhs).value);
- }
- return new CronoFloat(val1 * val2);
- }else {
- if(rhs instanceof CronoFloat) {
- double val1, val2;
- val1 = (double)(((CronoInteger)lhs).value);
- val2 = ((CronoFloat)rhs).value;
- return new CronoFloat(val1 * val2);
- }else {
- long val1, val2;
- val1 = ((CronoInteger)lhs).value;
- val2 = ((CronoInteger)rhs).value;
- return new CronoInteger(val1 * val2);
- }
- }
- }
- public String toString() {
- return "*";
- }
+ CronoNumber.TYPEID, 2)
+ {
+ private static final String _bad_type =
+ "*: expected types :number :number, got %s %s";
+
+ public CronoType run(Visitor v, CronoType[] args) {
+ CronoNumber lhs = null, rhs = null;
+ if(!(args[0] instanceof CronoNumber &&
+ args[1] instanceof CronoNumber)) {
+ throw new InterpreterException(_bad_type, args[0].typeId(),
+ args[1].typeId());
+ }
+
+ lhs = (CronoNumber)(args[0]);
+ rhs = (CronoNumber)(args[1]);
+
+ if(lhs instanceof CronoFloat) {
+ double val1, val2;
+ val1 = ((CronoFloat)lhs).value;
+ if(rhs instanceof CronoFloat) {
+ val2 = ((CronoFloat)rhs).value;
+ }else {
+ val2 = (double)(((CronoInteger)rhs).value);
+ }
+ return new CronoFloat(val1 * val2);
+ }else {
+ if(rhs instanceof CronoFloat) {
+ double val1, val2;
+ val1 = (double)(((CronoInteger)lhs).value);
+ val2 = ((CronoFloat)rhs).value;
+ return new CronoFloat(val1 * val2);
+ }else {
+ long val1, val2;
+ val1 = ((CronoInteger)lhs).value;
+ val2 = ((CronoInteger)rhs).value;
+ return new CronoInteger(val1 * val2);
+ }
+ }
+ }
+ public String toString() {
+ return "*";
+ }
}),
DIV(new Function(new TypeId[]{CronoNumber.TYPEID, CronoNumber.TYPEID},
- CronoNumber.TYPEID, 2)
- {
- private static final String _bad_type =
- "/: expected types :number :number, got %s %s";
-
- public CronoType run(Visitor v, CronoType[] args) {
- CronoNumber lhs = null, rhs = null;
- if(!(args[0] instanceof CronoNumber &&
- args[1] instanceof CronoNumber)) {
- throw new InterpreterException(_bad_type, args[0].typeId(),
- args[1].typeId());
- }
-
- lhs = (CronoNumber)(args[0]);
- rhs = (CronoNumber)(args[1]);
-
- if(lhs instanceof CronoFloat) {
- double val1, val2;
- val1 = ((CronoFloat)lhs).value;
- if(rhs instanceof CronoFloat) {
- val2 = ((CronoFloat)rhs).value;
- }else {
- val2 = (double)(((CronoInteger)rhs).value);
- }
- return new CronoFloat(val1 / val2);
- }else {
- if(rhs instanceof CronoFloat) {
- double val1, val2;
- val1 = (double)(((CronoInteger)lhs).value);
- val2 = ((CronoFloat)rhs).value;
- return new CronoFloat(val1 / val2);
- }else {
- long val1, val2;
- val1 = ((CronoInteger)lhs).value;
- val2 = ((CronoInteger)rhs).value;
- return new CronoInteger(val1 / val2);
- }
- }
- }
-
- public String toString() {
- return "/";
- }
+ CronoNumber.TYPEID, 2)
+ {
+ private static final String _bad_type =
+ "/: expected types :number :number, got %s %s";
+
+ public CronoType run(Visitor v, CronoType[] args) {
+ CronoNumber lhs = null, rhs = null;
+ if(!(args[0] instanceof CronoNumber &&
+ args[1] instanceof CronoNumber)) {
+ throw new InterpreterException(_bad_type, args[0].typeId(),
+ args[1].typeId());
+ }
+
+ lhs = (CronoNumber)(args[0]);
+ rhs = (CronoNumber)(args[1]);
+
+ if(lhs instanceof CronoFloat) {
+ double val1, val2;
+ val1 = ((CronoFloat)lhs).value;
+ if(rhs instanceof CronoFloat) {
+ val2 = ((CronoFloat)rhs).value;
+ }else {
+ val2 = (double)(((CronoInteger)rhs).value);
+ }
+ return new CronoFloat(val1 / val2);
+ }else {
+ if(rhs instanceof CronoFloat) {
+ double val1, val2;
+ val1 = (double)(((CronoInteger)lhs).value);
+ val2 = ((CronoFloat)rhs).value;
+ return new CronoFloat(val1 / val2);
+ }else {
+ long val1, val2;
+ val1 = ((CronoInteger)lhs).value;
+ val2 = ((CronoInteger)rhs).value;
+ return new CronoInteger(val1 / val2);
+ }
+ }
+ }
+
+ public String toString() {
+ return "/";
+ }
}),
INT(new Function(new TypeId[]{CronoPrimitive.TYPEID},CronoInteger.TYPEID,1)
{
- public static final String _bad_type =
- "INT: Excepted one of :char, :float, or :int; got %s";
-
- public CronoType run(Visitor v, CronoType[] args) {
- if(args[0] instanceof CronoCharacter) {
- return new CronoInteger(((long)((CronoCharacter)args[0]).ch));
- }else if(args[0] instanceof CronoFloat) {
- return new CronoInteger(((long)((CronoFloat)args[0]).value));
- }else if(args[0] instanceof CronoInteger) {
- return args[0];
- }
- throw new InterpreterException(_bad_type, args[0].typeId());
- }
- public String toString() {
- return "int";
- }
+ public static final String _bad_type =
+ "INT: Excepted one of :char, :float, or :int; got %s";
+
+ public CronoType run(Visitor v, CronoType[] args) {
+ if(args[0] instanceof CronoCharacter) {
+ return new CronoInteger(((long)((CronoCharacter)args[0]).ch));
+ }else if(args[0] instanceof CronoFloat) {
+ return new CronoInteger(((long)((CronoFloat)args[0]).value));
+ }else if(args[0] instanceof CronoInteger) {
+ return args[0];
+ }
+ throw new InterpreterException(_bad_type, args[0].typeId());
+ }
+ public String toString() {
+ return "int";
+ }
}),
CHAR(new Function(new TypeId[]{CronoPrimitive.TYPEID},
- CronoCharacter.TYPEID, 1)
- {
- private static final String _bad_type =
- "CHAR: expected one of :int, or :char; got %s";
-
- public CronoType run(Visitor v, CronoType[] args) {
- if(args[0] instanceof CronoInteger) {
- return new CronoCharacter((char)((CronoInteger)args[0]).value);
- }else if(args[0] instanceof CronoFloat) {
- return new CronoCharacter((char)((CronoFloat)args[0]).value);
- }else if(args[0] instanceof CronoCharacter) {
- return args[0];
- }
- throw new InterpreterException(_bad_type, args[0].typeId());
- }
- public String toString() {
- return "char";
- }
+ CronoCharacter.TYPEID, 1)
+ {
+ private static final String _bad_type =
+ "CHAR: expected one of :int, or :char; got %s";
+
+ public CronoType run(Visitor v, CronoType[] args) {
+ if(args[0] instanceof CronoInteger) {
+ return new CronoCharacter((char)((CronoInteger)args[0]).value);
+ }else if(args[0] instanceof CronoFloat) {
+ return new CronoCharacter((char)((CronoFloat)args[0]).value);
+ }else if(args[0] instanceof CronoCharacter) {
+ return args[0];
+ }
+ throw new InterpreterException(_bad_type, args[0].typeId());
+ }
+ public String toString() {
+ return "char";
+ }
}),
FLOAT(new Function(new TypeId[]{CronoPrimitive.TYPEID},CronoFloat.TYPEID,1)
{
- private static final String _bad_type =
- "FLOAT: expected one of :int, or :float; got %s";
-
- public CronoType run(Visitor v, CronoType[] args) {
- if(args[0] instanceof CronoInteger) {
- return new CronoFloat((double)((CronoInteger)args[0]).value);
- }else if(args[0] instanceof CronoCharacter) {
- return new CronoFloat((double)((CronoCharacter)args[0]).ch);
- }else if(args[0] instanceof CronoFloat) {
- return args[0];
- }
-
- throw new InterpreterException(_bad_type, args[0].typeId());
- }
- public String toString() {
- return "float";
- }
+ private static final String _bad_type =
+ "FLOAT: expected one of :int, or :float; got %s";
+
+ public CronoType run(Visitor v, CronoType[] args) {
+ if(args[0] instanceof CronoInteger) {
+ return new CronoFloat((double)((CronoInteger)args[0]).value);
+ }else if(args[0] instanceof CronoCharacter) {
+ return new CronoFloat((double)((CronoCharacter)args[0]).ch);
+ }else if(args[0] instanceof CronoFloat) {
+ return args[0];
+ }
+
+ throw new InterpreterException(_bad_type, args[0].typeId());
+ }
+ public String toString() {
+ return "float";
+ }
}),
LOAD(new Function(new TypeId[]{CronoString.TYPEID}, CronoType.TYPEID, 1)
{
- private static final String _bad_type =
- "LOAD: expected :string, got %s";
- private static final String _file_not_found =
- "LOAD: could not open file %s";
- private static final String _bad_parse =
- "LOAD: error parsing file:\n%s";
-
- private CronoType loadLisp(Visitor v, String fname) {
- InputStream is = null;
- try {
- is = new FileInputStream(fname);
- }catch(FileNotFoundException fnfe) {
- throw new InterpreterException(_file_not_found,
- fnfe.getMessage());
- }
- Parser p = new Parser(is);
- CronoType program = null;
- try {
- program = p.program();
- }catch(ParseException pe) {
- throw new InterpreterException(_bad_parse, pe.getMessage());
- }
- return program.accept(v);
- }
- private CronoType loadPackage(Visitor v, String fname) {
- CronoPackage pack = CronoPackage.load(fname);
- Environment env = v.getEnv();
- Function[] funcs = pack.functions();
- if(funcs != null) {
- for(Function f : funcs) {
- env.put(new Symbol(f.toString()), f);
- }
- }
- TypeId[] types = pack.types();
- if(types != null) {
- for(TypeId t : types) {
- env.put(t);
- }
- }
-
- CronoPackage.SymbolPair[] syms = pack.symbols();
- if(syms != null) {
- for(CronoPackage.SymbolPair s : syms) {
- env.put(s.sym, s.type);
- }
- }
-
- return TruthValue.T;
- }
-
- public CronoType run(Visitor v, CronoType[] args) {
- if(!(args[0] instanceof CronoString)) {
- throw new InterpreterException(_bad_type, args[0].typeId());
- }
- String fname = ((CronoString)args[0]).toString();
- String lname = fname.toLowerCase();
- if(lname.endsWith(".lisp") || lname.endsWith(".crono")) {
- return loadLisp(v, fname);
- }
- return loadPackage(v, fname);
- }
- public String toString() {
- return "load";
+ private static final String _bad_type =
+ "LOAD: expected :string, got %s";
+ private static final String _file_not_found =
+ "LOAD: could not open file %s";
+ private static final String _bad_parse =
+ "LOAD: error parsing file:\n%s";
+
+ private CronoType loadLisp(Visitor v, String fname) {
+ InputStream is = null;
+ try {
+ is = new FileInputStream(fname);
+ }catch(FileNotFoundException fnfe) {
+ throw new InterpreterException(_file_not_found,
+ fnfe.getMessage());
+ }
+ Parser p = new Parser(is);
+ CronoType[] program = null;
+ try {
+ program = p.program();
+ }catch(ParseException pe) {
+ throw new InterpreterException(_bad_parse, pe.getMessage());
+ }
+ for(int i = 0; i < program.length; ++i) {
+ program[i].accept(v);
+ }
+ return TruthValue.T;
+ }
+ private CronoType loadPackage(Visitor v, String fname) {
+ CronoPackage pack = CronoPackage.load(fname);
+ Environment env = v.getEnv();
+ Function[] funcs = pack.functions();
+ if(funcs != null) {
+ for(Function f : funcs) {
+ env.put(new Symbol(f.toString()), f);
+ }
+ }
+ TypeId[] types = pack.types();
+ if(types != null) {
+ for(TypeId t : types) {
+ env.put(t);
+ }
+ }
+
+ CronoPackage.SymbolPair[] syms = pack.symbols();
+ if(syms != null) {
+ for(CronoPackage.SymbolPair s : syms) {
+ env.put(s.sym, s.type);
+ }
+ }
+
+ return TruthValue.T;
+ }
+
+ public CronoType run(Visitor v, CronoType[] args) {
+ if(!(args[0] instanceof CronoString)) {
+ throw new InterpreterException(_bad_type, args[0].typeId());
+ }
+ String fname = ((CronoString)args[0]).toString();
+ String lname = fname.toLowerCase();
+ if(lname.matches("[^\\n\\r]*\\.[^\\n\\r]*")) {
+ return loadLisp(v, fname);
+ }
+ return loadPackage(v, fname);
+ }
+ public String toString() {
+ return "load";
}
}),
PRINT(new Function(new TypeId[]{CronoType.TYPEID}, Nil.TYPEID, 1, true)
{
public CronoType run(Visitor v, CronoType[] args) {
- for(int i = 0; i < args.length; ++i) {
- System.out.print(args[i].toString());
- }
- return Nil.NIL;
+ for(int i = 0; i < args.length; ++i) {
+ System.out.print(args[i].toString());
+ }
+ return Nil.NIL;
}
public String toString() {
- return "print";
+ return "print";
}
}),
PRINTLN(new Function(new TypeId[]{CronoType.TYPEID}, Nil.TYPEID, 1, true)
{
- public CronoType run(Visitor v, CronoType[] args) {
- PRINT.function.run(v, args);
- System.out.println();
- return Nil.NIL;
- }
- public String toString() {
- return "println";
- }
+ public CronoType run(Visitor v, CronoType[] args) {
+ PRINT.function.run(v, args);
+ System.out.println();
+ return Nil.NIL;
+ }
+ public String toString() {
+ return "println";
+ }
}),
STRUCT(new Function(new TypeId[]{Symbol.TYPEID}, CronoStruct.TYPEID, 1,
- false, EvalType.NONE)
+ false, EvalType.NONE)
{
- private static final String _name = "struct";
- private static final String _no_struct_in_scope =
- "struct: No structure definition for %s in scope";
+ private static final String _name = "struct";
+ private static final String _no_struct_in_scope =
+ "struct: No structure definition for %s in scope";
public CronoType run(Visitor v, CronoType[] args) {
- CronoStruct struct = v.getEnv().getStruct((Symbol)args[0]);
- if(struct == null) {
- throw new InterpreterException(_no_struct_in_scope, args[0]);
- }
-
- return struct.copy();
+ CronoStruct struct = v.getEnv().getStruct((Symbol)args[0]);
+ if(struct == null) {
+ throw new InterpreterException(_no_struct_in_scope, args[0]);
+ }
+
+ return struct.copy();
}
public String toString() {
- return _name;
+ return _name;
}
}),
SUBSTRUCT(new Function(new TypeId[]{Symbol.TYPEID, Symbol.TYPEID,
- Cons.TYPEID},
- Nil.TYPEID, 3, false, EvalType.NONE)
+ Cons.TYPEID},
+ Nil.TYPEID, 3, false, EvalType.NONE)
{
- private static final String _name = "substruct";
- private static final String _no_struct_in_scope =
- "substruct: no structure definition for %s in scope";
-
+ private static final String _name = "substruct";
+ private static final String _no_struct_in_scope =
+ "substruct: no structure definition for %s in scope";
+
public CronoType run(Visitor v, CronoType[] args) {
- CronoStruct par = v.getEnv().getStruct((Symbol)args[1]);
- if(par == null) {
- throw new InterpreterException(_no_struct_in_scope, args[1]);
- }
- Map<String, CronoStruct.Field> fields;
- fields = CronoStruct.BuildFieldMap(_name, (Cons)args[2]);
- v.getEnv().put(new CronoStruct(args[0].toString(), fields, par));
- return Nil.NIL;
+ CronoStruct par = v.getEnv().getStruct((Symbol)args[1]);
+ if(par == null) {
+ throw new InterpreterException(_no_struct_in_scope, args[1]);
+ }
+ Map<String, CronoStruct.Field> fields;
+ fields = CronoStruct.BuildFieldMap(_name, (Cons)args[2]);
+ v.getEnv().put(new CronoStruct(args[0].toString(), fields, par));
+ return Nil.NIL;
}
public String toString() {
- return _name;
+ return _name;
}
}),
DEFSTRUCT(new Function(new TypeId[]{Symbol.TYPEID, Cons.TYPEID},
- Nil.TYPEID, 2, false, EvalType.NONE)
+ Nil.TYPEID, 2, false, EvalType.NONE)
{
- private static final String _name = "defstruct";
+ private static final String _name = "defstruct";
public CronoType run(Visitor v, CronoType[] args) {
- Map<String, CronoStruct.Field> fields;
- fields = CronoStruct.BuildFieldMap(_name, (Cons)args[1]);
- v.getEnv().put(new CronoStruct(args[0].toString(), fields));
-
- InfDatabase.insertDefstruct(args[0].toString(),fields);
-
- return Nil.NIL;
+ Map<String, CronoStruct.Field> fields;
+ fields = CronoStruct.BuildFieldMap(_name, (Cons)args[1]);
+ v.getEnv().put(new CronoStruct(args[0].toString(), fields));
+
+ /* Inferencing Engine */
+ InfDatabase.insertDefstruct(args[0].toString(),fields);
+ return Nil.NIL;
}
public String toString() {
- return _name;
+ return _name;
}
}),
- EVAL(new Function(new TypeId[]{CronoString.TYPEID}, Cons.TYPEID, 1)
+ EXEC(new Function(new TypeId[]{CronoType.TYPEID}, CronoType.TYPEID, 1,
+ true)
{
public CronoType run(Visitor v, CronoType[] args) {
- StringReader reader;
- reader = new StringReader(((CronoString)args[0]).toString());
-
- Parser p = new Parser(reader);
-
- try {
- return p.program().accept(v);
- }catch(ParseException pe) {
- throw new InterpreterException("EVAL: parse error\n%s",
- pe.getMessage());
- }
+ return args[args.length - 1];
}
public String toString() {
- return "eval";
+ return "exec";
}
}),
- ENTAIL(new Function(new TypeId[]{}, TruthValue.TYPEID, 0)
+ EVAL(new Function(new TypeId[]{CronoString.TYPEID}, Cons.TYPEID, 1)
{
- public CronoType run(Visitor v, CronoType[] args) {
- Environment env = v.getEnv();
- InfDatabase.entail(env);
- System.out.println(InfDatabase.printdb());
- return TruthValue.T;
- }
- public String toString(){
- return "entail";
- }
+ public CronoType run(Visitor v, CronoType[] args) {
+ StringReader reader;
+ reader = new StringReader(((CronoString)args[0]).toString());
+
+ Parser p = new Parser(reader);
+
+ try {
+ CronoType[] program = p.program();
+ CronoType result = Nil.NIL;
+ for(int i = 0; i < program.length; ++i) {
+ result = program[i].accept(v);
+ }
+ return result;
+ }catch(ParseException pe) {
+ throw new InterpreterException("EVAL: parse error\n%s",
+ pe.getMessage());
+ }
+ }
+ public String toString() {
+ return "eval";
+ }
}),
TRY(new Function(new TypeId[]{Symbol.TYPEID, CronoType.TYPEID,
CronoType.TYPEID}, CronoType.TYPEID, 3,
@@ -824,10 +997,24 @@ public String toString() {
return "raise";
}
}),
+ TYPEOF(new Function(new TypeId[]{CronoType.TYPEID}, CronoTypeId.TYPEID, 1)
+ {
+ public CronoType run(Visitor v, CronoType[] args) {
+ CronoTypeId id = new CronoTypeId(args[0].typeId());
+ CronoTypeId nid = v.getEnv().getType(id);
+ if(id == null) {
+ throw new TypeScopeException(id.type);
+ }
+ return nid;
+ }
+ public String toString() {
+ return "typeof";
+ }
+ }),
;
public final Function function;
private CronoFunction(Function fun) {
- this.function = fun;
+ this.function = fun;
}
}
View
5 crono/src/crono/Environment.java
@@ -60,6 +60,8 @@ public Environment(boolean builtins) {
public Environment(Environment env) {
symbols = new HashMap<String, CronoType>(env.symbols);
+ structs = new HashMap<String, CronoStruct>(env.structs);
+ types = new HashMap<String, CronoTypeId>(env.types);
show_builtins = env.show_builtins;
multiline = env.multiline;
show_types = env.show_types;
@@ -91,7 +93,8 @@ public CronoStruct getStruct(Symbol sym) {
return structs.get(sym.toString());
}
public CronoTypeId getType(CronoTypeId id) {
- return getType(id.type.image);
+ CronoTypeId nid = getType(id.type.image);
+ return (nid == null) ? id : nid;
}
public CronoTypeId getType(String str) {
return types.get(str);
View
52 crono/src/crono/Interpreter.java
@@ -26,6 +26,7 @@
public boolean dynamic, rDynamic;
public boolean trace, rTrace;
public boolean printAST, rPrintAST;
+ public boolean debug, rDebug;
public Stack<Environment> envStack;
public InterpreterState() {
@@ -39,6 +40,8 @@ public InterpreterState() {
rTrace = Interpreter.this.rTrace;
printAST = Interpreter.this.printAST;
rPrintAST = Interpreter.this.rPrintAST;
+ debug = Interpreter.this.debug;
+ rDebug = Interpreter.this.rDebug;
envStack = new Stack<Environment>();
envStack.addAll(Interpreter.this.envStack);
@@ -59,6 +62,7 @@ public InterpreterState() {
protected boolean dynamic, rDynamic;
protected boolean trace, rTrace;
protected boolean printAST, rPrintAST;
+ protected boolean debug, rDebug;
protected EvalType eval;
protected StringBuilder indent;
@@ -77,6 +81,7 @@ public Interpreter() {
dynamic(false);
trace(false);
printAST(false);
+ debug(false);
lambdaDepth = 0;
@@ -129,6 +134,14 @@ public void printAST(boolean on) {
printAST = on;
rPrintAST = on;
}
+ /**
+ * Turns debug printing on or off.
+ * @param on If the Interpreter should print dprint messages.
+ */
+ public void debug(boolean on) {
+ debug = on;
+ rDebug = on;
+ }
/**
* Helper method to indent correctly.
@@ -159,6 +172,7 @@ protected void resetOptions() {
dynamic = rDynamic;
trace = rTrace;
printAST = rPrintAST;
+ debug = rDebug;
}
/**
* Turns off all options that only affect information that is printed.
@@ -345,7 +359,9 @@ public CronoType visit(Cons c) {
}
if(arglen > nargs && !fun.variadic) {
eval = reserve;
- except(new TooManyArgsException(fun, arglen, nargs));
+ CronoType[] argarray =
+ args.toArray(new CronoType[args.size()]);
+ except(new TooManyArgsException(fun, arglen, nargs, argarray));
}
/* Full evaluation */
@@ -353,13 +369,16 @@ public CronoType visit(Cons c) {
CronoType[] argarray =
args.toArray(new CronoType[args.size()]);
- if(fun instanceof LambdaFunction) {
+ boolean islfun = (fun instanceof LambdaFunction);
+ if(islfun) {
LambdaFunction lfun = (LambdaFunction)fun;
if(dynamic) {
lfun = new LambdaFunction(lfun.arglist, lfun.body,
getEnv());
}
fun = substitute(lfun, argarray);
+ argarray = new CronoType[0];
+ args.clear();
}
TypeId[] types = new TypeId[args.size()];
@@ -367,9 +386,9 @@ public CronoType visit(Cons c) {
types[i] = argarray[i].typeId();
}
int check = 0;
- for(int i = 0; i < fun.args.length; ++i) {
- check = Math.min(i, argarray.length);
- if(!(fun.args[i].isType(argarray[check]))) {
+ for(int i = 0; i < argarray.length; ++i) {
+ check = Math.min(i, fun.args.length - 1);
+ if(!(fun.args[check].isType(argarray[i]))) {
String argstr = Arrays.toString(types);
String expected = Arrays.toString(fun.args);
except(new InterpreterException(_type_mismatch, fun,
@@ -377,14 +396,18 @@ public CronoType visit(Cons c) {
}
}
- optionsOff();
+ if(!islfun) {
+ optionsOff();
+ }
CronoType fresult = null;
try {
fresult = fun.run(this, args.toArray(argarray));
}catch(RuntimeException re) {
except(re);
}
- resetOptions();
+ if(!islfun) {
+ resetOptions();
+ }
deindent();
traceResult(fresult);
@@ -408,6 +431,7 @@ public CronoType visit(Cons c) {
}
CronoType conres = Cons.fromList(args);
traceResult(conres);
+ deindent();
return conres;
}
deindent();
@@ -431,7 +455,7 @@ public CronoType visit(Cons c) {
* @return The value obtained by visiting this node.
*/
public CronoType visit(Atom a) {
- printASTNode(String.format("Atom Node -> %s[%s]\n", a, a.typeId()));
+ printASTNode(String.format("Atom Node -> %s[%s]", a, a.typeId()));
traceVisit(a);
if(eval == EvalType.NONE) {
traceResult(a);
@@ -450,7 +474,7 @@ public CronoType visit(Atom a) {
}
/* Not else-if, so that we perform a double-resolution on a symbol that
* represents a TypeId */
- if(t instanceof CronoTypeId) {
+ if(t instanceof CronoTypeId && !((CronoTypeId)t).complete()) {
CronoType res = t; /*< Save symbol resolution */
t = getEnv().getType((CronoTypeId)t);
if(t == null) {
@@ -508,6 +532,12 @@ public void setState(Visitor.VisitorState state) {
}
}
+ public void dprint(String message, Object... args) {
+ if(debug) {
+ System.out.printf(message, args);
+ }
+ }
+
/* Cut down on code duplication. */
private LambdaFunction substitute(LambdaFunction lfun, CronoType[] args) {
EvalType reserve = eval;
@@ -541,8 +571,8 @@ private LambdaFunction doSubst(LambdaFunction lfun, CronoType[] args) {
CronoType[] body = new CronoType[lfun.body.length];
int remain = lfun.arglist.length - args.length;
if(remain < 0) {
- throw new TooManyArgsException(lfun, lfun.arglist.length,
- args.length);
+ except(new TooManyArgsException(lfun, lfun.arglist.length,
+ args.length, args));
}
Symbol[] largs = new Symbol[remain];