<- Back to shtanton's homepage
aboutsummaryrefslogtreecommitdiff
path: root/main/parse.go
diff options
context:
space:
mode:
Diffstat (limited to 'main/parse.go')
-rw-r--r--main/parse.go64
1 files changed, 27 insertions, 37 deletions
diff --git a/main/parse.go b/main/parse.go
index 1972b66..ef50e81 100644
--- a/main/parse.go
+++ b/main/parse.go
@@ -57,18 +57,18 @@ func (p *parser) parseSubex() subex.SubexAST {
return subexAST
}
-func (p *parser) parseBasicCommand(commandChar rune) Command {
+func (p *parser) parseBasicCommand(commands []Command, commandChar rune) []Command {
switch commandChar {
case 'p':
- return PrintValueCommand{}
+ return append(commands, PrintValueCommand{})
case 'd':
- return DeleteValueCommand{}
+ return append(commands, DeleteValueCommand{})
case 'D':
- return DeletePathCommand{}
+ return append(commands, DeletePathCommand{})
case 'n':
- return NextCommand{}
+ return append(commands, NextCommand{})
case 'N':
- return AppendNextCommand{}
+ return append(commands, AppendNextCommand{})
case 's', 'S', 'f', 'F', 'l', 'L', 'a', 'A':
ast := p.parseSubex()
switch commandChar {
@@ -120,77 +120,67 @@ func (p *parser) parseBasicCommand(commandChar rune) Command {
}
}
subex := subex.CompileTransducer(ast)
- var next Command
- token := p.peek()
- switch token.typ {
- case TokenEOF, TokenRBrace:
- next = NoopCommand{}
- default:
- next = p.parseCommand()
- }
switch commandChar {
case 's', 'a':
- return SubstituteValueCommand {subex, next}
+ return append(commands, SubstituteValueCommand {subex}, JumpCommand {len(commands) + 3})
case 'S', 'f', 'F', 'l', 'L', 'A':
- return SubstitutePathCommand {subex, next}
+ return append(commands, SubstitutePathCommand {subex}, JumpCommand {len(commands) + 3})
default:
panic("Unreachable!?!?")
}
case 'o':
- return NoopCommand{}
+ return append(commands, NoopCommand{})
case 'x':
- return SwapXRegCommand{}
+ return append(commands, SwapXRegCommand{})
case 'X':
- return AppendXRegCommand{}
+ return append(commands, AppendXRegCommand{})
case 'y':
- return SwapYRegCommand{}
+ return append(commands, SwapYRegCommand{})
case 'Y':
- return AppendYRegCommand{}
+ return append(commands, AppendYRegCommand{})
case 'z':
- return SwapZRegCommand{}
+ return append(commands, SwapZRegCommand{})
case 'Z':
- return AppendZRegCommand{}
+ return append(commands, AppendZRegCommand{})
case 'k':
- return SwapPathCommand{}
+ return append(commands, SwapPathCommand{})
case 'K':
- return AppendPathCommand{}
+ return append(commands, AppendPathCommand{})
default:
panic("Invalid command")
}
}
-func (p *parser) parseCommand() Command {
+func (p *parser) parseCommand(commands []Command) []Command {
token := p.next()
switch token.typ {
case TokenLBrace:
- commands := p.parseCommands()
+ jumpToBlockCommand := &JumpCommand{0}
+ commands = append(commands, JumpCommand {len(commands) + 2}, jumpToBlockCommand)
+ commands = p.parseCommands(commands)
if p.next().typ != TokenRBrace {
panic("Missing matching }")
}
- return SequenceCommand {commands}
+ jumpToBlockCommand.destination = len(commands)
+ return commands
case TokenCommand:
commandChar, _, err := strings.NewReader(token.val).ReadRune()
if err != nil {
panic("Error reading a command character!?")
}
- return p.parseBasicCommand(commandChar)
+ return p.parseBasicCommand(commands, commandChar)
default:
panic("Invalid token, expected command")
}
}
-func (p *parser) parseCommands() []Command {
- var commands []Command
+func (p *parser) parseCommands(commands []Command) []Command {
for {
nextToken := p.peek()
if nextToken.typ == TokenEOF || nextToken.typ == TokenRBrace {
return commands
}
- commands = append(commands, p.parseCommand())
- endToken := p.peek()
- if endToken.typ == TokenEOF || endToken.typ == TokenRBrace {
- return commands
- }
+ commands = p.parseCommand(commands)
}
}
@@ -198,5 +188,5 @@ func Parse(tokens chan Token) []Command {
p := parser {
tokenStream: tokens,
}
- return p.parseCommands()
+ return p.parseCommands(nil)
}