diff --git a/embed.go b/embed.go index 5e518e1..cdea195 100644 --- a/embed.go +++ b/embed.go @@ -60,9 +60,10 @@ var ( } embedBytecodeManipulation = func(lib *Library) []*EmbeddedFunctionData { return []*EmbeddedFunctionData{ - {"unwrapBytecodeArg", 3, lib.evalUnwrapBytecodeArg}, + {"parseBytecodeArg", 3, lib.evalParseBytecodeArg}, {"parseBytecodePrefix", 1, lib.evalParseBytecodePrefix}, - {"evalBytecodeArg", 3, lib.evalEvalBytecodeArg}, + //{"evalBytecodeArg", 3, lib.evalBytecodeArg}, + {"eval", 1, lib.evalBytecode}, // evaluates closed formula } } ) @@ -200,46 +201,46 @@ func (lib *Library) embedBytecodeManipulation() { // $2 - number of the parameter to return // Panics if the bytecode is not the valid call of the specified function or number of the parameter is out of bounds // Returns code of the argument if it is a call function, or data is it is a constant - //lib.embedLong("unwrapBytecodeArg", 3, lib.evalUnwrapBytecodeArg) + //lib.embedLong("unwrapBytecodeArg", 3, lib.evalParseBytecodeArg) //lib.embedLong("parseBytecodePrefix", 1, lib.evalParseBytecodePrefix) - //lib.embedLong("evalBytecodeArg", 3, lib.evalEvalBytecodeArg) + //lib.embedLong("evalBytecodeArg", 3, lib.evalBytecodeArg) lib.UpgradeWthEmbeddedLong(embedBytecodeManipulation(lib)...) _, _, binCode, err := lib.CompileExpression("slice(0x01020304,1,2)") AssertNoError(err) - src := fmt.Sprintf("unwrapBytecodeArg(0x%s, #slice, %d)", hex.EncodeToString(binCode), 0) + src := fmt.Sprintf("parseBytecodeArg(0x%s, #slice, %d)", hex.EncodeToString(binCode), 0) lib.MustEqual(src, "0x01020304") - src = fmt.Sprintf("unwrapBytecodeArg(0x%s, #slice, %d)", hex.EncodeToString(binCode), 1) + src = fmt.Sprintf("parseBytecodeArg(0x%s, #slice, %d)", hex.EncodeToString(binCode), 1) lib.MustEqual(src, "1") - src = fmt.Sprintf("unwrapBytecodeArg(0x%s, #slice, %d)", hex.EncodeToString(binCode), 2) + src = fmt.Sprintf("parseBytecodeArg(0x%s, #slice, %d)", hex.EncodeToString(binCode), 2) lib.MustEqual(src, "2") src = fmt.Sprintf("parseBytecodePrefix(0x%s)", hex.EncodeToString(binCode)) lib.MustEqual(src, "#slice") - src = fmt.Sprintf("evalBytecodeArg(0x%s, #slice, %d)", hex.EncodeToString(binCode), 0) - lib.MustEqual(src, "0x01020304") - src = fmt.Sprintf("evalBytecodeArg(0x%s, #slice, %d)", hex.EncodeToString(binCode), 1) - lib.MustEqual(src, "1") - src = fmt.Sprintf("evalBytecodeArg(0x%s, #slice, %d)", hex.EncodeToString(binCode), 2) - lib.MustEqual(src, "2") - - _, _, binCode, err = lib.CompileExpression("slice(concat(1,2,concat(3,4)),1,2)") - AssertNoError(err) - src = fmt.Sprintf("evalBytecodeArg(0x%s, #slice, %d)", hex.EncodeToString(binCode), 0) - lib.MustEqual(src, "0x01020304") - src = fmt.Sprintf("evalBytecodeArg(0x%s, #slice, %d)", hex.EncodeToString(binCode), 1) - lib.MustEqual(src, "1") - src = fmt.Sprintf("evalBytecodeArg(0x%s, #slice, %d)", hex.EncodeToString(binCode), 2) - lib.MustEqual(src, "2") - - _, _, binCode, err = lib.CompileExpression("slice(concat(1,concat(2,3),4),byte(0x020301, 2),add(1,1))") - AssertNoError(err) - src = fmt.Sprintf("evalBytecodeArg(0x%s, #slice, %d)", hex.EncodeToString(binCode), 0) - lib.MustEqual(src, "0x01020304") - src = fmt.Sprintf("evalBytecodeArg(0x%s, #slice, %d)", hex.EncodeToString(binCode), 1) - lib.MustEqual(src, "1") - src = fmt.Sprintf("evalBytecodeArg(0x%s, #slice, %d)", hex.EncodeToString(binCode), 2) - lib.MustEqual(src, "u64/2") + //src = fmt.Sprintf("evalBytecodeArg(0x%s, #slice, %d)", hex.EncodeToString(binCode), 0) + //lib.MustEqual(src, "0x01020304") + //src = fmt.Sprintf("evalBytecodeArg(0x%s, #slice, %d)", hex.EncodeToString(binCode), 1) + //lib.MustEqual(src, "1") + //src = fmt.Sprintf("evalBytecodeArg(0x%s, #slice, %d)", hex.EncodeToString(binCode), 2) + //lib.MustEqual(src, "2") + // + //_, _, binCode, err = lib.CompileExpression("slice(concat(1,2,concat(3,4)),1,2)") + //AssertNoError(err) + //src = fmt.Sprintf("evalBytecodeArg(0x%s, #slice, %d)", hex.EncodeToString(binCode), 0) + //lib.MustEqual(src, "0x01020304") + //src = fmt.Sprintf("evalBytecodeArg(0x%s, #slice, %d)", hex.EncodeToString(binCode), 1) + //lib.MustEqual(src, "1") + //src = fmt.Sprintf("evalBytecodeArg(0x%s, #slice, %d)", hex.EncodeToString(binCode), 2) + //lib.MustEqual(src, "2") + // + //_, _, binCode, err = lib.CompileExpression("slice(concat(1,concat(2,3),4),byte(0x020301, 2),add(1,1))") + //AssertNoError(err) + //src = fmt.Sprintf("evalBytecodeArg(0x%s, #slice, %d)", hex.EncodeToString(binCode), 0) + //lib.MustEqual(src, "0x01020304") + //src = fmt.Sprintf("evalBytecodeArg(0x%s, #slice, %d)", hex.EncodeToString(binCode), 1) + //lib.MustEqual(src, "1") + //src = fmt.Sprintf("evalBytecodeArg(0x%s, #slice, %d)", hex.EncodeToString(binCode), 2) + //lib.MustEqual(src, "u64/2") } // ----------------------------------------------------------------- @@ -578,28 +579,28 @@ func evalRShift64(par *CallParams) []byte { return ret[:] } -func (lib *Library) evalUnwrapBytecodeArg(par *CallParams) []byte { +func (lib *Library) evalParseBytecodeArg(par *CallParams) []byte { a0 := par.Arg(0) _, prefix, args, err := lib.ParseBytecodeOneLevel(a0) if err != nil { - par.TracePanic("evalUnwrapBytecodeArg:: %v", err) + par.TracePanic("evalParseBytecodeArg:: %v", err) } expectedPrefix := par.Arg(1) idx := par.Arg(2) if !bytes.Equal(prefix, expectedPrefix) { _, _, _, symPrefix, err := lib.parseCallPrefix(prefix) if err != nil { - par.TracePanic("evalUnwrapBytecodeArg: can't parse prefix '%s': %v", Fmt(prefix), err) + par.TracePanic("evalParseBytecodeArg: can't parse prefix '%s': %v", Fmt(prefix), err) } _, _, _, symExpectedPrefix, err := lib.parseCallPrefix(expectedPrefix) if err != nil { - par.TracePanic("evalUnwrapBytecodeArg: can't parse expected prefix '%s': %v", Fmt(expectedPrefix), err) + par.TracePanic("evalParseBytecodeArg: can't parse expected prefix '%s': %v", Fmt(expectedPrefix), err) } - par.TracePanic("evalUnwrapBytecodeArg: unexpected function prefix. Expected '%s'('%s'), got '%s'('%s')", + par.TracePanic("evalParseBytecodeArg: unexpected function prefix. Expected '%s'('%s'), got '%s'('%s')", Fmt(expectedPrefix), symExpectedPrefix, Fmt(prefix), symPrefix) } if len(idx) != 1 || len(args) <= int(idx[0]) { - par.TracePanic("evalUnwrapBytecodeArg: wrong parameter index") + par.TracePanic("evalParseBytecodeArg: wrong parameter index") } ret := StripDataPrefix(args[idx[0]]) par.Trace("unwrapBytecodeArg:: %s, %s, %s -> %s", Fmt(a0), Fmt(expectedPrefix), Fmt(idx), Fmt(ret)) @@ -616,35 +617,44 @@ func (lib *Library) evalParseBytecodePrefix(par *CallParams) []byte { return prefix } -func (lib *Library) evalEvalBytecodeArg(par *CallParams) []byte { +func (lib *Library) evalBytecodeArg(par *CallParams) []byte { a0 := par.Arg(0) _, prefix, args, err := lib.ParseBytecodeOneLevel(a0) if err != nil { - par.TracePanic("evalUnwrapBytecodeArg:: %v", err) + par.TracePanic("evalParseBytecodeArg:: %v", err) } expectedPrefix := par.Arg(1) idx := par.Arg(2) if !bytes.Equal(prefix, expectedPrefix) { _, _, _, symPrefix, err := lib.parseCallPrefix(prefix) if err != nil { - par.TracePanic("evalEvalBytecodeArg: can't parse prefix '%s': %v", Fmt(prefix), err) + par.TracePanic("evalBytecodeArg: can't parse prefix '%s': %v", Fmt(prefix), err) } _, _, _, symExpectedPrefix, err := lib.parseCallPrefix(expectedPrefix) if err != nil { - par.TracePanic("evalEvalBytecodeArg: can't parse expected prefix '%s': %v", Fmt(expectedPrefix), err) + par.TracePanic("evalBytecodeArg: can't parse expected prefix '%s': %v", Fmt(expectedPrefix), err) } - par.TracePanic("evalEvalBytecodeArg: unexpected function prefix. Expected '%s'('%s'), got '%s'('%s')", + par.TracePanic("evalBytecodeArg: unexpected function prefix. Expected '%s'('%s'), got '%s'('%s')", Fmt(expectedPrefix), symExpectedPrefix, Fmt(prefix), symPrefix) } if len(idx) != 1 || len(args) <= int(idx[0]) { - par.TracePanic("evalUnwrapBytecodeArg: wrong parameter index") + par.TracePanic("evalParseBytecodeArg: wrong parameter index") } ret, err := lib.EvalFromBytecode(par.ctx.glb, args[idx[0]]) if err != nil { - par.TracePanic("evaldBytecodeArg:: %s, %s, %s", Fmt(a0), Fmt(expectedPrefix), Fmt(idx)) + par.TracePanic("evalBytecodeArg:: %s, %s, %s", Fmt(a0), Fmt(expectedPrefix), Fmt(idx)) } - par.Trace("evaldBytecodeArg:: %s, %s, %s -> %s", Fmt(a0), Fmt(expectedPrefix), Fmt(idx), Fmt(ret)) + par.Trace("evalBytecodeArg:: %s, %s, %s -> %s", Fmt(a0), Fmt(expectedPrefix), Fmt(idx), Fmt(ret)) + return ret +} + +func (lib *Library) evalBytecode(par *CallParams) []byte { + ret, err := lib.EvalFromBytecode(par.ctx.glb, par.Arg(0)) + if err != nil { + par.TracePanic("evalBytecode:: %v", err) + } + par.Trace("evalBytecode:: %s} -> %s", Fmt(par.Arg(0)), Fmt(ret)) return ret } diff --git a/library_test.go b/library_test.go index 69201a2..5bcb5ac 100644 --- a/library_test.go +++ b/library_test.go @@ -1004,4 +1004,20 @@ func TestBytecodeParams(t *testing.T) { res := EvalExpression(nil, expr, []byte{0xff}) t.Logf("eval: %s", Fmt(res)) }) + t.Run("4", func(t *testing.T) { + res, err := lib.EvalFromSource(nil, "concat(42,41)") + require.NoError(t, err) + + require.EqualValues(t, res, []byte{42, 41}) + + res1, err := lib.EvalFromSource(nil, "eval(bytecode(concat(42,41)))") + require.NoError(t, err) + require.EqualValues(t, res, res1) + }) + t.Run("5", func(t *testing.T) { + lib.MustEqual("123", "eval(bytecode(123))") + lib.MustEqual("0x", "eval(bytecode(0x))") + lib.MustEqual("u64/1234567890", "eval(bytecode(u64/1234567890))") + lib.MustEqual("concat(1,2,3)", "eval(bytecode(concat(1,2,3)))") + }) }