Skip to content

Commit

Permalink
Simplify multi-value conversion AST production
Browse files Browse the repository at this point in the history
  • Loading branch information
Gene Gleyzer committed Sep 18, 2024
1 parent 8533b62 commit 33267ce
Show file tree
Hide file tree
Showing 7 changed files with 105 additions and 57 deletions.
15 changes: 10 additions & 5 deletions javatools/src/main/java/org/xvm/asm/Register.java
Original file line number Diff line number Diff line change
Expand Up @@ -881,11 +881,16 @@ public RegAllocAST getRegAllocAST()
@Override
public ExprAST getRegisterAST()
{
NarrowedExprAST astNarrowed = m_astNarrowed;
ExprAST astNarrowed = m_astNarrowed;
if (astNarrowed == null)
{
astNarrowed = m_astNarrowed = new NarrowedExprAST(
Register.this.getRegisterAST(), getType());
TypeConstant typeNarrowed = getType();
TypeConstant typeOrig = getOriginalType();
ExprAST astOrig = Register.this.getRegisterAST();

astNarrowed = m_astNarrowed = typeNarrowed.equals(typeOrig)
? astOrig
: new NarrowedExprAST(astOrig, typeNarrowed);
}
return astNarrowed;
}
Expand Down Expand Up @@ -921,9 +926,9 @@ public boolean equals(Object obj)
private boolean m_fInPlace = false;

/**
* Cached NarrowedExprAST.
* Cached ExprAST for shadow register (could be the same as for the original register).
*/
private NarrowedExprAST m_astNarrowed;
private ExprAST m_astNarrowed;
}


Expand Down
9 changes: 9 additions & 0 deletions javatools/src/main/java/org/xvm/asm/ast/ConvertExprAST.java
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,15 @@ public ConvertExprAST(ExprAST expr, TypeConstant[] types, MethodConstant[] convM
this.convMethods = convMethods;
}

public ConvertExprAST(ExprAST expr, TypeConstant type, MethodConstant convMethod) {
super(expr);

assert type != null && convMethod != null;

this.types = new TypeConstant[] {type};
this.convMethods = new MethodConstant[] {convMethod};
}

public Constant[] getConvMethods() {
return convMethods;
}
Expand Down
1 change: 0 additions & 1 deletion javatools/src/main/java/org/xvm/asm/ast/StmtExprAST.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
import static org.xvm.util.Handy.indentLines;



/**
* A statement expression.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -813,8 +813,14 @@ protected boolean emit(Context ctx, boolean fReachable, Code code, ErrorListener
fCompletes &= rvalue.isCompletable();
}

// for now, we only "unwrap" rvalue if it's a ConvertExpression; if necessary, we
// should create a corresponding abstract method on Expression an implement
// as required
astLVal = combineLValueAST(astLVal, lvalueExpr.getExprAST(ctx));
astAssign = new AssignAST(astLVal, Operator.Asn, rvalue.getExprAST(ctx));
astAssign = rvalue instanceof ConvertExpression exprConv &&
!exprConv.isSingle() && !exprConv.isConstant()
? exprConv.unwrapConverAST(ctx, astLVal)
: new AssignAST(astLVal, Operator.Asn, rvalue.getExprAST(ctx));
break;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package org.xvm.compiler.ast;


import java.util.ArrayList;
import java.util.List;

import org.xvm.asm.Argument;
import org.xvm.asm.Constant;
import org.xvm.asm.ErrorListener;
Expand All @@ -9,9 +12,14 @@
import org.xvm.asm.Op;
import org.xvm.asm.Register;

import org.xvm.asm.ast.AssignAST;
import org.xvm.asm.ast.AssignAST.Operator;
import org.xvm.asm.ast.ConstantExprAST;
import org.xvm.asm.ast.ConvertExprAST;
import org.xvm.asm.ast.ExprAST;
import org.xvm.asm.ast.InvokeExprAST;
import org.xvm.asm.ast.MultiExprAST;
import org.xvm.asm.ast.StmtExprAST;

import org.xvm.asm.constants.MethodConstant;
import org.xvm.asm.constants.TypeConstant;
Expand Down Expand Up @@ -61,7 +69,7 @@ public ConvertExpression(Expression expr, MethodConstant[] aidConv, ErrorListene

if (expr.isSingle())
{
assert aidConv[0] != null;
assert aidConv.length == 1 && aidConv[0] != null;

TypeConstant type = aidConv[0].getRawReturns()[0];
Constant val = null;
Expand Down Expand Up @@ -277,6 +285,69 @@ public ExprAST getExprAST(Context ctx)
: new ConvertExprAST(expr.getExprAST(ctx), getTypes(), m_aidConv);
}

/**
* Unwrap multi-conversion assignment into an equivalent statement expression.
*
* In a way of example, let's say we have a function:
* <pre><code>
* (Int32, Int32) f() {...}
* </code></pre>
* and we call it like this:
* <pre><code>
* (Int x, Int y) = f();
* </code></pre>
* The BAST that we are going to create will look like a standard compilation of the following:
* <pre><code>
* (Int32 tmpX, Int32 tmpY) = f();
* Int x = tmpX.toInt64();
* Int y = tmpY.toInt64();
* </code></pre>
*/
public ExprAST unwrapConverAST(Context ctx, ExprAST astLVal)
{
ExprAST astFrom = expr.getExprAST(ctx);
int cVals = expr.getValueCount();

assert cVals > 1 && cVals == m_aidConv.length;

TypeConstant[] atypeFrom = expr.getTypes();
TypeConstant[] atypeTo = this.getTypes();

Register[] aRegFrom = new Register[cVals];
ExprAST[] aAstRegFrom = new ExprAST[cVals];
for (int i = 0; i < cVals; i++)
{
aRegFrom[i] = ctx.createRegister(atypeFrom[i], null);
aAstRegFrom[i] = aRegFrom[i].getRegAllocAST();
}

List<ExprAST> listAst = new ArrayList<>();
listAst.add(new AssignAST(new MultiExprAST(aAstRegFrom), Operator.Asn, astFrom));

ExprAST[] aAstRegTo = new ExprAST[cVals];
for (int i = 0; i < cVals; i++)
{
MethodConstant idConv = m_aidConv[i];
Register regFrom = aRegFrom[i];
if (idConv == null)
{
aAstRegTo[i] = regFrom.getRegisterAST();
}
else
{
Register regTo = ctx.createRegister(atypeTo[i], null);
ExprAST astConvert = new InvokeExprAST(idConv,
new TypeConstant[] {atypeTo[i]}, regFrom.getRegisterAST(),
ExprAST.NO_EXPRS, false);
listAst.add(new AssignAST(regTo.getRegAllocAST(), Operator.Asn, astConvert));
aAstRegTo[i] = regTo.getRegisterAST();
}
}
listAst.add(new AssignAST(astLVal, Operator.Asn, new MultiExprAST(aAstRegTo)));

return new StmtExprAST(new MultiExprAST(listAst.toArray(ExprAST.NO_EXPRS)), atypeTo);
}


// ----- debugging assistance ------------------------------------------------------------------

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1797,8 +1797,7 @@ else if (cTypeParams == 1)
Register regFn = code.createRegister(typeFn, fTargetOnStack);
code.add(new Invoke_01(argFn, idConv, regFn));
argFn = regFn;
astFn = new ConvertExprAST(astFn,
new TypeConstant[]{typeFn}, new MethodConstant[]{idConv});
astFn = new ConvertExprAST(astFn, typeFn, idConv);
}

TypeConstant[] atypeParams = pool.extractFunctionParams(typeFn);
Expand Down
53 changes: 6 additions & 47 deletions manualTests/src/main/x/TestSimple.x
Original file line number Diff line number Diff line change
Expand Up @@ -2,56 +2,15 @@ module TestSimple {
@Inject Console console;

void run() {
console.print(new test1.Base1<String>().add("hello1"));
console.print(new test1.Base2<String>().add("hello2"));

console.print("test2");
console.print(new test2.Base1<String>().add("hello1"));
console.print(new test2.Base2<String>().add("hello2"));
console.print(test());
}

// a number of things below used to fail to compile (those are excerpts from the tck)
package test1 {
mixin MixIn<ElementM> into Base1<ElementM> | Base2<ElementM> {
@Override String add(ElementM e) = $"MX[{e=} " + super(e) + " ]MX";
}

class Super1<Element> {
String add(Element e) = $"S[{e=}]S";
}
class Base1<ElementM> extends Super1<ElementM> incorporates MixIn<ElementM> {
@Override String add(ElementM e) = $"B[{e=} " + super(e) + " ]B";
}
class Super2<Element> {
String add(Element e) = $"s[{e=}]s";
}
class Base2<ElementM> extends Super2<ElementM> incorporates MixIn<ElementM> {
@Override String add(ElementM e) = $"b[{e=} " + super(e) + " ]b";
}
Int test() {
(Int year, _, Int day, _) = calcDate();
return year;
}

package test2 {
mixin MixIn<ElementM> into Base1<ElementM> | Base2<ElementM> {
@Override String add(ElementM e) = $"MX[{e=} " + super(e) + " ]MX";
}
class Super1<ElementS1> {
String add(ElementS1 e) = $"S[{e=}]S";
}
class Base1<ElementB1> extends Super1<ElementB1> incorporates MixIn<ElementB1> {
@Override String add(ElementB1 e) = $"B[{e=} " + super(e) + " ]B";
}
class Super2<ElementS2> {
String add(ElementS2 e) = $"s[{e=}]s";
}
class Base2<ElementB2> extends Super2<ElementB2> incorporates MixIn<ElementB2> {
@Override String add(ElementB2 e) = $"b[{e=} " + super(e) + " ]b";
}
static (Int32 year, Int32 month, Int32 day, Int32 dayOfYear) calcDate() {
return 2024, 9, 16, 276;
}
}

0 comments on commit 33267ce

Please sign in to comment.