Skip to content

Commit

Permalink
Add list insertion
Browse files Browse the repository at this point in the history
  • Loading branch information
mitchpaulus committed Nov 27, 2024
1 parent 963942a commit 62dbdb9
Show file tree
Hide file tree
Showing 5 changed files with 47 additions and 1 deletion.
1 change: 1 addition & 0 deletions doc/mshell.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
`map`: Map a quotation over a list, `(list quote -- list)`
`each`: Execute a quotation for each element in a list, `(list quote -- )`
`del`: Delete element from list, `(list index -- list)` or `(index list -- list)`
`insert`: Insert element into list, `(list element index -- list)`

## Variables

Expand Down
41 changes: 40 additions & 1 deletion mshell/Evaluator.go
Original file line number Diff line number Diff line change
Expand Up @@ -510,7 +510,46 @@ MainLoop:
}

stack.Push(newList)
} else if t.Lexeme == "del" {
} else if t.Lexeme == "insert" {
// Expected stack:
// List item index
// Index 0 based, negative indexes allowed
obj1, err := stack.Pop()
if err != nil {
return FailWithMessage(fmt.Sprintf("%d:%d: Cannot do 'insert' 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 'insert' operation on a stack with only one item.\n", t.Line, t.Column))
}

obj3, err := stack.Pop()
if err != nil {
return FailWithMessage(fmt.Sprintf("%d:%d: Cannot do 'insert' operation on a stack with only two items.\n", t.Line, t.Column))
}

obj1Index, ok := obj1.(*MShellInt)
if !ok {
return FailWithMessage(fmt.Sprintf("%d:%d: Cannot insert at a non-integer index.\n", t.Line, t.Column))
}

obj3List, ok := obj3.(*MShellList)
if !ok {
return FailWithMessage(fmt.Sprintf("%d:%d: Cannot insert into a non-list.\n", t.Line, t.Column))
}

if obj1Index.Value < 0 {
obj1Index.Value = len(obj3List.Items) + obj1Index.Value
}

if obj1Index.Value < 0 || obj1Index.Value > len(obj3List.Items) {
return FailWithMessage(fmt.Sprintf("%d:%d: Index out of range for 'insert'.\n", t.Line, t.Column))
}

obj3List.Items = append(obj3List.Items[:obj1Index.Value], append([]MShellObject{obj2}, obj3List.Items[obj1Index.Value:]...)...)
stack.Push(obj3List)
} 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))
Expand Down
Binary file modified mshell/mshell
Binary file not shown.
4 changes: 4 additions & 0 deletions tests/indexing.msh
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,7 @@ def cjoin ", " join wl end
1 ["a" "b" "c" "d"] del cjoin
["a" "b" "c" "d"] -1 del cjoin
-1 ["a" "b" "c" "d"] del cjoin

# Test insertion at index
["a" "b" "c" "d"] "x" 2 insert cjoin
["a" "b" "c" "d"] "x" -1 insert cjoin
2 changes: 2 additions & 0 deletions tests/indexing.msh.stdout
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,5 @@ a, b, d
a, c, d
a, b, c
a, b, c
a, b, x, c, d
a, b, c, x, d

0 comments on commit 62dbdb9

Please sign in to comment.