diff options
author | Charlie Stanton <charlie@shtanton.xyz> | 2023-04-20 16:57:48 +0100 |
---|---|---|
committer | Charlie Stanton <charlie@shtanton.xyz> | 2023-04-20 16:57:48 +0100 |
commit | 3cb886859e9b4df4ece183583dfd8b5ba7a59584 (patch) | |
tree | ae634d27d3fde1dbb7d5ac377f9aea80064e0a47 | |
parent | 9bffe238bd97d1dc606c84f2dfc4c73c99b36eea (diff) | |
download | stred-go-3cb886859e9b4df4ece183583dfd8b5ba7a59584.tar |
Adds some shorthands for substituting the beginning and end of the path register
-rw-r--r-- | main/lex.go | 2 | ||||
-rw-r--r-- | main/parse.go | 67 |
2 files changed, 53 insertions, 16 deletions
diff --git a/main/lex.go b/main/lex.go index 2826b1e..ecb0d3d 100644 --- a/main/lex.go +++ b/main/lex.go @@ -179,7 +179,7 @@ func lexCommand(l *lexer) stateFunc { case '}': l.emit(TokenRBrace) return lexCommand - case 's', 'S': + case 's', 'S', 'f', 'F', 'l', 'L': l.emit(TokenCommand) return lexSubstitution } diff --git a/main/parse.go b/main/parse.go index 198b746..dc86fd6 100644 --- a/main/parse.go +++ b/main/parse.go @@ -33,7 +33,7 @@ func (p *parser) peek() Token { return token } -func (p *parser) parseSubex() subex.SubexState { +func (p *parser) parseSubex() subex.SubexAST { delim := p.next() if delim.typ != TokenSubstituteDelimiter { panic("Missing substitute delimiter") @@ -50,12 +50,11 @@ func (p *parser) parseSubex() subex.SubexState { } reader := subex.NewStringRuneReader(subexProgram) subexAST := subex.Parse(reader) - subex := subex.CompileTransducer(subexAST) delim = p.next() if delim.typ != TokenSubstituteDelimiter { panic("Missing end substitute delimiter") } - return subex + return subexAST } func (p *parser) parseBasicCommand(commandChar rune) Command { @@ -70,8 +69,49 @@ func (p *parser) parseBasicCommand(commandChar rune) Command { return NextCommand{} case 'N': return AppendNextCommand{} - case 's', 'S': - subex := p.parseSubex() + case 's', 'S', 'f', 'F', 'l', 'L': + ast := p.parseSubex() + switch commandChar { + case 'f': + ast = subex.SubexASTConcat { + First: ast, + Second: subex.SubexASTRepeat { + Content: subex.SubexASTCopyAny{}, + Acceptable: []subex.ConvexRange{{Start: -1, End: 0}}, + }, + } + case 'F': + ast = subex.SubexASTConcat { + First: subex.SubexASTStore { + Slot: '_', + Match: ast, + }, + Second: subex.SubexASTRepeat { + Content: subex.SubexASTCopyAny{}, + Acceptable: []subex.ConvexRange{{Start: -1, End: 0}}, + }, + } + case 'l': + ast = subex.SubexASTConcat { + First: subex.SubexASTRepeat { + Content: subex.SubexASTCopyAny{}, + Acceptable: []subex.ConvexRange{{Start: 0, End: -1}}, + }, + Second: ast, + } + case 'L': + ast = subex.SubexASTConcat { + First: subex.SubexASTRepeat { + Content: subex.SubexASTCopyAny{}, + Acceptable: []subex.ConvexRange{{Start: 0, End: -1}}, + }, + Second: subex.SubexASTStore { + Slot: '_', + Match: ast, + }, + } + } + subex := subex.CompileTransducer(ast) var next Command token := p.peek() switch token.typ { @@ -80,16 +120,13 @@ func (p *parser) parseBasicCommand(commandChar rune) Command { default: next = p.parseCommand() } - if (commandChar == 's') { - return SubstituteValueCommand { - subex: subex, - next: next, - } - } else { - return SubstitutePathCommand { - subex: subex, - next: next, - } + switch commandChar { + case 's': + return SubstituteValueCommand {subex, next} + case 'S', 'f', 'F', 'l', 'L': + return SubstitutePathCommand {subex, next} + default: + panic("Unreachable!?!?") } case 'o': return NoopCommand{} |