diff options
| author | Charlie Stanton <charlie@shtanton.xyz> | 2023-04-19 15:19:42 +0100 | 
|---|---|---|
| committer | Charlie Stanton <charlie@shtanton.xyz> | 2023-04-19 15:19:42 +0100 | 
| commit | dae74317d84471f6a859117fcbba1cf546be8ea1 (patch) | |
| tree | db8516ba8a5a208d16aaa0e6da439541dd496b94 | |
| parent | 10f847acc7087317b0fbe20b7cf3307a0fafab8a (diff) | |
| download | stred-go-dae74317d84471f6a859117fcbba1cf546be8ea1.tar | |
Adds parsing substitute commands, though executing them currently does nothing
| -rw-r--r-- | main/command.go | 8 | ||||
| -rw-r--r-- | main/lex.go | 27 | ||||
| -rw-r--r-- | main/main.go | 5 | ||||
| -rw-r--r-- | main/parse.go | 23 | ||||
| -rw-r--r-- | subex/lex.go | 8 | 
5 files changed, 66 insertions, 5 deletions
| diff --git a/main/command.go b/main/command.go index c61b0cd..8053b86 100644 --- a/main/command.go +++ b/main/command.go @@ -2,6 +2,7 @@ package main  import (  	"main/walk" +	"main/subex"  )  type PrintValueCommand struct {} @@ -103,6 +104,13 @@ func (cmd DeleteAllCommand) exec(state *ProgramState) {  	state.space = nil  } +type SubstituteCommand struct { +	subex subex.SubexState +} +func (cmd SubstituteCommand) exec(state *ProgramState) { +	// TODO +} +  type Command interface {  	exec(*ProgramState)  }
\ No newline at end of file diff --git a/main/lex.go b/main/lex.go index 0daf2d1..e82c309 100644 --- a/main/lex.go +++ b/main/lex.go @@ -147,6 +147,7 @@ const (  	TokenNumberLiteral // A number literal  	TokenPatternStringIndex // A string index in a pattern  	TokenPatternIntegerIndex // An integer index in a pattern +	TokenSubex // A subex  )  type Token struct { @@ -269,6 +270,9 @@ func lexCommand(l *lexer) stateFunc {  		case 'i':  			l.emit(TokenCommand)  			return lexMultipleLiterals +		case 's': +			l.emit(TokenCommand) +			return lexSubstitution  		case 'S':  			l.emit(TokenCommand)  			return lexBigSubstitution @@ -280,6 +284,29 @@ func lexCommand(l *lexer) stateFunc {  	return l.errorf("Expected command found something else")  } +func lexSubstitution(l *lexer) stateFunc { +	delimiter := l.next() +	if delimiter == eof { +		return l.errorf("Missing subex in substitution command") +	} +	l.emit(TokenSubstituteDelimiter) +	loop: for { +		r := l.next() +		switch r { +			case delimiter: +				l.backup() +				l.emit(TokenSubex) +				l.next() +				l.emit(TokenSubstituteDelimiter) +				break loop +			case eof: +				return l.errorf("Missing closing substitution delimiter") +			default: +		} +	} +	return lexCommand +} +  func lexBigSubstitution(l *lexer) stateFunc {  	delimiter := l.next()  	if delimiter == eof || isAlphaNumeric(delimiter) { diff --git a/main/main.go b/main/main.go index 3da414d..902c5b9 100644 --- a/main/main.go +++ b/main/main.go @@ -3,7 +3,6 @@ package main  import (  	"os"  	"bufio" -	"main/subex"  	"main/walk"  ) @@ -17,10 +16,6 @@ type ProgramState struct {  }  func main() { -	subex.Main() -} - -func mainISH() {  	quiet := false  	var input string  	hasInput := false diff --git a/main/parse.go b/main/parse.go index 73c7913..bf2f0ac 100644 --- a/main/parse.go +++ b/main/parse.go @@ -5,6 +5,7 @@ import (  	"strconv"  	"fmt"  	"main/walk" +	"main/subex"  )  type parser struct { @@ -202,6 +203,25 @@ func (p *parser) parseLiterals() (items []walk.WalkItem) {  	return items  } +func (p *parser) parseSubex() subex.SubexState { +	delim := p.next() +	if delim.typ != TokenSubstituteDelimiter { +		panic("Missing substitute delimiter") +	} +	subexProgramToken := p.next() +	if subexProgramToken.typ != TokenSubex { +		panic("Missing subex from substitution") +	} +	reader := subex.NewStringRuneReader(subexProgramToken.val) +	subexAST := subex.Parse(reader) +	subex := subex.CompileTransducer(subexAST) +	delim = p.next() +	if delim.typ != TokenSubstituteDelimiter { +		panic("Missing end substitute delimiter") +	} +	return subex +} +  func (p *parser) parseBasicCommand(commandChar rune) Command {  	switch commandChar {  		case 'p': @@ -212,6 +232,9 @@ func (p *parser) parseBasicCommand(commandChar rune) Command {  			return NextCommand{}  		case 'N':  			return AppendNextCommand{} +		case 's': +			subex := p.parseSubex() +			return SubstituteCommand {subex: subex}  		case 'i':  			items := p.parseLiterals()  			return PrintLiteralsCommand {items: items} diff --git a/subex/lex.go b/subex/lex.go index 74bf370..0f00a99 100644 --- a/subex/lex.go +++ b/subex/lex.go @@ -22,3 +22,11 @@ func (l *StringRuneReader) Next() rune {  func (l *StringRuneReader) Rewind() {  	l.pos -= l.width  } + +func NewStringRuneReader(input string) RuneReader { +	return &StringRuneReader { +		input: input, +		pos: 0, +		width: 0, +	} +} | 
