📄 codeexpression.java
字号:
private static void printCE(CodeExpression ce) { System.out.print("\"" + ce.getExpr() + "\"\t"); if (ce.dependsOnEverything) System.out.print(" ALL"); for (Variable.Key varKey: ce.dependsOn()) System.out.print(" " + varKey); if (ce.parseException != null) System.out.print(" ? " + ce.parseException.getMessage()); else System.out.print(" -> \"" + ce.spiceText + "\""); System.out.println(); } private static class EvalContext { private Object getDrive() { return null; } private Object subDrive(String instName, String varName) { return null; } private Object get(Variable.Key varKey) { return null; } } private static abstract class Expr { static final int MIN_PRECEDENCE = 1; static final int MAX_PRECEDENCE = EvalSpice.Op.COND.precedence; int numSubExprs() { return 0; } Expr getSubExpr(int i) { throw new IndexOutOfBoundsException(); } void appendText(StringBuilder sb, int outerPrecedence) { if (outerPrecedence < precedence()) { sb.append('('); appendText(sb); sb.append(')'); } else { appendText(sb); } } abstract void appendText(StringBuilder sb); int precedence() { return MIN_PRECEDENCE; } boolean dependsOnEverything() { for (int i = 0; i < numSubExprs(); i++) { if (getSubExpr(i).dependsOnEverything()) return true; } return false; } abstract Object eval(EvalContext context); static boolean bool(double d) { return d != 0; } } private static class ConstExpr extends Expr { private final Object value; ConstExpr(Object value) { this.value = value; } void appendText(StringBuilder sb) { String s = TextUtils.formatDoublePostFix(((Double)value).doubleValue()); sb.append(s); } Object eval(EvalContext context) { return value; } } private static class VarExpr extends Expr { private final Variable.Key varKey; VarExpr(Variable.Key varKey) { if (varKey == null) throw new NullPointerException(); this.varKey = varKey; } void appendText(StringBuilder sb) { String name = varKey.getName(); if (name.startsWith("ATTR_")) name = name.substring(5); sb.append(name); } Object eval(EvalContext context) { return context.get(varKey); } } private static class GetDriveExpr extends Expr { GetDriveExpr() { } void appendText(StringBuilder sb) { sb.append("LE.getdrive()"); } boolean dependsOnEverything() { return true; } Object eval(EvalContext context) { return context.getDrive(); } } private static class SubDriveExpr extends Expr { private final String instName, varName; SubDriveExpr(String instName, String varName) { this.instName = instName; this.varName = varName; } void appendText(StringBuilder sb) { sb.append("LE.subdrive(\"" + instName +"\",\"" + varName + "\")"); } boolean dependsOnEverything() { return true; } Object eval(EvalContext context) { return context.subDrive(instName, varName); } } private static abstract class UnaryExpr extends Expr { final Expr s; UnaryExpr(Expr s) { this.s = s; } int numSubExprs() { return 1; } Expr getSubExpr(int i) { if (i == 0) return s; return super.getSubExpr(i); } Object eval(EvalContext context) { double v = ((Number)s.eval(context)).doubleValue(); return Double.valueOf(apply(v)); } abstract double apply(double v); } private static class UnaryOpExpr extends UnaryExpr { private static final String opName = EvalSpice.Op.MINUS.name; private static final int opPrecedence = MIN_PRECEDENCE; UnaryOpExpr(Expr s) { super(s); } void appendText(StringBuilder sb) { sb.append(opName); s.appendText(sb, opPrecedence); } int precedence() { return opPrecedence; } double apply(double v) { return -v; } } private static class UnaryFunExpr extends UnaryExpr { enum Fun { sin, abs, sqrt, int_; @Override public String toString() { return this == int_ ? "int" : super.toString(); } }; private final Fun fun; UnaryFunExpr(Fun fun, Expr s) { super(s); this.fun = fun; } void appendText(StringBuilder sb) { sb.append(fun); sb.append('('); s.appendText(sb, MAX_PRECEDENCE); sb.append(')'); } double apply(double v) { switch (fun) { case sin: return Math.sin(v); case abs: return Math.abs(v); case sqrt: return Math.sqrt(v); case int_: return (int)v; } throw new AssertionError(); } } private static abstract class BinaryExpr extends Expr { final Expr ls, rs; BinaryExpr(Expr ls, Expr rs) { this.ls = ls; this.rs = rs; } int numSubExprs() { return 2; } Expr getSubExpr(int i) { if (i == 0) return ls; if (i == 1) return rs; return super.getSubExpr(i); } Object eval(EvalContext context) { double lv = ((Double)ls.eval(context)).doubleValue(); double rv = ((Double)rs.eval(context)).doubleValue(); return Double.valueOf(apply(lv, rv)); } abstract double apply(double lv, double rv); } private static class BinaryOpExpr extends BinaryExpr { private final EvalSpice.Op op; BinaryOpExpr(Expr ls, EvalSpice.Op op, Expr rs) { super(ls, rs); this.op = op; } void appendText(StringBuilder sb) { ls.appendText(sb, op.precedence); sb.append(op.name); rs.appendText(sb, op.precedence - 1); } int precedence() { return op.precedence; } double apply(double lv, double rv) { if (op == EvalSpice.Op.MULT) return lv * rv; if (op == EvalSpice.Op.DIV) return lv / rv; if (op == EvalSpice.Op.PLUS) return lv + rv; if (op == EvalSpice.Op.MINUS) return lv - rv; if (op == EvalSpice.Op.LT) return valueOf(lv < rv); if (op == EvalSpice.Op.LTOE) return valueOf(lv <= rv); if (op == EvalSpice.Op.GT) return valueOf(lv > rv); if (op == EvalSpice.Op.GTOE) return valueOf(lv >= rv); if (op == EvalSpice.Op.EQ) return valueOf(lv == rv); if (op == EvalSpice.Op.NE) return valueOf(lv != rv); if (op == EvalSpice.Op.LAND) return valueOf(bool(lv) && bool(rv)); if (op == EvalSpice.Op.LOR) return valueOf(bool(lv) || bool(rv)); throw new AssertionError(); } private static double valueOf(boolean b) { return b ? 1 : 0; } } private static class BinaryFunExpr extends BinaryExpr { enum Fun { min, max }; private final Fun fun; BinaryFunExpr(Fun fun, Expr ls, Expr rs) { super(ls, rs); this.fun = fun; } void appendText(StringBuilder sb) { sb.append(fun); sb.append('('); ls.appendText(sb, MAX_PRECEDENCE); sb.append(','); rs.appendText(sb, MAX_PRECEDENCE); sb.append(')'); } double apply(double lv, double rv) { switch (fun) { case min: return Math.min(lv, rv); case max: return Math.max(lv, rv); } throw new AssertionError(); } } private static class IfThenElseExpr extends Expr { private static final int precedence = MAX_PRECEDENCE; final Expr condS, thenS, elseS; IfThenElseExpr(Expr condS, Expr thenS, Expr elseS) { this.condS = condS; this.thenS = thenS; this.elseS = elseS; } int numSubExprs() { return 3; } Expr getSubExpr(int i) { if (i == 0) return condS; if (i == 1) return thenS; if (i == 2) return elseS; return super.getSubExpr(i); } void appendText(StringBuilder sb) { condS.appendText(sb, precedence - 1); sb.append('?'); thenS.appendText(sb, precedence - 1); sb.append(':'); elseS.appendText(sb, precedence); } int precedence() { return MAX_PRECEDENCE; } Object eval(EvalContext context) { boolean condV = bool(((Double)condS.eval(context)).doubleValue()); double v = ((Double)(condV ? thenS : elseS).eval(context)).doubleValue(); return Double.valueOf(v); } } static Expr parse(String expr, boolean isJava) throws EvalSpice.ParseException { return new ParseSpice_(expr, isJava).parse(); } static class ParseSpice_ { private String expr; private boolean isJava; private StringReader reader; private StreamTokenizer tokenizer; EvalSpice.Op op; private ParseSpice_(String expr, boolean isJava) { this.expr = expr; this.isJava = isJava; reader = new StringReader(expr);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -