/* * This file is a part of Alchemy OS project. * Copyright (C) 2011-2014, Sergey Basalaev <sbasalaev@gmail.com> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package alchemy.system; /** * Function is an atomic piece of program execution. * Subclasses should provide implementation of * the {@link #invoke(Process, Object[]) invoke()} method. * <p> * Primitive types must be wrapped to the following classes: * </p> * <table border="1"> * <thead> * <th>Native type</th> <th>Wrapper class</th> * </thead> * <tbody> * <tr> * <td><code>boolean, byte, short, char, int</code></td> * <td><code>alchemy.types.Int32</code></td> * </tr> * <tr> * <td><code>long</code></td> * <td><code>alchemy.types.Int64</code></td> * </tr> * <tr> * <td><code>float</code></td> * <td><code>alchemy.types.Float32</code></td> * </tr> * <tr> * <td><code>double</code></td> * <td><code>alchemy.types.Float64</code></td> * </tr> * </tbody> * </table> * <p> * Functions should properly handle exceptional cases. * Any runtime exceptions should be wrapped in * AlchemyException class. The function is also supposed * to put itself in a stack trace using * {@link AlchemyException#addTraceElement(Function, String) }. * If debugging information is available, second argument should * be in form <i>source:line</i> otherwise it can be any information * helpful in debugging. A typical exception handling: * <pre> * Object invoke(Process p, Object[] args) throws AlchemyException { * try { * // function body * ... * } catch (AlchemyException e) { * e.addTraceElement(this.name, debugString); * throw e; * } catch (Throwable t) { * AlchemyException e = new AlchemyException(t); * e.addTraceElement(this.name, debugString); * throw e; * } * } * </pre> * * @author Sergey Basalaev */ public abstract class Function { /** Function signature. */ public final String name; /** Owner of this function. */ public final Library library; /** * Constructor for subclasses. * @param library owner library, may be null if this function is generated in runtime * @param name function name */ protected Function(Library library, String name) { if (name == null) throw new NullPointerException(); this.name = name; this.library = library; } /** * Invokes this function. * @param p calling process * @param args function arguments * @return function result * @throws AlchemyException if an exception occurs * @throws ProcessKilledException if the process was killed */ public abstract Object invoke(Process p, Object[] args) throws AlchemyException, ProcessKilledException; /** * Returns string representation of this object. * This method returns string in form * <pre> * libraryname:functionname * </pre> */ public final String toString() { return ((library != null && library.name != null) ? library.name : "<dynamic>") + ':' + name; } }