pnuts.lang.PnutsFunction represents a set of functions that share a certain name. The following methods can be overriden in a subclass of pnuts.lang.PnutsFunction.
The next class is a PnutsFunction subclass which adds the functionality of checking types of arguments.
import pnuts.lang.*; public class MyFunc extends PnutsFunction { Class[] paramTypes; public MyFunc(String name, Class[] paramTypes){ super(name); this.paramTypes = paramTypes; } protected Object exec(Object[] args, Context context){ if (args.length != paramTypes.length){ throw new RuntimeException("type mismatch"); } for (int i = 0; i < paramTypes.length; i++){ if (!paramTypes[i].isInstance(args[i])){ throw new RuntimeException("type mismatch"); } } return super.exec(args, context); } }
If a function's name is already defined as a PnutsFunction object which has the same name, additional function definitions are added to the object. In the next example, the overriden method exec() defined above is used when the function foo() is called.
foo = MyFunc("foo", [Integer]) function foo(x) println(x + 1) foo(1) ==> 2 foo(1.0) ==> error "java.lang.RuntimeException: type mismatch"
PnutsFunction.added() method can be used as a hook function which is called when a function is added to a PnutsFunction object.
protected void added(int nargs)
The following class overrides the added() method so that the function is recompiled when a definition is added to an instance of the class.
import pnuts.lang.PnutsFunction; import pnuts.compiler.Compiler; public class AutoCompile extends PnutsFunction { Compiler compiler; public AutoCompile(String name){ super(name); this.compiler = new Compiler(); } private boolean flag = false; protected void added(int nargs){ if (!flag){ flag = true; System.out.println("compiling " + getName()); compiler.compile(this); flag = false; } } }
foo = AutoCompile("foo") function foo(n) n