aboutsummaryrefslogtreecommitdiff
path: root/tcl.go
blob: 3eef16eca709bcd0844963f84e88c7d5fb27a65c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
package tcl

import (
	"log"
	"os"

	"github.com/davecgh/go-spew/spew"
	. "github.com/oec/goparsify"
)

// Tcl parser, using combinators
// Based on the grammer in:
// https://wiki.tcl-lang.org/page/BNF+for+Tcl

var (
	word     Parser
	commands Parser
	script   Parser
)

var (
	comment = NewParser("comment", Merge(NoAutoWS(Seq("#", NotChars("\r\n"))))).Map(found("comment"))
	wordExp = NewParser("{*}word", NoAutoWS(Seq("{*}", &word))).Map(found("wordExp"))
	wordSub = NewParser("[*]word", NoAutoWS(Seq("[*]", &word))).Map(found("wordSub"))
	wordBrc = NewParser("{word}", Seq("{", &word, "}")).Map(found("wordBrc"))
	wordQtd = NewParser(`"word"`, StringLit(`"`)).Map(found("wordQtd"))
	wordSmp = NewParser("simple", NotChars("{}[]*")).Map(found("simple"))
	command = NewParser("command", Many(&word)).Map(found("command")).Map(found("command"))
)

func init() {
	word = NewParser("word", Any(&wordSmp, &wordQtd, &wordBrc, &wordSub, &wordExp)).Map(found("word"))
	commands = NewParser("commands", Any(&command, Maybe(Chars(";"))))
	script = NewParser("script", Many(Any(&comment, &commands)))
}

func Parse(input string) (data interface{}, e error) {
	data, e = Run(&script, input, ASCIIWhitespace)
	return
}

func ParseDebug(input string) (data interface{}, e error) {
	EnableLogging(os.Stdout)
	data, e = Run(&script, input, ASCIIWhitespace)
	return
}

func found(typ string) func(*Result) {
	return func(r *Result) {
		log.Println("found a", typ)
		spew.Dump(r)

	}
}
func dump(r *Result) {
	spew.Dump(r)
}