summaryrefslogtreecommitdiff
path: root/conflang.go
diff options
context:
space:
mode:
Diffstat (limited to 'conflang.go')
-rw-r--r--conflang.go160
1 files changed, 0 insertions, 160 deletions
diff --git a/conflang.go b/conflang.go
deleted file mode 100644
index 0b4a856..0000000
--- a/conflang.go
+++ /dev/null
@@ -1,160 +0,0 @@
-package main
-
-import (
- "bufio"
- "fmt"
- "io"
-)
-
-type toktype int
-
-const (
- tText toktype = iota
- tNextCmd
-)
-
-type token struct {
- Type toktype
- Data string
- Line int
-}
-
-func scan(r io.Reader, tokens chan<- token, errch chan<- error) {
- emit := func(t toktype, d []byte, line int) {
- if t == tText && len(d) == 0 {
- return
- }
- tokens <- token{t, string(d), line}
- }
-
- err := func() error {
- br := bufio.NewReader(r)
-
- escaped := false
- data := []byte{}
- line := 1
-
- for {
- b, err := br.ReadByte()
-
- switch err {
- case nil:
- case io.EOF:
- return nil
- default:
- return ErrorAtLine{line, err}
- }
-
- if b == '\n' {
- line++
- }
-
- if escaped {
- data = append(data, b)
- escaped = false
- continue
- }
-
- switch b {
- case '\\':
- escaped = true
- case ' ', '\t':
- emit(tText, data, line)
- data = data[:0]
- case '\n':
- emit(tText, data, line)
- data = data[:0]
- emit(tNextCmd, nil, line)
- default:
- data = append(data, b)
- }
- }
-
- emit(tText, data, line)
- emit(tNextCmd, nil, line)
- return nil
- }()
-
- close(tokens)
- errch <- err
-}
-
-type command struct {
- Name string
- Params []string
- Line int
-}
-
-func parse(tokens <-chan token, cmds chan<- command) {
- defer close(cmds)
-
- startcmd := true
- cmd := command{"", make([]string, 0), 0}
-
- for tok := range tokens {
- switch tok.Type {
- case tText:
- if startcmd {
- cmd.Name = tok.Data
- cmd.Line = tok.Line
- startcmd = false
- } else {
- cmd.Params = append(cmd.Params, tok.Data)
- }
- case tNextCmd:
- if !startcmd {
- cmds <- cmd
- cmd.Name = ""
- cmd.Params = make([]string, 0)
- startcmd = true
- }
- }
- }
-}
-
-type cmdfunc func(params []string) error
-
-var commands = map[string]cmdfunc{
- "nop": func(_ []string) error { return nil },
-}
-
-func RegisterCommand(name string, f cmdfunc) {
- commands[name] = f
-}
-
-type ErrorAtLine struct {
- Line int
- Err error
-}
-
-func (err ErrorAtLine) Error() string {
- return fmt.Sprintf("%s (at line %d)", err.Err, err.Line)
-}
-
-type CommandNotFound string
-
-func (c CommandNotFound) Error() string {
- return fmt.Sprintf("Command \"%s\" not found", c)
-}
-
-func RunCommands(r io.Reader) error {
- errch := make(chan error)
- tokens := make(chan token)
- cmds := make(chan command)
-
- go scan(r, tokens, errch)
- go parse(tokens, cmds)
-
- for cmd := range cmds {
- f, ok := commands[cmd.Name]
- if !ok {
- return ErrorAtLine{cmd.Line, CommandNotFound(cmd.Name)}
- }
-
- if err := f(cmd.Params); err != nil {
- return ErrorAtLine{cmd.Line, err}
- }
- }
-
- return <-errch
-}