diff --git a/convex-core/src/main/java/convex/core/cvm/CVMTag.java b/convex-core/src/main/java/convex/core/cvm/CVMTag.java index b041ece23..038a20f14 100644 --- a/convex-core/src/main/java/convex/core/cvm/CVMTag.java +++ b/convex-core/src/main/java/convex/core/cvm/CVMTag.java @@ -77,11 +77,14 @@ public class CVMTag { // ========================================== // CVM Ops - // General ops with byte flag + // General ops with a single byte flag public static final byte OP_CODED = (byte) 0xC0; public static final byte OPCODE_CONSTANT = (byte) 0xB0; + public static final byte OPCODE_LOOKUP = (byte) 0xB1; public static final byte OPCODE_LAMBDA = (byte) 0xBF; - + + public static final byte OP_LOOKUP = (byte) 0xC1; + public static final byte OP_DEF = (byte) 0xCD; public static final byte OP_DO = (byte)0xDA; // (do ...) diff --git a/convex-core/src/main/java/convex/core/cvm/Ops.java b/convex-core/src/main/java/convex/core/cvm/Ops.java index 2c16f8e68..f3c0ce827 100644 --- a/convex-core/src/main/java/convex/core/cvm/Ops.java +++ b/convex-core/src/main/java/convex/core/cvm/Ops.java @@ -3,7 +3,6 @@ import convex.core.cvm.ops.Constant; 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; @@ -22,7 +21,6 @@ public class Ops { public static final byte TRY = 3; public static final byte LET = 4; public static final byte LOOP = 5; - public static final byte LOOKUP = 7; public static final byte LAMBDA = 8; public static final byte QUERY = 9; @@ -52,8 +50,6 @@ public static AOp read(byte tag, Blob b, int pos) throws Ba return Constant.read(b,pos); case Ops.TRY: return Try.read(b,pos); - case Ops.LOOKUP: - return Lookup.read(b,pos); case CVMTag.OPCODE_LAMBDA: return (AOp) Lambda.read(b,pos); case Ops.LET: diff --git a/convex-core/src/main/java/convex/core/cvm/ops/Lookup.java b/convex-core/src/main/java/convex/core/cvm/ops/Lookup.java index 7642990cb..67486aaf0 100644 --- a/convex-core/src/main/java/convex/core/cvm/ops/Lookup.java +++ b/convex-core/src/main/java/convex/core/cvm/ops/Lookup.java @@ -3,14 +3,12 @@ import convex.core.ErrorCodes; import convex.core.cvm.AOp; import convex.core.cvm.Address; +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.Blob; -import convex.core.data.Cells; import convex.core.data.Format; -import convex.core.data.IRefFunction; import convex.core.data.Ref; import convex.core.data.Symbol; import convex.core.data.util.BlobBuilder; @@ -28,17 +26,13 @@ * * @param Result type of Op */ -public class Lookup extends AOp { - private final AOp
address; - private final Symbol symbol; - - private Lookup(AOp
address,Symbol symbol) { - this.address=address; - this.symbol = symbol; +public class Lookup extends ACodedOp,Symbol> { + private Lookup(Ref> address,Ref symbol) { + super (CVMTag.OP_LOOKUP,address,symbol); } public static Lookup create(AOp
address, Symbol form) { - return new Lookup(address,form); + return new Lookup(Ref.get(address),form.getRef()); } public static Lookup create(AOp
address, String name) { @@ -61,6 +55,7 @@ public static Lookup create(String name) { public Context execute(Context context) { Context rctx=context; Address namespaceAddress=null; + AOp
address=code.getValue(); if (address!=null) { rctx=rctx.execute(address); if (rctx.isExceptional()) return rctx; @@ -71,30 +66,21 @@ public Context execute(Context context) { // Do a dynamic lookup, with address if specified or address from current context otherwise namespaceAddress=(address==null)?context.getAddress():namespaceAddress; + Symbol symbol=value.getValue(); return rctx.lookupDynamic(namespaceAddress,symbol).consumeJuice(Juice.LOOKUP_DYNAMIC); } @Override public boolean print(BlobBuilder bb, long limit) { + AOp
address=code.getValue(); if (address!=null) { if (!address.print(bb,limit)) return false; bb.append('/'); } + Symbol symbol=value.getValue(); return symbol.print(bb,limit); } - @Override - public byte opCode() { - return Ops.LOOKUP; - } - - @Override - public int encodeAfterOpcode(byte[] bs, int pos) { - pos= symbol.encode(bs, pos); - pos= Format.write(bs,pos, address); // might be null - return pos; - } - /** * Reads a Lookup op from a Blob encoding * @param Type of Lookup value @@ -104,48 +90,34 @@ public int encodeAfterOpcode(byte[] bs, int pos) { * @throws BadFormatException In the event of any encoding error */ public static Lookup 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+1; // skip tag to get to data - Symbol sym = Format.read(b,epos); - if (sym==null) throw new BadFormatException("Lookup symbol cannot be null"); - epos+=Cells.getEncodingLength(sym); + Ref> addr=Format.readRef(b, epos); + epos+=addr.getEncodingLength(); - AOp
address = Format.read(b,epos); - epos+=Cells.getEncodingLength(address); + Ref sym=Format.readRef(b, epos); + epos+=sym.getEncodingLength(); - Lookup result= create(address,sym); + Lookup result= new Lookup(addr,sym); result.attachEncoding(b.slice(pos, epos)); return result; } - @Override - public int getRefCount() { - if (address==null) return 0; - return address.getRefCount(); - } - @Override - public Ref getRef(int i) { - if (address==null) throw new IndexOutOfBoundsException(); - return address.getRef(i); - } - - @Override - public Lookup updateRefs(IRefFunction func) { - if (address==null) return this; - AOp
newAddress=address.updateRefs(func); - if (address==newAddress) return this; - return create(newAddress,symbol); - } @Override public void validateCell() throws InvalidDataException { - if (address!=null) address.validateCell(); - symbol.validateCell(); + // TODO: any checks? } public AOp
getAddress() { - return address; + return code.getValue(); + } + + @Override + protected AOp rebuild(Ref> newCode, Ref newValue) { + if ((code==newCode)&&(value==newValue)) return this; + return new Lookup(newCode,newValue); } diff --git a/convex-core/src/main/java/convex/core/cvm/ops/Set.java b/convex-core/src/main/java/convex/core/cvm/ops/Set.java index 95f7591d2..704c72416 100644 --- a/convex-core/src/main/java/convex/core/cvm/ops/Set.java +++ b/convex-core/src/main/java/convex/core/cvm/ops/Set.java @@ -5,11 +5,9 @@ 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.AVector; import convex.core.data.Blob; -import convex.core.data.Cells; import convex.core.data.Format; import convex.core.data.Ref; import convex.core.data.prim.CVMLong; @@ -77,15 +75,15 @@ public Context execute(Context ctx) { * @throws BadFormatException In the event of any encoding error */ public static Set 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+1; // skip tag to get to data - long position = Format.readVLQLong(b,epos); - epos+=Format.getVLQLongLength(position); + Ref index=Format.readRef(b, epos); + epos+=index.getEncodingLength(); - AOp op = Format.read(b,epos); - epos+=Cells.getEncodingLength(op); + Ref> op=Format.readRef(b, epos); + epos+=op.getEncodingLength(); - Set result= create(position, op); + Set result= new Set(index,op); result.attachEncoding(b.slice(pos, epos)); return result; } diff --git a/convex-core/src/main/java/convex/core/data/Format.java b/convex-core/src/main/java/convex/core/data/Format.java index 1eff53fd1..d3edac441 100644 --- a/convex-core/src/main/java/convex/core/data/Format.java +++ b/convex-core/src/main/java/convex/core/data/Format.java @@ -27,6 +27,7 @@ import convex.core.cvm.ops.Def; import convex.core.cvm.ops.Do; import convex.core.cvm.ops.Local; +import convex.core.cvm.ops.Lookup; import convex.core.cvm.ops.Special; import convex.core.cvm.transactions.Call; import convex.core.cvm.transactions.Invoke; @@ -499,21 +500,26 @@ private static T readDataStructure(byte tag, Blob b, int pos) } private static ACell readCode(byte tag, Blob b, int pos) throws BadFormatException { - - if (tag == CVMTag.OP_DEF) { - return Def.read(b, pos); - } - - if (tag == CVMTag.OP_CODED) return Ops.read(tag,b, pos); - - if (tag == CVMTag.FN_MULTI) { - AFn fn = MultiFn.read(b,pos); - return fn; - } - - if (tag == CVMTag.FN) { - AFn fn = Fn.read(b,pos); - return fn; + try { + if (tag == CVMTag.OP_CODED) return Ops.read(tag,b, pos); + + if (tag == CVMTag.OP_LOOKUP) return Lookup.read(b,pos); + + if (tag == CVMTag.OP_DEF) { + return Def.read(b, pos); + } + + if (tag == CVMTag.FN_MULTI) { + AFn fn = MultiFn.read(b,pos); + return fn; + } + + if (tag == CVMTag.FN) { + AFn fn = Fn.read(b,pos); + return fn; + } + } catch (Exception e) { + // something went wrong, fall through to reading a generic coded value } return CodedValue.read(tag,b,pos);