<- Back to shtanton's homepage
aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCharlie Stanton <charlie@shtanton.xyz>2024-04-23 20:25:49 +0100
committerCharlie Stanton <charlie@shtanton.xyz>2024-04-23 20:25:49 +0100
commit7084f5e1ceb61eab199512410048ad53e3ea08d7 (patch)
tree54db2851f4eb4b06998e00173d0bf30b9991d43f
parent663dd2ede81e6415a3c16a46d8e9cfa2e209238f (diff)
downloadstred-go-7084f5e1ceb61eab199512410048ad53e3ea08d7.tar
Add full merge command
-rw-r--r--main/command.go33
-rw-r--r--main/lex.go2
-rw-r--r--main/main_test.go7
-rw-r--r--main/parse.go4
4 files changed, 43 insertions, 3 deletions
diff --git a/main/command.go b/main/command.go
index 38e1c95..e795333 100644
--- a/main/command.go
+++ b/main/command.go
@@ -138,9 +138,38 @@ func (cmd MergeCommand) String() string {
return "m"
}
-type FullMergeCommand struct {}
+type FullMergeCommand struct {
+ subex subex.Transducer
+}
func (cmd FullMergeCommand) exec(state *ProgramState) {
- panic("Unimplemented")
+ _, notOk := runSubex(cmd.subex, state.value)
+ if notOk || state.end {
+ state.pc++
+ return
+ }
+
+ for {
+ item, err := state.Read()
+ if err != nil {
+ panic("Missing next value")
+ }
+
+ _, nonTerminal := runSubex(cmd.subex, []walk.Value{item.Value})
+
+ state.value = append(
+ state.value[:len(state.value) - 1],
+ walk.Merge(state.value[len(state.value) - 1], item.Value)...
+ )
+
+ if !nonTerminal && item.End {
+ state.prevStart = item.PrevStart
+ state.start = item.Start
+ state.end = item.End
+ state.nextEnd = item.NextEnd
+ state.pc += 2
+ return
+ }
+ }
}
func (cmd FullMergeCommand) String() string {
return "M"
diff --git a/main/lex.go b/main/lex.go
index 8e66890..da517cc 100644
--- a/main/lex.go
+++ b/main/lex.go
@@ -180,7 +180,7 @@ func lexCommand(l *lexer) stateFunc {
case '}':
l.emit(TokenRBrace)
return lexCommand
- case 's', 'S':
+ case 's', 'S', 'M':
l.emit(TokenCommand)
return lexSubstitution
case 'x', 'X', 'y', 'Y', 'z', 'Z', 'n', 'N':
diff --git a/main/main_test.go b/main/main_test.go
index 1ac89f6..b745202 100644
--- a/main/main_test.go
+++ b/main/main_test.go
@@ -93,6 +93,13 @@ func TestMain(t *testing.T) {
input: miscInput,
expected: `"Hello world these are values"`,
},
+ {
+ name: "Short concat array values",
+ program: "M/#( \"array\" :(): )#/{ s/#( \"array\"$_ :( .{-0} )- )-/ s/-( ~(.{-0}` `)-{-0} ~(.{-0})- )~/p }",
+ quiet: true,
+ input: miscInput,
+ expected: `"Hello world these are values"`,
+ },
}
for _, test := range tests {
diff --git a/main/parse.go b/main/parse.go
index 36917ac..36bd3ee 100644
--- a/main/parse.go
+++ b/main/parse.go
@@ -77,6 +77,10 @@ func (p *parser) parseBasicCommand(commands []Command, commandChar rune) []Comma
return append(commands, SubstituteAppendNextCommand {subex}, JumpCommand {len(commands) + 3})
case 'm':
return append(commands, MergeCommand{})
+ case 'M':
+ ast := p.parseSubex()
+ subex := subex.CompileTransducer(ast)
+ return append(commands, FullMergeCommand {subex}, JumpCommand {len(commands) + 3})
case 's':
ast := p.parseSubex()
subex := subex.CompileTransducer(ast)