From d3660c578700ae158f6cd89c097eec7b8c391c4a Mon Sep 17 00:00:00 2001 From: Linus Lee Date: Sun, 23 Feb 2020 21:27:35 -0500 Subject: [PATCH] Represent proxy values in repl as their underlying values --- pkg/xin/lib.go | 1 + pkg/xin/map.go | 16 ++++++++++++---- pkg/xin/reader.go | 8 ++++++++ pkg/xin/runtime.go | 5 ++--- pkg/xin/value.go | 7 +++++++ pkg/xin/vec.go | 6 +++++- 6 files changed, 35 insertions(+), 8 deletions(-) diff --git a/pkg/xin/lib.go b/pkg/xin/lib.go index 8b4994e..eb3a1dd 100644 --- a/pkg/xin/lib.go +++ b/pkg/xin/lib.go @@ -25,6 +25,7 @@ func loadStandardLibrary(vm *Vm) InterpreterError { "str", "src", "stat", + "os", "test", } diff --git a/pkg/xin/map.go b/pkg/xin/map.go index ba26a53..03b00bc 100644 --- a/pkg/xin/map.go +++ b/pkg/xin/map.go @@ -1,16 +1,20 @@ package xin +import ( + "strings" +) + // StringValue is of type []byte, which is unhashable // so we convert StringValues to hashable string type // before using as map keys type hashableStringProxy string func (v hashableStringProxy) String() string { - return "( " + string(v) + ")" + return string(v) } func (v hashableStringProxy) Repr() string { - return v.String() + return "'" + strings.ReplaceAll(string(v), "'", "\\'") + "'" } func (v hashableStringProxy) Equal(ov Value) bool { @@ -22,7 +26,7 @@ func (v hashableStringProxy) Equal(ov Value) bool { type hashableNativeFormProxy string func (v hashableNativeFormProxy) String() string { - return "( " + string(v) + ")" + return "( " + string(v) + ")" } func (v hashableNativeFormProxy) Repr() string { @@ -76,7 +80,11 @@ func (v MapValue) String() string { } func (v MapValue) Repr() string { - return v.String() + ss := "" + for k, val := range *v.items { + ss += " " + k.Repr() + "->" + val.Repr() + } + return "(" + ss + ")" } func (v MapValue) Equal(o Value) bool { diff --git a/pkg/xin/reader.go b/pkg/xin/reader.go index 09fd55d..ba1d473 100644 --- a/pkg/xin/reader.go +++ b/pkg/xin/reader.go @@ -3,6 +3,7 @@ package xin import ( "io" "io/ioutil" + "strings" ) type reader struct { @@ -25,6 +26,13 @@ func newReader(path string, r io.Reader) (*reader, error) { max: len(asString), } rdr.position.path = path + + // read shebang line if present + if strings.HasPrefix(asString, "#!") { + rdr.upto("\n") + rdr.skip() + } + return &rdr, nil } func (rdr *reader) done() bool { diff --git a/pkg/xin/runtime.go b/pkg/xin/runtime.go index e78947a..646abc7 100644 --- a/pkg/xin/runtime.go +++ b/pkg/xin/runtime.go @@ -2,7 +2,6 @@ package xin import ( "bufio" - "fmt" "io" "math" "math/rand" @@ -19,7 +18,7 @@ type NativeFormValue struct { } func (v NativeFormValue) String() string { - return fmt.Sprintf("( %s)", v.name) + return "( " + v.name + ")" } func (v NativeFormValue) Repr() string { @@ -39,7 +38,7 @@ func loadAllDefaultValues(vm *Vm) { stdoutStream := NewStream() stdoutStream.callbacks.sink = func(v Value) InterpreterError { - fmt.Printf(v.String()) + os.Stdout.Write([]byte(v.String())) return nil } fr.Put("os::stdout", stdoutStream) diff --git a/pkg/xin/value.go b/pkg/xin/value.go index d2d0d84..a12810f 100644 --- a/pkg/xin/value.go +++ b/pkg/xin/value.go @@ -14,8 +14,15 @@ import ( // exception to this case, where a proxy Value type is used instead // which is hashable. type Value interface { + // String is stable, string representation of a Xin value + // that can be used to back the to-string type conversion of values String() string + + // Repr is an unstable, human-readable representation of Xin values used for + // debugging and the repl, should not be considered a stable API + // to be used in the language internally. Repr() string + Equal(Value) bool } diff --git a/pkg/xin/vec.go b/pkg/xin/vec.go index 727a2cf..e079f36 100644 --- a/pkg/xin/vec.go +++ b/pkg/xin/vec.go @@ -28,7 +28,11 @@ func (v VecValue) String() string { } func (v VecValue) Repr() string { - return v.String() + ss := "" + for _, item := range v.underlying.items { + ss += " " + item.Repr() + } + return "(" + ss + ")" } func (v VecValue) Equal(o Value) bool {