diff options
| author | Charlie Stanton <charlie@shtanton.xyz> | 2024-04-23 20:25:49 +0100 | 
|---|---|---|
| committer | Charlie Stanton <charlie@shtanton.xyz> | 2024-04-23 20:25:49 +0100 | 
| commit | 7084f5e1ceb61eab199512410048ad53e3ea08d7 (patch) | |
| tree | 54db2851f4eb4b06998e00173d0bf30b9991d43f /main | |
| parent | 663dd2ede81e6415a3c16a46d8e9cfa2e209238f (diff) | |
| download | stred-go-7084f5e1ceb61eab199512410048ad53e3ea08d7.tar | |
Add full merge command
Diffstat (limited to 'main')
| -rw-r--r-- | main/command.go | 33 | ||||
| -rw-r--r-- | main/lex.go | 2 | ||||
| -rw-r--r-- | main/main_test.go | 7 | ||||
| -rw-r--r-- | main/parse.go | 4 | 
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) | 
