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

prompto.expression.SliceExpression Maven / Gradle / Ivy

The newest version!
package prompto.expression;

import java.util.HashMap;
import java.util.Map;

import prompto.compiler.Flags;
import prompto.compiler.ISlicerFunction;
import prompto.compiler.MethodInfo;
import prompto.compiler.ResultInfo;
import prompto.error.NullReferenceError;
import prompto.error.PromptoError;
import prompto.error.SyntaxError;
import prompto.intrinsic.PromptoList;
import prompto.intrinsic.PromptoRange;
import prompto.runtime.Context;
import prompto.transpiler.Transpiler;
import prompto.type.IType;
import prompto.type.IntegerType;
import prompto.type.ListType;
import prompto.type.RangeType;
import prompto.type.TextType;
import prompto.utils.CodeWriter;
import prompto.value.ISliceable;
import prompto.value.IValue;
import prompto.value.IntegerValue;

public class SliceExpression extends SelectorBase {

	IExpression first;
	IExpression last;
	
	public SliceExpression(IExpression first, IExpression last) {
		this.first = first;
		this.last = last;
	}
	
	public SliceExpression(IExpression parent, IExpression first, IExpression last) {
		super(parent);
		this.first = first;
		this.last = last;
	}

	public IExpression getFirst() {
		return first;
	}
	
	public IExpression getLast() {
		return last;
	}

	@Override
	public void toDialect(CodeWriter writer) {
		parent.toDialect(writer);
		writer.append('[');
		if(first!=null)
			first.toDialect(writer);
		writer.append(':');
		if(last!=null)
			last.toDialect(writer);
		writer.append(']');
	}
	
	@Override
	public IType check(Context context) {
		IType firstType = first!=null ? first.check(context) : null;
		IType lastType = last!=null ? last.check(context) : null;
		if(firstType!=null && !(firstType instanceof IntegerType))
			throw new SyntaxError(firstType.toString() + " is not an integer");
		if(lastType!=null && !(lastType instanceof IntegerType))
			throw new SyntaxError(lastType.toString() + " is not an integer");
		IType parentType = parent.check(context);
		return parentType.checkSlice(context);
	}
	
	@Override
	public IValue interpret(Context context) throws PromptoError {
        IValue o = parent.interpret(context);
        if (o == null)
            throw new NullReferenceError();
        ISliceable sliceable = o.asSliceable(context);
        if (sliceable!=null)
        {
            Object fi = first != null ? first.interpret(context) : null;
            if (fi != null && !(fi instanceof IntegerValue))
                throw new SyntaxError("Illegal sliced type: " + fi);
            Object li = last != null ? last.interpret(context) : null;
            if (li != null && !(li instanceof IntegerValue))
                throw new SyntaxError("Illegal sliced type: " + li);
            return sliceable.slice((IntegerValue)fi, (IntegerValue)li);
        }
        else
			throw new SyntaxError("Illegal sliced object: " + parent);
	}

	static Map, ISlicerFunction> slicers = createSlicers();
	
	private static Map, ISlicerFunction> createSlicers() {
		Map, ISlicerFunction> map = new HashMap<>(); 
		map.put(String.class, TextType::compileSlice); 
		map.put(PromptoRange.Character.class, RangeType::compileSlice);
		map.put(PromptoRange.Date.class, RangeType::compileSlice);
		map.put(PromptoRange.Time.class, RangeType::compileSlice);
		map.put(PromptoRange.Long.class, RangeType::compileSlice);
		/*map.put(PromptoTuple.class, RangeBase::compileSlice)*/;
		map.put(PromptoList.class, ListType::compileSlice);
		return map;
	}

	@Override
	public ResultInfo compile(Context context, MethodInfo method, Flags flags, boolean asParent) {
		ResultInfo pinfo = parent.compile(context, method, flags.withPrimitive(false));
		ISlicerFunction slicer = slicers.get(pinfo.getType());
		if(slicer==null) {
			System.err.println("Missing ISlicerFunction for slice " + pinfo.getType().getTypeName());
			throw new SyntaxError("Cannot slice " + pinfo.getType().getTypeName());
		}
		return slicer.compile(context, method, flags, pinfo, first, last);
	}
	
	@Override
	public void declare(Transpiler transpiler) {
	    this.parent.declare(transpiler);
	    IType parentType = this.parent.check(transpiler.getContext());
	    parentType.declareSlice(transpiler, this.first, this.last);
	}
	
	@Override
	public boolean transpile(Transpiler transpiler) {
	    this.parent.transpile(transpiler);
	    IType parentType = this.parent.check(transpiler.getContext());
	    parentType.transpileSlice(transpiler, this.first, this.last);
	    return false;
	}

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy