Compare commits
3 Commits
52a627c747
...
526982a564
Author | SHA1 | Date | |
---|---|---|---|
526982a564 | |||
252514943e | |||
32686fac62 |
@ -7,7 +7,6 @@ package expr
|
|||||||
//https://www.youmath.it/lezioni/algebra-elementare/lezioni-di-algebra-e-aritmetica-per-scuole-medie/553-dalle-frazioni-a-numeri-decimali.html
|
//https://www.youmath.it/lezioni/algebra-elementare/lezioni-di-algebra-e-aritmetica-per-scuole-medie/553-dalle-frazioni-a-numeri-decimali.html
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -41,7 +40,7 @@ func evalFraction(ctx ExprContext, opTerm *term) (v any, err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
if den == 0 {
|
if den == 0 {
|
||||||
err = errors.New("division by zero")
|
err = opTerm.errDivisionByZero()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,7 +5,6 @@
|
|||||||
package expr
|
package expr
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -69,7 +68,7 @@ func divValues(opTerm *term, leftValue, rightValue any) (v any, err error) {
|
|||||||
if IsFloat(leftValue) || IsFloat(rightValue) {
|
if IsFloat(leftValue) || IsFloat(rightValue) {
|
||||||
d := numAsFloat(rightValue)
|
d := numAsFloat(rightValue)
|
||||||
if d == 0.0 {
|
if d == 0.0 {
|
||||||
err = errors.New("division by zero")
|
err = opTerm.errDivisionByZero()
|
||||||
} else {
|
} else {
|
||||||
v = numAsFloat(leftValue) / d
|
v = numAsFloat(leftValue) / d
|
||||||
}
|
}
|
||||||
@ -78,11 +77,36 @@ func divValues(opTerm *term, leftValue, rightValue any) (v any, err error) {
|
|||||||
} else {
|
} else {
|
||||||
leftInt, _ := leftValue.(int64)
|
leftInt, _ := leftValue.(int64)
|
||||||
if rightInt, _ := rightValue.(int64); rightInt == 0 {
|
if rightInt, _ := rightValue.(int64); rightInt == 0 {
|
||||||
err = errors.New("division by zero")
|
err = opTerm.errDivisionByZero()
|
||||||
} else {
|
} else {
|
||||||
v = leftInt / rightInt
|
v = leftInt / rightInt
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else if IsString(leftValue) && IsString(rightValue) {
|
||||||
|
source := leftValue.(string)
|
||||||
|
sep := rightValue.(string)
|
||||||
|
v = ListFromStrings(strings.Split(source, sep))
|
||||||
|
} else if IsString(leftValue) && IsInteger(rightValue) {
|
||||||
|
source := leftValue.(string)
|
||||||
|
partSize := int(rightValue.(int64))
|
||||||
|
if partSize == 0 {
|
||||||
|
err = opTerm.errDivisionByZero()
|
||||||
|
} else {
|
||||||
|
partCount := len(source) / partSize
|
||||||
|
remainder := len(source) % partSize
|
||||||
|
listSize := partCount
|
||||||
|
if remainder > 0 {
|
||||||
|
listSize++
|
||||||
|
}
|
||||||
|
parts := make([]any, 0, listSize)
|
||||||
|
for i := 0; i < partCount; i++ {
|
||||||
|
parts = append(parts, source[i*partSize:(i+1)*partSize])
|
||||||
|
}
|
||||||
|
if remainder > 0 {
|
||||||
|
parts = append(parts, source[len(source)-remainder:])
|
||||||
|
}
|
||||||
|
v = newList(parts)
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
err = opTerm.errIncompatibleTypes(leftValue, rightValue)
|
err = opTerm.errIncompatibleTypes(leftValue, rightValue)
|
||||||
}
|
}
|
||||||
@ -121,7 +145,7 @@ func evalDivideAsFloat(ctx ExprContext, floatDivTerm *term) (v any, err error) {
|
|||||||
if isNumOrFract(leftValue) && isNumOrFract(rightValue) {
|
if isNumOrFract(leftValue) && isNumOrFract(rightValue) {
|
||||||
d := numAsFloat(rightValue)
|
d := numAsFloat(rightValue)
|
||||||
if d == 0.0 {
|
if d == 0.0 {
|
||||||
err = errors.New("division by zero")
|
err = floatDivTerm.errDivisionByZero()
|
||||||
} else {
|
} else {
|
||||||
v = numAsFloat(leftValue) / d
|
v = numAsFloat(leftValue) / d
|
||||||
}
|
}
|
||||||
@ -146,7 +170,7 @@ func remainderValues(opTerm *term, leftValue, rightValue any) (v any, err error)
|
|||||||
if IsInteger(leftValue) && IsInteger(rightValue) {
|
if IsInteger(leftValue) && IsInteger(rightValue) {
|
||||||
rightInt, _ := rightValue.(int64)
|
rightInt, _ := rightValue.(int64)
|
||||||
if rightInt == 0 {
|
if rightInt == 0 {
|
||||||
err = errors.New("division by zero")
|
err = opTerm.errDivisionByZero()
|
||||||
} else {
|
} else {
|
||||||
leftInt, _ := leftValue.(int64)
|
leftInt, _ := leftValue.(int64)
|
||||||
v = leftInt % rightInt
|
v = leftInt % rightInt
|
||||||
|
@ -452,9 +452,12 @@ func (parser *parser) parseGeneral(scanner *scanner, ctx parserContext, termSymb
|
|||||||
case SymOpenRound:
|
case SymOpenRound:
|
||||||
var subTree *ast
|
var subTree *ast
|
||||||
if subTree, err = parser.parseGeneral(scanner, ctx, SymClosedRound); err == nil {
|
if subTree, err = parser.parseGeneral(scanner, ctx, SymClosedRound); err == nil {
|
||||||
subTree.root.priority = priValue
|
exprTerm := newExprTerm(subTree.root)
|
||||||
err = tree.addTerm(newExprTerm(subTree.root))
|
err = tree.addTerm(exprTerm)
|
||||||
currentTerm = subTree.root
|
currentTerm = exprTerm
|
||||||
|
// subTree.root.priority = priValue
|
||||||
|
// err = tree.addTerm(newExprTerm(subTree.root))
|
||||||
|
// currentTerm = subTree.root
|
||||||
}
|
}
|
||||||
case SymFuncCall:
|
case SymFuncCall:
|
||||||
var funcCallTerm *term
|
var funcCallTerm *term
|
||||||
|
@ -25,7 +25,7 @@ func TestFractionsParser(t *testing.T) {
|
|||||||
/* 12 */ {`builtin "math.arith"; add(1:2, 1.0, 2)`, float64(3.5), nil},
|
/* 12 */ {`builtin "math.arith"; add(1:2, 1.0, 2)`, float64(3.5), nil},
|
||||||
/* 13 */ {`builtin "math.arith"; mul(1:2, 2:3)`, newFraction(2, 6), nil},
|
/* 13 */ {`builtin "math.arith"; mul(1:2, 2:3)`, newFraction(2, 6), nil},
|
||||||
/* 14 */ {`builtin "math.arith"; mul(1:2, 1.0, 2)`, float64(1.0), nil},
|
/* 14 */ {`builtin "math.arith"; mul(1:2, 1.0, 2)`, float64(1.0), nil},
|
||||||
/* 15 */ {`1:0`, nil, `division by zero`},
|
/* 15 */ {`1:0`, nil, `[1:3] division by zero`},
|
||||||
/* 16 */ {`fract(-0.5)`, newFraction(-1, 2), nil},
|
/* 16 */ {`fract(-0.5)`, newFraction(-1, 2), nil},
|
||||||
/* 17 */ {`fract("")`, (*FractionType)(nil), `bad syntax`},
|
/* 17 */ {`fract("")`, (*FractionType)(nil), `bad syntax`},
|
||||||
/* 18 */ {`fract("-1")`, newFraction(-1, 1), nil},
|
/* 18 */ {`fract("-1")`, newFraction(-1, 1), nil},
|
||||||
@ -34,7 +34,7 @@ func TestFractionsParser(t *testing.T) {
|
|||||||
/* 21 */ {`fract(1,0)`, nil, `fract(): division by zero`},
|
/* 21 */ {`fract(1,0)`, nil, `fract(): division by zero`},
|
||||||
/* 22 */ {`string(1:2)`, "1:2", nil},
|
/* 22 */ {`string(1:2)`, "1:2", nil},
|
||||||
/* 23 */ {`1+1:2+0.5`, float64(2), nil},
|
/* 23 */ {`1+1:2+0.5`, float64(2), nil},
|
||||||
/* 24 */ {`1:(2-2)`, nil, `division by zero`},
|
/* 24 */ {`1:(2-2)`, nil, `[1:3] division by zero`},
|
||||||
/* 25 */ {`[0,1][1-1]:1`, newFraction(0, 1), nil},
|
/* 25 */ {`[0,1][1-1]:1`, newFraction(0, 1), nil},
|
||||||
}
|
}
|
||||||
// runTestSuiteSpec(t, section, inputs, 25)
|
// runTestSuiteSpec(t, section, inputs, 25)
|
||||||
|
@ -78,8 +78,8 @@ func TestGeneralParser(t *testing.T) {
|
|||||||
/* 64 */ {`"1.5" != `, nil, `[1:8] infix operator "!=" requires two non-nil operands, got 1`},
|
/* 64 */ {`"1.5" != `, nil, `[1:8] infix operator "!=" requires two non-nil operands, got 1`},
|
||||||
/* 65 */ {"+1.5", float64(1.5), nil},
|
/* 65 */ {"+1.5", float64(1.5), nil},
|
||||||
/* 66 */ {"+", nil, `[1:2] prefix operator "+" requires one non-nil operand`},
|
/* 66 */ {"+", nil, `[1:2] prefix operator "+" requires one non-nil operand`},
|
||||||
/* 67 */ {"4 / 0", nil, `division by zero`},
|
/* 67 */ {"4 / 0", nil, `[1:4] division by zero`},
|
||||||
/* 68 */ {"4.0 / 0", nil, `division by zero`},
|
/* 68 */ {"4.0 / 0", nil, `[1:6] division by zero`},
|
||||||
/* 69 */ {"4.0 / \n2", float64(2.0), nil},
|
/* 69 */ {"4.0 / \n2", float64(2.0), nil},
|
||||||
/* 70 */ {`123`, int64(123), nil},
|
/* 70 */ {`123`, int64(123), nil},
|
||||||
/* 71 */ {`1.`, float64(1.0), nil},
|
/* 71 */ {`1.`, float64(1.0), nil},
|
||||||
|
@ -16,6 +16,12 @@ func TestStringsParser(t *testing.T) {
|
|||||||
/* 4 */ {`"uno" * (2+1)`, `unounouno`, nil},
|
/* 4 */ {`"uno" * (2+1)`, `unounouno`, nil},
|
||||||
/* 5 */ {`"abc"[1]`, `b`, nil},
|
/* 5 */ {`"abc"[1]`, `b`, nil},
|
||||||
/* 6 */ {`#"abc"`, int64(3), nil},
|
/* 6 */ {`#"abc"`, int64(3), nil},
|
||||||
|
/* 7 */ {`"192.168.0.240" / "."`, newListA("192", "168", "0", "240"), nil},
|
||||||
|
/* 8 */ {`("192.168.0.240" / ".")[1]`, "168", nil},
|
||||||
|
/* 9 */ {`"AF3B0Dz" / 2`, newListA("AF", "3B", "0D", "z"), nil},
|
||||||
|
/* 10 */ {`"AF3B0Dz" / 0`, nil, "[1:12] division by zero"},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// runTestSuiteSpec(t, "String", inputs, 8)
|
||||||
runTestSuite(t, "String", inputs)
|
runTestSuite(t, "String", inputs)
|
||||||
}
|
}
|
||||||
|
4
term.go
4
term.go
@ -203,6 +203,10 @@ func (term *term) errIncompatibleType(value any) error {
|
|||||||
term.source(), value, TypeName(value))
|
term.source(), value, TypeName(value))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (term *term) errDivisionByZero() error {
|
||||||
|
return term.tk.Errorf("division by zero")
|
||||||
|
}
|
||||||
|
|
||||||
func (term *term) Errorf(template string, args ...any) (err error) {
|
func (term *term) Errorf(template string, args ...any) (err error) {
|
||||||
err = term.tk.Errorf(template, args...)
|
err = term.tk.Errorf(template, args...)
|
||||||
return
|
return
|
||||||
|
Loading…
Reference in New Issue
Block a user