package org.simantics.scl.compiler.elaboration.modules; import java.util.ArrayList; import java.util.List; import org.simantics.scl.compiler.common.names.Name; import org.simantics.scl.compiler.common.precedence.Precedence; import org.simantics.scl.compiler.constants.Constant; import org.simantics.scl.compiler.elaboration.contexts.SimplificationContext; import org.simantics.scl.compiler.elaboration.expressions.Expression; import org.simantics.scl.compiler.elaboration.macros.MacroRule; import org.simantics.scl.compiler.errors.Locations; import org.simantics.scl.compiler.internal.codegen.references.IVal; import org.simantics.scl.compiler.internal.codegen.utils.TransientClassBuilder; import org.simantics.scl.compiler.types.Type; import org.simantics.scl.compiler.types.util.Typed; /** * Information about SCL values that is needed in parsing * and elaboration phases. * @author Hannu Niemistö */ public final class SCLValue implements Typed { private static final int SIMPLIFIED = 1; private static final int INLINE_IN_SIMPLIFICATION = 2; private static final int FLAG_MASK = 0xffff; private Name name; private Type type; private Precedence precedence = Precedence.DEFAULT; private IVal value; private Expression expression; private MacroRule macroRule; private int flags = 0; private ArrayList properties = new ArrayList(2); public String documentation; public long definitionLocation = Locations.NO_LOCATION; public SCLValue(Name name) { this.name = name; } public SCLValue(Name name, Constant value) { this(name); setValue(value); } public Name getName() { return name; } public Type getType() { return type; } public void setType(Type type) { this.type = type; } public void addProperty(SCLValueProperty property) { properties.add(property); } public List getProperties() { return properties; } public Precedence getPrecedence() { return precedence; } public void setPrecedence(Precedence precedence) { this.precedence = precedence; } public IVal getValue() { return value; } public void setValue(IVal value) { this.value = value; if(type == null) type = value.getType(); } public Expression getExpression() { return expression; } public Expression getSimplifiedExpression(SimplificationContext context) { if(expression != null && (flags & SIMPLIFIED) == 0) { //System.out.println("Simplify: " + name); //System.out.println("BEFORE: " + expression); expression = expression.simplify(context); //System.out.println("AFTER: " + expression); flags |= SIMPLIFIED; } return expression; } public void setExpression(Expression expression) { this.expression = expression; } public MacroRule getMacroRule() { return macroRule; } public void setMacroRule(MacroRule macroRule) { this.macroRule = macroRule; } @Override public String toString() { return name.toString(); } private void setFlag(int flagMask, boolean value) { if(value) flags |= flagMask; else flags &= FLAG_MASK - flagMask; } public void setSimplified(boolean value) { setFlag(SIMPLIFIED, value); } public void setInlineInSimplification(boolean value) { setFlag(INLINE_IN_SIMPLIFICATION, value); } public boolean getInlineInSimplification() { return (flags & INLINE_IN_SIMPLIFICATION) != 0; } public Object realizeValue(TransientClassBuilder classLoader) { return getValue().realizeValue(classLoader); } public boolean isPrivate() { for(SCLValueProperty property : properties) if(property == PrivateProperty.INSTANCE) return true; return false; } public String isDeprecated() { for(SCLValueProperty property : properties) if(property instanceof DeprecatedProperty) return ((DeprecatedProperty)property).description; return null; } public void setDocumentation(String documentation) { this.documentation = documentation; } public String getDocumentation() { return documentation; } public boolean isPrivateOrDerived() { for(SCLValueProperty property : properties) if(property == PrivateProperty.INSTANCE || property == DerivedProperty.INSTANCE) return true; return false; } }