Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(gnolang): add support for octals without 'o' (eg. 0755) #1331

Merged
merged 11 commits into from
Dec 18, 2023
2 changes: 2 additions & 0 deletions gnovm/pkg/gnolang/op_eval.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@
_, 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)

Check warning on line 60 in gnovm/pkg/gnolang/op_eval.go

View check run for this annotation

Codecov / codecov/patch

gnovm/pkg/gnolang/op_eval.go#L59-L60

Added lines #L59 - L60 were not covered by tests
notJoon marked this conversation as resolved.
Show resolved Hide resolved
default:
ok = false
}
Expand Down
75 changes: 75 additions & 0 deletions gnovm/pkg/gnolang/op_eval_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
package gnolang_test

import (
"fmt"
"math/big"
"testing"
)

// parseIntegerLiteral function is a Mock-up of the doOpEval() function in `op_eval.go`.
func parseIntegerLiteral(value string) (*big.Int, error) {
if len(value) > 2 && value[0] == '0' {
bi := big.NewInt(0)
var ok bool
switch value[1] {
case 'b', 'B':
_, ok = bi.SetString(value[2:], 2)
case 'o', 'O':
_, ok = bi.SetString(value[2:], 8)
case 'x', 'X':
_, ok = bi.SetString(value[2:], 16)
case '0', '1', '2', '3', '4', '5', '6', '7':
_, ok = bi.SetString(value, 8)
default:
ok = false
}
if !ok {
return nil, fmt.Errorf("invalid integer constant: %s", value)
}
return bi, nil
} else {
bi, ok := new(big.Int).SetString(value, 10)
if !ok {
return nil, fmt.Errorf("invalid integer constant: %s", value)
}
return bi, nil
}
}

type testCase struct {
input string
expected string
hasError bool
}

func TestParseIntegerLiteral(t *testing.T) {
testCases := []testCase{
{"012345", "5349", false},
{"02001", "1025", false},
{"002001", "1025", false},
{"0002001", "1025", false},
{"0o12345", "5349", false},
{"0x1a2b", "6699", false},
{"0xbeefcafe", "3203386110", false},
{"0b1010", "10", false},
{"12345", "12345", false},
{"invalid", "", true},
{"0o12345invalid", "", true},
{"", "", true},
}

for _, tc := range testCases {
result, err := parseIntegerLiteral(tc.input)
notJoon marked this conversation as resolved.
Show resolved Hide resolved
if tc.hasError {
if err == nil {
t.Errorf("Expected error for input %s, but got none", tc.input)
}
} else {
if err != nil {
t.Errorf("Unexpected error for input %s: %v", tc.input, err)
} else if result.String() != tc.expected {
t.Errorf("For input %s, expected %s but got %s", tc.input, tc.expected, result.String())
}
}
}
}
Loading