All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.sf.beezle.mork.semantics.Attribution Maven / Gradle / Ivy

The newest version!
/*
 * Copyright 1&1 Internet AG, http://www.1and1.org
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation; either version 2 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 Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program.  If not, see .
 */

package net.sf.beezle.mork.semantics;

import net.sf.beezle.mork.grammar.Grammar;
import net.sf.beezle.mork.misc.StringArrayList;
import net.sf.beezle.mork.reflect.Function;
import net.sf.beezle.mork.scanner.Position;

import java.io.PrintStream;
import java.io.Serializable;
import java.lang.reflect.InvocationTargetException;

/**
 * Attribute function call.
 */
public class Attribution implements Serializable {
    private final Function function;

    // ofs -1: left hand side

    private final int resultOfs;
    private final int resultAttr;

    private final int[] argsOfs;
    private final int[] argsAttr;

    private final transient Object[] args;

    /**
     * Nonterminal attribution.
     * ofs = -1 for left hand side.
     */
    public Attribution(
        Function function, int resultOfs, int resultAttr, int[] argsOfs, int[] argsAttr)
    {
        this.function = function;
        this.resultOfs = resultOfs;
        this.resultAttr = resultAttr;
        this.argsOfs = argsOfs;
        this.argsAttr = argsAttr;
        this.args = new Object[argsOfs.length];
    }

    /**
     * Caution: do not call this method concurrently!
     *
     * @param ctx  left-hand-side node
     */
    public void eval(Node ctx, PrintStream verbose) throws SemanticError {
        Object result;
        int i;
        Throwable t;
        Position pos;

        for (i = 0; i < args.length; i++) {
            args[i] = ctx.get(argsOfs[i]).attrs[argsAttr[i]];
        }
        try {
            result = function.invoke(args);
        } catch (InvocationTargetException e) {
            t = e.getTargetException();
            if (t instanceof RuntimeException) {
                throw (RuntimeException) t;
            }
            if (t instanceof Error) {
                throw (Error) t;
            }
            if (t instanceof Exception) {
                if (verbose != null) {
                    log("[FAILURE]", verbose);
                }
                pos = new Position();
                pos.set(ctx.position);
                throw new SemanticError(pos, (Exception) t);
            }
            throw new RuntimeException("illegal exception type: " + t);
        }
        ctx.get(resultOfs).attrs[resultAttr] = result;
        if (verbose != null) {
            log(result, verbose);
        }
    }

    /**
     * @param verbose != null
     */
    private void log(Object result, PrintStream verbose) {
        int i;

        verbose.print("attribution: ");
        verbose.print(shortName(result));
        verbose.print(" <- ");
        verbose.print(function.getName());
        verbose.print('(');
        for (i = 0; i < args.length; i++) {
            if (i > 0) {
                verbose.print(", ");
            }
            verbose.print(shortName(args[i]));
        }
        verbose.println(")");
    }

    private static String shortName(Object obj) {
        String clazz;
        int idx;

        if (obj == null) {
            return "null";
        } else {
            clazz = obj.getClass().getName();
            idx = clazz.lastIndexOf('.');
            clazz = clazz.substring(idx + 1); // ok for idx == -1
            return clazz + "#" + Integer.toHexString(obj.hashCode());
        }
    }

    @Override
    public String toString() {
        int i;
        StringBuilder buf;

        buf = new StringBuilder();
        buf.append(function.toString());
        buf.append(resultAttr);
        buf.append('$');
        buf.append(resultOfs);
        buf.append('(');
        for (i = 0; i < argsOfs.length; i++) {
            if (i > 0) {
                buf.append(", ");
            }
            buf.append(argsAttr[i] + "$" + argsOfs[i]);
        }
        buf.append(')');
        return buf.toString();
    }

    public String toString(StringArrayList symTab, Grammar grm) {
        StringBuilder buf;
        int i;

        buf = new StringBuilder();
        buf.append('\t');
        buf.append("" + function);
        buf.append("\n\t\t");
        buf.append(toStringRef(resultOfs, resultAttr));
        buf.append("\t<- ");
        for (i = 0; i < argsOfs.length; i++) {
            if (i > 0) {
                buf.append(", ");
            }
            buf.append(toStringRef(argsOfs[i], argsAttr[i]));
        }
        buf.append('\n');
        return buf.toString();
    }

    private static String toStringRef(int ofs, int attr) {
        return "($" + (ofs + 1) + ")." + attr;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy