}
public Environment createGlobalEnvironment(Environment parent) {
Environment env = new HashEnvironment(parent, context());
env.bind("println", _theContext.createProcedure(new Procedure() {
public void call(Object[] args) {
System.out.println(args[0]);
}
public int arity() {
return 1;
}
}));
env.bind("SOP", _theContext.createFunction(new Function() {
public Object apply(Object[] args) {
try {
System.out.println(args[0]);
return args[0];
} catch (Exception ex) {
throw new FunctionCallException("SOP", args[0], ex);
}
}
public int arity() {
return 1;
}
}));
env.bind("logValue", _theContext.createFunction(new Function() {
public Object apply(Object[] args) {
try {
PrintStream output = new PrintStream(new FileOutputStream(
_theContext.stringValue(args[0]), true));
output.println(args[1].toString());
output.close();
return args[1];
} catch (Exception ex) {
throw new FunctionCallException("logValue", args[0], ex);
}
}
public int arity() {
return 2;
}
}));
env.bind("Integers", _theContext.createFunction(new Function() {
public Object apply(Object[] args) {
try {
int a = _theContext.intValue(args[0]);
int b = _theContext.intValue(args[1]);
List res = (b < a) ? Collections.EMPTY_LIST
: new IntegerList(_theContext, a, b);
return _theContext.createList(res);
} catch (Exception ex) {
throw new FunctionCallException("Integers", args[0],
args[1], ex);
}
}
public int arity() {
return 2;
}
}));
env.bind("$not", _theContext.createFunction(new Function() {
public Object apply(Object[] args) {
try {
BooleanToken b = (BooleanToken) args[0];
return b.not();
} catch (Exception ex) {
throw new FunctionCallException("$not", args[0], ex);
}
}
public int arity() {
return 1;
}
}));
env.bind("$and", _theContext.createFunction(new Function() {
public Object apply(Object[] args) {
try {
BooleanToken a = (BooleanToken) args[0];
BooleanToken b = (BooleanToken) args[1];
return a.and(b);
} catch (Exception ex) {
throw new FunctionCallException("$and", args[0], args[1],
ex);
}
}
public int arity() {
return 2;
}
}));
env.bind("$or", _theContext.createFunction(new Function() {
public Object apply(Object[] args) {
try {
BooleanToken a = (BooleanToken) args[0];
BooleanToken b = (BooleanToken) args[1];
return a.or(b);
} catch (Exception ex) {
throw new FunctionCallException("$or", args[0], args[1], ex);
}
}
public int arity() {
return 2;
}
}));
env.bind("$eq", _theContext.createFunction(new Function() {
public Object apply(Object[] args) {
try {
Token a = (Token) args[0];
Token b = (Token) args[1];
return a.isEqualTo(b);
} catch (Exception ex) {
throw new FunctionCallException("$eq", args[0], args[1], ex);
}
}
public int arity() {
return 2;
}
}));
env.bind("$ne", _theContext.createFunction(new Function() {
public Object apply(Object[] args) {
try {
Token a = (Token) args[0];
Token b = (Token) args[1];
return a.isEqualTo(b).not();
} catch (Exception ex) {
throw new FunctionCallException("$ne", args[0], args[1], ex);
}
}
public int arity() {
return 2;
}
}));
env.bind("$lt", _theContext.createFunction(new Function() {
public Object apply(Object[] args) {
try {
ScalarToken a = (ScalarToken) args[0];
ScalarToken b = (ScalarToken) args[1];
return a.isLessThan(b);
} catch (Exception ex) {
throw new FunctionCallException("$lt", args[0], args[1], ex);
}
}
public int arity() {
return 2;
}
}));
env.bind("$le", _theContext.createFunction(new Function() {
public Object apply(Object[] args) {
try {
ScalarToken a = (ScalarToken) args[0];
ScalarToken b = (ScalarToken) args[1];
return a.isGreaterThan(b).not();
} catch (Exception ex) {
throw new FunctionCallException("$le", args[0], args[1], ex);
}
}
public int arity() {
return 2;
}
}));
env.bind("$gt", _theContext.createFunction(new Function() {
public Object apply(Object[] args) {
try {
ScalarToken a = (ScalarToken) args[0];
ScalarToken b = (ScalarToken) args[1];
return a.isGreaterThan(b);
} catch (Exception ex) {
throw new FunctionCallException("$gt", args[0], args[1], ex);
}
}
public int arity() {
return 2;
}
}));
env.bind("$ge", _theContext.createFunction(new Function() {
public Object apply(Object[] args) {
try {
ScalarToken a = (ScalarToken) args[0];
ScalarToken b = (ScalarToken) args[1];
return a.isLessThan(b).not();
} catch (Exception ex) {
throw new FunctionCallException("$ge", args[0], args[1], ex);
}
}
public int arity() {
return 2;
}
}));
env.bind("$negate", _theContext.createFunction(new Function() {
public Object apply(Object[] args) {
try {
ScalarToken a = (ScalarToken) args[0];
return a.zero().subtract(a);
} catch (Exception ex) {
throw new FunctionCallException("$negate", args[0], ex);
}
}
public int arity() {
return 1;
}
}));
env.bind("$add", _theContext.createFunction(new Function() {
// Compute the add operation on scalar arguments, the
// list concatenation operation on lists, or the set
// union on sets.
public Object apply(Object[] args) {
try {
Token a = (Token) args[0];
Token b = (Token) args[1];
if (a instanceof ObjectToken && b instanceof ObjectToken) {
Object oa = ((ObjectToken) a).getValue();
Object ob = ((ObjectToken) b).getValue();
if (oa instanceof Collection
&& ob instanceof Collection) {
Collection result;
if (oa instanceof Set) {
result = new HashSet((Set) oa);
} else if (oa instanceof List) {
result = new ArrayList((List) oa);
} else {
throw new Exception(
"Unknown object type: expected Set or List.");
}
result.addAll((Collection) ob);
return new ObjectToken(result);
} else {
throw new Exception(
"Unknown object types: expected Collection.");
}
} else {
return a.add(b);
}
} catch (Exception ex) {
throw new FunctionCallException("$add", args[0], args[1],
ex);
}
}
public int arity() {
return 2;
}
}));
env.bind("$mul", _theContext.createFunction(new Function() {
// Compute the multiply operation on scalar arguments,
// or the set intersection operation on sets.
public Object apply(Object[] args) {
try {
Token a = (Token) args[0];
Token b = (Token) args[1];
if (a instanceof ObjectToken && b instanceof ObjectToken) {
Object oa = ((ObjectToken) a).getValue();
Object ob = ((ObjectToken) b).getValue();
if (oa instanceof Set && ob instanceof Collection) {
Set result = new HashSet((Set) oa);
result.retainAll((Collection) ob);
return new ObjectToken(result);
} else {
throw new InterpreterException(
"Unknown object types: expected Set and Collection.");
}
} else {
return a.multiply(b);
}
} catch (Exception ex) {
throw new FunctionCallException("$mul", args[0], args[1],
ex);
}
}
public int arity() {
return 2;
}
}));
env.bind("$sub", _theContext.createFunction(new Function() {
// Compute the subtraction operation on scalar arguments,
// or the set subtraction operation on sets.
public Object apply(Object[] args) {
try {
Token a = (Token) args[0];
Token b = (Token) args[1];
if (a instanceof ObjectToken && b instanceof ObjectToken) {
Object oa = ((ObjectToken) a).getValue();
Object ob = ((ObjectToken) b).getValue();
if (oa instanceof Collection
&& ob instanceof Collection) {
Collection result;
if (oa instanceof Set) {
result = new HashSet((Set) oa);
} else if (oa instanceof List) {
result = new ArrayList((List) oa);
} else {
throw new Exception(
"Unknown object type: expected Set or List.");
}
result.removeAll((Collection) ob);
return new ObjectToken(result);
} else {
throw new InterpreterException(
"Unknown object types: expected Collection.");
}
} else {
return a.subtract(b);
}
} catch (Exception ex) {
throw new FunctionCallException("$sub", args[0], args[1],
ex);
}
}
public int arity() {
return 2;
}
}));
env.bind("$div", _theContext.createFunction(new Function() {
public Object apply(Object[] args) {
try {
Token a = (Token) args[0];
Token b = (Token) args[1];
return a.divide(b);
} catch (Exception ex) {
throw new FunctionCallException("$div", args[0], args[1],
ex);
}
}
public int arity() {
return 2;
}
}));
env.bind("$mod", _theContext.createFunction(new Function() {
public Object apply(Object[] args) {
try {
Token a = (Token) args[0];
Token b = (Token) args[1];
return a.modulo(b);
} catch (Exception ex) {
throw new FunctionCallException("$mod", args[0], args[1],
ex);
}
}
public int arity() {
return 2;
}
}));
env.bind("$size", _theContext.createFunction(new Function() {
// Compute the number of elements in the given set,
// list, or array.
public Object apply(Object[] args) {
try {
Token a = (Token) args[0];
if (a instanceof ObjectToken) {
Object oa = ((ObjectToken) a).getValue();
if (oa instanceof Collection) {
return new IntToken(((Collection) oa).size());
} else {
throw new InterpreterException(
"Unknown object type: expected Collection.");
}
} else if (a instanceof ArrayToken) {
return _theContext.createInteger(((ArrayToken) a)
.length());
} else {
throw new InterpreterException(
"Unknown type: expected Array, Set, or List");
}
} catch (Exception ex) {
throw new FunctionCallException("$size", args[0], ex);
}
}
public int arity() {
return 1;
}
}));
env.bind("$createList", _theContext.createFunction(new Function() {
// Create a list that contains the results of applying
// the second argument (a one argument function) to
// every element in the first argument (a collection).
public Object apply(Object[] args) {
try {
Collection c = _theContext.getCollection(args[0]);
FunctionToken f = (FunctionToken) args[1];
Object[] argument = new Object[1];
List res = new ArrayList();
for (Iterator i = c.iterator(); i.hasNext();) {
argument[0] = i.next();
Object listFragment = _theContext.applyFunction(f,
argument);
res.addAll(_theContext.getCollection(listFragment));
}
return _theContext.createList(res);
} catch (Exception ex) {
throw new FunctionCallException("Failed to create list.",
args[0], args[1], ex);
}
}
public int arity() {
return 2;
}
}));
env.bind("$createSet", _theContext.createFunction(new Function() {
// Create a set that contains the results of applying
// the second argument (a one argument function) to
// every element in the first argument (a collection).
public Object apply(Object[] args) {
try {
Collection c = _theContext.getCollection(args[0]);
FunctionToken f = (FunctionToken) args[1];
Object[] argument = new Object[1];
Set res = new HashSet();
for (Iterator i = c.iterator(); i.hasNext();) {
argument[0] = i.next();
Object setFragment = _theContext.applyFunction(f,
argument);
res.addAll(_theContext.getCollection(setFragment));
}
return _theContext.createSet(res);
} catch (Exception ex) {
throw new FunctionCallException("Failed to create set.",
args[0], args[1], ex);
}
}
public int arity() {
return 2;
}
}));
env.bind("$createMap", _theContext.createFunction(new Function() {
// Create a map that contains the results of applying
// the second argument (a one argument function) to
// every element in the first argument (a collection).
public Object apply(Object[] args) {
try {
Collection c = _theContext.getCollection(args[0]);
FunctionToken f = (FunctionToken) args[1];
Object[] argument = new Object[1];
Map res = new HashMap();
for (Iterator i = c.iterator(); i.hasNext();) {
argument[0] = i.next();
Object mapFragment = _theContext.applyFunction(f,
argument);
res.putAll(_theContext.getMap(mapFragment));
}
return _theContext.createMap(res);
} catch (Exception ex) {
throw new FunctionCallException("Failed to create map.",
args[0], args[1], ex);
}
}
public int arity() {
return 2;
}
}));
env.bind("$iterate", _theContext.createProcedure(new Procedure() {
// Invoke the second argument (a one argument
// procedure) on every element of the first argument
// (a collection).
public void call(Object[] args) {
try {