diff options
Diffstat (limited to 'ethutil/parsing.go')
-rw-r--r-- | ethutil/parsing.go | 108 |
1 files changed, 108 insertions, 0 deletions
diff --git a/ethutil/parsing.go b/ethutil/parsing.go new file mode 100644 index 000000000..2c41fb4df --- /dev/null +++ b/ethutil/parsing.go @@ -0,0 +1,108 @@ +package ethutil + +import ( + "errors" + "fmt" + "math/big" + "strconv" + "strings" +) + +// Op codes +var OpCodes = map[string]string{ + "STOP": "0", + "ADD": "1", + "MUL": "2", + "SUB": "3", + "DIV": "4", + "SDIV": "5", + "MOD": "6", + "SMOD": "7", + "EXP": "8", + "NEG": "9", + "LT": "10", + "LE": "11", + "GT": "12", + "GE": "13", + "EQ": "14", + "NOT": "15", + "MYADDRESS": "16", + "TXSENDER": "17", + + "PUSH": "48", + "POP": "49", + "LOAD": "54", +} + +func CompileInstr(s string) (string, error) { + tokens := strings.Split(s, " ") + if OpCodes[tokens[0]] == "" { + return s, errors.New(fmt.Sprintf("OP not found: %s", tokens[0])) + } + + code := OpCodes[tokens[0]] // Replace op codes with the proper numerical equivalent + op := new(big.Int) + op.SetString(code, 0) + + args := make([]*big.Int, 6) + for i, val := range tokens[1:len(tokens)] { + num := new(big.Int) + num.SetString(val, 0) + args[i] = num + } + + // Big int equation = op + x * 256 + y * 256**2 + z * 256**3 + a * 256**4 + b * 256**5 + c * 256**6 + base := new(big.Int) + x := new(big.Int) + y := new(big.Int) + z := new(big.Int) + a := new(big.Int) + b := new(big.Int) + c := new(big.Int) + + if args[0] != nil { + x.Mul(args[0], big.NewInt(256)) + } + if args[1] != nil { + y.Mul(args[1], BigPow(256, 2)) + } + if args[2] != nil { + z.Mul(args[2], BigPow(256, 3)) + } + if args[3] != nil { + a.Mul(args[3], BigPow(256, 4)) + } + if args[4] != nil { + b.Mul(args[4], BigPow(256, 5)) + } + if args[5] != nil { + c.Mul(args[5], BigPow(256, 6)) + } + + base.Add(op, x) + base.Add(base, y) + base.Add(base, z) + base.Add(base, a) + base.Add(base, b) + base.Add(base, c) + + return base.String(), nil +} + +func Instr(instr string) (int, []string, error) { + base := new(big.Int) + base.SetString(instr, 0) + + args := make([]string, 7) + for i := 0; i < 7; i++ { + // int(int(val) / int(math.Pow(256,float64(i)))) % 256 + exp := BigPow(256, i) + num := new(big.Int) + num.Div(base, exp) + + args[i] = num.Mod(num, big.NewInt(256)).String() + } + op, _ := strconv.Atoi(args[0]) + + return op, args[1:7], nil +} |