add json translator

master
Jordan Orelli 10 years ago
parent cbbeff9908
commit 64d05746e6

@ -1,37 +1,37 @@
package main
import (
"encoding/json"
"flag"
"fmt"
"io"
"os"
)
func input() io.ReadCloser {
if flag.Arg(1) == "" {
func input(n int) io.ReadCloser {
if flag.Arg(n) == "" {
return os.Stdin
} else {
f, err := os.Open(flag.Arg(1))
f, err := os.Open(flag.Arg(n))
if err != nil {
fmt.Fprintf(os.Stderr, "error: %s\n", err)
os.Exit(1)
bail(1, "input error: %s", err)
}
return f
}
}
func check() {
r := input()
r := input(1)
defer r.Close()
_, err := parse(r)
if err != nil {
fmt.Fprintf(os.Stderr, "%s\n", err)
bail(1, "parse error: %s", err)
}
}
func lexx() {
r := input()
r := input(1)
defer r.Close()
c := lex(r)
@ -41,20 +41,65 @@ func lexx() {
}
func parsse() {
r := input()
r := input(1)
defer r.Close()
n, err := parse(r)
if err != nil {
fmt.Fprintf(os.Stderr, "error: %s\n", err)
os.Exit(1)
bail(1, "parse error: %s", err)
}
if err := n.pretty(os.Stdout, ""); err != nil {
fmt.Fprintf(os.Stderr, "error: %s\n", err)
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) {
@ -64,11 +109,11 @@ func main() {
lexx()
case "parse":
parsse()
case "to":
to()
case "":
fmt.Fprintf(os.Stderr, "specify an action (check)\n")
os.Exit(1)
bail(1, "must specify an action.\nvalid actions: check lex parse to")
default:
fmt.Fprintf(os.Stderr, "no such action: %s\n", flag.Arg(0))
os.Exit(1)
bail(1, "no such action:%s", flag.Arg(0))
}
}

@ -23,6 +23,7 @@ type node interface {
Type() nodeType
parse(*parser) error
pretty(io.Writer, string) error
eval(map[string]interface{}) error
}
type rootNode struct {
@ -90,6 +91,15 @@ func (n *rootNode) pretty(w io.Writer, prefix string) error {
return nil
}
func (n *rootNode) eval(ctx map[string]interface{}) error {
for _, child := range n.children {
if err := child.eval(ctx); err != nil {
return err
}
}
return nil
}
type commentNode struct {
body string
}
@ -126,6 +136,10 @@ func (n *commentNode) pretty(w io.Writer, prefix string) error {
return nil
}
func (n *commentNode) eval(ctx map[string]interface{}) error {
return nil
}
type assignmentNode struct {
name string
value interface{}
@ -167,5 +181,13 @@ func (n *assignmentNode) pretty(w io.Writer, prefix string) error {
return nil
}
func (n *assignmentNode) eval(ctx map[string]interface{}) error {
if _, ok := ctx[n.name]; ok {
return fmt.Errorf("invalid re-declaration: %s", n.name)
}
ctx[n.name] = n.value
return nil
}
type list []interface{}
type object map[string]interface{}

Loading…
Cancel
Save