Compare commits
4 Commits
v0.30.0
...
e43823740f
| Author | SHA1 | Date | |
|---|---|---|---|
| e43823740f | |||
| 526982a564 | |||
| 252514943e | |||
| 32686fac62 |
+3
-1
@@ -754,10 +754,12 @@ The table below shows all supported operators by decreasing priorities.
|
|||||||
.2+|*SELECT*| [blue]`? : ::` | _Multi-Infix_ | _Case-Selector_ | _any-expr_ `?` _case-list_ _case-expr_ `:` _case-list_ _case-expr_ ... `::` _default-expr_ -> _any_
|
.2+|*SELECT*| [blue]`? : ::` | _Multi-Infix_ | _Case-Selector_ | _any-expr_ `?` _case-list_ _case-expr_ `:` _case-list_ _case-expr_ ... `::` _default-expr_ -> _any_
|
||||||
| [blue]`? : ::` | _Multi-Infix_ | _Index-Selector_ | _int-expr_ `?` _case-expr_ `:` _case-expr_ ... `::` _default-expr_ -> _any_
|
| [blue]`? : ::` | _Multi-Infix_ | _Index-Selector_ | _int-expr_ `?` _case-expr_ `:` _case-expr_ ... `::` _default-expr_ -> _any_
|
||||||
.1+|*FRACT*| [blue]`:` | _Infix_ | _Fraction_ | _integer_ `:` _integer_ -> _fraction_
|
.1+|*FRACT*| [blue]`:` | _Infix_ | _Fraction_ | _integer_ `:` _integer_ -> _fraction_
|
||||||
.5+|*PROD*| [blue]`*` | _Infix_ | _Product_ | _number_ `*` _number_ -> _number_
|
.7+|*PROD*| [blue]`*` | _Infix_ | _Product_ | _number_ `*` _number_ -> _number_
|
||||||
| [blue]`*` | _Infix_ | _String-repeat_ | _string_ `*` _integer_ -> _string_
|
| [blue]`*` | _Infix_ | _String-repeat_ | _string_ `*` _integer_ -> _string_
|
||||||
| [blue]`/` | _Infix_ | _Division_ | _number_ `/` _number_ -> _number_
|
| [blue]`/` | _Infix_ | _Division_ | _number_ `/` _number_ -> _number_
|
||||||
| [blue]`./` | _Infix_ | _Float-division_ | __number__ `./` _number_ -> _float_
|
| [blue]`./` | _Infix_ | _Float-division_ | __number__ `./` _number_ -> _float_
|
||||||
|
| [blue]`/` | _Infix_ | _Split_ | _string_ `/` _string_ -> _list_
|
||||||
|
| [blue]`/` | _Infix_ | _Split_ | _string_ `/` integer -> _list_
|
||||||
| [blue]`%` | _Infix_ | _Integer-remainder_ | _integer_ `%` _integer_ -> _integer_
|
| [blue]`%` | _Infix_ | _Integer-remainder_ | _integer_ `%` _integer_ -> _integer_
|
||||||
.6+|*SUM*| [blue]`+` | _Infix_ | _Sum_ | _number_ `+` _number_ -> _number_
|
.6+|*SUM*| [blue]`+` | _Infix_ | _Sum_ | _number_ `+` _number_ -> _number_
|
||||||
| [blue]`+` | _Infix_ | _String-concat_ | (_string_\|_number_) `+` (_string_\|_number_) -> _string_
|
| [blue]`+` | _Infix_ | _String-concat_ | (_string_\|_number_) `+` (_string_\|_number_) -> _string_
|
||||||
|
|||||||
+14
-2
@@ -2008,7 +2008,7 @@ These operators have a high priority, in particular higher than the operator <co
|
|||||||
<td class="tableblock halign-center valign-top"><p class="tableblock"><em>integer</em> <code>:</code> <em>integer</em> → <em>fraction</em></p></td>
|
<td class="tableblock halign-center valign-top"><p class="tableblock"><em>integer</em> <code>:</code> <em>integer</em> → <em>fraction</em></p></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td class="tableblock halign-center valign-top" rowspan="5"><p class="tableblock"><strong>PROD</strong></p></td>
|
<td class="tableblock halign-center valign-top" rowspan="7"><p class="tableblock"><strong>PROD</strong></p></td>
|
||||||
<td class="tableblock halign-center valign-top"><p class="tableblock"><code class="blue">*</code></p></td>
|
<td class="tableblock halign-center valign-top"><p class="tableblock"><code class="blue">*</code></p></td>
|
||||||
<td class="tableblock halign-center valign-top"><p class="tableblock"><em>Infix</em></p></td>
|
<td class="tableblock halign-center valign-top"><p class="tableblock"><em>Infix</em></p></td>
|
||||||
<td class="tableblock halign-center valign-top"><p class="tableblock"><em>Product</em></p></td>
|
<td class="tableblock halign-center valign-top"><p class="tableblock"><em>Product</em></p></td>
|
||||||
@@ -2033,6 +2033,18 @@ These operators have a high priority, in particular higher than the operator <co
|
|||||||
<td class="tableblock halign-center valign-top"><p class="tableblock"><em>number</em> <code>./</code> <em>number</em> → <em>float</em></p></td>
|
<td class="tableblock halign-center valign-top"><p class="tableblock"><em>number</em> <code>./</code> <em>number</em> → <em>float</em></p></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
|
<td class="tableblock halign-center valign-top"><p class="tableblock"><code class="blue">/</code></p></td>
|
||||||
|
<td class="tableblock halign-center valign-top"><p class="tableblock"><em>Infix</em></p></td>
|
||||||
|
<td class="tableblock halign-center valign-top"><p class="tableblock"><em>Split</em></p></td>
|
||||||
|
<td class="tableblock halign-center valign-top"><p class="tableblock"><em>string</em> <code>/</code> <em>string</em> → <em>list</em></p></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="tableblock halign-center valign-top"><p class="tableblock"><code class="blue">/</code></p></td>
|
||||||
|
<td class="tableblock halign-center valign-top"><p class="tableblock"><em>Infix</em></p></td>
|
||||||
|
<td class="tableblock halign-center valign-top"><p class="tableblock"><em>Split</em></p></td>
|
||||||
|
<td class="tableblock halign-center valign-top"><p class="tableblock"><em>string</em> <code>/</code> integer → <em>list</em></p></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
<td class="tableblock halign-center valign-top"><p class="tableblock"><code class="blue">%</code></p></td>
|
<td class="tableblock halign-center valign-top"><p class="tableblock"><code class="blue">%</code></p></td>
|
||||||
<td class="tableblock halign-center valign-top"><p class="tableblock"><em>Infix</em></p></td>
|
<td class="tableblock halign-center valign-top"><p class="tableblock"><em>Infix</em></p></td>
|
||||||
<td class="tableblock halign-center valign-top"><p class="tableblock"><em>Integer-remainder</em></p></td>
|
<td class="tableblock halign-center valign-top"><p class="tableblock"><em>Integer-remainder</em></p></td>
|
||||||
@@ -2476,7 +2488,7 @@ g(@p):any{}`
|
|||||||
</div>
|
</div>
|
||||||
<div id="footer">
|
<div id="footer">
|
||||||
<div id="footer-text">
|
<div id="footer-text">
|
||||||
Last updated 2024-12-28 09:13:00 +0100
|
Last updated 2024-12-28 19:21:30 +0100
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
|
|||||||
@@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+29
-5
@@ -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
|
||||||
|
|||||||
+2
-2
@@ -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)
|
||||||
|
|||||||
+2
-2
@@ -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)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user