Completed transition of the symbol '|' from fraction to operator binary or. New fraction symbol is ':'.
Also, fixed and improved some parsing sections concerning collection indeces and ranges
This commit is contained in:
parent
f50ddf48db
commit
6211be8a8f
@ -50,9 +50,9 @@ func makeGeneratingFraction(s string) (f *FractionType, err error) {
|
|||||||
} else if s[0] == '+' {
|
} else if s[0] == '+' {
|
||||||
s = s[1:]
|
s = s[1:]
|
||||||
}
|
}
|
||||||
// if strings.HasSuffix(s, "()") {
|
// if strings.HasSuffix(s, "()") {
|
||||||
// s = s[0 : len(s)-2]
|
// s = s[0 : len(s)-2]
|
||||||
// }
|
// }
|
||||||
s = strings.TrimSuffix(s, "()")
|
s = strings.TrimSuffix(s, "()")
|
||||||
parts = strings.SplitN(s, ".", 2)
|
parts = strings.SplitN(s, ".", 2)
|
||||||
if num, err = strconv.ParseInt(parts[0], 10, 64); err != nil {
|
if num, err = strconv.ParseInt(parts[0], 10, 64); err != nil {
|
||||||
@ -124,7 +124,7 @@ func (f *FractionType) String() string {
|
|||||||
func (f *FractionType) ToString(opt FmtOpt) string {
|
func (f *FractionType) ToString(opt FmtOpt) string {
|
||||||
var sb strings.Builder
|
var sb strings.Builder
|
||||||
if opt&MultiLine == 0 {
|
if opt&MultiLine == 0 {
|
||||||
sb.WriteString(fmt.Sprintf("%d|%d", f.num, f.den))
|
sb.WriteString(fmt.Sprintf("%d:%d", f.num, f.den))
|
||||||
} else {
|
} else {
|
||||||
var s, num string
|
var s, num string
|
||||||
if f.num < 0 && opt&TTY == 0 {
|
if f.num < 0 && opt&TTY == 0 {
|
||||||
|
@ -100,5 +100,5 @@ func evalBinaryOr(ctx ExprContext, self *term) (v any, err error) {
|
|||||||
func init() {
|
func init() {
|
||||||
registerTermConstructor(SymTilde, newBinNotTerm)
|
registerTermConstructor(SymTilde, newBinNotTerm)
|
||||||
registerTermConstructor(SymAmpersand, newBinAndTerm)
|
registerTermConstructor(SymAmpersand, newBinAndTerm)
|
||||||
// registerTermConstructor(SymVertBar, newBinOrTerm)
|
registerTermConstructor(SymVertBar, newBinOrTerm)
|
||||||
}
|
}
|
||||||
|
@ -49,19 +49,23 @@ func evalFraction(ctx ExprContext, opTerm *term) (v any, err error) {
|
|||||||
den = -den
|
den = -den
|
||||||
num = -num
|
num = -num
|
||||||
}
|
}
|
||||||
g := gcd(num, den)
|
if num != 0 {
|
||||||
num = num / g
|
g := gcd(num, den)
|
||||||
den = den / g
|
num = num / g
|
||||||
if den == 1 {
|
den = den / g
|
||||||
v = num
|
if den == 1 {
|
||||||
|
v = num
|
||||||
|
} else {
|
||||||
|
v = &FractionType{num, den}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
v = &FractionType{num, den}
|
v = &FractionType{0, den}
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// init
|
// init
|
||||||
func init() {
|
func init() {
|
||||||
registerTermConstructor(SymVertBar, newFractionTerm)
|
// registerTermConstructor(SymVertBar, newFractionTerm)
|
||||||
// registerTermConstructor(SymColon, newFractionTerm)
|
registerTermConstructor(SymColon, newFractionTerm)
|
||||||
}
|
}
|
||||||
|
@ -113,6 +113,9 @@ func evalIndex(ctx ExprContext, opTerm *term) (v any, err error) {
|
|||||||
} else if IsDict(leftValue) {
|
} else if IsDict(leftValue) {
|
||||||
d := leftValue.(*DictType)
|
d := leftValue.(*DictType)
|
||||||
v, err = getDictItem(d, indexTerm, indexList, rightValue)
|
v, err = getDictItem(d, indexTerm, indexList, rightValue)
|
||||||
|
} else {
|
||||||
|
rightChild := opTerm.children[1]
|
||||||
|
err = rightChild.Errorf("invalid index type: %v", (*indexList)[0])
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
78
parser.go
78
parser.go
@ -162,29 +162,33 @@ func paramAlreadyDefined(args []*term, param *term) (position int) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (parser *parser) parseList(scanner *scanner, ctx parserContext) (subtree *term, err error) {
|
func (parser *parser) parseList(scanner *scanner, ctx parserContext) (listTerm *term, err error) {
|
||||||
r, c := scanner.lastPos()
|
r, c := scanner.lastPos()
|
||||||
args := make([]*term, 0)
|
args := make([]*term, 0)
|
||||||
lastSym := SymUnknown
|
lastSym := SymUnknown
|
||||||
itemExpected := false
|
itemExpected := false
|
||||||
|
itemCtx := remFlags(ctx, allowIndex)
|
||||||
for lastSym != SymClosedSquare && lastSym != SymEos {
|
for lastSym != SymClosedSquare && lastSym != SymEos {
|
||||||
var subTree *ast
|
|
||||||
zeroRequired := scanner.current.Sym == SymColon
|
zeroRequired := scanner.current.Sym == SymColon
|
||||||
if subTree, err = parser.parseItem(scanner, ctx, SymComma, SymClosedSquare); err == nil {
|
var itemTree *ast
|
||||||
root := subTree.root
|
if itemTree, err = parser.parseItem(scanner, itemCtx, SymComma, SymClosedSquare); err == nil {
|
||||||
|
root := itemTree.root
|
||||||
if root != nil {
|
if root != nil {
|
||||||
//if !parsingIndeces && root.symbol() == SymColon {
|
if hasFlag(ctx, allowIndex) && root.symbol() == SymColon {
|
||||||
if !hasFlag(ctx, allowIndex) && root.symbol() == SymColon {
|
changeColonToRange(root)
|
||||||
err = root.Errorf("unexpected range expression")
|
}
|
||||||
|
if !hasFlag(ctx, allowIndex) && root.symbol() == SymRange {
|
||||||
|
// err = root.Errorf("unexpected range expression")
|
||||||
|
err = errRangeUnexpectedExpression(root)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
args = append(args, root)
|
args = append(args, root)
|
||||||
// if parsingIndeces && root.symbol() == SymColon && zeroRequired { //len(root.children) == 0 {
|
if hasFlag(ctx, allowIndex) && root.symbol() == SymRange && zeroRequired { //len(root.children) == 0 {
|
||||||
if hasFlag(ctx, allowIndex) && root.symbol() == SymColon && zeroRequired { //len(root.children) == 0 {
|
|
||||||
if len(root.children) == 1 {
|
if len(root.children) == 1 {
|
||||||
root.children = append(root.children, root.children[0])
|
root.children = append(root.children, root.children[0])
|
||||||
} else if len(root.children) > 1 {
|
} else if len(root.children) > 1 {
|
||||||
err = root.Errorf("invalid range specification")
|
// err = root.Errorf("invalid range specification")
|
||||||
|
err = errRangeInvalidSpecification(root)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
zeroTk := NewValueToken(root.tk.row, root.tk.col, SymInteger, "0", int64(0))
|
zeroTk := NewValueToken(root.tk.row, root.tk.col, SymInteger, "0", int64(0))
|
||||||
@ -201,13 +205,15 @@ func (parser *parser) parseList(scanner *scanner, ctx parserContext) (subtree *t
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
lastSym = scanner.Previous().Sym
|
lastSym = scanner.Previous().Sym
|
||||||
itemExpected = lastSym == SymComma
|
if itemExpected = lastSym == SymComma; itemExpected {
|
||||||
|
remFlags(ctx, allowIndex)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if err == nil {
|
if err == nil {
|
||||||
if lastSym != SymClosedSquare {
|
if lastSym != SymClosedSquare {
|
||||||
err = scanner.Previous().ErrorExpectedGot("]")
|
err = scanner.Previous().ErrorExpectedGot("]")
|
||||||
} else {
|
} else {
|
||||||
subtree = newListTerm(r, c, args)
|
listTerm = newListTerm(r, c, args)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
@ -302,7 +308,6 @@ func (parser *parser) parseDictionary(scanner *scanner, ctx parserContext) (subt
|
|||||||
err = scanner.Previous().ErrorExpectedGot("}")
|
err = scanner.Previous().ErrorExpectedGot("}")
|
||||||
} else {
|
} else {
|
||||||
subtree = newDictTerm(args)
|
subtree = newDictTerm(args)
|
||||||
// subtree = newMapTerm(args)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
@ -311,6 +316,7 @@ func (parser *parser) parseDictionary(scanner *scanner, ctx parserContext) (subt
|
|||||||
func (parser *parser) parseSelectorCase(scanner *scanner, ctx parserContext, defaultCase bool) (caseTerm *term, err error) {
|
func (parser *parser) parseSelectorCase(scanner *scanner, ctx parserContext, defaultCase bool) (caseTerm *term, err error) {
|
||||||
var filterList *term
|
var filterList *term
|
||||||
var caseExpr *ast
|
var caseExpr *ast
|
||||||
|
ctx = remFlags(ctx, allowIndex)
|
||||||
tk := parser.Next(scanner)
|
tk := parser.Next(scanner)
|
||||||
startRow := tk.row
|
startRow := tk.row
|
||||||
startCol := tk.col
|
startCol := tk.col
|
||||||
@ -358,6 +364,8 @@ func addSelectorCase(selectorTerm, caseTerm *term) {
|
|||||||
|
|
||||||
func (parser *parser) parseSelector(scanner *scanner, tree *ast, ctx parserContext) (selectorTerm *term, err error) {
|
func (parser *parser) parseSelector(scanner *scanner, tree *ast, ctx parserContext) (selectorTerm *term, err error) {
|
||||||
var caseTerm *term
|
var caseTerm *term
|
||||||
|
|
||||||
|
ctx = remFlags(ctx, allowIndex)
|
||||||
tk := scanner.makeToken(SymSelector, '?')
|
tk := scanner.makeToken(SymSelector, '?')
|
||||||
if selectorTerm, err = tree.addToken(tk); err != nil {
|
if selectorTerm, err = tree.addToken(tk); err != nil {
|
||||||
return
|
return
|
||||||
@ -386,13 +394,20 @@ func couldBeACollection(t *term) bool {
|
|||||||
return sym == SymList || sym == SymString || sym == SymDict || sym == SymExpression || sym == SymVariable
|
return sym == SymList || sym == SymString || sym == SymDict || sym == SymExpression || sym == SymVariable
|
||||||
}
|
}
|
||||||
|
|
||||||
// func areSymbolsOutOfCtx(tk *Token, ctxTerm *term, syms ...Symbol) bool {
|
func listSubTree(tree *ast, listTerm *term, allowIndeces bool) (root *term, err error) {
|
||||||
// var areOut = false
|
var tk *Token
|
||||||
// if ctxTerm != nil {
|
if allowIndeces {
|
||||||
// areOut = tk.IsOneOf(syms)
|
tk = NewToken(listTerm.tk.row, listTerm.tk.col, SymIndex, listTerm.source())
|
||||||
// }
|
root = newTerm(tk)
|
||||||
// return areOut
|
if err = tree.addTerm(root); err == nil {
|
||||||
// }
|
err = tree.addTerm(listTerm)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
root = listTerm
|
||||||
|
err = tree.addTerm(listTerm)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
func (parser *parser) parseGeneral(scanner *scanner, ctx parserContext, termSymbols ...Symbol) (tree *ast, err error) {
|
func (parser *parser) parseGeneral(scanner *scanner, ctx parserContext, termSymbols ...Symbol) (tree *ast, err error) {
|
||||||
var selectorTerm *term = nil
|
var selectorTerm *term = nil
|
||||||
@ -448,16 +463,7 @@ func (parser *parser) parseGeneral(scanner *scanner, ctx parserContext, termSymb
|
|||||||
var listTerm *term
|
var listTerm *term
|
||||||
newCtx := addFlagsCond(addFlags(ctx, squareContext), allowIndex, couldBeACollection(currentTerm))
|
newCtx := addFlagsCond(addFlags(ctx, squareContext), allowIndex, couldBeACollection(currentTerm))
|
||||||
if listTerm, err = parser.parseList(scanner, newCtx); err == nil {
|
if listTerm, err = parser.parseList(scanner, newCtx); err == nil {
|
||||||
if hasFlag(newCtx, allowIndex) {
|
currentTerm, err = listSubTree(tree, listTerm, hasFlag(newCtx, allowIndex))
|
||||||
indexTk := NewToken(listTerm.tk.row, listTerm.tk.col, SymIndex, listTerm.source())
|
|
||||||
indexTerm := newTerm(indexTk)
|
|
||||||
if err = tree.addTerm(indexTerm); err == nil {
|
|
||||||
err = tree.addTerm(listTerm)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
err = tree.addTerm(listTerm)
|
|
||||||
}
|
|
||||||
currentTerm = listTerm
|
|
||||||
}
|
}
|
||||||
case SymOpenBrace:
|
case SymOpenBrace:
|
||||||
if currentTerm != nil && currentTerm.symbol() == SymColon {
|
if currentTerm != nil && currentTerm.symbol() == SymColon {
|
||||||
@ -493,6 +499,7 @@ func (parser *parser) parseGeneral(scanner *scanner, ctx parserContext, termSymb
|
|||||||
case SymQuestion:
|
case SymQuestion:
|
||||||
if selectorTerm, err = parser.parseSelector(scanner, tree, ctx); err == nil {
|
if selectorTerm, err = parser.parseSelector(scanner, tree, ctx); err == nil {
|
||||||
currentTerm = selectorTerm
|
currentTerm = selectorTerm
|
||||||
|
addFlags(ctx, selectorContext)
|
||||||
}
|
}
|
||||||
case SymColon, SymDoubleColon:
|
case SymColon, SymDoubleColon:
|
||||||
var caseTerm *term
|
var caseTerm *term
|
||||||
@ -505,9 +512,12 @@ func (parser *parser) parseGeneral(scanner *scanner, ctx parserContext, termSymb
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
// if hasFlag(ctx, allowIndex) {
|
||||||
|
// tk.Sym = SymRange
|
||||||
|
// }
|
||||||
currentTerm, err = tree.addToken(tk)
|
currentTerm, err = tree.addToken(tk)
|
||||||
}
|
}
|
||||||
if tk.IsSymbol(SymColon) {
|
if tk.IsOneOfA(SymColon, SymRange) {
|
||||||
// Colon outside a selector term acts like a separator
|
// Colon outside a selector term acts like a separator
|
||||||
firstToken = true
|
firstToken = true
|
||||||
}
|
}
|
||||||
@ -517,7 +527,7 @@ func (parser *parser) parseGeneral(scanner *scanner, ctx parserContext, termSymb
|
|||||||
|
|
||||||
if currentTerm != nil && currentTerm.tk.Sym != SymSelector && currentTerm.parent != nil && currentTerm.parent.tk.Sym != SymSelector {
|
if currentTerm != nil && currentTerm.tk.Sym != SymSelector && currentTerm.parent != nil && currentTerm.parent.tk.Sym != SymSelector {
|
||||||
selectorTerm = nil
|
selectorTerm = nil
|
||||||
|
remFlags(ctx, selectorContext)
|
||||||
}
|
}
|
||||||
// lastSym = tk.Sym
|
// lastSym = tk.Sym
|
||||||
}
|
}
|
||||||
@ -535,9 +545,5 @@ func (parser *parser) parseGeneral(scanner *scanner, ctx parserContext, termSymb
|
|||||||
err = tk.Error()
|
err = tk.Error()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// if err == nil {
|
|
||||||
// err = tk.Error()
|
|
||||||
// }
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -30,9 +30,9 @@ func TestFuncBase(t *testing.T) {
|
|||||||
/* 16 */ {`isString("3" + 1)`, true, nil},
|
/* 16 */ {`isString("3" + 1)`, true, nil},
|
||||||
/* 17 */ {`isList(["3", 1])`, true, nil},
|
/* 17 */ {`isList(["3", 1])`, true, nil},
|
||||||
/* 18 */ {`isDict({"a":"3", "b":1})`, true, nil},
|
/* 18 */ {`isDict({"a":"3", "b":1})`, true, nil},
|
||||||
/* 19 */ {`isFract(1|3)`, true, nil},
|
/* 19 */ {`isFract(1:3)`, true, nil},
|
||||||
/* 20 */ {`isFract(3|1)`, false, nil},
|
/* 20 */ {`isFract(3:1)`, false, nil},
|
||||||
/* 21 */ {`isRational(3|1)`, true, nil},
|
/* 21 */ {`isRational(3:1)`, true, nil},
|
||||||
/* 22 */ {`fract("2.2(3)")`, newFraction(67, 30), nil},
|
/* 22 */ {`fract("2.2(3)")`, newFraction(67, 30), nil},
|
||||||
/* 23 */ {`fract("1.21(3)")`, newFraction(91, 75), nil},
|
/* 23 */ {`fract("1.21(3)")`, newFraction(91, 75), nil},
|
||||||
/* 24 */ {`fract(1.21(3))`, newFraction(91, 75), nil},
|
/* 24 */ {`fract(1.21(3))`, newFraction(91, 75), nil},
|
||||||
@ -45,16 +45,16 @@ func TestFuncBase(t *testing.T) {
|
|||||||
/* 31 */ {`dec()`, nil, `dec(): too few params -- expected 1, got 0`},
|
/* 31 */ {`dec()`, nil, `dec(): too few params -- expected 1, got 0`},
|
||||||
/* 32 */ {`dec(1,2,3)`, nil, `dec(): too many params -- expected 1, got 3`},
|
/* 32 */ {`dec(1,2,3)`, nil, `dec(): too many params -- expected 1, got 3`},
|
||||||
/* 33 */ {`isBool(false)`, true, nil},
|
/* 33 */ {`isBool(false)`, true, nil},
|
||||||
/* 34 */ {`fract(1|2)`, newFraction(1, 2), nil},
|
/* 34 */ {`fract(1:2)`, newFraction(1, 2), nil},
|
||||||
/* 35 */ {`fract(12,2)`, newFraction(6, 1), nil},
|
/* 35 */ {`fract(12,2)`, newFraction(6, 1), nil},
|
||||||
/* 36 */ {`bool(2)`, true, nil},
|
/* 36 */ {`bool(2)`, true, nil},
|
||||||
/* 37 */ {`bool(1|2)`, true, nil},
|
/* 37 */ {`bool(1:2)`, true, nil},
|
||||||
/* 38 */ {`bool(1.0)`, true, nil},
|
/* 38 */ {`bool(1.0)`, true, nil},
|
||||||
/* 39 */ {`bool("1")`, true, nil},
|
/* 39 */ {`bool("1")`, true, nil},
|
||||||
/* 40 */ {`bool(false)`, false, nil},
|
/* 40 */ {`bool(false)`, false, nil},
|
||||||
/* 41 */ {`bool([1])`, nil, `bool(): can't convert list to bool`},
|
/* 41 */ {`bool([1])`, nil, `bool(): can't convert list to bool`},
|
||||||
/* 42 */ {`dec(false)`, float64(0), nil},
|
/* 42 */ {`dec(false)`, float64(0), nil},
|
||||||
/* 43 */ {`dec(1|2)`, float64(0.5), nil},
|
/* 43 */ {`dec(1:2)`, float64(0.5), nil},
|
||||||
/* 44 */ {`dec([1])`, nil, `dec(): can't convert list to float`},
|
/* 44 */ {`dec([1])`, nil, `dec(): can't convert list to float`},
|
||||||
// /* 45 */ {`string([1])`, nil, `string(): can't convert list to string`},
|
// /* 45 */ {`string([1])`, nil, `string(): can't convert list to string`},
|
||||||
}
|
}
|
||||||
|
@ -11,36 +11,39 @@ import (
|
|||||||
func TestFractionsParser(t *testing.T) {
|
func TestFractionsParser(t *testing.T) {
|
||||||
section := "Fraction"
|
section := "Fraction"
|
||||||
inputs := []inputType{
|
inputs := []inputType{
|
||||||
/* 1 */ {`1|2`, newFraction(1, 2), nil},
|
/* 1 */ {`1:2`, newFraction(1, 2), nil},
|
||||||
/* 2 */ {`1|2 + 1`, newFraction(3, 2), nil},
|
/* 2 */ {`1:2 + 1`, newFraction(3, 2), nil},
|
||||||
/* 3 */ {`1|2 - 1`, newFraction(-1, 2), nil},
|
/* 3 */ {`1:2 - 1`, newFraction(-1, 2), nil},
|
||||||
/* 4 */ {`1|2 * 1`, newFraction(1, 2), nil},
|
/* 4 */ {`1:2 * 1`, newFraction(1, 2), nil},
|
||||||
/* 5 */ {`1|2 * 2|3`, newFraction(2, 6), nil},
|
/* 5 */ {`1:2 * 2:3`, newFraction(2, 6), nil},
|
||||||
/* 6 */ {`1|2 / 2|3`, newFraction(3, 4), nil},
|
/* 6 */ {`1:2 / 2:3`, newFraction(3, 4), nil},
|
||||||
/* 7 */ {`1|"5"`, nil, `denominator must be integer, got string (5)`},
|
/* 7 */ {`1:"5"`, nil, `denominator must be integer, got string (5)`},
|
||||||
/* 8 */ {`"1"|5`, nil, `numerator must be integer, got string (1)`},
|
/* 8 */ {`"1":5`, nil, `numerator must be integer, got string (1)`},
|
||||||
/* 9 */ {`1|+5`, nil, `[1:3] infix operator "|" requires two non-nil operands, got 1`},
|
/* 9 */ {`1:+5`, newFraction(1, 5), nil},
|
||||||
/* 10 */ {`1|(-2)`, newFraction(-1, 2), nil},
|
/* 10 */ {`1:(-2)`, newFraction(-1, 2), nil},
|
||||||
/* 11 */ {`builtin "math.arith"; add(1|2, 2|3)`, newFraction(7, 6), nil},
|
/* 11 */ {`builtin "math.arith"; add(1:2, 2:3)`, newFraction(7, 6), nil},
|
||||||
/* 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, `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},
|
||||||
/* 19 */ {`fract("+1")`, newFraction(1, 1), nil},
|
/* 19 */ {`fract("+1")`, newFraction(1, 1), nil},
|
||||||
/* 20 */ {`fract("1a")`, (*FractionType)(nil), `strconv.ParseInt: parsing "1a": invalid syntax`},
|
/* 20 */ {`fract("1a")`, (*FractionType)(nil), `strconv.ParseInt: parsing "1a": invalid syntax`},
|
||||||
/* 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},
|
||||||
|
/* 24 */ {`1:(2-2)`, nil, `division by zero`},
|
||||||
|
/* 25 */ {`[0,1][1-1]:1`, newFraction(0, 1), nil},
|
||||||
}
|
}
|
||||||
runTestSuiteSpec(t, section, inputs, 1)
|
// runTestSuiteSpec(t, section, inputs, 25)
|
||||||
// runTestSuite(t, section, inputs)
|
runTestSuite(t, section, inputs)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFractionToStringSimple(t *testing.T) {
|
func TestFractionToStringSimple(t *testing.T) {
|
||||||
source := newFraction(1, 2)
|
source := newFraction(1, 2)
|
||||||
want := "1|2"
|
want := "1:2"
|
||||||
got := source.ToString(0)
|
got := source.ToString(0)
|
||||||
if got != want {
|
if got != want {
|
||||||
t.Errorf(`(1,2) -> result = %v [%T], want = %v [%T]`, got, got, want, want)
|
t.Errorf(`(1,2) -> result = %v [%T], want = %v [%T]`, got, got, want, want)
|
||||||
|
@ -16,11 +16,13 @@ func TestCollections(t *testing.T) {
|
|||||||
/* 3 */ {`"abcdef"[1:]`, "bcdef", nil},
|
/* 3 */ {`"abcdef"[1:]`, "bcdef", nil},
|
||||||
/* 4 */ {`"abcdef"[:]`, "abcdef", nil},
|
/* 4 */ {`"abcdef"[:]`, "abcdef", nil},
|
||||||
// /* 5 */ {`[0,1,2,3,4][:]`, ListType{int64(0), int64(1), int64(2), int64(3), int64(4)}, nil},
|
// /* 5 */ {`[0,1,2,3,4][:]`, ListType{int64(0), int64(1), int64(2), int64(3), int64(4)}, nil},
|
||||||
/* 5 */ {`"abcdef"[1:2:3]`, nil, `[1:14] left operand '(1, 2)' [pair] and right operand '3' [integer] are not compatible with operator ":"`},
|
/* 5 */ {`"abcdef"[1:2:3]`, nil, `[1:14] invalid range specification`},
|
||||||
|
/* 6 */ {`"abcdef"[((1>0)?{1}:{0}):3]`, "bc", nil},
|
||||||
|
/* 7 */ {`"abcdef"[[0,1][0]:1]`, "a", nil},
|
||||||
}
|
}
|
||||||
|
|
||||||
t.Setenv("EXPR_PATH", ".")
|
t.Setenv("EXPR_PATH", ".")
|
||||||
|
|
||||||
// parserTestSpec(t, section, inputs, 5)
|
// runTestSuiteSpec(t, section, inputs, 5)
|
||||||
runTestSuite(t, section, inputs)
|
runTestSuite(t, section, inputs)
|
||||||
}
|
}
|
||||||
|
@ -77,7 +77,7 @@ func TestGeneralParser(t *testing.T) {
|
|||||||
/* 63 */ {`"1.5" == `, nil, `[1:8] infix operator "==" requires two non-nil operands, got 1`},
|
/* 63 */ {`"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`},
|
/* 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 not nil operand`},
|
/* 66 */ {"+", nil, `[1:2] prefix operator "+" requires one non-nil operand`},
|
||||||
/* 67 */ {"4 / 0", nil, `division by zero`},
|
/* 67 */ {"4 / 0", nil, `division by zero`},
|
||||||
/* 68 */ {"4.0 / 0", nil, `division by zero`},
|
/* 68 */ {"4.0 / 0", nil, `division by zero`},
|
||||||
/* 69 */ {"4.0 / \n2", float64(2.0), nil},
|
/* 69 */ {"4.0 / \n2", float64(2.0), nil},
|
||||||
@ -132,15 +132,13 @@ func TestGeneralParser(t *testing.T) {
|
|||||||
/* 118 */ {`{"key":}`, nil, "[1:9] expected `dictionary-value`, got `}`"},
|
/* 118 */ {`{"key":}`, nil, "[1:9] expected `dictionary-value`, got `}`"},
|
||||||
/* 119 */ {`{}`, &DictType{}, nil},
|
/* 119 */ {`{}`, &DictType{}, nil},
|
||||||
/* 120 */ {`v=10; v++; v`, int64(11), nil},
|
/* 120 */ {`v=10; v++; v`, int64(11), nil},
|
||||||
/* 121 */ {`1+1|2+0.5`, float64(2), nil},
|
/* 121 */ {`1.2()`, newFraction(6, 5), nil},
|
||||||
/* 122 */ {`1.2()`, newFraction(6, 5), nil},
|
/* 122 */ {`x="abc"; x ?! #x`, int64(3), nil},
|
||||||
/* 123 */ {`1|(2-2)`, nil, `division by zero`},
|
/* 123 */ {`x ?! #x`, nil, `[1:7] prefix/postfix operator "#" do not support operand '<nil>' [nil]`},
|
||||||
/* 124 */ {`x="abc"; x ?! #x`, int64(3), nil},
|
/* 124 */ {`x ?! (x+1)`, nil, nil},
|
||||||
/* 125 */ {`x ?! #x`, nil, `[1:7] prefix/postfix operator "#" do not support operand '<nil>' [nil]`},
|
/* 125 */ {`"abx" ?! (x+1)`, nil, `[1:6] left operand of "?!" must be a variable`},
|
||||||
/* 126 */ {`x ?! (x+1)`, nil, nil},
|
/* 126 */ {`"abx" ?? "pqr"`, nil, `[1:6] left operand of "??" must be a variable`},
|
||||||
/* 127 */ {`"abx" ?! (x+1)`, nil, `[1:6] left operand of "?!" must be a variable`},
|
/* 127 */ {`"abx" ?= "pqr"`, nil, `[1:6] left operand of "?=" must be a variable`},
|
||||||
/* 128 */ {`"abx" ?? "pqr"`, nil, `[1:6] left operand of "??" must be a variable`},
|
|
||||||
/* 129 */ {`"abx" ?= "pqr"`, nil, `[1:6] left operand of "?=" must be a variable`},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// t.Setenv("EXPR_PATH", ".")
|
// t.Setenv("EXPR_PATH", ".")
|
||||||
|
@ -21,9 +21,9 @@ func TestRelational(t *testing.T) {
|
|||||||
/* 8 */ {`true != false`, true, nil},
|
/* 8 */ {`true != false`, true, nil},
|
||||||
/* 9 */ {`1.0 != 3.0-2`, false, nil},
|
/* 9 */ {`1.0 != 3.0-2`, false, nil},
|
||||||
/* 10 */ {`[1,2] != [2,1]`, true, nil},
|
/* 10 */ {`[1,2] != [2,1]`, true, nil},
|
||||||
/* 11 */ {`1|2 == 1|3`, false, nil},
|
/* 11 */ {`1:2 == 1:3`, false, nil},
|
||||||
/* 12 */ {`1|2 != 1|3`, true, nil},
|
/* 12 */ {`1:2 != 1:3`, true, nil},
|
||||||
/* 13 */ {`1|2 == 4|8`, true, nil},
|
/* 13 */ {`1:2 == 4:8`, true, nil},
|
||||||
/* 14 */ {`1 < 8`, true, nil},
|
/* 14 */ {`1 < 8`, true, nil},
|
||||||
/* 15 */ {`1 <= 8`, true, nil},
|
/* 15 */ {`1 <= 8`, true, nil},
|
||||||
/* 16 */ {`"a" < "b"`, true, nil},
|
/* 16 */ {`"a" < "b"`, true, nil},
|
||||||
@ -32,10 +32,10 @@ func TestRelational(t *testing.T) {
|
|||||||
/* 19 */ {`1.0 <= 8`, true, nil},
|
/* 19 */ {`1.0 <= 8`, true, nil},
|
||||||
/* 20 */ {`1.0 <= 1.0`, true, nil},
|
/* 20 */ {`1.0 <= 1.0`, true, nil},
|
||||||
/* 21 */ {`1.0 == 1`, true, nil},
|
/* 21 */ {`1.0 == 1`, true, nil},
|
||||||
/* 22 */ {`1|2 < 1|3`, false, nil},
|
/* 22 */ {`1:2 < 1:3`, false, nil},
|
||||||
/* 23 */ {`1|2 <= 1|3`, false, nil},
|
/* 23 */ {`1:2 <= 1:3`, false, nil},
|
||||||
/* 24 */ {`1|2 > 1|3`, true, nil},
|
/* 24 */ {`1:2 > 1:3`, true, nil},
|
||||||
/* 25 */ {`1|2 >= 1|3`, true, nil},
|
/* 25 */ {`1:2 >= 1:3`, true, nil},
|
||||||
/* 26 */ {`[1,2,3] > [2]`, true, nil},
|
/* 26 */ {`[1,2,3] > [2]`, true, nil},
|
||||||
/* 27 */ {`[1,2,3] > [9]`, false, nil},
|
/* 27 */ {`[1,2,3] > [9]`, false, nil},
|
||||||
/* 28 */ {`[1,2,3] >= [6]`, false, nil},
|
/* 28 */ {`[1,2,3] >= [6]`, false, nil},
|
||||||
|
Loading…
Reference in New Issue
Block a user