aboutsummaryrefslogtreecommitdiffstats
path: root/parsing.go
blob: d5dcce04fa878bc357666cd191e711b2083ee0d6 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
package main

import (
  "fmt"
  "strings"
  "errors"
  "math/big"
  "strconv"
)

// Op codes
var OpCodes = map[string]string{
  "STOP":       "0",
  "ADD":        "16",  // 0x10
  "SUB":        "17",  // 0x11
  "MUL":        "18",  // 0x12
  "DIV":        "19",  // 0x13
  "SDIV":       "20",  // 0x14
  "MOD":        "21",  // 0x15
  "SMOD":       "22",  // 0x16
  "EXP":        "23",  // 0x17
  "NEG":        "24",  // 0x18
  "LT":         "32",  // 0x20
  "LE":         "33",  // 0x21
  "GT":         "34",  // 0x22
  "GE":         "35",  // 0x23
  "EQ":         "36",  // 0x24
  "NOT":        "37",  // 0x25
  "SHA256":     "48",  // 0x30
  "RIPEMD160":  "49",  // 0x31
  "ECMUL":      "50",  // 0x32
  "ECADD":      "51",  // 0x33
  "SIGN":       "52",  // 0x34
  "RECOVER":    "53",  // 0x35
  "COPY":       "64",  // 0x40
  "ST":         "65",  // 0x41
  "LD":         "66",  // 0x42
  "SET":        "67",  // 0x43
  "JMP":        "80",  // 0x50
  "JMPI":       "81",  // 0x51
  "IND":        "82",  // 0x52
  "EXTRO":      "96",  // 0x60
  "BALANCE":    "97",  // 0x61
  "MKTX":       "112", // 0x70
  "DATA":       "128", // 0x80
  "DATAN":      "129", // 0x81
  "MYADDRESS":  "144", // 0x90
  "BLKHASH":    "145", // 0x91
  "COINBASE":   "146", // 0x92
  "SUICIDE":    "255", // 0xff
}


func CompileInstr(s string) (string, error) {
  tokens := strings.Split(s, " ")
  if OpCodes[tokens[0]] == "" {
    return "", 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
}