package org.rascalmpl.library.util; import org.rascalmpl.interpreter.cursors.Context; import org.rascalmpl.interpreter.cursors.CursorFactory; import org.rascalmpl.interpreter.cursors.ICursor; import org.rascalmpl.interpreter.cursors.InvertorContext; import org.rascalmpl.interpreter.cursors.SetCursor; import org.rascalmpl.interpreter.cursors.TopContext; import org.rascalmpl.interpreter.cursors.UnionContext; import org.rascalmpl.interpreter.result.ICallableValue; import org.rascalmpl.interpreter.utils.RuntimeExceptionFactory; import org.rascalmpl.value.IBool; import org.rascalmpl.value.IList; import org.rascalmpl.value.ISet; import org.rascalmpl.value.IString; import org.rascalmpl.value.IValue; import org.rascalmpl.value.IValueFactory; import org.rascalmpl.value.type.Type; import org.rascalmpl.value.type.TypeFactory; import org.rascalmpl.value.type.TypeStore; public class Cursor { private static final TypeStore cursors = new TypeStore(); private static final TypeFactory tf = TypeFactory.getInstance(); public static final Type Nav = tf.abstractDataType(cursors, "Nav"); public static final Type Nav_root = tf.constructor(cursors, Nav, "root", tf.stringType(), "name"); public static final Type Nav_fieldName = tf.constructor(cursors, Nav, "field", tf.stringType(), "name"); public static final Type Nav_fieldPosition = tf.constructor(cursors, Nav, "field", tf.integerType(), "position"); public static final Type Nav_argumentPosition = tf.constructor(cursors, Nav, "argument", tf.integerType(), "position"); public static final Type Nav_argumentName = tf.constructor(cursors, Nav, "argument", tf.stringType(), "name"); public static final Type Nav_keywordParam = tf.constructor(cursors, Nav, "keywordParam", tf.stringType(), "name"); public static final Type Nav_element = tf.constructor(cursors, Nav, "element", tf.integerType(), "index"); public static final Type Nav_sublist = tf.constructor(cursors, Nav, "sublist", tf.integerType(), "from", tf.integerType(), "to"); public static final Type Nav_lookup = tf.constructor(cursors, Nav, "lookup", tf.valueType(), "key"); public static final Type Nav_selectByIndex = tf.constructor(cursors, Nav, "select", tf.listType(tf.integerType()), "indices"); public static final Type Nav_selectByLabel = tf.constructor(cursors, Nav, "select", tf.listType(tf.stringType()), "labels"); public static final Type Path = tf.aliasType(cursors, "Path", tf.listType(Nav)); private final IValueFactory vf; public Cursor(IValueFactory vf) { this.vf = vf; } public IValue makeCursor(IValue v) { return CursorFactory.makeCursor(v, new TopContext()); } public IValue makeCursor(IValue v, IString name) { return CursorFactory.makeCursor(v, new TopContext(name.getValue())); } public ISet subset(ISet sub, ISet backing) { checkCursorness("second", backing); return new SetCursor(sub, new UnionContext(((ICursor)backing).getCtx(), (ISet) ((ICursor)backing).getWrappedValue())); } public IValue update(IValue cursor, IValue v) { checkCursorness("first", cursor); return CursorFactory.makeCursor(v, ((ICursor) cursor).getCtx()); } public IValue compute(IValue cursor, IValue to, IValue from) { checkCursorness("first", cursor); checkUnaryFunction("second", to); checkUnaryFunction("third", from); ICursor c = (ICursor)cursor; Context ctx = new InvertorContext(c.getCtx(), (ICallableValue)from); ICallableValue f = (ICallableValue)to; IValue computed = f.call(new Type[] {c.getWrappedValue().getType()}, new IValue[] { c.getWrappedValue() }, null).getValue(); return CursorFactory.makeCursor(computed, ctx); } public IValue getRoot(IValue typ, IValue cursor) { checkCursorness("first", cursor); return ((ICursor) cursor).root(); } public IList toPath(IValue cursor) { checkCursorness("first", cursor); return ((ICursor)cursor).getCtx().toPath(vf); } public IBool isCursor(IValue v) { return vf.bool(v instanceof ICursor); } private static void checkCursorness(String arg, IValue cursor) { if (!(cursor instanceof ICursor)) { throw RuntimeExceptionFactory.illegalArgument(cursor, null, null, arg + " argument should be a cursor"); } } private static void checkUnaryFunction(String arg, IValue f) { // if (!(f instanceof ICallableValue) || ((ICallableValue)f).getArity() != 1) { // throw RuntimeExceptionFactory.illegalArgument(f, null, null, // arg + " argument should be a unary function"); // } } }