Created
May 17, 2017 08:01
-
-
Save chrisbarrett/a8b0c94b6d71bda91b80bc8c8a683844 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Compiler from Go types to an S-Expression representation. | |
// | |
// The output a drop-in replacement for the Elisp JSON parser output, and can be | |
// consumed directly with `read`. | |
package main | |
import ( | |
"strconv" | |
"strings" | |
) | |
type JsRepr interface { | |
ToJs() js | |
} | |
// TODO: Implement conversions from k8s types to this JSON representation. | |
func Compile(o JsRepr) string { | |
return o.ToJs().toSexp().render() | |
} | |
// JSON representation | |
type js interface { | |
toSexp() sexp | |
} | |
type jarray struct { | |
contents []js | |
} | |
func (a jarray) toSexp() sexp { | |
sexps := make([]sexp, len(a.contents)) | |
for i := range a.contents { | |
entry := a.contents[i] | |
sexps[i] = entry.toSexp() | |
} | |
return svector{sexps} | |
} | |
type jobject struct { | |
contents map[string]js | |
} | |
func (o jobject) toSexp() sexp { | |
kvps := make([]sexp, len(o.contents)) | |
i := 0 | |
for key, value := range o.contents { | |
car := ssymbol{key} | |
cdr := value.toSexp() | |
kvps[i] = scons{car, cdr} | |
i++ | |
} | |
return slist{kvps} | |
} | |
type jstring struct { | |
value string | |
} | |
func (s jstring) toSexp() sexp { | |
return sstring{s.value} | |
} | |
type jnumber struct { | |
value float64 | |
} | |
func (n jnumber) toSexp() sexp { | |
return snumber{n.value} | |
} | |
type jtrue struct{} | |
func (t jtrue) toSexp() sexp { | |
return ssymbol{"t"} | |
} | |
type jfalse struct{} | |
func (f jfalse) toSexp() sexp { | |
return ssymbol{":json-false"} | |
} | |
type jnull struct{} | |
func (n jnull) toSexp() sexp { | |
return ssymbol{"nil"} | |
} | |
// Raw S-Expressions | |
type sexp interface { | |
render() string | |
} | |
type slist struct { | |
contents []sexp | |
} | |
func (ls slist) render() string { | |
inner := make([]string, len(ls.contents)) | |
for i := range ls.contents { | |
entry := ls.contents[i] | |
inner[i] = entry.render() | |
} | |
rendered := strings.Join(inner, " ") | |
return "(" + rendered + ")" | |
} | |
type svector struct { | |
contents []sexp | |
} | |
func (v svector) render() string { | |
inner := make([]string, len(v.contents)) | |
for i := range v.contents { | |
entry := v.contents[i] | |
inner[i] = entry.render() | |
} | |
rendered := strings.Join(inner, " ") | |
return "[" + rendered + "]" | |
} | |
type scons struct { | |
car sexp | |
cdr sexp | |
} | |
func (c scons) render() string { | |
car := c.car.render() | |
cdr := c.cdr.render() | |
return "(" + car + " . " + cdr + ")" | |
} | |
type snumber struct { | |
value float64 | |
} | |
func (n snumber) render() string { | |
return strconv.FormatFloat(n.value, 'f', -1, 64) | |
} | |
type sstring struct { | |
value string | |
} | |
func (s sstring) render() string { | |
return s.value | |
} | |
type ssymbol struct { | |
value string | |
} | |
func (s ssymbol) render() string { | |
return s.value | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment