diff options
Diffstat (limited to 'main/parse.go')
-rw-r--r-- | main/parse.go | 103 |
1 files changed, 73 insertions, 30 deletions
diff --git a/main/parse.go b/main/parse.go index 141ae7e..36bd3ee 100644 --- a/main/parse.go +++ b/main/parse.go @@ -44,13 +44,7 @@ func (p *parser) parseSubex() subex.SubexAST { if subexProgramToken.typ != TokenSubex { panic("Missing subex from substitution") } - var subexProgram string - if delim.val == "=" || delim.val == "~" || delim.val == "\"" || delim.val == "`" || delim.val == "^" { - subexProgram = delim.val + subexProgramToken.val + delim.val - } else { - subexProgram = subexProgramToken.val - } - reader := subex.NewStringRuneReader(subexProgram) + reader := subex.NewStringRuneReader(subexProgramToken.val) subexAST := subex.Parse(reader) delim = p.next() if delim.typ != TokenSubstituteDelimiter { @@ -65,41 +59,90 @@ func (p *parser) parseBasicCommand(commands []Command, commandChar rune) []Comma return append(commands, PrintValueCommand{}) case 'd': return append(commands, DeleteValueCommand{}) - case 'D': - return append(commands, DeletePathCommand{}) case 'n': - return append(commands, NextCommand{}) - case 'N': - return append(commands, AppendNextCommand{}) - case 's', 'S': + delim := p.peek() + if delim.typ != TokenSubstituteDelimiter { + return append(commands, NextCommand{}) + } ast := p.parseSubex() subex := subex.CompileTransducer(ast) - switch commandChar { - case 's': - return append(commands, SubstituteValueCommand {subex}, JumpCommand {len(commands) + 3}) - case 'S': - return append(commands, SubstitutePathCommand {subex}, JumpCommand {len(commands) + 3}) - default: - panic("Unreachable!?!?") + return append(commands, SubstituteNextCommand {subex}, JumpCommand {len(commands) + 3}) + case 'N': + delim := p.peek() + if delim.typ != TokenSubstituteDelimiter { + return append(commands, AppendNextCommand{}) } + ast := p.parseSubex() + subex := subex.CompileTransducer(ast) + 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) + return append(commands, SubstituteValueCommand {subex}, JumpCommand {len(commands) + 3}) case 'o': return append(commands, NoopCommand{}) case 'x': - return append(commands, SwapXRegCommand{}) + delim := p.peek() + if delim.typ != TokenSubstituteDelimiter { + return append(commands, SwapXRegCommand{}) + } + ast := p.parseSubex() + subex := subex.CompileTransducer(ast) + return append(commands, SubstituteToXRegCommand {subex}, JumpCommand {len(commands) + 3}) case 'X': - return append(commands, AppendXRegCommand{}) + delim := p.peek() + if delim.typ != TokenSubstituteDelimiter { + return append(commands, AppendXRegCommand{}) + } + ast := p.parseSubex() + subex := subex.CompileTransducer(ast) + return append(commands, SubstituteAppendXRegCommand {subex}, JumpCommand {len(commands) + 3}) case 'y': - return append(commands, SwapYRegCommand{}) + delim := p.peek() + if delim.typ != TokenSubstituteDelimiter { + return append(commands, SwapYRegCommand{}) + } + ast := p.parseSubex() + subex := subex.CompileTransducer(ast) + return append(commands, SubstituteToYRegCommand {subex}, JumpCommand {len(commands) + 3}) case 'Y': - return append(commands, AppendYRegCommand{}) + delim := p.peek() + if delim.typ != TokenSubstituteDelimiter { + return append(commands, AppendYRegCommand{}) + } + ast := p.parseSubex() + subex := subex.CompileTransducer(ast) + return append(commands, SubstituteAppendYRegCommand {subex}, JumpCommand {len(commands) + 3}) case 'z': - return append(commands, SwapZRegCommand{}) + delim := p.peek() + if delim.typ != TokenSubstituteDelimiter { + return append(commands, SwapZRegCommand{}) + } + ast := p.parseSubex() + subex := subex.CompileTransducer(ast) + return append(commands, SubstituteToZRegCommand {subex}, JumpCommand {len(commands) + 3}) case 'Z': - return append(commands, AppendZRegCommand{}) - case 'k': - return append(commands, SwapPathCommand{}) - case 'K': - return append(commands, AppendPathCommand{}) + delim := p.peek() + if delim.typ != TokenSubstituteDelimiter { + return append(commands, AppendZRegCommand{}) + } + ast := p.parseSubex() + subex := subex.CompileTransducer(ast) + return append(commands, SubstituteAppendZRegCommand {subex}, JumpCommand {len(commands) + 3}) + case 'a': + return append(commands, IsStartCommand{}, JumpCommand {len(commands) + 3}) + case 'A': + return append(commands, IsPrevStartCommand{}, JumpCommand {len(commands) + 3}) + case 'e': + return append(commands, IsEndCommand{}, JumpCommand {len(commands) + 3}) + case 'E': + return append(commands, IsNextEndCommand{}, JumpCommand {len(commands) + 3}) case ':': labelToken := p.next() if labelToken.typ != TokenLabel { |