Skip to content

Commit

Permalink
feat(gnolang): add support for octals without 'o' (eg. 0755) (#1331)
Browse files Browse the repository at this point in the history
Updated the condition in `doOpEval` to detect octal literals that start
with a '0' followed by octal digits (0-7)

related with: #1322
  • Loading branch information
notJoon authored Dec 18, 2023
1 parent 384ef75 commit 1cfe9b4
Show file tree
Hide file tree
Showing 4 changed files with 127 additions and 2 deletions.
69 changes: 69 additions & 0 deletions gnovm/pkg/gnolang/gno_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,75 @@ func main() {
m.RunMain()
}

func TestDoOpEvalBaseConversion(t *testing.T) {
m := NewMachine("test", nil)

type testCase struct {
input string
expect string
expectErr bool
}

testCases := []testCase{
// binary
{input: "0b101010", expect: "42", expectErr: false},
{input: "0B101010", expect: "42", expectErr: false},
{input: "0b111111111111111111111111111111111111111111111111111111111111111", expect: "9223372036854775807", expectErr: false},
{input: "0b0", expect: "0", expectErr: false},
{input: "0b000000101010", expect: "42", expectErr: false},
{input: " 0b101010", expectErr: true},
{input: "0b", expectErr: true},
{input: "0bXXXX", expectErr: true},
{input: "42b0", expectErr: true},
// octal
{input: "0o42", expect: "34", expectErr: false},
{input: "0o0", expect: "0", expectErr: false},
{input: "042", expect: "34", expectErr: false},
{input: "0777", expect: "511", expectErr: false},
{input: "0O0000042", expect: "34", expectErr: false},
{input: "0777777777777777777777", expect: "9223372036854775807", expectErr: false},
{input: "0o777777777777777777777", expect: "9223372036854775807", expectErr: false},
{input: "048", expectErr: true},
{input: "0o", expectErr: true},
{input: "0oXXXX", expectErr: true},
{input: "0OXXXX", expectErr: true},
{input: "0o42x42", expectErr: true},
{input: "0O42x42", expectErr: true},
{input: "0420x42", expectErr: true},
{input: "0o420o42", expectErr: true},
// hex
{input: "0x2a", expect: "42", expectErr: false},
{input: "0X2A", expect: "42", expectErr: false},
{input: "0x7FFFFFFFFFFFFFFF", expect: "9223372036854775807", expectErr: false},
{input: "0x2a ", expectErr: true},
{input: "0x", expectErr: true},
{input: "0xXXXX", expectErr: true},
{input: "0xGHIJ", expectErr: true},
{input: "0x42o42", expectErr: true},
{input: "0x2ax42", expectErr: true},
// decimal
{input: "42", expect: "42", expectErr: false},
{input: "0", expect: "0", expectErr: false},
{input: "0000000000", expect: "0", expectErr: false},
{input: "9223372036854775807", expect: "9223372036854775807", expectErr: false},
}

for _, tc := range testCases {
m.PushExpr(&BasicLitExpr{
Kind: INT,
Value: tc.input,
})

if tc.expectErr {
assert.Panics(t, func() { m.doOpEval() })
} else {
m.doOpEval()
v := m.PopValue()
assert.Equal(t, v.V.String(), tc.expect)
}
}
}

func TestEval(t *testing.T) {
t.Parallel()

Expand Down
6 changes: 4 additions & 2 deletions gnovm/pkg/gnolang/op_eval.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,15 +47,17 @@ func (m *Machine) doOpEval() {
bi := big.NewInt(0)
// TODO optimize.
// TODO deal with base.
if len(x.Value) > 2 && x.Value[0] == '0' {
var ok bool = false
var ok bool
if len(x.Value) >= 2 && x.Value[0] == '0' {
switch x.Value[1] {
case 'b', 'B':
_, ok = bi.SetString(x.Value[2:], 2)
case 'o', 'O':
_, ok = bi.SetString(x.Value[2:], 8)
case 'x', 'X':
_, ok = bi.SetString(x.Value[2:], 16)
case '0', '1', '2', '3', '4', '5', '6', '7':
_, ok = bi.SetString(x.Value, 8)
default:
ok = false
}
Expand Down
27 changes: 27 additions & 0 deletions gnovm/tests/files/base_conv0.gno
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package main

func main() {
// binary
println(0b1010)
println(0B1010)

// decimal
println(10)

// octal
println(0o12)
println(012)

// hex
println(0xA)
println(0xa)
}

// Output:
// 10
// 10
// 10
// 10
// 10
// 10
// 10
27 changes: 27 additions & 0 deletions gnovm/tests/files/base_conv1.gno
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package main

func main() {
// binary
println(-0b1010)
println(-0B1010)

// decimal
println(-10)

// octal
println(-0o12)
println(-012)

// hex
println(-0xA)
println(-0xa)
}

// Output:
// -10
// -10
// -10
// -10
// -10
// -10
// -10

0 comments on commit 1cfe9b4

Please sign in to comment.