alias operators: '<<' same as '<+', '>>' same as '+>'. Insert and append operation optimized with linked lists
This commit is contained in:
+69
-16
@@ -31,6 +31,41 @@ func newAppendTerm(tk *scan.Token) (inst *scan.Term) {
|
||||
}
|
||||
}
|
||||
|
||||
func prependToList(ctx kern.ExprContext, opTerm *scan.Term, leftValue, rightValue any) (result any, err error) {
|
||||
if list, ok := rightValue.(*kern.ListType); ok {
|
||||
var it kern.Iterator
|
||||
if it, ok = leftValue.(kern.Iterator); !ok {
|
||||
if it, err = NewIterator(ctx, leftValue, nil); err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
ls := kern.NewLinkedList()
|
||||
ls.SeqPushBack(it)
|
||||
|
||||
newList := kern.ListType(nil)
|
||||
if newSize := len(*list) + int(ls.Len()); newSize > cap(*list) {
|
||||
newList = make([]any, 0, newSize)
|
||||
for node := ls.FirstNode(); node != nil; node = node.Next() {
|
||||
newList = append(newList, node.Data())
|
||||
}
|
||||
}
|
||||
for _, item := range *list {
|
||||
newList = append(newList, item)
|
||||
}
|
||||
result = &newList
|
||||
|
||||
// ***** EVENTUALMENTE ABILITARE LA MODIFICA DELLA VARIABILE
|
||||
// ***** CON UN OPERATORE SPECIFICO
|
||||
// if opTerm.Children[1].Symbol() == scan.SymVariable {
|
||||
// ctx.UnsafeSetVar(opTerm.Children[1].Source(), result)
|
||||
// }
|
||||
} else {
|
||||
err = opTerm.ErrIncompatibleTypes(leftValue, rightValue)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func evalPrepend(ctx kern.ExprContext, opTerm *scan.Term) (v any, err error) {
|
||||
var leftValue, rightValue any
|
||||
|
||||
@@ -38,13 +73,39 @@ func evalPrepend(ctx kern.ExprContext, opTerm *scan.Term) (v any, err error) {
|
||||
return
|
||||
}
|
||||
|
||||
if kern.IsList(rightValue) {
|
||||
list, _ := rightValue.(*kern.ListType)
|
||||
newList := append(kern.ListType{leftValue}, *list...)
|
||||
v = &newList
|
||||
if opTerm.Children[1].Symbol() == scan.SymVariable {
|
||||
ctx.UnsafeSetVar(opTerm.Children[1].Source(), v)
|
||||
v, err = prependToList(ctx, opTerm, leftValue, rightValue)
|
||||
return
|
||||
}
|
||||
|
||||
func appendToList(ctx kern.ExprContext, opTerm *scan.Term, leftValue, rightValue any) (result any, err error) {
|
||||
if list, ok := leftValue.(*kern.ListType); ok {
|
||||
var it kern.Iterator
|
||||
if it, ok = rightValue.(kern.Iterator); !ok {
|
||||
if it, err = NewIterator(ctx, rightValue, nil); err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
ls := kern.NewLinkedList()
|
||||
ls.SeqPushBack(it)
|
||||
|
||||
newList := *list
|
||||
if newSize := len(*list) + int(ls.Len()); newSize > cap(*list) {
|
||||
newList = make([]any, 0, newSize)
|
||||
for _, item := range *list {
|
||||
newList = append(newList, item)
|
||||
}
|
||||
}
|
||||
for node := ls.FirstNode(); node != nil; node = node.Next() {
|
||||
newList = append(newList, node.Data())
|
||||
}
|
||||
result = &newList
|
||||
|
||||
// ***** EVENTUALMENTE ABILITARE LA MODIFICA DELLA VARIABILE
|
||||
// ***** CON UN OPERATORE SPECIFICO
|
||||
// if opTerm.Children[0].Symbol() == scan.SymVariable {
|
||||
// ctx.UnsafeSetVar(opTerm.Children[0].Source(), result)
|
||||
// }
|
||||
} else {
|
||||
err = opTerm.ErrIncompatibleTypes(leftValue, rightValue)
|
||||
}
|
||||
@@ -58,16 +119,8 @@ func evalAppend(ctx kern.ExprContext, opTerm *scan.Term) (v any, err error) {
|
||||
return
|
||||
}
|
||||
|
||||
if kern.IsList(leftValue) {
|
||||
list, _ := leftValue.(*kern.ListType)
|
||||
newList := append(*list, rightValue)
|
||||
v = &newList
|
||||
if opTerm.Children[0].Symbol() == scan.SymVariable {
|
||||
ctx.UnsafeSetVar(opTerm.Children[0].Source(), v)
|
||||
}
|
||||
} else {
|
||||
err = opTerm.ErrIncompatibleTypes(leftValue, rightValue)
|
||||
}
|
||||
v, err = appendToList(ctx, opTerm, leftValue, rightValue)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user