diff --git a/mshell/Evaluator.go b/mshell/Evaluator.go index c8ad0b5..b87c0dc 100644 --- a/mshell/Evaluator.go +++ b/mshell/Evaluator.go @@ -491,7 +491,53 @@ MainLoop: } stack.Push(newList) - } else if t.Lexeme == "~" || strings.HasPrefix(t.Lexeme, "~/") { + } else if t.Lexeme == "del" { + obj1, err := stack.Pop() + if err != nil { + return FailWithMessage(fmt.Sprintf("%d:%d: Cannot do 'del' operation on an empty stack.\n", t.Line, t.Column)) + } + + obj2, err := stack.Pop() + if err != nil { + return FailWithMessage(fmt.Sprintf("%d:%d: Cannot do 'del' operation on a stack with only one item.\n", t.Line, t.Column)) + } + + switch obj1.(type) { + case *MShellInt: + switch obj2.(type) { + case *MShellList: + index := obj1.(*MShellInt).Value + if index < 0 { + index = len(obj2.(*MShellList).Items) + index + } + + if index < 0 || index >= len(obj2.(*MShellList).Items) { + return FailWithMessage(fmt.Sprintf("%d:%d: Index out of range for 'del'.\n", t.Line, t.Column)) + } + obj2.(*MShellList).Items = append(obj2.(*MShellList).Items[:index], obj2.(*MShellList).Items[index+1:]...) + stack.Push(obj2) + default: + return FailWithMessage(fmt.Sprintf("%d:%d: Cannot delete from a %s.\n", t.Line, t.Column, obj2.TypeName())) + } + case *MShellList: + switch obj2.(type) { + case *MShellInt: + index := obj2.(*MShellInt).Value + if index < 0 { + index = len(obj1.(*MShellList).Items) + index + } + if index < 0 || index >= len(obj1.(*MShellList).Items) { + return FailWithMessage(fmt.Sprintf("%d:%d: Index out of range for 'del'.\n", t.Line, t.Column)) + } + obj1.(*MShellList).Items = append(obj1.(*MShellList).Items[:index], obj1.(*MShellList).Items[index+1:]...) + stack.Push(obj1) + default: + return FailWithMessage(fmt.Sprintf("%d:%d: Cannot delete from a %s.\n", t.Line, t.Column, obj2.TypeName())) + } + default: + return FailWithMessage(fmt.Sprintf("%d:%d: Cannot delete from a %s.\n", t.Line, t.Column, obj1.TypeName())) + } + } else if t.Lexeme == "~" || strings.HasPrefix(t.Lexeme, "~/") { // Only do tilde expansion homeDir, err := os.UserHomeDir() if err != nil { diff --git a/mshell/mshell b/mshell/mshell index ebb9c85..b0a6534 100755 Binary files a/mshell/mshell and b/mshell/mshell differ diff --git a/tests/indexing.msh b/tests/indexing.msh index ef41eb7..a2f5f53 100644 --- a/tests/indexing.msh +++ b/tests/indexing.msh @@ -19,3 +19,11 @@ echo "12345" -3: wl # 345 "12345" :-4 wl # 1 "12345" -4:-2 wl # 23 + +def cjoin ", " join wl end + +# Test deletion at index +["a" "b" "c" "d"] 2 del cjoin +1 ["a" "b" "c" "d"] del cjoin +["a" "b" "c" "d"] -1 del cjoin +-1 ["a" "b" "c" "d"] del cjoin diff --git a/tests/indexing.msh.stdout b/tests/indexing.msh.stdout index b574bda..39a1a36 100644 --- a/tests/indexing.msh.stdout +++ b/tests/indexing.msh.stdout @@ -6,3 +6,7 @@ ul 345 1 23 +a, b, d +a, c, d +a, b, c +a, b, c