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

prompto.literal.TupleLiteral Maven / Gradle / Ivy

The newest version!
package prompto.literal;

import prompto.compiler.CompilerUtils;
import prompto.compiler.Flags;
import prompto.compiler.IOperand;
import prompto.compiler.MethodConstant;
import prompto.compiler.MethodInfo;
import prompto.compiler.Opcode;
import prompto.compiler.ResultInfo;
import prompto.error.PromptoError;
import prompto.expression.IExpression;
import prompto.intrinsic.PromptoTuple;
import prompto.runtime.Context;
import prompto.transpiler.Transpiler;
import prompto.type.IType;
import prompto.type.TupleType;
import prompto.utils.CodeWriter;
import prompto.utils.ExpressionList;
import prompto.value.IValue;
import prompto.value.TupleValue;

public class TupleLiteral extends Literal {

	ExpressionList expressions = null;
	boolean mutable = false;
	
	public TupleLiteral(boolean mutable) {
		super("()",new TupleValue(mutable));
		this.mutable = mutable;
	}
	
	public TupleLiteral(ExpressionList expressions, boolean mutable) {
		super(()->toTupleString(expressions),new TupleValue(mutable));
		this.expressions = expressions;
		this.mutable = mutable;
	}
	
	
	private static String toTupleString(ExpressionList expressions) {
		return "(" + expressions.toString() + (expressions.size()==1 ? "," : "") + ")";
	}

	public boolean isMutable() {
		return mutable;
	}
	
	@Override
	public IType check(Context context) {
		return TupleType.instance(); 
	}
	
	@Override
	public IValue interpret(Context context) throws PromptoError {
		if(expressions==null || expressions.isEmpty())
			return value;
		else {
			check(context); // force computation of itemType
			PromptoTuple list = new PromptoTuple(mutable);
			for(IExpression exp : expressions) {
				IValue item = exp.interpret(context);
				list.add(item);
			}
			return new TupleValue(list);
		}
	}

	public ExpressionList getExpressions() {
		return expressions;
	}
	
	@Override
	public void toDialect(CodeWriter writer) {
		if(mutable)
			writer.append("mutable ");
		if(expressions!=null) {
			writer.append('(');
			expressions.toDialect(writer);
			if(expressions.size()==1)
				writer.append(',');
			writer.append(')');
		} else
			writer.append("()");
	}

	@Override
	public ResultInfo compile(Context context, MethodInfo method, Flags flags) {
		ResultInfo info = CompilerUtils.compileNewRawInstance(method, PromptoTuple.class);
		method.addInstruction(Opcode.DUP);
		method.addInstruction(mutable ? Opcode.ICONST_1 : Opcode.ICONST_0);
		CompilerUtils.compileCallConstructor(method, PromptoTuple.class, boolean.class);
		if(expressions!=null)
			addItems(context, method, flags);
		return info;
	}

	private void addItems(Context context, MethodInfo method, Flags flags) {
		for(IExpression e : expressions) {
			method.addInstruction(Opcode.DUP); // need to keep a reference to the list on top of stack
			e.compile(context, method, flags.withPrimitive(false));
			IOperand c = new MethodConstant(PromptoTuple.class, "add", 
					Object.class, boolean.class);
			method.addInstruction(Opcode.INVOKEVIRTUAL, c);
			method.addInstruction(Opcode.POP); // consume the returned boolean
		}
	}
	
	@Override
	public void declare(Transpiler transpiler) {
	    transpiler.require("List");
	    transpiler.require("Tuple");
	    this.expressions.declare(transpiler);
	}
	
	@Override
	public boolean transpile(Transpiler transpiler) {
	    transpiler.append("new Tuple(").append(this.mutable).append(", [");
	    this.expressions.transpile(transpiler);
	    transpiler.append("])");
	    return false;
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy