Skip to content

Commit

Permalink
Refactor Do op as dense record
Browse files Browse the repository at this point in the history
  • Loading branch information
mikera committed Dec 2, 2024
1 parent 5f7bde8 commit 0d815a8
Show file tree
Hide file tree
Showing 13 changed files with 126 additions and 37 deletions.
7 changes: 6 additions & 1 deletion convex-core/src/main/java/convex/core/cvm/CVMTag.java
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ public class CVMTag {

public static final byte PEER_STATUS = (byte) 0xD9;

// Some ops in here

public static final byte RESULT = (byte)0xDD; // transaction result

public static final byte BLOCK_RESULT = (byte) 0xDE;
Expand Down Expand Up @@ -81,7 +83,10 @@ public class CVMTag {

public static final byte OP_DEF = (byte) 0xCD;


public static final byte OP_DO = (byte)0xDA; // (do ...)
public static final byte OP_INVOKE = (byte)0xDB; // (...) - function Invoke
public static final byte OP_COND = (byte)0xDB; // (cond ...)


public static final byte FN = (byte) 0xCF;

Expand Down
10 changes: 5 additions & 5 deletions convex-core/src/main/java/convex/core/cvm/Ops.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@

import convex.core.cvm.ops.Cond;
import convex.core.cvm.ops.Constant;
import convex.core.cvm.ops.Do;
import convex.core.cvm.ops.Invoke;
import convex.core.cvm.ops.Lambda;
import convex.core.cvm.ops.Let;
import convex.core.cvm.ops.Lookup;
import convex.core.cvm.ops.Query;
import convex.core.cvm.ops.Set;
import convex.core.cvm.ops.Try;
import convex.core.data.ACell;
import convex.core.data.Blob;
import convex.core.exceptions.BadFormatException;
Expand All @@ -23,7 +23,7 @@ public class Ops {
public static final byte CONSTANT = 0;
public static final byte INVOKE = 1;
public static final byte COND = 2;
public static final byte DO = 3;
public static final byte TRY = 3;
public static final byte LET = 4;
public static final byte LOOP = 5;
public static final byte DEF = 6;
Expand Down Expand Up @@ -62,8 +62,8 @@ public static <T extends ACell> AOp<T> read(byte tag, Blob b, int pos) throws Ba
return Invoke.read(b,pos);
case Ops.COND:
return Cond.read(b,pos);
case Ops.DO:
return Do.read(b,pos);
case Ops.TRY:
return Try.read(b,pos);
case Ops.LOOKUP:
return Lookup.read(b,pos);
case Ops.LAMBDA:
Expand All @@ -78,7 +78,7 @@ public static <T extends ACell> AOp<T> read(byte tag, Blob b, int pos) throws Ba
return Set.read(b,pos);

default:
throw new BadFormatException("Invalide OpCode: " + opCode);
throw new BadFormatException("Invalide OpCode: " + opCode + " with tag "+tag);
}
}

Expand Down
61 changes: 61 additions & 0 deletions convex-core/src/main/java/convex/core/cvm/ops/AFlatMultiOp.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package convex.core.cvm.ops;

import convex.core.cvm.AOp;
import convex.core.data.ACell;
import convex.core.data.AVector;
import convex.core.data.IRefFunction;
import convex.core.data.Ref;
import convex.core.util.ErrorMessages;

public abstract class AFlatMultiOp<T extends ACell> extends AMultiOp<T> {

protected final byte tag;

protected AFlatMultiOp(byte tag, AVector<AOp<ACell>> ops) {
super(ops);
this.tag=tag;
}

@Override
public byte getTag() {
return tag;
}

@Override
public byte opCode() {
// TODO remove from hierarchy
throw new Error(ErrorMessages.UNREACHABLE);
}

@Override
public int encodeRaw(byte[] bs, int pos) {
int epos=pos;
epos=ops.encodeRaw(bs, epos);
return epos;
}

@Override
public int encodeAfterOpcode(byte[] bs, int pos) {
throw new Error(ErrorMessages.UNREACHABLE);
}

@Override
public final int getRefCount() {
return ops.getRefCount();
}


@SuppressWarnings("unchecked")
@Override
public Ref<?> getRef(int i) {
return ops.getRef(i);
}

@Override
public final AFlatMultiOp<T> updateRefs(IRefFunction func) {
AVector<AOp<ACell>> newOps=(AVector<AOp<ACell>>) ops.updateRefs(func);
return recreate(newOps);
}

protected abstract AFlatMultiOp<T> recreate(AVector<AOp<ACell>> newOps);
}
5 changes: 2 additions & 3 deletions convex-core/src/main/java/convex/core/cvm/ops/AMultiOp.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

import convex.core.cvm.AOp;
import convex.core.data.ACell;
import convex.core.data.ASequence;
import convex.core.data.AVector;
import convex.core.data.Format;
import convex.core.data.IRefFunction;
Expand Down Expand Up @@ -30,7 +29,7 @@ protected AMultiOp(AVector<AOp<ACell>> ops) {
* @param newOps
* @return
*/
protected abstract AMultiOp<T> recreate(ASequence<AOp<ACell>> newOps);
protected abstract AMultiOp<T> recreate(AVector<AOp<ACell>> newOps);

@Override
public int encodeAfterOpcode(byte[] bs, int pos) {
Expand All @@ -45,7 +44,7 @@ public int estimatedEncodingSize() {

@Override
public AMultiOp<T> updateRefs(IRefFunction func) {
ASequence<AOp<ACell>> newOps = ops.updateRefs(func);
AVector<AOp<ACell>> newOps = ops.updateRefs(func);
return recreate(newOps);
}

Expand Down
4 changes: 2 additions & 2 deletions convex-core/src/main/java/convex/core/cvm/ops/Cond.java
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ public static <T extends ACell> Cond<T> create(AOp<?>... ops) {
}

@Override
protected Cond<T> recreate(ASequence<AOp<ACell>> newOps) {
protected Cond<T> recreate(AVector<AOp<ACell>> newOps) {
if (ops==newOps) return this;
return new Cond<T>(newOps.toVector());
}
Expand Down Expand Up @@ -120,7 +120,7 @@ public static <T extends ACell> Cond<T> read(Blob b, int pos) throws BadFormatEx

@Override
public Cond<T> updateRefs(IRefFunction func) {
ASequence<AOp<ACell>> newOps= ops.updateRefs(func);
AVector<AOp<ACell>> newOps= ops.updateRefs(func);
return recreate(newOps);
}

Expand Down
34 changes: 15 additions & 19 deletions convex-core/src/main/java/convex/core/cvm/ops/Do.java
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
package convex.core.cvm.ops;

import convex.core.cvm.AOp;
import convex.core.cvm.CVMTag;
import convex.core.cvm.Context;
import convex.core.cvm.Juice;
import convex.core.cvm.Ops;
import convex.core.data.ACell;
import convex.core.data.ASequence;
import convex.core.data.AVector;
import convex.core.data.Blob;
import convex.core.data.Cells;
import convex.core.data.Format;
import convex.core.data.Vectors;
import convex.core.data.util.BlobBuilder;
import convex.core.exceptions.BadFormatException;
Expand All @@ -23,24 +22,18 @@
*
* @param <T> Result type of Do Op
*/
public class Do<T extends ACell> extends AMultiOp<T> {
public class Do<T extends ACell> extends AFlatMultiOp<T> {

public static final Do<?> EMPTY = Do.create();

protected Do(AVector<AOp<ACell>> ops) {
super(ops);
super(CVMTag.OP_DO,ops);
}

public static <T extends ACell> Do<T> create(AOp<?>... ops) {
return new Do<T>(Vectors.create(ops));
}

@Override
protected Do<T> recreate(ASequence<AOp<ACell>> newOps) {
if (ops == newOps) return this;
return new Do<T>(newOps.toVector());
}


public static <T extends ACell> Do<T> create(ASequence<AOp<ACell>> ops) {
return new Do<T>(ops.toVector());
}
Expand Down Expand Up @@ -73,12 +66,7 @@ public boolean print(BlobBuilder bb, long limit) {
bb.append(')');
return bb.check(limit);
}

@Override
public byte opCode() {
return Ops.DO;
}


/**
* Decodes a Do op from a Blob encoding
*
Expand All @@ -89,13 +77,21 @@ public byte opCode() {
* @throws BadFormatException In the event of any encoding error
*/
public static <T extends ACell> Do<T> read(Blob b, int pos) throws BadFormatException {
int epos=pos+Ops.OP_DATA_OFFSET; // skip tag and opcode to get to data
int epos=pos;

AVector<AOp<ACell>> ops = Format.read(b,epos);
AVector<AOp<ACell>> ops = Vectors.read(b, epos);
epos+=Cells.getEncodingLength(ops);

Do<T> result=create(ops);
result.attachEncoding(b.slice(pos, epos));
return result;
}

@Override
protected AFlatMultiOp<T> recreate(AVector<AOp<ACell>> newOps) {
if (newOps==ops) return this;
return new Do<T>(newOps);
}


}
2 changes: 1 addition & 1 deletion convex-core/src/main/java/convex/core/cvm/ops/Invoke.java
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ public static <T extends ACell, A extends AOp<ACell>, F extends AOp<ACell>> Invo
}

@Override
protected Invoke<T> recreate(ASequence<AOp<ACell>> newOps) {
protected Invoke<T> recreate(AVector<AOp<ACell>> newOps) {
if (ops == newOps) return this;
return create(newOps);
}
Expand Down
2 changes: 1 addition & 1 deletion convex-core/src/main/java/convex/core/cvm/ops/Let.java
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ public final <R extends ACell> Ref<R> getRef(int i) {
}

@Override
protected Let<T> recreate(ASequence<AOp<ACell>> newOps) {
protected Let<T> recreate(AVector<AOp<ACell>> newOps) {
return recreate(newOps, symbols);
}

Expand Down
2 changes: 1 addition & 1 deletion convex-core/src/main/java/convex/core/cvm/ops/Query.java
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public static <T extends ACell> Query<T> create(AOp<?>... ops) {
}

@Override
protected Query<T> recreate(ASequence<AOp<ACell>> newOps) {
protected Query<T> recreate(AVector<AOp<ACell>> newOps) {
if (ops == newOps) return this;
return new Query<T>(newOps.toVector());
}
Expand Down
4 changes: 2 additions & 2 deletions convex-core/src/main/java/convex/core/cvm/ops/Try.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ public static <T extends ACell> Try<T> create(AOp<?>... ops) {
}

@Override
protected Try<T> recreate(ASequence<AOp<ACell>> newOps) {
protected Try<T> recreate(AVector<AOp<ACell>> newOps) {
if (ops == newOps) return this;
return new Try<T>(newOps.toVector());
}
Expand Down Expand Up @@ -88,7 +88,7 @@ public boolean print(BlobBuilder bb, long limit) {

@Override
public byte opCode() {
return Ops.DO;
return Ops.TRY;
}

/**
Expand Down
6 changes: 6 additions & 0 deletions convex-core/src/main/java/convex/core/data/Format.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import convex.core.cvm.State;
import convex.core.cvm.Syntax;
import convex.core.cvm.ops.Def;
import convex.core.cvm.ops.Do;
import convex.core.cvm.ops.Local;
import convex.core.cvm.ops.Special;
import convex.core.cvm.transactions.Call;
Expand Down Expand Up @@ -719,6 +720,11 @@ private static <T extends ACell> T readDenseRecord(byte tag, Blob b, int pos) th
return (T) BlockResult.read(b,pos);
}

if (tag == CVMTag.OP_DO) {
return (T) Do.read(b,pos);
}


if (tag == CVMTag.PEER_STATUS) return (T) PeerStatus.read(b,pos);
if (tag == CVMTag.ACCOUNT_STATUS) return (T) AccountStatus.read(b,pos);
} catch (Exception e) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ public static void doCellTests(ACell a) {
private static final CAD3Encoder CAD3_ENCODER=new CAD3Encoder();
private static final CVMEncoder CVM_ENCODER=new CVMEncoder();

private static void doCAD3Tests(ACell a) {
public static void doCAD3Tests(ACell a) {
Blob enc=Format.encodeMultiCell(a, true);
try {
ACell cad=CAD3_ENCODER.decodeMultiCell(enc);
Expand Down
24 changes: 23 additions & 1 deletion convex-core/src/test/java/convex/core/lang/OpsTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,12 @@
import convex.core.cvm.ops.Lookup;
import convex.core.cvm.ops.Set;
import convex.core.cvm.ops.Special;
import convex.core.cvm.ops.Try;
import convex.core.data.ACell;
import convex.core.data.AMap;
import convex.core.data.AString;
import convex.core.data.Blob;
import convex.core.data.DenseRecord;
import convex.core.data.ExtensionValue;
import convex.core.data.Format;
import convex.core.data.ObjectsTest;
Expand Down Expand Up @@ -149,7 +151,7 @@ public void testUndeclaredLookup() {
}

@Test
public void testDo() {
public void testDo() throws BadFormatException {
Context c = context();

AOp<AString> op = Do.create(Def.create("foo", Constant.createString("bar")), Lookup.create("foo"));
Expand All @@ -158,10 +160,30 @@ public void testDo() {
long expectedJuice = INITIAL_JUICE - (Juice.CONSTANT + Juice.DEF + Juice.LOOKUP_DYNAMIC + Juice.DO);
assertEquals(expectedJuice, c2.getJuiceAvailable());
assertEquals("bar", c2.getResult().toString());

Blob enc=op.getEncoding();

assertEquals(CVMTag.OP_DO,op.getTag());
assertEquals(op,DenseRecord.read(CVMTag.OP_DO, enc,0));

ObjectsTest.doCAD3Tests(op);

doOpTest(op);
}

@Test
public void testTry() throws BadFormatException {
AOp<CVMLong> op = Try.create(Invoke.create(Constant.of(CVMLong.ZERO)), Constant.of(CVMLong.ONE));

Context c = context();
Context c2 = c.execute(op);
assertFalse(c2.isExceptional());
assertEquals(CVMLong.ONE,c2.getResult());

doOpTest(op);
}


@Test
public void testSpecial() {
Context c = context();
Expand Down

0 comments on commit 0d815a8

Please sign in to comment.