Can process hex numbers

This commit is contained in:
Mike Farah 2021-09-02 15:26:44 +10:00
parent f848e334ee
commit eea2c97cd8
7 changed files with 117 additions and 9 deletions

View File

@ -15,6 +15,16 @@ var pathTests = []struct {
expectedTokens []interface{} expectedTokens []interface{}
expectedPostFix []interface{} expectedPostFix []interface{}
}{ }{
{
"0x12",
append(make([]interface{}, 0), "18 (int64)"),
append(make([]interface{}, 0), "18 (int64)"),
},
{
"0X12",
append(make([]interface{}, 0), "18 (int64)"),
append(make([]interface{}, 0), "18 (int64)"),
},
{ {
".a\n", ".a\n",
append(make([]interface{}, 0), "a"), append(make([]interface{}, 0), "a"),

View File

@ -166,6 +166,20 @@ func numberValue() lex.Action {
} }
} }
func hexValue() lex.Action {
return func(s *lex.Scanner, m *machines.Match) (interface{}, error) {
var originalString = string(m.Bytes)
var numberString = originalString[2:]
log.Debugf("numberString: %v", numberString)
var number, errParsingInt = strconv.ParseInt(numberString, 16, 64) // nolint
if errParsingInt != nil {
return nil, errParsingInt
}
return &token{TokenType: operationToken, Operation: createValueOperation(number, originalString)}, nil
}
}
func floatValue() lex.Action { func floatValue() lex.Action {
return func(s *lex.Scanner, m *machines.Match) (interface{}, error) { return func(s *lex.Scanner, m *machines.Match) (interface{}, error) {
var numberString = string(m.Bytes) var numberString = string(m.Bytes)
@ -328,6 +342,7 @@ func initLexer() (*lex.Lexer, error) {
lexer.Add([]byte(`\|`), opToken(pipeOpType)) lexer.Add([]byte(`\|`), opToken(pipeOpType))
lexer.Add([]byte(`0[xX][0-9A-Fa-f]+`), hexValue())
lexer.Add([]byte(`-?\d+(\.\d+)`), floatValue()) lexer.Add([]byte(`-?\d+(\.\d+)`), floatValue())
lexer.Add([]byte(`-?[1-9](\.\d+)?[Ee][-+]?\d+`), floatValue()) lexer.Add([]byte(`-?[1-9](\.\d+)?[Ee][-+]?\d+`), floatValue())
lexer.Add([]byte(`-?\d+`), numberValue()) lexer.Add([]byte(`-?\d+`), numberValue())

View File

@ -6,6 +6,8 @@ import (
"bytes" "bytes"
"container/list" "container/list"
"fmt" "fmt"
"strconv"
"strings"
logging "gopkg.in/op/go-logging.v1" logging "gopkg.in/op/go-logging.v1"
yaml "gopkg.in/yaml.v3" yaml "gopkg.in/yaml.v3"
@ -117,6 +119,17 @@ type Operation struct {
UpdateAssign bool // used for assign ops, when true it means we evaluate the rhs given the lhs UpdateAssign bool // used for assign ops, when true it means we evaluate the rhs given the lhs
} }
// yaml numbers can be hex encoded...
func parseInt(numberString string) (string, int64, error) {
if strings.HasPrefix(numberString, "0x") ||
strings.HasPrefix(numberString, "0X") {
num, err := strconv.ParseInt(numberString[2:], 16, 64) // nolint
return "0x%X", num, err
}
num, err := strconv.ParseInt(numberString, 10, 64) // nolint
return "%v", num, err
}
func createScalarNode(value interface{}, stringValue string) *yaml.Node { func createScalarNode(value interface{}, stringValue string) *yaml.Node {
var node = &yaml.Node{Kind: yaml.ScalarNode} var node = &yaml.Node{Kind: yaml.ScalarNode}
node.Value = stringValue node.Value = stringValue

View File

@ -76,17 +76,17 @@ func addScalars(target *CandidateNode, lhs *yaml.Node, rhs *yaml.Node) (*Candida
target.Node.Tag = "!!str" target.Node.Tag = "!!str"
target.Node.Value = lhs.Value + rhs.Value target.Node.Value = lhs.Value + rhs.Value
} else if lhs.Tag == "!!int" && rhs.Tag == "!!int" { } else if lhs.Tag == "!!int" && rhs.Tag == "!!int" {
lhsNum, err := strconv.Atoi(lhs.Value) format, lhsNum, err := parseInt(lhs.Value)
if err != nil { if err != nil {
return nil, err return nil, err
} }
rhsNum, err := strconv.Atoi(rhs.Value) _, rhsNum, err := parseInt(rhs.Value)
if err != nil { if err != nil {
return nil, err return nil, err
} }
sum := lhsNum + rhsNum sum := lhsNum + rhsNum
target.Node.Tag = "!!int" target.Node.Tag = "!!int"
target.Node.Value = fmt.Sprintf("%v", sum) target.Node.Value = fmt.Sprintf(format, sum)
} else if (lhs.Tag == "!!int" || lhs.Tag == "!!float") && (rhs.Tag == "!!int" || rhs.Tag == "!!float") { } else if (lhs.Tag == "!!int" || lhs.Tag == "!!float") && (rhs.Tag == "!!int" || rhs.Tag == "!!float") {
lhsNum, err := strconv.ParseFloat(lhs.Value, 64) lhsNum, err := strconv.ParseFloat(lhs.Value, 64)
if err != nil { if err != nil {

View File

@ -91,15 +91,15 @@ func multiplyIntegers(lhs *CandidateNode, rhs *CandidateNode) (*CandidateNode, e
target.Node.Style = lhs.Node.Style target.Node.Style = lhs.Node.Style
target.Node.Tag = "!!int" target.Node.Tag = "!!int"
lhsNum, err := strconv.Atoi(lhs.Node.Value) format, lhsNum, err := parseInt(lhs.Node.Value)
if err != nil { if err != nil {
return nil, err return nil, err
} }
rhsNum, err := strconv.Atoi(rhs.Node.Value) _, rhsNum, err := parseInt(rhs.Node.Value)
if err != nil { if err != nil {
return nil, err return nil, err
} }
target.Node.Value = fmt.Sprintf("%v", lhsNum*rhsNum) target.Node.Value = fmt.Sprintf(format, lhsNum*rhsNum)
return target, nil return target, nil
} }

View File

@ -62,17 +62,17 @@ func subtractScalars(target *CandidateNode, lhs *yaml.Node, rhs *yaml.Node) (*Ca
if lhs.Tag == "!!str" { if lhs.Tag == "!!str" {
return nil, fmt.Errorf("strings cannot be subtracted") return nil, fmt.Errorf("strings cannot be subtracted")
} else if lhs.Tag == "!!int" && rhs.Tag == "!!int" { } else if lhs.Tag == "!!int" && rhs.Tag == "!!int" {
lhsNum, err := strconv.Atoi(lhs.Value) format, lhsNum, err := parseInt(lhs.Value)
if err != nil { if err != nil {
return nil, err return nil, err
} }
rhsNum, err := strconv.Atoi(rhs.Value) _, rhsNum, err := parseInt(rhs.Value)
if err != nil { if err != nil {
return nil, err return nil, err
} }
result := lhsNum - rhsNum result := lhsNum - rhsNum
target.Node.Tag = "!!int" target.Node.Tag = "!!int"
target.Node.Value = fmt.Sprintf("%v", result) target.Node.Value = fmt.Sprintf(format, result)
} else if (lhs.Tag == "!!int" || lhs.Tag == "!!float") && (rhs.Tag == "!!int" || rhs.Tag == "!!float") { } else if (lhs.Tag == "!!int" || lhs.Tag == "!!float") && (rhs.Tag == "!!int" || rhs.Tag == "!!float") {
lhsNum, err := strconv.ParseFloat(lhs.Value, 64) lhsNum, err := strconv.ParseFloat(lhs.Value, 64)
if err != nil { if err != nil {

View File

@ -12,6 +12,76 @@ var valueOperatorScenarios = []expressionScenario{
"D0, P[], (!!int)::1\n", "D0, P[], (!!int)::1\n",
}, },
}, },
{
document: ``,
expression: `0x9f`,
expected: []string{
"D0, P[], (!!int)::0x9f\n",
},
},
{
document: ``,
expression: `0x1A`,
expected: []string{
"D0, P[], (!!int)::0x1A\n",
},
},
{
document: ``,
expression: `0x1A + 2`,
expected: []string{
"D0, P[], (!!int)::0x1C\n",
},
},
{
document: ``,
expression: `0x12 * 2`,
expected: []string{
"D0, P[], (!!int)::0x24\n",
},
},
{
document: ``,
expression: `0xF - 1`,
expected: []string{
"D0, P[], (!!int)::0xE\n",
},
},
{
document: ``,
expression: `12`,
expected: []string{
"D0, P[], (!!int)::12\n",
},
},
{
document: ``,
expression: `12 + 2`,
expected: []string{
"D0, P[], (!!int)::14\n",
},
},
{
document: ``,
expression: `12 * 2`,
expected: []string{
"D0, P[], (!!int)::24\n",
},
},
{
document: ``,
expression: `12 - 2`,
expected: []string{
"D0, P[], (!!int)::10\n",
},
},
{
document: ``,
expression: `0X12`,
expected: []string{
"D0, P[], (!!int)::0X12\n",
},
},
{ {
document: ``, document: ``,
expression: `-1`, expression: `-1`,