Skip to content

Commit

Permalink
Add split/join for strings
Browse files Browse the repository at this point in the history
  • Loading branch information
mitchpaulus committed Nov 11, 2024
1 parent 665c5f0 commit 384f825
Show file tree
Hide file tree
Showing 4 changed files with 85 additions and 2 deletions.
6 changes: 4 additions & 2 deletions doc/mshell.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@
`str`: Convert to string
`findReplace`: Find and replace in string. `findReplace (string string, string find, string replace -- string)`
`lines`: Split string into list of string lines
`split`: Split string into list of strings by delimiter, use `ws` literal or `"ws"` for whitespace. (string delimiter -- list)
`join`: Join list of strings into a single string, (list delimiter -- string)

### List Functions

Expand All @@ -38,9 +40,9 @@

```mshell
# Storing
10 @a
10 my_var!
# Retrieving
a!
@my_var
```

## Process Substitution
Expand Down
79 changes: 79 additions & 0 deletions mshell-go/Evaluator.go
Original file line number Diff line number Diff line change
Expand Up @@ -386,6 +386,85 @@ func (state *EvalState) Evaluate(objects []MShellParseItem, stack *MShellStack,
return FailWithMessage(fmt.Sprintf("%d:%d: Cannot find-replace a %s.\n", t.Line, t.Column, obj1.TypeName()))
}

} else if t.Lexeme == "split" {
delimiter, err := stack.Pop()
if err != nil {
return FailWithMessage(fmt.Sprintf("%d:%d: Cannot do 'split' operation on an empty stack.\n", t.Line, t.Column))
}

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


var delimiterStr string
var strToSplit string

switch delimiter.(type) {
case *MShellString:
delimiterStr = delimiter.(*MShellString).Content
case *MShellLiteral:
delimiterStr = delimiter.(*MShellLiteral).LiteralText
default:
return FailWithMessage(fmt.Sprintf("%d:%d: Cannot split with a %s.\n", t.Line, t.Column, delimiter.TypeName()))
}

switch strLiteral.(type) {
case *MShellString:
strToSplit = strLiteral.(*MShellString).Content
case *MShellLiteral:
strToSplit = strLiteral.(*MShellLiteral).LiteralText
default:
return FailWithMessage(fmt.Sprintf("%d:%d: Cannot split a %s.\n", t.Line, t.Column, strLiteral.TypeName()))
}

split := strings.Split(strToSplit, delimiterStr)
newList := &MShellList { Items: make([]MShellObject, len(split)), StandardInputFile: "", StandardOutputFile: "", StdoutBehavior: STDOUT_NONE }
for i, item := range split {
newList.Items[i] = &MShellString { item }
}
stack.Push(newList)
} else if t.Lexeme == "join" {
delimiter, err := stack.Pop()
if err != nil {
return FailWithMessage(fmt.Sprintf("%d:%d: Cannot do 'join' operation on an empty stack.\n", t.Line, t.Column))
}

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

var delimiterStr string
var listItems []string

switch delimiter.(type) {
case *MShellString:
delimiterStr = delimiter.(*MShellString).Content
case *MShellLiteral:
delimiterStr = delimiter.(*MShellLiteral).LiteralText
default:
return FailWithMessage(fmt.Sprintf("%d:%d: Cannot join with a %s.\n", t.Line, t.Column, delimiter.TypeName()))
}

switch list.(type) {
case *MShellList:
for _, item := range list.(*MShellList).Items {
switch item.(type) {
case *MShellString:
listItems = append(listItems, item.(*MShellString).Content)
case *MShellLiteral:
listItems = append(listItems, item.(*MShellLiteral).LiteralText)
default:
return FailWithMessage(fmt.Sprintf("%d:%d: Cannot join a list with a %s inside (%s).\n", t.Line, t.Column, item.TypeName(), item.DebugString()))
}
}
default:
return FailWithMessage(fmt.Sprintf("%d:%d: Cannot join a %s.\n", t.Line, t.Column, list.TypeName()))
}

stack.Push(&MShellString { strings.Join(listItems, delimiterStr) })
} else if t.Lexeme == "lines" {
obj, err := stack.Pop()
if err != nil {
Expand Down
1 change: 1 addition & 0 deletions mshell/tests/split_join.msh
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
"cell1|cell2|cell3" "|" split ":" join wl
1 change: 1 addition & 0 deletions mshell/tests/split_join.msh.stdout
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
cell1:cell2:cell3

0 comments on commit 384f825

Please sign in to comment.