/* * JAME 6.2.1 * http://jame.sourceforge.net * * Copyright 2001, 2016 Andrea Medeghini * * This file is part of JAME. * * JAME is an application for creating fractals and other graphics artifacts. * * JAME 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. * * JAME 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 JAME. If not, see <http://www.gnu.org/licenses/>. * */ package net.sf.jame.contextfree.parser; import org.antlr.v4.runtime.Token; class ASTVariable extends ASTExpression { private String text; private int stringIndex; private int stackIndex; private int count; private boolean isParameter; public ASTVariable(int stringIndex, String text, Token location) { super(location); this.stringIndex = stringIndex; this.isParameter = false; this.stackIndex = 0; this.text = text; this.count = 0; } @Override public void entropy(StringBuilder e) { e.append(text); } @Override public ASTExpression compile(ECompilePhase ph) { switch (ph) { case TypeCheck: { boolean isGlobal = false; ASTParameter bound = Builder.currentBuilder().findExpression(stringIndex, isGlobal); if (bound == null) { error("internal error."); return null; } String name = Builder.currentBuilder().shapeToString(stringIndex); if (bound.getStackIndex() == -1) { ASTExpression ret = bound.constCopy(name); if (ret == null) { error("internal error."); } return ret; } else { if (bound.getType() == EExpType.RuleType) { ASTRuleSpecifier ret = new ASTRuleSpecifier(stringIndex, name, location); ret.compile(ph); return ret; } count = bound.getType() == EExpType.NumericType ? bound.getTupleSize() : 1; stackIndex = bound.getStackIndex() - (isGlobal ? 0: Builder.currentBuilder().getLocalStackDepth()); type = bound.getType(); isNatural = bound.isNatural(); locality = bound.getLocality(); isParameter = bound.isParameter(); } } break; case Simplify: break; default: break; } return null; } @Override public int evaluate(double[] result, int length, RTI rti) { if (type != EExpType.NumericType) { error("Non-numeric variable in a numeric context"); return -1; } if (result != null && length < count) { return -1; } if (result != null) { if (rti == null) throw new DeferUntilRuntimeException(); StackType stackItem = rti.stackItem(stackIndex); for (int i = 0; i < count; ++i) { result[i] = stackItem.getNumber(); } } return count; } @Override public void evaluate(Modification[] result, boolean shapeDest, RTI rti) { if (type != EExpType.ModType) { error("Non-adjustment variable referenced in an adjustment context"); } if (rti == null) throw new DeferUntilRuntimeException(); StackType stackItem = rti.stackItem(stackIndex); Modification mod = stackItem.modification(); if (shapeDest) { result[0].concat(mod); } else { if (result[0].merge(mod)) { rti.colorConflict(); } } } public String getText() { return text; } public int getStringIndex() { return stringIndex; } public int getStackIndex() { return stackIndex; } public int getCount() { return count; } public boolean isParameter() { return isParameter; } }