expr/operator-insert.go
Celestino Amoroso d91e7eb979 The list operator '<<' (append) and '>>' (prepend) have been replaced
with the new operators '<+' and '+>' respectively.
'<<' and '>>' are now used only for left and right binary shit
respectively. Further, their priority has been increased moving them to
a higher priority than that of the assignment operator.
2024-12-28 09:17:27 +01:00

92 lines
2.0 KiB
Go

// Copyright (c) 2024 Celestino Amoroso (celestino.amoroso@gmail.com).
// All rights reserved.
// operator-insert.go
package expr
//-------- prepend term
func newPrependTerm(tk *Token) (inst *term) {
return &term{
tk: *tk,
children: make([]*term, 0, 2),
position: posInfix,
priority: priInsert,
evalFunc: evalPrepend,
}
}
func newAppendTerm(tk *Token) (inst *term) {
return &term{
tk: *tk,
children: make([]*term, 0, 2),
position: posInfix,
priority: priInsert,
evalFunc: evalAppend,
}
}
func evalPrepend(ctx ExprContext, opTerm *term) (v any, err error) {
var leftValue, rightValue any
if leftValue, rightValue, err = opTerm.evalInfix(ctx); err != nil {
return
}
if IsList(rightValue) {
list, _ := rightValue.(*ListType)
newList := append(ListType{leftValue}, *list...)
v = &newList
if opTerm.children[1].symbol() == SymVariable {
ctx.UnsafeSetVar(opTerm.children[1].source(), v)
}
} else {
err = opTerm.errIncompatibleTypes(leftValue, rightValue)
}
return
}
func evalAppend(ctx ExprContext, opTerm *term) (v any, err error) {
var leftValue, rightValue any
if leftValue, rightValue, err = opTerm.evalInfix(ctx); err != nil {
return
}
if IsList(leftValue) {
list, _ := leftValue.(*ListType)
newList := append(*list, rightValue)
v = &newList
if opTerm.children[0].symbol() == SymVariable {
ctx.UnsafeSetVar(opTerm.children[0].source(), v)
}
} else {
err = opTerm.errIncompatibleTypes(leftValue, rightValue)
}
return
}
// func evalAssignAppend(ctx ExprContext, self *term) (v any, err error) {
// var leftValue, rightValue any
// if leftValue, rightValue, err = self.evalInfix(ctx); err != nil {
// return
// }
// if IsList(leftValue) {
// list, _ := leftValue.(*ListType)
// newList := append(*list, rightValue)
// v = &newList
// if
// } else {
// err = self.errIncompatibleTypes(leftValue, rightValue)
// }
// return
// }
// init
func init() {
registerTermConstructor(SymPlusGreater, newPrependTerm)
registerTermConstructor(SymLessPlus, newAppendTerm)
}