Skip to content

Commit

Permalink
eval function
Browse files Browse the repository at this point in the history
  • Loading branch information
lunfardo314 committed May 24, 2024
1 parent c7dc45b commit f0c3c02
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 45 deletions.
100 changes: 55 additions & 45 deletions embed.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
}
)
Expand Down Expand Up @@ -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")
}

// -----------------------------------------------------------------
Expand Down Expand Up @@ -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))
Expand All @@ -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
}
16 changes: 16 additions & 0 deletions library_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)))")
})
}

0 comments on commit f0c3c02

Please sign in to comment.