/*
* Copyright 2013 Guidewire Software, Inc.
*/
package gw.internal.gosu.parser;
import gw.internal.gosu.parser.expressions.ImplicitTypeAsExpression;
import gw.lang.parser.IExpression;
import gw.lang.reflect.IType;
import gw.lang.reflect.TypeSystem;
import gw.lang.reflect.gs.IExternalSymbolMap;
/**
* The root class for all Expressions represented in a parse tree as specified
* in the Gosu grammar.
*
* @see gw.lang.parser.IGosuParser
*/
public abstract class Expression extends ParsedElement implements IExpression
{
protected IType _type;
/**
* Returns this Expression's IType.
*/
public IType getType()
{
IType type = getTypeImpl();
if (TypeSystem.isDeleted(type)) {
type = TypeSystem.getErrorType();
}
return type;
}
protected IType getTypeImpl() {
return _type;
}
/**
* Sets this Expression's IType.
*/
public void setType( IType type )
{
_type = type;
}
@Override
public boolean isNullSafe()
{
return false;
}
@Override
public Object evaluate()
{
if( getGosuProgram() == null )
{
throw new IllegalStateException( "Expression was not compiled to bytecode" );
}
return getGosuProgram().evaluate( null );
}
@Override
public Object evaluate( IExternalSymbolMap externalSymbols )
{
if( !isCompileTimeConstant() )
{
if( getGosuProgram() == null )
{
throw new IllegalStateException( "Expression was not compiled to bytecode" );
}
return getGosuProgram().evaluate( externalSymbols );
}
else
{
return evaluate();
}
}
public IType getReturnType()
{
return getType();
}
/**
* Context type is the type this literal value evaluates as in the context
* of a containing expression e.g., given the expression, n == "42", the
* literal "42" is always converted to a Number. This feature is most useful
* for source code tools that provide source-sensitive help (e.g., rule composer).
*/
public IType getContextType()
{
if( getParent() instanceof ImplicitTypeAsExpression )
{
return ((Expression)getParent()).getType();
}
return getType();
}
/**
* Subclasses should return a String representing the parsed expression.
*/
public abstract String toString();
}