Skip to content

Commit

Permalink
it works
Browse files Browse the repository at this point in the history
  • Loading branch information
nicksnyder committed Dec 3, 2023
1 parent 2adf25a commit 11caa5f
Show file tree
Hide file tree
Showing 3 changed files with 105 additions and 8 deletions.
9 changes: 5 additions & 4 deletions v2/internal/plural/codegen/xml.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,12 +47,13 @@ func (pr *PluralRule) Condition() string {
return pr.Rule[:i]
}

// Examples returns the integer and decimal exmaples for the PLuralRule.
// Examples returns the integer and decimal examples for the PluralRule.
func (pr *PluralRule) Examples() (integer []string, decimal []string) {
ex := strings.Replace(pr.Rule, ", …", "", -1)
ex := strings.ReplaceAll(pr.Rule, ", …", "")
ddelim := "@decimal"
if i := strings.Index(ex, ddelim); i > 0 {
dex := strings.TrimSpace(ex[i+len(ddelim):])
dex = strings.ReplaceAll(dex, "c", "e")
decimal = strings.Split(dex, ", ")
ex = ex[:i]
}
Expand All @@ -64,13 +65,13 @@ func (pr *PluralRule) Examples() (integer []string, decimal []string) {
return integer, decimal
}

// IntegerExamples returns the integer exmaples for the PluralRule.
// IntegerExamples returns the integer examples for the PluralRule.
func (pr *PluralRule) IntegerExamples() []string {
integer, _ := pr.Examples()
return integer
}

// DecimalExamples returns the decimal exmaples for the PluralRule.
// DecimalExamples returns the decimal examples for the PluralRule.
func (pr *PluralRule) DecimalExamples() []string {
_, decimal := pr.Examples()
return decimal
Expand Down
75 changes: 71 additions & 4 deletions v2/internal/plural/operands.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,17 +81,84 @@ func newOperandsInt64(i int64) *Operands {
return &Operands{float64(i), i, 0, 0, 0, 0, 0}
}

func splitSignificandExponent(s string) (significand, exponent string) {
i := strings.IndexAny(s, "eE")
if i < 0 {
return s, ""
}
return s[:i], s[i+1:]
}

func shiftDecimalLeft(s string, n int) string {
if n <= 0 {
return s
}
i := strings.IndexRune(s, '.')
tilt := 0
if i < 0 {
i = len(s)
tilt = -1
}
switch {
case n == i:
return "0." + s[:i] + s[i+1+tilt:]
case n > i:
return "0." + strings.Repeat("0", n-i) + s[:i] + s[i+1+tilt:]
default:
return s[:i-n] + "." + s[i-n:i] + s[i+1+tilt:]
}
}

func shiftDecimalRight(s string, n int) string {
if n <= 0 {
return s
}
i := strings.IndexRune(s, '.')
if i < 0 {
return s + strings.Repeat("0", n)
}
switch rest := len(s) - i - 1; {
case n == rest:
return s[:i] + s[i+1:]
case n > rest:
return s[:i] + s[i+1:] + strings.Repeat("0", n-rest)
default:
return s[:i] + s[i+1:i+1+n] + "." + s[i+1+n:]
}
}

func applyExponent(s string, exponent int) string {
switch {
case exponent > 0:
return shiftDecimalRight(s, exponent)
case exponent < 0:
return shiftDecimalLeft(s, -exponent)
}
return s
}

func newOperandsString(s string) (*Operands, error) {
if s[0] == '-' {
s = s[1:]
}
// TODO: actually parse scientific notation and populate C
n, err := strconv.ParseFloat(s, 64)
ops := &Operands{}
var err error
ops.N, err = strconv.ParseFloat(s, 64)
if err != nil {
return nil, err
}
ops := &Operands{N: n}
parts := strings.SplitN(s, ".", 2)
significand, exponent := splitSignificandExponent(s)
if exponent != "" {
// We are storing C as an int64 but only allowing
// numbers that fit into the bitsize of an int
// so C is safe to cast as a int later.
ops.C, err = strconv.ParseInt(exponent, 10, 0)
if err != nil {
return nil, err
}
}
value := applyExponent(significand, int(ops.C))
parts := strings.SplitN(value, ".", 2)
ops.I, err = strconv.ParseInt(parts[0], 10, 64)
if err != nil {
return nil, err
Expand Down
29 changes: 29 additions & 0 deletions v2/internal/plural/operands_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,35 @@ func TestNewOperands(t *testing.T) {
{"1.230", &Operands{1.23, 1, 3, 2, 230, 23, 0}, false},
{"20.0230", &Operands{20.023, 20, 4, 3, 230, 23, 0}, false},
{20.0230, nil, true},

{"1200", &Operands{1200, 1200, 0, 0, 0, 0, 0}, false},
{"1.2e3", &Operands{1200, 1200, 0, 0, 0, 0, 3}, false},
{"1.2E3", &Operands{1200, 1200, 0, 0, 0, 0, 3}, false},

{"1234", &Operands{1234, 1234, 0, 0, 0, 0, 0}, false},
{"1234e0", &Operands{1234, 1234, 0, 0, 0, 0, 0}, false},
{"123.4e1", &Operands{1234, 1234, 0, 0, 0, 0, 1}, false},
{"12.34e2", &Operands{1234, 1234, 0, 0, 0, 0, 2}, false},
{"1.234e3", &Operands{1234, 1234, 0, 0, 0, 0, 3}, false},
{"0.1234e4", &Operands{1234, 1234, 0, 0, 0, 0, 4}, false},
{"0.01234e5", &Operands{1234, 1234, 0, 0, 0, 0, 5}, false},

{"1234.0", &Operands{1234, 1234, 1, 0, 0, 0, 0}, false},
{"12340e-1", &Operands{1234, 1234, 1, 0, 0, 0, -1}, false},

{"1200.5", &Operands{1200.5, 1200, 1, 1, 5, 5, 0}, false},
{"1.2005e3", &Operands{1200.5, 1200, 1, 1, 5, 5, 3}, false},

{"1200e3", &Operands{1200000, 1200000, 0, 0, 0, 0, 3}, false},

{"0.0012340", &Operands{0.001234, 0, 7, 6, 12340, 1234, 0}, false},
{"0.012340e-1", &Operands{0.001234, 0, 7, 6, 12340, 1234, -1}, false},
{"0.12340e-2", &Operands{0.001234, 0, 7, 6, 12340, 1234, -2}, false},
{"1.2340e-3", &Operands{0.001234, 0, 7, 6, 12340, 1234, -3}, false},
{"12.340e-4", &Operands{0.001234, 0, 7, 6, 12340, 1234, -4}, false},
{"123.40e-5", &Operands{0.001234, 0, 7, 6, 12340, 1234, -5}, false},
{"1234.0e-6", &Operands{0.001234, 0, 7, 6, 12340, 1234, -6}, false},
{"12340e-7", &Operands{0.001234, 0, 7, 6, 12340, 1234, -7}, false},
}
for _, test := range tests {
ops, err := NewOperands(test.input)
Expand Down

0 comments on commit 11caa5f

Please sign in to comment.