Added new special operators like &= and <<=.
Also made a litle change to scanner function moveOn(): now it moves on the last char passed and only if there are more than one chars.
This commit is contained in:
parent
e43823740f
commit
eccb0c4dc9
@ -183,6 +183,14 @@ func evalOpAssign(ctx ExprContext, opTerm *term) (v any, err error) {
|
|||||||
v, err = divValues(opTerm, leftValue, rightValue)
|
v, err = divValues(opTerm, leftValue, rightValue)
|
||||||
case SymPercEqual:
|
case SymPercEqual:
|
||||||
v, err = remainderValues(opTerm, leftValue, rightValue)
|
v, err = remainderValues(opTerm, leftValue, rightValue)
|
||||||
|
case SymAmpersandEqual:
|
||||||
|
v, err = bitwiseAnd(opTerm, leftValue, rightValue)
|
||||||
|
case SymVertBarEqual:
|
||||||
|
v, err = bitwiseOr(opTerm, leftValue, rightValue)
|
||||||
|
case SymDoubleLessEqual:
|
||||||
|
v, err = bitLeftShift(opTerm, leftValue, rightValue)
|
||||||
|
case SymDoubleGreaterEqual:
|
||||||
|
v, err = bitRightShift(opTerm, leftValue, rightValue)
|
||||||
default:
|
default:
|
||||||
err = opTerm.Errorf("unsupported assign operator %q", opTerm.source())
|
err = opTerm.Errorf("unsupported assign operator %q", opTerm.source())
|
||||||
}
|
}
|
||||||
@ -201,4 +209,9 @@ func init() {
|
|||||||
registerTermConstructor(SymMinusEqual, newOpAssignTerm)
|
registerTermConstructor(SymMinusEqual, newOpAssignTerm)
|
||||||
registerTermConstructor(SymStarEqual, newOpAssignTerm)
|
registerTermConstructor(SymStarEqual, newOpAssignTerm)
|
||||||
registerTermConstructor(SymSlashEqual, newOpAssignTerm)
|
registerTermConstructor(SymSlashEqual, newOpAssignTerm)
|
||||||
|
registerTermConstructor(SymPercEqual, newOpAssignTerm)
|
||||||
|
registerTermConstructor(SymDoubleLessEqual, newOpAssignTerm)
|
||||||
|
registerTermConstructor(SymDoubleGreaterEqual, newOpAssignTerm)
|
||||||
|
registerTermConstructor(SymAmpersandEqual, newOpAssignTerm)
|
||||||
|
registerTermConstructor(SymVertBarEqual, newOpAssignTerm)
|
||||||
}
|
}
|
||||||
|
@ -1,104 +0,0 @@
|
|||||||
// Copyright (c) 2024 Celestino Amoroso (celestino.amoroso@gmail.com).
|
|
||||||
// All rights reserved.
|
|
||||||
|
|
||||||
// operator-binary.go
|
|
||||||
package expr
|
|
||||||
|
|
||||||
//-------- NOT term
|
|
||||||
|
|
||||||
func newBinNotTerm(tk *Token) (inst *term) {
|
|
||||||
return &term{
|
|
||||||
tk: *tk,
|
|
||||||
children: make([]*term, 0, 1),
|
|
||||||
position: posPrefix,
|
|
||||||
priority: priBinNot,
|
|
||||||
evalFunc: evalBinaryNot,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func evalBinaryNot(ctx ExprContext, opTerm *term) (v any, err error) {
|
|
||||||
var value any
|
|
||||||
|
|
||||||
if value, err = opTerm.evalPrefix(ctx); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if IsInteger(value) {
|
|
||||||
i, _ := value.(int64)
|
|
||||||
v = ^i
|
|
||||||
} else {
|
|
||||||
err = opTerm.errIncompatibleType(value)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
//-------- Binary AND term
|
|
||||||
|
|
||||||
func newBinAndTerm(tk *Token) (inst *term) {
|
|
||||||
return &term{
|
|
||||||
tk: *tk,
|
|
||||||
children: make([]*term, 0, 2),
|
|
||||||
position: posInfix,
|
|
||||||
priority: priBinAnd,
|
|
||||||
evalFunc: evalBinaryAnd,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func evalBinaryAnd(ctx ExprContext, self *term) (v any, err error) {
|
|
||||||
var leftValue, rightValue any
|
|
||||||
var leftInt, rightInt int64
|
|
||||||
var lok, rok bool
|
|
||||||
|
|
||||||
if leftValue, rightValue, err = self.evalInfix(ctx); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
leftInt, lok = leftValue.(int64)
|
|
||||||
rightInt, rok = rightValue.(int64)
|
|
||||||
|
|
||||||
if lok && rok {
|
|
||||||
v = leftInt & rightInt
|
|
||||||
} else {
|
|
||||||
err = self.errIncompatibleTypes(leftValue, rightValue)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
//-------- Binary OR term
|
|
||||||
|
|
||||||
func newBinOrTerm(tk *Token) (inst *term) {
|
|
||||||
return &term{
|
|
||||||
tk: *tk,
|
|
||||||
children: make([]*term, 0, 2),
|
|
||||||
position: posInfix,
|
|
||||||
priority: priBinOr,
|
|
||||||
evalFunc: evalBinaryOr,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func evalBinaryOr(ctx ExprContext, self *term) (v any, err error) {
|
|
||||||
var leftValue, rightValue any
|
|
||||||
var leftInt, rightInt int64
|
|
||||||
var lok, rok bool
|
|
||||||
|
|
||||||
if leftValue, rightValue, err = self.evalInfix(ctx); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
leftInt, lok = leftValue.(int64)
|
|
||||||
rightInt, rok = rightValue.(int64)
|
|
||||||
|
|
||||||
if lok && rok {
|
|
||||||
v = leftInt | rightInt
|
|
||||||
} else {
|
|
||||||
err = self.errIncompatibleTypes(leftValue, rightValue)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// init
|
|
||||||
func init() {
|
|
||||||
registerTermConstructor(SymTilde, newBinNotTerm)
|
|
||||||
registerTermConstructor(SymAmpersand, newBinAndTerm)
|
|
||||||
registerTermConstructor(SymVertBar, newBinOrTerm)
|
|
||||||
}
|
|
115
operator-bitwise.go
Normal file
115
operator-bitwise.go
Normal file
@ -0,0 +1,115 @@
|
|||||||
|
// Copyright (c) 2024 Celestino Amoroso (celestino.amoroso@gmail.com).
|
||||||
|
// All rights reserved.
|
||||||
|
|
||||||
|
// operator-bitwise.go
|
||||||
|
package expr
|
||||||
|
|
||||||
|
//-------- Bitwise NOT term
|
||||||
|
|
||||||
|
func newBitwiseNotTerm(tk *Token) (inst *term) {
|
||||||
|
return &term{
|
||||||
|
tk: *tk,
|
||||||
|
children: make([]*term, 0, 1),
|
||||||
|
position: posPrefix,
|
||||||
|
priority: priBitwiseNot,
|
||||||
|
evalFunc: evalBitwiseNot,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func evalBitwiseNot(ctx ExprContext, opTerm *term) (v any, err error) {
|
||||||
|
var value any
|
||||||
|
|
||||||
|
if value, err = opTerm.evalPrefix(ctx); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if IsInteger(value) {
|
||||||
|
i, _ := value.(int64)
|
||||||
|
v = ^i
|
||||||
|
} else {
|
||||||
|
err = opTerm.errIncompatibleType(value)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------- Bitwise AND term
|
||||||
|
|
||||||
|
func newBitwiseAndTerm(tk *Token) (inst *term) {
|
||||||
|
return &term{
|
||||||
|
tk: *tk,
|
||||||
|
children: make([]*term, 0, 2),
|
||||||
|
position: posInfix,
|
||||||
|
priority: priBitwiseAnd,
|
||||||
|
evalFunc: evalBitwiseAnd,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func bitwiseAnd(opTerm *term, leftValue, rightValue any) (v any, err error) {
|
||||||
|
var leftInt, rightInt int64
|
||||||
|
var lok, rok bool
|
||||||
|
|
||||||
|
leftInt, lok = leftValue.(int64)
|
||||||
|
rightInt, rok = rightValue.(int64)
|
||||||
|
|
||||||
|
if lok && rok {
|
||||||
|
v = leftInt & rightInt
|
||||||
|
} else {
|
||||||
|
err = opTerm.errIncompatibleTypes(leftValue, rightValue)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func evalBitwiseAnd(ctx ExprContext, opTerm *term) (v any, err error) {
|
||||||
|
var leftValue, rightValue any
|
||||||
|
|
||||||
|
if leftValue, rightValue, err = opTerm.evalInfix(ctx); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
v, err = bitwiseAnd(opTerm, leftValue, rightValue)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------- Bitwise OR term
|
||||||
|
|
||||||
|
func newBitwiseOrTerm(tk *Token) (inst *term) {
|
||||||
|
return &term{
|
||||||
|
tk: *tk,
|
||||||
|
children: make([]*term, 0, 2),
|
||||||
|
position: posInfix,
|
||||||
|
priority: priBitwiseOr,
|
||||||
|
evalFunc: evalBitwiseOr,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func bitwiseOr(opTerm *term, leftValue, rightValue any) (v any, err error) {
|
||||||
|
var leftInt, rightInt int64
|
||||||
|
var lok, rok bool
|
||||||
|
|
||||||
|
leftInt, lok = leftValue.(int64)
|
||||||
|
rightInt, rok = rightValue.(int64)
|
||||||
|
|
||||||
|
if lok && rok {
|
||||||
|
v = leftInt | rightInt
|
||||||
|
} else {
|
||||||
|
err = opTerm.errIncompatibleTypes(leftValue, rightValue)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func evalBitwiseOr(ctx ExprContext, opTerm *term) (v any, err error) {
|
||||||
|
var leftValue, rightValue any
|
||||||
|
|
||||||
|
if leftValue, rightValue, err = opTerm.evalInfix(ctx); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
v, err = bitwiseOr(opTerm, leftValue, rightValue)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// init
|
||||||
|
func init() {
|
||||||
|
registerTermConstructor(SymTilde, newBitwiseNotTerm)
|
||||||
|
registerTermConstructor(SymAmpersand, newBitwiseAndTerm)
|
||||||
|
registerTermConstructor(SymVertBar, newBitwiseOrTerm)
|
||||||
|
}
|
@ -4,7 +4,7 @@
|
|||||||
// operator-shift.go
|
// operator-shift.go
|
||||||
package expr
|
package expr
|
||||||
|
|
||||||
//-------- shift term
|
//-------- bit right shift term
|
||||||
|
|
||||||
func newRightShiftTerm(tk *Token) (inst *term) {
|
func newRightShiftTerm(tk *Token) (inst *term) {
|
||||||
return &term{
|
return &term{
|
||||||
@ -16,13 +16,7 @@ func newRightShiftTerm(tk *Token) (inst *term) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func evalRightShift(ctx ExprContext, opTerm *term) (v any, err error) {
|
func bitRightShift(opTerm *term, leftValue, rightValue any) (v any, err error) {
|
||||||
var leftValue, rightValue any
|
|
||||||
|
|
||||||
if leftValue, rightValue, err = opTerm.evalInfix(ctx); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if IsInteger(leftValue) && IsInteger(rightValue) {
|
if IsInteger(leftValue) && IsInteger(rightValue) {
|
||||||
leftInt := leftValue.(int64)
|
leftInt := leftValue.(int64)
|
||||||
rightInt := rightValue.(int64)
|
rightInt := rightValue.(int64)
|
||||||
@ -33,6 +27,17 @@ func evalRightShift(ctx ExprContext, opTerm *term) (v any, err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func evalRightShift(ctx ExprContext, opTerm *term) (v any, err error) {
|
||||||
|
var leftValue, rightValue any
|
||||||
|
|
||||||
|
if leftValue, rightValue, err = opTerm.evalInfix(ctx); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
v, err = bitRightShift(opTerm, leftValue, rightValue)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
func newLeftShiftTerm(tk *Token) (inst *term) {
|
func newLeftShiftTerm(tk *Token) (inst *term) {
|
||||||
return &term{
|
return &term{
|
||||||
tk: *tk,
|
tk: *tk,
|
||||||
@ -43,13 +48,7 @@ func newLeftShiftTerm(tk *Token) (inst *term) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func evalLeftShift(ctx ExprContext, opTerm *term) (v any, err error) {
|
func bitLeftShift(opTerm *term, leftValue, rightValue any) (v any, err error) {
|
||||||
var leftValue, rightValue any
|
|
||||||
|
|
||||||
if leftValue, rightValue, err = opTerm.evalInfix(ctx); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if IsInteger(leftValue) && IsInteger(rightValue) {
|
if IsInteger(leftValue) && IsInteger(rightValue) {
|
||||||
leftInt := leftValue.(int64)
|
leftInt := leftValue.(int64)
|
||||||
rightInt := rightValue.(int64)
|
rightInt := rightValue.(int64)
|
||||||
@ -60,23 +59,16 @@ func evalLeftShift(ctx ExprContext, opTerm *term) (v any, err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// func evalAssignAppend(ctx ExprContext, self *term) (v any, err error) {
|
func evalLeftShift(ctx ExprContext, opTerm *term) (v any, err error) {
|
||||||
// var leftValue, rightValue any
|
var leftValue, rightValue any
|
||||||
|
|
||||||
// if leftValue, rightValue, err = self.evalInfix(ctx); err != nil {
|
if leftValue, rightValue, err = opTerm.evalInfix(ctx); err != nil {
|
||||||
// return
|
return
|
||||||
// }
|
}
|
||||||
|
|
||||||
// if IsList(leftValue) {
|
v, err = bitLeftShift(opTerm, leftValue, rightValue)
|
||||||
// list, _ := leftValue.(*ListType)
|
return
|
||||||
// newList := append(*list, rightValue)
|
}
|
||||||
// v = &newList
|
|
||||||
// if
|
|
||||||
// } else {
|
|
||||||
// err = self.errIncompatibleTypes(leftValue, rightValue)
|
|
||||||
// }
|
|
||||||
// return
|
|
||||||
// }
|
|
||||||
|
|
||||||
// init
|
// init
|
||||||
func init() {
|
func init() {
|
||||||
|
35
scanner.go
35
scanner.go
@ -169,6 +169,8 @@ func (scanner *scanner) fetchNextToken() (tk *Token) {
|
|||||||
case '|':
|
case '|':
|
||||||
if next, _ := scanner.peek(); next == '|' {
|
if next, _ := scanner.peek(); next == '|' {
|
||||||
tk = scanner.moveOn(SymDoubleVertBar, ch, next)
|
tk = scanner.moveOn(SymDoubleVertBar, ch, next)
|
||||||
|
} else if next, _ = scanner.peek(); next == '=' {
|
||||||
|
tk = scanner.moveOn(SymVertBarEqual, ch, next)
|
||||||
} else {
|
} else {
|
||||||
tk = scanner.makeToken(SymVertBar, ch)
|
tk = scanner.makeToken(SymVertBar, ch)
|
||||||
}
|
}
|
||||||
@ -234,11 +236,17 @@ func (scanner *scanner) fetchNextToken() (tk *Token) {
|
|||||||
case '&':
|
case '&':
|
||||||
if next, _ := scanner.peek(); next == '&' {
|
if next, _ := scanner.peek(); next == '&' {
|
||||||
tk = scanner.moveOn(SymDoubleAmpersand, ch, next)
|
tk = scanner.moveOn(SymDoubleAmpersand, ch, next)
|
||||||
|
} else if next, _ = scanner.peek(); next == '=' {
|
||||||
|
tk = scanner.moveOn(SymAmpersandEqual, ch, next)
|
||||||
} else {
|
} else {
|
||||||
tk = scanner.makeToken(SymAmpersand, ch)
|
tk = scanner.makeToken(SymAmpersand, ch)
|
||||||
}
|
}
|
||||||
case '%':
|
case '%':
|
||||||
|
if next, _ := scanner.peek(); next == '=' {
|
||||||
|
tk = scanner.moveOn(SymPercEqual, ch, next)
|
||||||
|
} else {
|
||||||
tk = scanner.makeToken(SymPercent, ch)
|
tk = scanner.makeToken(SymPercent, ch)
|
||||||
|
}
|
||||||
case '#':
|
case '#':
|
||||||
tk = scanner.makeToken(SymHash, ch)
|
tk = scanner.makeToken(SymHash, ch)
|
||||||
case '@':
|
case '@':
|
||||||
@ -267,7 +275,14 @@ func (scanner *scanner) fetchNextToken() (tk *Token) {
|
|||||||
if next, _ := scanner.peek(); next == '=' {
|
if next, _ := scanner.peek(); next == '=' {
|
||||||
tk = scanner.moveOn(SymLessOrEqual, ch, next)
|
tk = scanner.moveOn(SymLessOrEqual, ch, next)
|
||||||
} else if next == '<' {
|
} else if next == '<' {
|
||||||
tk = scanner.moveOn(SymDoubleLess, ch, next)
|
scanner.readChar()
|
||||||
|
next2, _ := scanner.readChar()
|
||||||
|
scanner.unreadChar()
|
||||||
|
if next2 == '=' {
|
||||||
|
tk = scanner.moveOn(SymDoubleLessEqual, ch, next, next2)
|
||||||
|
} else {
|
||||||
|
tk = scanner.accept(SymDoubleLess, ch, next)
|
||||||
|
}
|
||||||
} else if next == '>' {
|
} else if next == '>' {
|
||||||
tk = scanner.moveOn(SymLessGreater, ch, next)
|
tk = scanner.moveOn(SymLessGreater, ch, next)
|
||||||
} else if next == '+' {
|
} else if next == '+' {
|
||||||
@ -279,7 +294,14 @@ func (scanner *scanner) fetchNextToken() (tk *Token) {
|
|||||||
if next, _ := scanner.peek(); next == '=' {
|
if next, _ := scanner.peek(); next == '=' {
|
||||||
tk = scanner.moveOn(SymGreaterOrEqual, ch, next)
|
tk = scanner.moveOn(SymGreaterOrEqual, ch, next)
|
||||||
} else if next == '>' {
|
} else if next == '>' {
|
||||||
tk = scanner.moveOn(SymDoubleGreater, ch, next)
|
scanner.readChar()
|
||||||
|
next2, _ := scanner.readChar()
|
||||||
|
scanner.unreadChar()
|
||||||
|
if next2 == '=' {
|
||||||
|
tk = scanner.moveOn(SymDoubleGreaterEqual, ch, next, next2)
|
||||||
|
} else {
|
||||||
|
tk = scanner.accept(SymDoubleGreater, ch, next)
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
tk = scanner.makeToken(SymGreater, ch)
|
tk = scanner.makeToken(SymGreater, ch)
|
||||||
}
|
}
|
||||||
@ -634,9 +656,16 @@ func (scanner *scanner) translate(sym Symbol) Symbol {
|
|||||||
|
|
||||||
func (scanner *scanner) moveOn(sym Symbol, chars ...byte) (tk *Token) {
|
func (scanner *scanner) moveOn(sym Symbol, chars ...byte) (tk *Token) {
|
||||||
tk = NewToken(scanner.row, scanner.column, scanner.translate(sym), string(chars))
|
tk = NewToken(scanner.row, scanner.column, scanner.translate(sym), string(chars))
|
||||||
for i := 1; i < len(chars); i++ {
|
// for i := 1; i < len(chars); i++ {
|
||||||
|
if len(chars) > 1 {
|
||||||
scanner.readChar()
|
scanner.readChar()
|
||||||
}
|
}
|
||||||
|
// }
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (scanner *scanner) accept(sym Symbol, chars ...byte) (tk *Token) {
|
||||||
|
tk = NewToken(scanner.row, scanner.column, scanner.translate(sym), string(chars))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -95,8 +95,12 @@ func init() {
|
|||||||
SymStarEqual: {"*=", symClassOperator}, // 60: '*='
|
SymStarEqual: {"*=", symClassOperator}, // 60: '*='
|
||||||
SymSlashEqual: {"/=", symClassOperator}, // 61: '/='
|
SymSlashEqual: {"/=", symClassOperator}, // 61: '/='
|
||||||
SymPercEqual: {"%=", symClassOperator}, // 62: '%='
|
SymPercEqual: {"%=", symClassOperator}, // 62: '%='
|
||||||
SymPlusGreater: {"+>", symClassOperator}, // 63: '+>'
|
SymDoubleLessEqual: {"<<=", symClassOperator}, // 63: '<<='
|
||||||
SymLessPlus: {"<+", symClassOperator}, // 64: '<+'
|
SymDoubleGreaterEqual: {">>=", symClassOperator}, // 64: '>>='
|
||||||
|
SymAmpersandEqual: {"&=", symClassOperator}, // 65: '&='
|
||||||
|
SymVertBarEqual: {"|=", symClassOperator}, // 65: '|='
|
||||||
|
SymPlusGreater: {"+>", symClassOperator}, // 66: '+>'
|
||||||
|
SymLessPlus: {"<+", symClassOperator}, // 67: '<+'
|
||||||
// SymChangeSign
|
// SymChangeSign
|
||||||
// SymUnchangeSign
|
// SymUnchangeSign
|
||||||
// SymIdentifier
|
// SymIdentifier
|
||||||
|
@ -71,8 +71,12 @@ const (
|
|||||||
SymStarEqual // 60: '*='
|
SymStarEqual // 60: '*='
|
||||||
SymSlashEqual // 61: '/='
|
SymSlashEqual // 61: '/='
|
||||||
SymPercEqual // 62: '%='
|
SymPercEqual // 62: '%='
|
||||||
SymPlusGreater // 63: '+>'
|
SymDoubleLessEqual // 63: '<<='
|
||||||
SymLessPlus // 64: '<+'
|
SymDoubleGreaterEqual // 64: '>>='
|
||||||
|
SymAmpersandEqual // 65: '&='
|
||||||
|
SymVertBarEqual // 65: '|='
|
||||||
|
SymPlusGreater // 66: '+>'
|
||||||
|
SymLessPlus // 67: '<+'
|
||||||
SymChangeSign
|
SymChangeSign
|
||||||
SymUnchangeSign
|
SymUnchangeSign
|
||||||
SymIdentifier
|
SymIdentifier
|
||||||
|
@ -38,9 +38,9 @@ func TestListParser(t *testing.T) {
|
|||||||
/* 24 */ {`["a","b","c","d"][1]`, "b", nil},
|
/* 24 */ {`["a","b","c","d"][1]`, "b", nil},
|
||||||
/* 25 */ {`["a","b","c","d"][1,1]`, nil, `[1:19] one index only is allowed`},
|
/* 25 */ {`["a","b","c","d"][1,1]`, nil, `[1:19] one index only is allowed`},
|
||||||
/* 26 */ {`[0,1,2,3,4][:]`, newListA(int64(0), int64(1), int64(2), int64(3), int64(4)), nil},
|
/* 26 */ {`[0,1,2,3,4][:]`, newListA(int64(0), int64(1), int64(2), int64(3), int64(4)), nil},
|
||||||
/* 27 */ {`["a", "b", "c"] << ;`, nil, `[1:18] infix operator "<<" requires two non-nil operands, got 1`},
|
/* 27 */ {`["a", "b", "c"] <+ ;`, nil, `[1:18] infix operator "<+" requires two non-nil operands, got 1`},
|
||||||
/* 28 */ {`2 << 3;`, int64(16), nil},
|
/* 28 */ {`2 << 3;`, int64(16), nil},
|
||||||
/* 29 */ {`but >> ["a", "b", "c"]`, nil, `[1:6] infix operator ">>" requires two non-nil operands, got 0`},
|
/* 29 */ {`but +> ["a", "b", "c"]`, nil, `[1:6] infix operator "+>" requires two non-nil operands, got 0`},
|
||||||
/* 30 */ {`2 >> 3;`, int64(0), nil},
|
/* 30 */ {`2 >> 3;`, int64(0), nil},
|
||||||
/* 31 */ {`a=[1,2]; a<+3`, newListA(int64(1), int64(2), int64(3)), nil},
|
/* 31 */ {`a=[1,2]; a<+3`, newListA(int64(1), int64(2), int64(3)), nil},
|
||||||
/* 32 */ {`a=[1,2]; 5+>a`, newListA(int64(5), int64(1), int64(2)), nil},
|
/* 32 */ {`a=[1,2]; 5+>a`, newListA(int64(5), int64(1), int64(2)), nil},
|
||||||
|
@ -14,10 +14,24 @@ func TestOperator(t *testing.T) {
|
|||||||
/* 1 */ {`a=1; unset "a"; a`, nil, `undefined variable or function "a"`},
|
/* 1 */ {`a=1; unset "a"; a`, nil, `undefined variable or function "a"`},
|
||||||
/* 2 */ {`a=1; unset ["a", "b"]`, int64(1), nil},
|
/* 2 */ {`a=1; unset ["a", "b"]`, int64(1), nil},
|
||||||
/* 3 */ {`f=func(){3}; unset "f()"`, int64(1), nil},
|
/* 3 */ {`f=func(){3}; unset "f()"`, int64(1), nil},
|
||||||
|
/* 4 */ {`a=1; a<<=1+0`, int64(2), nil},
|
||||||
|
/* 5 */ {`a=2; a>>=1+0`, int64(1), nil},
|
||||||
|
/* 6 */ {`1<<1`, int64(2), nil},
|
||||||
|
/* 7 */ {`1>>1`, int64(0), nil},
|
||||||
|
/* 8 */ {`1|2`, int64(3), nil},
|
||||||
|
/* 9 */ {`a=1; a|=2`, int64(3), nil},
|
||||||
|
/* 10 */ {`3&1`, int64(1), nil},
|
||||||
|
/* 11 */ {`a=3; a&=1`, int64(1), nil},
|
||||||
|
/* 12 */ {`~1`, int64(-2), nil},
|
||||||
|
/* 13 */ {`0x10`, int64(16), nil},
|
||||||
|
/* 14 */ {`0x1X`, nil, `[1:5] two adjacent operators: "1" and "X"`},
|
||||||
|
/* 15 */ {`0o10`, int64(8), nil},
|
||||||
|
/* 16 */ {`0b10`, int64(2), nil},
|
||||||
|
/* 17 */ {`~true`, nil, `[1:2] prefix/postfix operator "~" do not support operand 'true' [bool]`},
|
||||||
}
|
}
|
||||||
|
|
||||||
// t.Setenv("EXPR_PATH", ".")
|
// t.Setenv("EXPR_PATH", ".")
|
||||||
|
|
||||||
//runTestSuiteSpec(t, section, inputs, 3)
|
// runTestSuiteSpec(t, section, inputs, 4)
|
||||||
runTestSuite(t, section, inputs)
|
runTestSuite(t, section, inputs)
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestStringsParser(t *testing.T) {
|
func TestStringsParser(t *testing.T) {
|
||||||
|
section := "String"
|
||||||
inputs := []inputType{
|
inputs := []inputType{
|
||||||
/* 1 */ {`"uno" + "due"`, `unodue`, nil},
|
/* 1 */ {`"uno" + "due"`, `unodue`, nil},
|
||||||
/* 2 */ {`"uno" + 2`, `uno2`, nil},
|
/* 2 */ {`"uno" + 2`, `uno2`, nil},
|
||||||
@ -22,6 +23,6 @@ func TestStringsParser(t *testing.T) {
|
|||||||
/* 10 */ {`"AF3B0Dz" / 0`, nil, "[1:12] division by zero"},
|
/* 10 */ {`"AF3B0Dz" / 0`, nil, "[1:12] division by zero"},
|
||||||
}
|
}
|
||||||
|
|
||||||
// runTestSuiteSpec(t, "String", inputs, 8)
|
// runTestSuiteSpec(t, section, inputs, 8)
|
||||||
runTestSuite(t, "String", inputs)
|
runTestSuite(t, section, inputs)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user