⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 codeexpression.java

📁 The ElectricTM VLSI Design System is an open-source Electronic Design Automation (EDA) system that c
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
/* -*- tab-width: 4 -*- * * Electric(tm) VLSI Design System * * File: CodeExpression.java * Written by: Dmitry Nadezhin, Sun Microsystems. * * Copyright (c) 2008 Sun Microsystems and Static Free Software * * Electric(tm) 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. * * Electric(tm) 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 Electric(tm); see the file COPYING.  If not, write to * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, Mass 02111-1307, USA. */package com.sun.electric.database.variable;import com.sun.electric.database.EObjectInputStream;import com.sun.electric.database.EObjectOutputStream;import com.sun.electric.database.id.IdReader;import com.sun.electric.database.id.IdWriter;import com.sun.electric.database.text.ArrayIterator;import com.sun.electric.database.text.TextUtils;import java.io.IOException;import java.io.Serializable;import java.io.StreamTokenizer;import java.io.StringReader;import java.util.Collections;import java.util.HashMap;import java.util.Iterator;import java.util.Set;import java.util.TreeMap;import java.util.TreeSet;import java.util.regex.Matcher;import java.util.regex.Pattern;/** * Class encapsulate expression in Java-like or Spice-like syntax */public class CodeExpression implements Serializable {    // Variable flags in C Electric	/** variable is interpreted code (with VCODE2) */	private static final int VCODE1 =                040;	/** variable is interpreted code (with VCODE1) */	private static final int VCODE2 =        04000000000;	/** variable is LISP */								private static final int VSPICE =             VCODE1;	/** variable is TCL */								private static final int VTCL =               VCODE2;	/** variable is Java */								private static final int VJAVA =      (VCODE1|VCODE2);    private static final HashMap <String,CodeExpression> javaExpressions = new HashMap<String,CodeExpression>();    private static final HashMap <String,CodeExpression> spiceExpressions = new HashMap<String,CodeExpression>();    private static final HashMap <String,CodeExpression> tclExpressions = new HashMap<String,CodeExpression>();    private static long numValueOfs;    /** For replacing @variable */ private static final Pattern pPat = Pattern.compile("P\\(\"(\\w+)\"\\)");    private final Code code;    private final String expr;    private final Set<Variable.Key> depends;    private final Expr exprTree;    private final boolean dependsOnEverything;    private final EvalSpice.ParseException parseException;    private final String spiceText;    private final String spiceTextPar;    /**     * The type of Code that determines how this Variable's     * value should be evaluated. If NONE, no evaluation is done.     */    public static enum Code {        /** Indicator that code is in Java. */	JAVA("Java", VJAVA),		/** Indicator that code is in Lisp. */	SPICE("Spice", VSPICE),		/** Indicator that code is in TCL. */	TCL("TCL (not avail.)", VTCL),		/** Indicator that this is not code. */	NONE("Not Code", 0);        private final String name;        private final int cFlags;        private static final Code[] allCodes = Code.class.getEnumConstants();        private Code(String name, int cFlags) {            this.name = name;            this.cFlags = cFlags;        }		/**		 * Method to return the bits value of this code type.		 * This is used in I/O.		 * @return the bits value of this code type.		 */        public int getCFlags() { return cFlags; }		/**		 * Method to return a printable version of this Code.		 * @return a printable version of this Code.		 */        public String toString() { return name; }        /**         * Method to get an iterator over all Code types.         */        public static Iterator<Code> getCodes() { return ArrayIterator.iterator(allCodes); }		/**		 * Method to convert a bits value to a Code object.		 * @param cBits the bits value (from I/O).		 * @return the Code associated with those bits.		 */        public static Code getByCBits(int cBits)        {            switch (cBits & (VCODE1|VCODE2))            {                case VJAVA: return JAVA;                case VSPICE: return SPICE;                case VTCL: return TCL;                default: return NONE;            }        }		/**		 * Method to get a Code constant by its ordinal number.		 * @param ordinal the ordinal number of this Code constant ( as returned by ordinal()		 * @return the Code associated with this ordinal number.		 */        public static Code getByOrdinal(int ordinal)        {            return allCodes[ordinal];        }    }    private CodeExpression(String expr, Code code) {        this.code = code;        this.expr = expr;        TreeSet<Variable.Key> varKeys = new TreeSet<Variable.Key>();        String replacedExpr = EvalJavaBsh.replace(expr);        Matcher pMat = pPat.matcher(replacedExpr);        while (pMat.find()) {            String varName = pMat.group(1);            varKeys.add(Variable.newKey(varName));        }        depends = Collections.unmodifiableSet(varKeys);        String patchedExpr = expr.replace("((Number)@X).doubleValue()", "@X");        Expr exprTree = null;        EvalSpice.ParseException parseException = null;        try {            switch (code) {                case JAVA: exprTree = parse(patchedExpr, true); break;                case SPICE: exprTree = parse(patchedExpr, false); break;                default: throw new EvalSpice.ParseException("Unsupported code " + code);            }        } catch (EvalSpice.ParseException e) {            parseException = e;        }        this.exprTree = exprTree;        this.parseException = parseException;        if (parseException != null) {            dependsOnEverything = true;            spiceTextPar = spiceText = parseException.getMessage();        } else {            dependsOnEverything = exprTree.dependsOnEverything();            StringBuilder sb = new StringBuilder();            exprTree.appendText(sb);            spiceText = new String(sb);            sb.setLength(0);            exprTree.appendText(sb, Expr.MIN_PRECEDENCE);            spiceTextPar = new String(sb);        }     }    private Object writeReplace() { return new CodeExpressionKey(this); }    private static class CodeExpressionKey extends EObjectInputStream.Key<CodeExpression> {        public CodeExpressionKey() {}        private CodeExpressionKey(CodeExpression ce) { super(ce); }        @Override        public void writeExternal(EObjectOutputStream out, CodeExpression ce) throws IOException {            out.writeUTF(ce.getExpr());            out.writeByte(ce.getCode().ordinal());        }        @Override        public CodeExpression readExternal(EObjectInputStream in) throws IOException, ClassNotFoundException {            String expr = in.readUTF();            Code code = Code.getByOrdinal(in.readByte());            return valueOf(expr, code);        }    }    public static synchronized CodeExpression valueOf(String expression, Code code) {        numValueOfs++;        HashMap<String,CodeExpression> allExpressions;        switch (code) {            case JAVA: allExpressions = javaExpressions; break;            case SPICE: allExpressions = spiceExpressions; break;            case TCL: allExpressions = tclExpressions; break;            default: throw new IllegalArgumentException("code");        }        CodeExpression ce = allExpressions.get(expression);        if (ce == null) {            ce = new CodeExpression(expression, code);            allExpressions.put(expression, ce);        }        return ce;    }    public Code getCode() { return code; }    public boolean isJava() { return code == Code.JAVA; }    public String getExpr() { return expr; }    public Set<Variable.Key> dependsOn() { return depends; }    public EvalSpice.ParseException getParseException() { return parseException; }    public String getSpiceText() { return spiceText; }    public String getHSpiceText(boolean inPar) {        return dependsOnEverything ? null : inPar ? spiceTextPar : spiceText;    }    public String getVerilogText() { return spiceText; }    public Object eval() {        if (parseException != null)            return parseException.getMessage();        return exprTree.eval(new EvalContext());    }    @Override    public int hashCode() {        return expr.hashCode();    }    @Override    public boolean equals(Object o) {        if (o instanceof CodeExpression) {            CodeExpression that = (CodeExpression)o;            return this.code == that.code && this.expr.equals(that.expr);        }        return false;    }    @Override    public String toString() { return expr; }    /**     * Write this CodeExpression to IdWriter.     * @param writer where to write.     */    public void write(IdWriter writer) throws IOException {        writer.writeString(expr);        writer.writeByte((byte)code.ordinal());    }    /**     * Read CodeExpression from SnapshotReader.     * @param reader from to write.     */    public static CodeExpression read(IdReader reader) throws IOException {        String expr = reader.readString();        Code code = Code.getByOrdinal(reader.readByte());        return valueOf(expr, code);    }    void check() {        assert expr != null;        assert code != null && code != Code.NONE;    }    /**     * Print statistics about CodeExpressions.     * @param verbose print all CodeExpressions     */    public static void printStatistics(boolean verbose) {        System.out.println((javaExpressions.size() + spiceExpressions.size() + tclExpressions.size()) +                " CodeExpressions after " + numValueOfs + " valueOf calls");        if (!verbose) return;        System.out.println(javaExpressions.size() + " java strings");        for (CodeExpression ce: new TreeMap<String,CodeExpression>(javaExpressions).values())            printCE(ce);        System.out.println(spiceExpressions.size() + " spice strings");        for (CodeExpression ce: new TreeMap<String,CodeExpression>(spiceExpressions).values())            printCE(ce);        System.out.println(tclExpressions.size() + " tcl strings");        for (CodeExpression ce: new TreeMap<String,CodeExpression>(tclExpressions).values())            printCE(ce);    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -