/* * 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 java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Stack; public class CFDG { private List<ShapeType> shapeTypes = new ArrayList<ShapeType>(); private Map<Integer, ASTDefine> functions = new HashMap<Integer, ASTDefine>(); private Stack<ASTRule> rules = new Stack<ASTRule>(); private Map<ECFGParam, Integer> paramDepth = new HashMap<ECFGParam, Integer>(); private Map<ECFGParam, ASTExpression> paramExp = new HashMap<ECFGParam, ASTExpression>(); private int parameters; private boolean usesColor; private boolean usesAlpha; private boolean uses16bitColor; private boolean usesTime; private boolean usesFrameTime; public int encodeShapeName(String s) { int i = tryEncodeShapeName(s); if (i >= 0) return i; shapeTypes.add(new ShapeType(s)); return shapeTypes.size() - 1; } public int tryEncodeShapeName(String s) { for (int i = 0; i < shapeTypes.size(); i++) { if (s.equals(shapeTypes.get(i).getName())) { return i; } } return -1; } public String decodeShapeName(int shape) { if (shape < shapeTypes.size()) { return shapeTypes.get(shape).getName(); } else { return "**unnamed shape**"; } } public ASTDefine findFunction(int index) { ASTDefine def = functions.get(index); if (def != null) { return def; } return null; } public String setShapeParams(int nameIndex, ASTRepContainer p, int argSize, boolean isPath) { ShapeType type = shapeTypes.get(nameIndex); if (type.isShape()) { if (p.getParameters().isEmpty()) { return "Shape has already been declared. Parameter declaration must be on the first shape declaration only"; } if (type.getShapeType() == EShapeType.PathType && !isPath) { return "Shape name already in use by another rule or path"; } if (isPath) { return "Path name already in use by another rule or path"; } return null; } if (type.getShapeType() != EShapeType.NewShape) { return "Shape name already in use by another rule or path"; } type.getParameters().clear(); type.getParameters().addAll(p.getParameters()); type.setIsShape(true); type.setArgSize(argSize); type.setShapeType(isPath ? EShapeType.PathType : EShapeType.NewShape); return null; } public boolean addRuleShape(ASTRule rule) { rules.push(rule); ShapeType type = shapeTypes.get(rule.getNameIndex()); if (type.getShapeType() == EShapeType.NewShape) { type.setShapeType(rule.isPath() ? EShapeType.PathType : EShapeType.RuleType); } if (!type.getParameters().isEmpty()) { rule.getRuleBody().getParameters().clear(); rule.getRuleBody().getParameters().addAll(type.getParameters()); } type.setHasRules(true); return type.isShape(); } public EShapeType getShapeType(int nameIndex) { return shapeTypes.get(nameIndex).getShapeType(); } public EShapeType getShapeType(String name) { for (int i = 0; i < shapeTypes.size(); i++) { if (shapeTypes.get(i).getName().equals(name)) { return shapeTypes.get(i).getShapeType(); } } return EShapeType.NewShape; } public ASTDefine declareFunction(int nameIndex, ASTDefine def) { ASTDefine prev = findFunction(nameIndex); if (prev != null) { return prev; } functions.put(nameIndex, def); return def; } public List<ASTParameter> getShapeParams(int nameIndex) { if (nameIndex < 0 || nameIndex >= shapeTypes.size() || !shapeTypes.get(nameIndex).isShape()) { return null; } return shapeTypes.get(nameIndex).getParameters(); } public ASTRule findRule(int nameIndex) { for (ASTRule rule: rules) { if (rule.getNameIndex() == nameIndex) { return rule; } } return null; } public boolean hasParameter(ECFGParam p, double[] value, RTI rti) { ASTExpression exp = hasParameter(p); if (exp == null || exp.getType() != EExpType.NumericType) { return false; } if (!exp.isConstant() && rti != null) { error("This expression must be constant"); return false; } else { exp.evaluate(value, 1, rti); } return true; } public boolean hasParameter(ECFGParam p, Modification[] value, RTI rti) { ASTExpression exp = hasParameter(p); if (exp == null || exp.getType() != EExpType.ModType) { return false; } if (!exp.isConstant() && rti != null) { error("This expression must be constant"); return false; } else { exp.evaluate(value, false, rti);//TODO controllare } return true; } public boolean hasParameter(ECFGParam p, EExpType type) { ASTExpression exp = hasParameter(p); if (exp == null || exp.getType() != type) { return false; } return true; } public ASTExpression hasParameter(ECFGParam p) { if (paramDepth.get(p).intValue() == -1) { return null; } return paramExp.get(p); } public boolean addParameter(String name, ASTExpression exp, int depth) { ECFGParam p = ECFGParam.valueOf(name); if (p == null) { return false; } if (depth < paramDepth.get(p)) { paramDepth.put(p, depth); paramExp.put(p, exp); } return true; } public void setShapeHasNoParam(int nameIndex, ASTExpression args) { if (nameIndex < shapeTypes.size() && args != null) { shapeTypes.get(nameIndex).setShouldHaveNoParams(true); } } public void addParameter(EParam param) { parameters |= param.getType(); usesColor = (parameters & EParam.Color.getType()) != 0; usesTime = (parameters & EParam.Time.getType()) != 0; usesFrameTime = (parameters & EParam.FrameTime.getType()) != 0; } protected void error(String message) { System.err.println(message); } }