All Downloads are FREE. Search and download functionalities are using the official Maven repository.

prompto.expression.UnresolvedIdentifier Maven / Gradle / Ivy

The newest version!
package prompto.expression;

import prompto.compiler.Flags;
import prompto.compiler.MethodInfo;
import prompto.compiler.ResultInfo;
import prompto.compiler.StackLocal;
import prompto.declaration.AttributeDeclaration;
import prompto.declaration.IDeclaration;
import prompto.declaration.IEnumeratedDeclaration;
import prompto.declaration.SingletonCategoryDeclaration;
import prompto.error.PromptoError;
import prompto.error.SyntaxError;
import prompto.grammar.Identifier;
import prompto.parser.CodeSection;
import prompto.parser.Dialect;
import prompto.parser.ICodeSection;
import prompto.problem.IProblemListener;
import prompto.problem.ProblemRaiser;
import prompto.runtime.Context;
import prompto.statement.MethodCall;
import prompto.store.AttributeInfo;
import prompto.store.IQueryBuilder;
import prompto.store.IStore;
import prompto.transpiler.Transpiler;
import prompto.type.AnyType;
import prompto.type.CategoryType;
import prompto.type.IType;
import prompto.utils.CodeWriter;
import prompto.utils.StoreUtils;
import prompto.value.IValue;

public class UnresolvedIdentifier extends CodeSection implements IPredicate {

	Identifier id;
	IExpression resolved;
	
	public UnresolvedIdentifier(Identifier id) {
		this.id = id;
	}
	
	public IExpression getResolved() {
		return resolved;
	}

	public Identifier getId() {
		return id;
	}
	
	public String getName() {
		return id.toString();
	}
	
	@Override
	public String toString() {
		return id.toString();
	}
	
	@Override
	public void toDialect(CodeWriter writer) {
		try {
			resolve(writer.getContext(), false, false);
		} catch(SyntaxError e) {
		}
		if(resolved!=null)
			resolved.toDialect(writer);
		else
			writer.append(id);
	}
	
	@Override
	public AttributeDeclaration checkAttribute(Context context, ICodeSection section) {
		AttributeDeclaration decl = context.findAttribute(id.toString());
		if(decl==null)
			context.getProblemListener().reportMissingAttribute(this, this.toString());
		return decl;
	}
	
	@Override
	public AttributeInfo checkAttributeInfo(Context context, ICodeSection section, IStore store) {
		return StoreUtils.getAttributeInfo(context, id.toString(), store);
	}

	@Override
	public IType check(Context context) {
		return resolveAndCheck(context, false);
	}
	
	@Override
	public IType checkReference(Context context) {
		resolve(context, false, false);
		return resolved!=null ? resolved.checkReference(context) : AnyType.instance();
	}
	
	@Override
	public void checkQuery(Context context) throws PromptoError {
		resolveAndCheck(context, false);
		if(resolved instanceof IPredicate)
			((IPredicate)resolved).checkQuery(context);
		else
			context.getProblemListener().reportIllegalPredicate(this, this);
	}
	
	public IType checkMember(Context context) {
		return resolveAndCheck(context, true);
	}
	
	@Override
	public IValue interpret(Context context) throws PromptoError {
		resolveAndCheck(context, false);
		return resolved.interpret(context);
	}
	
	@Override
	public IValue interpretReference(Context context) {
		resolve(context, false, false);
		return resolved.interpretReference(context);
	}
	
	
	@Override
	public void interpretQuery(Context context, IQueryBuilder query, IStore store) throws PromptoError {
		resolveAndCheck(context, false);
		if(resolved instanceof IPredicate)
			((IPredicate)resolved).interpretQuery(context, query, store);
		else
			throw new SyntaxError("Filtering expression must be a predicate !");
	}
	
	@Override
	public ResultInfo compile(Context context, MethodInfo method, Flags flags) {
		resolveAndCheck(context, false);
		return resolved.compile(context, method, flags);
	}
	
	@Override
	public ResultInfo compileReference(Context context, MethodInfo method, Flags flags) {
		StackLocal local = method.getRegisteredLocal(getName());
		if(local!=null) {
			return new InstanceExpression(id).compile(context, method, flags);
			
		} else
			return compile(context, method, flags);
	}
	
	@Override
	public void compileQuery(Context context, MethodInfo method, Flags flags) {
		resolveAndCheck(context, false);
		if(resolved instanceof IPredicate)
			((IPredicate)resolved).compileQuery(context, method, flags);
		else
			IPredicate.super.compileQuery(context, method, flags);
	}
	
	private IType resolveAndCheck(Context context, boolean forMember) {
		resolve(context, forMember, false);
		return resolved!=null ? resolved.check(context) : AnyType.instance();
	}

	public IExpression resolve(Context context, boolean forMember, boolean updateSelectorParent) {
		if(resolved==null) {
			final IProblemListener saved = context.getProblemListener(); 
			context.pushProblemListener(new ProblemRaiser() { @Override public boolean isCheckNative() { return saved.isCheckNative(); } });
			try {
				resolved = doResolve(context, forMember, updateSelectorParent);
			} finally {
				context.popProblemListener();
			}
			if(resolved==null)
				context.getProblemListener().reportUnknownIdentifier(this, id.toString());
			else if(resolved instanceof ICodeSection)
				((ICodeSection)resolved).setSectionFrom(this);
		}
		return resolved;
	}

	private IExpression doResolve(Context context, boolean forMember, boolean updateSelectorParent) {
		IExpression resolved = resolveSymbol(context);
		if(resolved!=null)
			return resolved;
		resolved = resolveTypeOrConstructor(context, forMember);
		if(resolved!=null)
			return resolved;
		resolved = resolveMethodCall(context, updateSelectorParent);
		if(resolved!=null)
			return resolved;
		resolved = resolveInstance(context);
		if(resolved!=null)
			return resolved;
		return null;
	}

	private IExpression resolveTypeOrConstructor(Context context, boolean forMember) {
		if(Character.isUpperCase(id.toString().charAt(0)))
			return resolveTypeOrConstructor(context);
		else
			return null;
	}

	private IExpression resolveTypeOrConstructor(Context context) {
		try {
			CategoryType type = new CategoryType(id);
			IDeclaration decl = type.getDeclaration(context);
			if(decl instanceof SingletonCategoryDeclaration || decl instanceof IEnumeratedDeclaration)
				return new TypeExpression(type);
			else {
				IExpression method = new ConstructorExpression(type, null, null);
				method.check(context);
				return method;
			}
		} catch(SyntaxError e) {
			// ignore resolution errors
			return null;
		}
	}

	private IExpression resolveInstance(Context context) {
		try {
			InstanceExpression exp = new InstanceExpression(id);
			exp.check(context);
			return exp;
		} catch(SyntaxError e) {
			// ignore resolution errors
			return null;
		}
	}

	private IExpression resolveMethodCall(Context context, boolean updateSelectorParent) {
		if(id.getDialect()!=Dialect.E)
			return null;
		try {
			MethodCall method = new MethodCall(new MethodSelector(id));
			method.setSectionFrom(this);
			method.check(context, updateSelectorParent);
			return method;
		} catch(SyntaxError e) {
			// ignore resolution errors
			return null;
		}
	}

	private IExpression resolveSymbol(Context context) {
		if(id.toString().equals(id.toString().toUpperCase()))
			return new SymbolExpression(id);
		else
			return null;
	}

	@Override
	public void declare(Transpiler transpiler) {
	    resolve(transpiler.getContext(), false, true);
	    resolved.declare(transpiler);
	}
	
	@Override
	public boolean transpile(Transpiler transpiler) {
	    resolve(transpiler.getContext(), false, true);
	    return resolved.transpile(transpiler);
	}
	
	@Override
	public void declareQuery(Transpiler transpiler) {
	    resolve(transpiler.getContext(), false, true);
	    if(resolved instanceof IPredicate)
	    	((IPredicate)resolved).declareQuery(transpiler);
	    else
	    	transpiler.getContext().getProblemListener().reportIllegalPredicate(id, this);
	}
	
	@Override
	public void transpileQuery(Transpiler transpiler, String builderName) {
	    resolve(transpiler.getContext(), false, true);
	    if(resolved instanceof IPredicate)
	    	((IPredicate)resolved).transpileQuery(transpiler, builderName);
	    else
	    	transpiler.getContext().getProblemListener().reportIllegalPredicate(id, this);
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy