package main import ( "encoding/json" "flag" "fmt" "io" "os" ) func input(n int) io.ReadCloser { if flag.Arg(n) == "" { return os.Stdin } else { f, err := os.Open(flag.Arg(n)) if err != nil { bail(1, "input error: %s", err) } return f } } func check() { r := input(1) defer r.Close() _, err := parse(r) if err != nil { bail(1, "parse error: %s", err) } } func lexx() { r := input(1) defer r.Close() c := lex(r) for t := range c { fmt.Println(t) } } func parsse() { r := input(1) defer r.Close() n, err := parse(r) if err != nil { bail(1, "parse error: %s", err) } if err := n.pretty(os.Stdout, ""); err != nil { bail(1, "output error: %s", err) } } func eval(r io.Reader) (map[string]interface{}, error) { n, err := parse(r) if err != nil { return nil, fmt.Errorf("parse error: %s\n", err) } ctx := make(map[string]interface{}) if _, err := n.eval(ctx); err != nil { return nil, fmt.Errorf("eval error: %s\n", err) } return ctx, nil } func to() { switch flag.Arg(1) { case "json": to_json(2) default: fmt.Fprintf(os.Stderr, "%s is not a valid output format\n", flag.Arg(1)) fmt.Fprintln(os.Stderr, "valid output formats: json") os.Exit(1) } } func to_json(n int) { v, err := eval(input(n)) if err != nil { bail(1, "input error: %s", err) } b, err := json.MarshalIndent(v, "", " ") if err != nil { bail(1, "encode error: %s", err) } os.Stdout.Write(b) } func bail(status int, t string, args ...interface{}) { var w io.Writer if status == 0 { w = os.Stdout } else { w = os.Stderr } fmt.Fprintf(w, t+"\n", args...) os.Exit(status) } func main() { flag.Parse() switch flag.Arg(0) { case "check": check() case "lex": lexx() case "parse": parsse() case "to": to() case "": bail(1, "must specify an action.\nvalid actions: check lex parse to") default: bail(1, "no such action:%s", flag.Arg(0)) } }