From 099d54d6ace836b4c769ecc9b5bd7ffd77e87894 Mon Sep 17 00:00:00 2001 From: James Hamlin Date: Sun, 3 Aug 2025 15:18:20 -0700 Subject: [PATCH] Remove outdated lang package alias Signed-off-by: James Hamlin --- Makefile | 2 +- pkg/glj/glj_test.go | 4 +- pkg/glj/init.go | 8 +- pkg/glj/var.go | 12 +- pkg/lang/symbol.go | 4 +- pkg/lang/vector.go | 6 +- pkg/reader/clj_conformance_test.go | 14 +- pkg/reader/reader.go | 250 ++++++++++++++--------------- pkg/reader/reader_test.go | 18 +-- pkg/reader/resolver.go | 10 +- pkg/repl/options.go | 6 +- pkg/repl/repl.go | 18 +-- pkg/repl/repl_wasm.go | 18 +-- pkg/runtime/envinit.go | 16 +- pkg/runtime/environment.go | 66 ++++---- pkg/runtime/eval.go | 51 +++--- pkg/runtime/evalast.go | 73 +++++---- pkg/runtime/readeval.go | 10 +- pkg/runtime/rtcompat.go | 17 +- pkg/runtime/scope.go | 8 +- 20 files changed, 303 insertions(+), 308 deletions(-) diff --git a/Makefile b/Makefile index 6edc7b0b..ef05f707 100644 --- a/Makefile +++ b/Makefile @@ -64,7 +64,7 @@ test: vet $(TEST_TARGETS) .PHONY: format format: - @if go fmt ./... | grep -q .; then \ + @if go fmt ./... | grep -q ''; then \ echo "Files were formatted. Please commit the changes."; \ exit 1; \ fi diff --git a/pkg/glj/glj_test.go b/pkg/glj/glj_test.go index 28219724..1304b106 100644 --- a/pkg/glj/glj_test.go +++ b/pkg/glj/glj_test.go @@ -3,13 +3,13 @@ package glj import ( "testing" - value "github.com/glojurelang/glojure/pkg/lang" + "github.com/glojurelang/glojure/pkg/lang" ) func TestGLJ(t *testing.T) { mp := Var("glojure.core", "map") inc := Var("glojure.core", "inc") - res := value.PrintString(mp.Invoke(inc, Read("[1 2 3]"))) + res := lang.PrintString(mp.Invoke(inc, Read("[1 2 3]"))) if res != "(2 3 4)" { t.Errorf("Expected (2 3 4), got %v", res) } diff --git a/pkg/glj/init.go b/pkg/glj/init.go index 3cafee36..21fcf9eb 100644 --- a/pkg/glj/init.go +++ b/pkg/glj/init.go @@ -6,8 +6,8 @@ import ( // Add the Go standard library to the pkgmap. _ "github.com/glojurelang/glojure/pkg/gen/gljimports" + "github.com/glojurelang/glojure/pkg/lang" - value "github.com/glojurelang/glojure/pkg/lang" "github.com/glojurelang/glojure/pkg/runtime" ) @@ -15,13 +15,13 @@ func init() { initEnv(os.Stdout) } -func initEnv(stdout io.Writer) value.Environment { +func initEnv(stdout io.Writer) lang.Environment { // TODO: clean up this code. copied from rtcompat.go. kvs := make([]interface{}, 0, 3) - for _, vr := range []*value.Var{value.VarCurrentNS, value.VarWarnOnReflection, value.VarUncheckedMath, value.VarDataReaders} { + for _, vr := range []*lang.Var{lang.VarCurrentNS, lang.VarWarnOnReflection, lang.VarUncheckedMath, lang.VarDataReaders} { kvs = append(kvs, vr, vr.Deref()) } - value.PushThreadBindings(value.NewMap(kvs...)) + lang.PushThreadBindings(lang.NewMap(kvs...)) return runtime.NewEnvironment(runtime.WithStdout(stdout)) } diff --git a/pkg/glj/var.go b/pkg/glj/var.go index 11ef706b..16b92193 100644 --- a/pkg/glj/var.go +++ b/pkg/glj/var.go @@ -1,15 +1,15 @@ package glj -import value "github.com/glojurelang/glojure/pkg/lang" +import "github.com/glojurelang/glojure/pkg/lang" // Var returns an IFn associated with the namespace and name. -func Var(ns, name interface{}) value.IFn { - return value.InternVarName(asSym(ns), asSym(name)) +func Var(ns, name interface{}) lang.IFn { + return lang.InternVarName(asSym(ns), asSym(name)) } -func asSym(x interface{}) *value.Symbol { +func asSym(x interface{}) *lang.Symbol { if str, ok := x.(string); ok { - return value.NewSymbol(str) + return lang.NewSymbol(str) } - return x.(*value.Symbol) + return x.(*lang.Symbol) } diff --git a/pkg/lang/symbol.go b/pkg/lang/symbol.go index ff882b60..0322d943 100644 --- a/pkg/lang/symbol.go +++ b/pkg/lang/symbol.go @@ -54,7 +54,7 @@ func (s *Symbol) Compare(other any) int { if !ok { panic(NewIllegalArgumentError(fmt.Sprintf("Cannot compare Symbol with %T", other))) } - + // Compare namespace first if s.ns != otherSym.ns { if s.ns == "" && otherSym.ns != "" { @@ -67,7 +67,7 @@ func (s *Symbol) Compare(other any) int { return nsComp } } - + // Then compare name return strings.Compare(s.name, otherSym.name) } diff --git a/pkg/lang/vector.go b/pkg/lang/vector.go index a5754341..2dc696b1 100644 --- a/pkg/lang/vector.go +++ b/pkg/lang/vector.go @@ -277,17 +277,17 @@ func (v *Vector) Compare(other any) int { if !ok { panic(NewIllegalArgumentError(fmt.Sprintf("Cannot compare Vector with %T", other))) } - + myCount := v.Count() otherCount := otherVec.Count() - + // Compare lengths first if myCount < otherCount { return -1 } else if myCount > otherCount { return 1 } - + // Compare element by element for i := 0; i < myCount; i++ { cmp := Compare(v.Nth(i), otherVec.Nth(i)) diff --git a/pkg/reader/clj_conformance_test.go b/pkg/reader/clj_conformance_test.go index f87ee224..e8ae5a2a 100644 --- a/pkg/reader/clj_conformance_test.go +++ b/pkg/reader/clj_conformance_test.go @@ -14,7 +14,7 @@ import ( "testing" "unicode" - value "github.com/glojurelang/glojure/pkg/lang" + "github.com/glojurelang/glojure/pkg/lang" "github.com/kylelemons/godebug/diff" ) @@ -22,26 +22,26 @@ type ( testSymbolResolver struct{} ) -func (sr *testSymbolResolver) CurrentNS() *value.Symbol { - return value.NewSymbol("user") +func (sr *testSymbolResolver) CurrentNS() *lang.Symbol { + return lang.NewSymbol("user") } -func (sr *testSymbolResolver) ResolveStruct(s *value.Symbol) *value.Symbol { +func (sr *testSymbolResolver) ResolveStruct(s *lang.Symbol) *lang.Symbol { if strings.Contains(s.Name(), ".") { return s } return nil } -func (sr *testSymbolResolver) ResolveAlias(s *value.Symbol) *value.Symbol { +func (sr *testSymbolResolver) ResolveAlias(s *lang.Symbol) *lang.Symbol { return s } -func (sr *testSymbolResolver) ResolveVar(s *value.Symbol) *value.Symbol { +func (sr *testSymbolResolver) ResolveVar(s *lang.Symbol) *lang.Symbol { if strings.Contains(s.String(), "/") { return s } - return value.NewSymbol("user/" + s.String()) + return lang.NewSymbol("user/" + s.String()) } // Running these fuzz tests is slow because clj is very slow to start diff --git a/pkg/reader/reader.go b/pkg/reader/reader.go index 737620cb..d0299cf3 100644 --- a/pkg/reader/reader.go +++ b/pkg/reader/reader.go @@ -10,16 +10,16 @@ import ( "strings" "unicode" - value "github.com/glojurelang/glojure/pkg/lang" + "github.com/glojurelang/glojure/pkg/lang" ) var ( - symQuote = value.NewSymbol("quote") - symList = value.NewSymbol("glojure.core/list") - symSeq = value.NewSymbol("glojure.core/seq") - symConcat = value.NewSymbol("glojure.core/concat") - symUnquote = value.NewSymbol("glojure.core/unquote") - symSpliceUnquote = value.NewSymbol("glojure.core/splice-unquote") + symQuote = lang.NewSymbol("quote") + symList = lang.NewSymbol("glojure.core/list") + symSeq = lang.NewSymbol("glojure.core/seq") + symConcat = lang.NewSymbol("glojure.core/concat") + symUnquote = lang.NewSymbol("glojure.core/unquote") + symSpliceUnquote = lang.NewSymbol("glojure.core/splice-unquote") specials = func() map[string]bool { specialStrs := []string{ @@ -176,11 +176,11 @@ type ( rs *trackingRuneScanner symbolResolver SymbolResolver - getCurrentNS func() *value.Namespace + getCurrentNS func() *lang.Namespace // map for function shorthand arguments. // non-nil only when reading a function shorthand. - fnArgMap map[int]*value.Symbol + fnArgMap map[int]*lang.Symbol argCounter int posStack []pos @@ -190,7 +190,7 @@ type ( type options struct { filename string resolver SymbolResolver - getCurrentNS func() *value.Namespace + getCurrentNS func() *lang.Namespace } // Option represents an option that can be passed to New. @@ -211,7 +211,7 @@ func WithSymbolResolver(resolver SymbolResolver) Option { } // WithGetCurrentNS sets the function to be used to get the current namespace. -func WithGetCurrentNS(getCurrentNS func() *value.Namespace) Option { +func WithGetCurrentNS(getCurrentNS func() *lang.Namespace) Option { return func(o *options) { o.getCurrentNS = getCurrentNS } @@ -223,11 +223,11 @@ func New(r io.RuneScanner, opts ...Option) *Reader { for _, opt := range opts { opt(&o) } - getCurrentNS := func() *value.Namespace { - if value.GlobalEnv != nil { // TODO: should be unnecessary - return value.GlobalEnv.CurrentNamespace() + getCurrentNS := func() *lang.Namespace { + if lang.GlobalEnv != nil { // TODO: should be unnecessary + return lang.GlobalEnv.CurrentNamespace() } - return value.FindOrCreateNamespace(value.NewSymbol("user")) + return lang.FindOrCreateNamespace(lang.NewSymbol("user")) } if o.getCurrentNS != nil { getCurrentNS = o.getCurrentNS @@ -300,16 +300,16 @@ func (r *Reader) error(format string, args ...interface{}) error { // popSection returns the last section read, ending at the current // input, and pops it off the stack. -func (r *Reader) popSection() value.IPersistentMap { +func (r *Reader) popSection() lang.IPersistentMap { top := r.posStack[len(r.posStack)-1] r.posStack = r.posStack[:len(r.posStack)-1] - return value.NewMap( - value.KWFile, r.rs.filename, - value.KWLine, top.Line, - value.KWColumn, top.Column, - value.KWEndLine, r.rs.pos().Line, - value.KWEndColumn, r.rs.pos().Column, + return lang.NewMap( + lang.KWFile, r.rs.filename, + lang.KWLine, top.Line, + lang.KWColumn, top.Column, + lang.KWEndLine, r.rs.pos().Line, + lang.KWEndColumn, r.rs.pos().Column, ) } @@ -354,14 +354,14 @@ func (r *Reader) readExpr() (expr interface{}, err error) { r.pushSection() defer func() { s := r.popSection() - obj, ok := expr.(value.IObj) + obj, ok := expr.(lang.IObj) if !ok { return } meta := obj.Meta() - for seq := value.Seq(s); seq != nil; seq = seq.Next() { - entry := seq.First().(value.IMapEntry) - meta = value.Assoc(meta, entry.Key(), entry.Val()).(value.IPersistentMap) + for seq := lang.Seq(s); seq != nil; seq = seq.Next() { + entry := seq.First().(lang.IMapEntry) + meta = lang.Assoc(meta, entry.Key(), entry.Val()).(lang.IPersistentMap) } expr = obj.WithMeta(meta) }() @@ -408,7 +408,7 @@ func (r *Reader) readExpr() (expr interface{}, err error) { if err != nil { return nil, err } - return value.WithMeta(val, meta) + return lang.WithMeta(val, meta) default: r.rs.UnreadRune() return r.readSymbol() @@ -436,7 +436,7 @@ func (r *Reader) readList() (interface{}, error) { } nodes = append(nodes, node) } - return value.NewList(nodes...), nil + return lang.NewList(nodes...), nil } func (r *Reader) readVector() (interface{}, error) { @@ -460,7 +460,7 @@ func (r *Reader) readVector() (interface{}, error) { } nodes = append(nodes, node) } - return value.NewVector(nodes...), nil + return lang.NewVector(nodes...), nil } func (r *Reader) readMap() (interface{}, error) { @@ -488,7 +488,7 @@ func (r *Reader) readMap() (interface{}, error) { return nil, r.error("map literal must contain an even number of forms") } - return value.NewMap(keyVals...), nil + return lang.NewMap(keyVals...), nil } func (r *Reader) readSet() (interface{}, error) { @@ -512,7 +512,7 @@ func (r *Reader) readSet() (interface{}, error) { } vals = append(vals, el) } - return value.NewSet(vals...), nil + return lang.NewSet(vals...), nil } func (r *Reader) readString() (interface{}, error) { @@ -556,12 +556,12 @@ func (r *Reader) nextID() int { return id } -func (r *Reader) genArg(i int) *value.Symbol { +func (r *Reader) genArg(i int) *lang.Symbol { prefix := "rest" if i != -1 { prefix = fmt.Sprintf("p%d", i) } - return value.NewSymbol(fmt.Sprintf("%s__%d#", prefix, r.nextID())) + return lang.NewSymbol(fmt.Sprintf("%s__%d#", prefix, r.nextID())) } func (r *Reader) readArg() (interface{}, error) { @@ -575,7 +575,7 @@ func (r *Reader) readArg() (interface{}, error) { return sym, nil } - argSuffix := sym.(*value.Symbol).Name()[1:] + argSuffix := sym.(*lang.Symbol).Name()[1:] switch { case argSuffix == "&": if r.fnArgMap[-1] == nil { @@ -606,7 +606,7 @@ func (r *Reader) readFunctionShorthand() (interface{}, error) { if r.fnArgMap != nil { return nil, r.error("nested #()s are not allowed") } - r.fnArgMap = make(map[int]*value.Symbol) + r.fnArgMap = make(map[int]*lang.Symbol) defer func() { r.fnArgMap = nil }() @@ -620,7 +620,7 @@ func (r *Reader) readFunctionShorthand() (interface{}, error) { const maxArgIndex = 20 args := make([]interface{}, 0, len(r.fnArgMap)) - var restSym *value.Symbol + var restSym *lang.Symbol // NB: arg keys are 1-indexed, -1 represents a "rest" arg for i, sym := range r.fnArgMap { for i > len(args) { @@ -636,7 +636,7 @@ func (r *Reader) readFunctionShorthand() (interface{}, error) { args[i-1] = sym } if restSym != nil { - args = append(args, value.NewSymbol("&"), restSym) + args = append(args, lang.NewSymbol("&"), restSym) } // fill in any missing args with generated args for i, arg := range args { @@ -646,9 +646,9 @@ func (r *Reader) readFunctionShorthand() (interface{}, error) { args[i] = r.genArg(i + 1) } - return value.NewList( - value.NewSymbol("fn*"), - value.NewVector(args...), + return lang.NewList( + lang.NewSymbol("fn*"), + lang.NewVector(args...), body, ), nil } @@ -703,11 +703,11 @@ func (r *Reader) readChar() (interface{}, error) { char += string(rn) } - rn, err := value.RuneFromCharLiteral("\\" + char) + rn, err := lang.RuneFromCharLiteral("\\" + char) if err != nil { return nil, r.error("invalid character literal: %w", err) } - return value.NewChar(rn), nil + return lang.NewChar(rn), nil } func (r *Reader) readQuoteType(form string) (interface{}, error) { @@ -716,7 +716,7 @@ func (r *Reader) readQuoteType(form string) (interface{}, error) { return nil, err } - return value.NewList(value.NewSymbol(form), node), nil + return lang.NewList(lang.NewSymbol(form), node), nil } func (r *Reader) readQuote() (interface{}, error) { @@ -732,18 +732,18 @@ func (r *Reader) readSyntaxQuote() (interface{}, error) { // symbolNameMap tracks the names of symbols that have been renamed. // symbols that end with a '#' have '#' replaced with a unique // suffix. - symbolNameMap := make(map[string]*value.Symbol) + symbolNameMap := make(map[string]*lang.Symbol) return r.syntaxQuote(symbolNameMap, node), nil } -func (r *Reader) syntaxQuote(symbolNameMap map[string]*value.Symbol, node interface{}) interface{} { +func (r *Reader) syntaxQuote(symbolNameMap map[string]*lang.Symbol, node interface{}) interface{} { switch node := node.(type) { - case value.Keyword, value.Char, string: + case lang.Keyword, lang.Char, string: return node - case *value.Symbol: + case *lang.Symbol: sym := node if specials[sym.String()] { - return value.NewList(symQuote, sym) + return lang.NewList(symQuote, sym) } switch { case sym.Namespace() == "" && strings.HasSuffix(sym.Name(), "#"): @@ -753,7 +753,7 @@ func (r *Reader) syntaxQuote(symbolNameMap map[string]*value.Symbol, node interf break } // TODO: use a global counter, not the length of this map - newSym := value.NewSymbol(strings.TrimSuffix(sym.Name(), "#") + "__" + strconv.Itoa(len(symbolNameMap)) + "__auto__") + newSym := lang.NewSymbol(strings.TrimSuffix(sym.Name(), "#") + "__" + strconv.Itoa(len(symbolNameMap)) + "__auto__") symbolNameMap[sym.String()] = newSym sym = newSym case sym.Namespace() == "" && strings.HasSuffix(sym.Name(), "."): @@ -764,16 +764,16 @@ func (r *Reader) syntaxQuote(symbolNameMap map[string]*value.Symbol, node interf // special class-like go value // TODO: is this a good syntax? case r.symbolResolver != nil: - var nsym *value.Symbol + var nsym *lang.Symbol if sym.Namespace() != "" { - alias := value.InternSymbol(nil, sym.Namespace()) + alias := lang.InternSymbol(nil, sym.Namespace()) nsym = r.symbolResolver.ResolveStruct(alias) if nsym == nil { nsym = r.symbolResolver.ResolveAlias(alias) } } if nsym != nil { - sym = value.InternSymbol(nsym.Name(), sym.Name()) + sym = lang.InternSymbol(nsym.Name(), sym.Name()) } else if sym.Namespace() == "" { rsym := r.symbolResolver.ResolveStruct(sym) if rsym == nil { @@ -782,7 +782,7 @@ func (r *Reader) syntaxQuote(symbolNameMap map[string]*value.Symbol, node interf if rsym != nil { sym = rsym } else { - sym = value.InternSymbol(r.symbolResolver.CurrentNS().Name(), sym.Name()) + sym = lang.InternSymbol(r.symbolResolver.CurrentNS().Name(), sym.Name()) } } default: @@ -794,91 +794,91 @@ func (r *Reader) syntaxQuote(symbolNameMap map[string]*value.Symbol, node interf sym = r.resolveSymbol(sym) } // TODO: match actual LispReader.java behavior - return value.NewList(symQuote, sym) - case value.IPersistentMap: + return lang.NewList(symQuote, sym) + case lang.IPersistentMap: var keyvals []interface{} - for seq := value.Seq(node); seq != nil; seq = seq.Next() { - entry := seq.First().(value.IMapEntry) + for seq := lang.Seq(node); seq != nil; seq = seq.Next() { + entry := seq.First().(lang.IMapEntry) keyvals = append(keyvals, entry.Key(), entry.Val()) } - return value.NewList( - value.NewSymbol("glojure.core/apply"), - value.NewSymbol("glojure.core/hash-map"), - value.NewList( - value.NewSymbol("glojure.core/seq"), - value.NewCons( - value.NewSymbol("glojure.core/concat"), + return lang.NewList( + lang.NewSymbol("glojure.core/apply"), + lang.NewSymbol("glojure.core/hash-map"), + lang.NewList( + lang.NewSymbol("glojure.core/seq"), + lang.NewCons( + lang.NewSymbol("glojure.core/concat"), r.sqExpandList(symbolNameMap, keyvals), ), ), ) - case value.IPersistentList, value.IPersistentVector: - _, isVector := node.(value.IPersistentVector) - if value.Count(node) == 0 { + case lang.IPersistentList, lang.IPersistentVector: + _, isVector := node.(lang.IPersistentVector) + if lang.Count(node) == 0 { if isVector { //(glojure.core/apply glojure.core/vector (glojure.core/seq (glojure.core/concat))) - return value.NewList( - value.NewSymbol("glojure.core/apply"), - value.NewSymbol("glojure.core/vector"), - value.NewList( - value.NewSymbol("glojure.core/seq"), - value.NewList( - value.NewSymbol("glojure.core/concat"), + return lang.NewList( + lang.NewSymbol("glojure.core/apply"), + lang.NewSymbol("glojure.core/vector"), + lang.NewList( + lang.NewSymbol("glojure.core/seq"), + lang.NewList( + lang.NewSymbol("glojure.core/concat"), ), ), ) } - return value.NewList(symList) + return lang.NewList(symList) } if r.isUnquote(node) { - return value.First(value.Rest(node)) + return lang.First(lang.Rest(node)) } elements := []interface{}{symConcat} - for seq := value.Seq(node); seq != nil; seq = seq.Next() { + for seq := lang.Seq(node); seq != nil; seq = seq.Next() { first := seq.First() - if seq, ok := first.(value.ISeq); ok && value.Equals(value.First(seq), symSpliceUnquote) { - elements = append(elements, value.First(value.Rest(first))) + if seq, ok := first.(lang.ISeq); ok && lang.Equals(lang.First(seq), symSpliceUnquote) { + elements = append(elements, lang.First(lang.Rest(first))) } else { - elements = append(elements, value.NewList(symList, r.syntaxQuote(symbolNameMap, first))) + elements = append(elements, lang.NewList(symList, r.syntaxQuote(symbolNameMap, first))) } } - ret := value.NewList(symSeq, - value.NewList(elements...)) + ret := lang.NewList(symSeq, + lang.NewList(elements...)) if isVector { - ret = value.NewList( - value.NewSymbol("glojure.core/apply"), - value.NewSymbol("glojure.core/vector"), + ret = lang.NewList( + lang.NewSymbol("glojure.core/apply"), + lang.NewSymbol("glojure.core/vector"), ret) } return ret } - return value.NewList(symQuote, node) + return lang.NewList(symQuote, node) } -func (r *Reader) sqExpandList(symbolNameMap map[string]*value.Symbol, els []interface{}) value.ISeq { - var ret value.IPersistentVector = value.NewVector() +func (r *Reader) sqExpandList(symbolNameMap map[string]*lang.Symbol, els []interface{}) lang.ISeq { + var ret lang.IPersistentVector = lang.NewVector() for _, v := range els { if r.isUnquote(v) { - ret = ret.Cons(value.NewList(value.NewSymbol("glojure.core/list"), value.First(value.Rest(v)))).(value.IPersistentVector) + ret = ret.Cons(lang.NewList(lang.NewSymbol("glojure.core/list"), lang.First(lang.Rest(v)))).(lang.IPersistentVector) } else if r.isUnquoteSplicing(v) { - ret = ret.Cons(value.First(value.Rest(v))).(value.IPersistentVector) + ret = ret.Cons(lang.First(lang.Rest(v))).(lang.IPersistentVector) } else { - ret = ret.Cons(value.NewList(value.NewSymbol("glojure.core/list"), r.syntaxQuote(symbolNameMap, v))).(value.IPersistentVector) + ret = ret.Cons(lang.NewList(lang.NewSymbol("glojure.core/list"), r.syntaxQuote(symbolNameMap, v))).(lang.IPersistentVector) } } - return value.Seq(ret) + return lang.Seq(ret) } func (r *Reader) isUnquote(form interface{}) bool { - seq, ok := form.(value.ISeq) - return ok && value.Equals(seq.First(), symUnquote) + seq, ok := form.(lang.ISeq) + return ok && lang.Equals(seq.First(), symUnquote) } func (r *Reader) isUnquoteSplicing(form interface{}) bool { - seq, ok := form.(value.ISeq) - return ok && value.Equals(seq.First(), symSpliceUnquote) + seq, ok := form.(lang.ISeq) + return ok && lang.Equals(seq.First(), symSpliceUnquote) } func (r *Reader) readDeref() (interface{}, error) { @@ -928,7 +928,7 @@ func (r *Reader) readDispatch() (interface{}, error) { if err != nil { return nil, err } - return value.NewList(value.NewSymbol("var"), expr), nil + return lang.NewList(lang.NewSymbol("var"), expr), nil case '"': return r.readRegex() case '^': @@ -948,7 +948,7 @@ func (r *Reader) readNamespacedMap() (interface{}, error) { return nil, err } - nsKW := nsKWVal.(value.Keyword) + nsKW := nsKWVal.(lang.Keyword) if strings.Contains(nsKW.String(), "/") { return nil, r.error("namespaced map must specify a valid namespace: %s", nsKW) } @@ -968,22 +968,22 @@ func (r *Reader) readNamespacedMap() (interface{}, error) { } newKeyVals := []interface{}{} - for mp := value.Seq(mapVal); mp != nil; mp = mp.Next() { + for mp := lang.Seq(mapVal); mp != nil; mp = mp.Next() { kv := mp.First() - key := kv.(*value.MapEntry).Key() - val := kv.(*value.MapEntry).Val() + key := kv.(*lang.MapEntry).Key() + val := kv.(*lang.MapEntry).Val() - keyKW, ok := key.(value.Keyword) + keyKW, ok := key.(lang.Keyword) if !ok || keyKW.Namespace() != "" { newKeyVals = append(newKeyVals, key, val) continue } - newKey := value.NewKeyword(nsKW.Name() + "/" + keyKW.Name()) + newKey := lang.NewKeyword(nsKW.Name() + "/" + keyKW.Name()) newKeyVals = append(newKeyVals, newKey, val) } - m, err := value.WithMeta(value.NewMap(newKeyVals...), mapVal.(value.IMeta).Meta()) + m, err := lang.WithMeta(lang.NewMap(newKeyVals...), mapVal.(lang.IMeta).Meta()) if err != nil { // This should never happen. Maps can have metadata. panic(err) @@ -996,7 +996,7 @@ func (r *Reader) readSymbolicValue() (interface{}, error) { if err != nil { return nil, err } - sym, ok := v.(*value.Symbol) + sym, ok := v.(*lang.Symbol) if !ok { return nil, r.error("symbolic value must be a symbol") } @@ -1064,7 +1064,7 @@ func (r *Reader) readNumber(numStr string) (interface{}, error) { if intRegex.MatchString(numStr) || hexRegex.MatchString(numStr) { if strings.HasSuffix(numStr, "N") { - bi, err := value.NewBigIntWithBase(numStr[:len(numStr)-1], base) + bi, err := lang.NewBigIntWithBase(numStr[:len(numStr)-1], base) if err != nil { return nil, r.error("invalid big int: %w", err) } @@ -1075,7 +1075,7 @@ func (r *Reader) readNumber(numStr string) (interface{}, error) { intVal, err := strconv.ParseInt(numStr, base, 64) if err != nil { if errors.Is(err, strconv.ErrRange) { - bi, err := value.NewBigIntWithBase(numStr, base) + bi, err := lang.NewBigIntWithBase(numStr, base) if err != nil { return nil, r.error("invalid big int: %w", err) } @@ -1090,21 +1090,21 @@ func (r *Reader) readNumber(numStr string) (interface{}, error) { if ratioRegex.MatchString(numStr) { parts := strings.Split(numStr, "/") - numBig, err := value.NewBigInt(parts[0]) + numBig, err := lang.NewBigInt(parts[0]) if err != nil { return nil, r.error("invalid ratio: %s", numStr) } - denomBig, err := value.NewBigInt(parts[1]) + denomBig, err := lang.NewBigInt(parts[1]) if err != nil { return nil, r.error("invalid ratio: %s", numStr) } - return value.NewRatioBigInt(numBig, denomBig), nil + return lang.NewRatioBigInt(numBig, denomBig), nil } // else, it's a float // if the last character is M, it's a big decimal if strings.HasSuffix(numStr, "M") { - bd, err := value.NewBigDecimal(numStr[:len(numStr)-1]) + bd, err := lang.NewBigDecimal(numStr[:len(numStr)-1]) if err != nil { return nil, r.error("invalid big decimal: %w", err) } @@ -1167,7 +1167,7 @@ func (r *Reader) readSymbol() (ret interface{}, retErr error) { } }() - return value.NewSymbol(sym), nil + return lang.NewSymbol(sym), nil } func (r *Reader) readKeyword() (interface{}, error) { @@ -1194,48 +1194,48 @@ func (r *Reader) readKeyword() (interface{}, error) { ns := r.getCurrentNS().Name().Name() sym = ns + "/" + sym[1:] } - return value.NewKeyword(sym), nil + return lang.NewKeyword(sym), nil } -func (r *Reader) readMeta() (value.IPersistentMap, error) { +func (r *Reader) readMeta() (lang.IPersistentMap, error) { res, err := r.readExpr() if err != nil { return nil, err } switch res := res.(type) { - case *value.Map: + case *lang.Map: return res, nil - case *value.Symbol, string: - return value.NewMap(value.KWTag, res), nil - case value.Keyword: - return value.NewMap(res, true), nil + case *lang.Symbol, string: + return lang.NewMap(lang.KWTag, res), nil + case lang.Keyword: + return lang.NewMap(res, true), nil default: return nil, r.error("metadata must be a map, symbol, keyword, or string") } } // Translated from Clojure's Compiler.java -func (r *Reader) resolveSymbol(sym *value.Symbol) *value.Symbol { +func (r *Reader) resolveSymbol(sym *lang.Symbol) *lang.Symbol { if strings.Contains(sym.Name(), ".") { return sym } if sym.Namespace() != "" { - ns := value.NamespaceFor(r.getCurrentNS(), sym) + ns := lang.NamespaceFor(r.getCurrentNS(), sym) if ns == nil || (ns.Name().Name() == "" && sym.Namespace() == "") || (ns.Name().Name() != "" && ns.Name().Name() == sym.Namespace()) { return sym } - return value.InternSymbol(ns.Name().Name(), sym.Name()) + return lang.InternSymbol(ns.Name().Name(), sym.Name()) } currentNS := r.getCurrentNS() o := currentNS.GetMapping(sym) switch o := o.(type) { case nil: - return value.InternSymbol(currentNS.Name().Name(), sym.Name()) - case *value.Var: - return value.InternSymbol(o.Namespace().Name().Name(), o.Symbol().Name()) + return lang.InternSymbol(currentNS.Name().Name(), sym.Name()) + case *lang.Var: + return lang.InternSymbol(o.Namespace().Name().Name(), o.Symbol().Name()) } return nil } diff --git a/pkg/reader/reader_test.go b/pkg/reader/reader_test.go index 69e9fcb5..7a34a27c 100644 --- a/pkg/reader/reader_test.go +++ b/pkg/reader/reader_test.go @@ -8,7 +8,7 @@ import ( "strings" "testing" - value "github.com/glojurelang/glojure/pkg/lang" + "github.com/glojurelang/glojure/pkg/lang" "github.com/kylelemons/godebug/diff" ) @@ -53,9 +53,9 @@ func TestRead(t *testing.T) { }) } - aliasNS := value.FindOrCreateNamespace(value.NewSymbol("resolved.alias")) - ns := value.FindOrCreateNamespace(value.NewSymbol("user")) - ns.AddAlias(value.NewSymbol("aliased"), aliasNS) + aliasNS := lang.FindOrCreateNamespace(lang.NewSymbol("resolved.alias")) + ns := lang.FindOrCreateNamespace(lang.NewSymbol("user")) + ns.AddAlias(lang.NewSymbol("aliased"), aliasNS) for _, tc := range testCases { tc := tc @@ -65,7 +65,7 @@ func TestRead(t *testing.T) { r := New(strings.NewReader(tc.input), WithFilename(tc.name), // WithSymbolResolver(&testSymbolResolver{}), // TODO: option to test with this - WithGetCurrentNS(func() *value.Namespace { + WithGetCurrentNS(func() *lang.Namespace { return ns }), ) @@ -174,10 +174,10 @@ func FuzzRead(f *testing.F) { } func testPrintString(x interface{}) string { - value.PushThreadBindings(value.NewMap( - value.VarPrintReadably, true, + lang.PushThreadBindings(lang.NewMap( + lang.VarPrintReadably, true, )) - defer value.PopThreadBindings() + defer lang.PopThreadBindings() if v, ok := x.(float64); ok { if math.IsNaN(v) { @@ -191,5 +191,5 @@ func testPrintString(x interface{}) string { } } - return value.PrintString(x) + return lang.PrintString(x) } diff --git a/pkg/reader/resolver.go b/pkg/reader/resolver.go index f58b5d19..fec0647f 100644 --- a/pkg/reader/resolver.go +++ b/pkg/reader/resolver.go @@ -1,12 +1,12 @@ package reader -import value "github.com/glojurelang/glojure/pkg/lang" +import "github.com/glojurelang/glojure/pkg/lang" type ( SymbolResolver interface { - CurrentNS() *value.Symbol - ResolveStruct(*value.Symbol) *value.Symbol - ResolveAlias(*value.Symbol) *value.Symbol - ResolveVar(*value.Symbol) *value.Symbol + CurrentNS() *lang.Symbol + ResolveStruct(*lang.Symbol) *lang.Symbol + ResolveAlias(*lang.Symbol) *lang.Symbol + ResolveVar(*lang.Symbol) *lang.Symbol } ) diff --git a/pkg/repl/options.go b/pkg/repl/options.go index 5b0f9297..fdd5240a 100644 --- a/pkg/repl/options.go +++ b/pkg/repl/options.go @@ -3,14 +3,14 @@ package repl import ( "io" - value "github.com/glojurelang/glojure/pkg/lang" + "github.com/glojurelang/glojure/pkg/lang" ) type options struct { stdin io.Reader stdout io.Writer namespace string - env value.Environment + env lang.Environment } // Option is a functional option for the REPL. @@ -31,7 +31,7 @@ func WithStdout(w io.Writer) Option { } // WithEnvironment sets the execution environment for the REPL. -func WithEnvironment(env value.Environment) Option { +func WithEnvironment(env lang.Environment) Option { return func(o *options) { o.env = env } diff --git a/pkg/repl/repl.go b/pkg/repl/repl.go index 9fbcdd2b..97549f22 100644 --- a/pkg/repl/repl.go +++ b/pkg/repl/repl.go @@ -14,7 +14,7 @@ import ( "github.com/chzyer/readline" - value "github.com/glojurelang/glojure/pkg/lang" + "github.com/glojurelang/glojure/pkg/lang" "github.com/glojurelang/glojure/pkg/reader" "github.com/glojurelang/glojure/pkg/runtime" @@ -54,9 +54,9 @@ func Start(opts ...Option) { o.env = initEnv(o.stdout) } { // set namespace - _, err := o.env.Eval(value.NewList( - value.NewSymbol("ns"), - value.NewSymbol(o.namespace), + _, err := o.env.Eval(lang.NewList( + lang.NewSymbol("ns"), + lang.NewSymbol(o.namespace), )) if err != nil { panic(err) @@ -90,7 +90,7 @@ func Start(opts ...Option) { } expr += line + "\n" - rdr := reader.New(strings.NewReader(expr), reader.WithFilename("repl"), reader.WithGetCurrentNS(func() *value.Namespace { + rdr := reader.New(strings.NewReader(expr), reader.WithFilename("repl"), reader.WithGetCurrentNS(func() *lang.Namespace { return o.env.CurrentNamespace() })) @@ -117,7 +117,7 @@ func Start(opts ...Option) { if err != nil { return "", err } - return value.PrintString(val), nil + return lang.PrintString(val), nil }() if err != nil { fmt.Fprintln(o.stdout, err) @@ -144,7 +144,7 @@ func readLine(r io.Reader) (string, error) { return line, nil } -func initEnv(stdout io.Writer) value.Environment { +func initEnv(stdout io.Writer) lang.Environment { if cpuProfile { f, err := os.Create("./gljInitEnvCpu.prof") if err != nil { @@ -157,10 +157,10 @@ func initEnv(stdout io.Writer) value.Environment { // TODO: clean up this code. copied from rtcompat.go. kvs := make([]interface{}, 0, 3) - for _, vr := range []*value.Var{value.VarCurrentNS, value.VarWarnOnReflection, value.VarUncheckedMath, value.VarDataReaders} { + for _, vr := range []*lang.Var{lang.VarCurrentNS, lang.VarWarnOnReflection, lang.VarUncheckedMath, lang.VarDataReaders} { kvs = append(kvs, vr, vr.Deref()) } - value.PushThreadBindings(value.NewMap(kvs...)) + lang.PushThreadBindings(lang.NewMap(kvs...)) env := runtime.NewEnvironment(runtime.WithStdout(stdout)) if debugMode { diff --git a/pkg/repl/repl_wasm.go b/pkg/repl/repl_wasm.go index 3499c123..2a0f9eaf 100644 --- a/pkg/repl/repl_wasm.go +++ b/pkg/repl/repl_wasm.go @@ -13,7 +13,7 @@ import ( "strings" "time" - value "github.com/glojurelang/glojure/pkg/lang" + "github.com/glojurelang/glojure/pkg/lang" "github.com/glojurelang/glojure/pkg/reader" "github.com/glojurelang/glojure/pkg/runtime" ) @@ -36,9 +36,9 @@ func Start(opts ...Option) { o.env = initEnv(o.stdout) } { // set namespace - _, err := o.env.Eval(value.NewList( - value.NewSymbol("ns"), - value.NewSymbol(o.namespace), + _, err := o.env.Eval(lang.NewList( + lang.NewSymbol("ns"), + lang.NewSymbol(o.namespace), )) if err != nil { panic(err) @@ -64,7 +64,7 @@ func Start(opts ...Option) { } expr += line + "\n" - rdr := reader.New(strings.NewReader(expr), reader.WithFilename("repl"), reader.WithGetCurrentNS(func() *value.Namespace { + rdr := reader.New(strings.NewReader(expr), reader.WithFilename("repl"), reader.WithGetCurrentNS(func() *lang.Namespace { return o.env.CurrentNamespace() })) @@ -91,7 +91,7 @@ func Start(opts ...Option) { if err != nil { return "", err } - return value.PrintString(val), nil + return lang.PrintString(val), nil }() if err != nil { fmt.Fprintln(o.stdout, err) @@ -118,7 +118,7 @@ func readLine(r io.Reader) (string, error) { return line, nil } -func initEnv(stdout io.Writer) value.Environment { +func initEnv(stdout io.Writer) lang.Environment { if cpuProfile { f, err := os.Create("./gljInitEnvCpu.prof") if err != nil { @@ -131,10 +131,10 @@ func initEnv(stdout io.Writer) value.Environment { // TODO: clean up this code. copied from rtcompat.go. kvs := make([]interface{}, 0, 3) - for _, vr := range []*value.Var{value.VarCurrentNS, value.VarWarnOnReflection, value.VarUncheckedMath, value.VarDataReaders} { + for _, vr := range []*lang.Var{lang.VarCurrentNS, lang.VarWarnOnReflection, lang.VarUncheckedMath, lang.VarDataReaders} { kvs = append(kvs, vr, vr.Deref()) } - value.PushThreadBindings(value.NewMap(kvs...)) + lang.PushThreadBindings(lang.NewMap(kvs...)) env := runtime.NewEnvironment(runtime.WithStdout(stdout)) if debugMode { diff --git a/pkg/runtime/envinit.go b/pkg/runtime/envinit.go index 57f9948b..94f41fa4 100644 --- a/pkg/runtime/envinit.go +++ b/pkg/runtime/envinit.go @@ -7,7 +7,7 @@ import ( "os" "strings" - value "github.com/glojurelang/glojure/pkg/lang" + "github.com/glojurelang/glojure/pkg/lang" "github.com/glojurelang/glojure/pkg/reader" "github.com/glojurelang/glojure/pkg/stdlib" ) @@ -43,14 +43,14 @@ func WithLoadPath(path []string) EvalOption { } } -func withEnv(env value.Environment) EvalOption { +func withEnv(env lang.Environment) EvalOption { e := env.(*environment) return func(opts *evalOptions) { opts.env = e } } -func NewEnvironment(opts ...EvalOption) value.Environment { +func NewEnvironment(opts ...EvalOption) lang.Environment { options := &evalOptions{ stdout: os.Stdout, stderr: os.Stderr, @@ -65,21 +65,21 @@ func NewEnvironment(opts ...EvalOption) value.Environment { env.loadPath = options.loadPath } // TODO: this is rather rather hacky - value.GlobalEnv = env + lang.GlobalEnv = env // bootstrap namespace control { // bootstrap implementation of the ns macro - env.DefVar(value.NewSymbol("in-ns"), value.IFnFunc(func(args ...interface{}) interface{} { + env.DefVar(lang.NewSymbol("in-ns"), lang.IFnFunc(func(args ...interface{}) interface{} { if len(args) != 1 { panic(fmt.Errorf("in-ns: expected namespace name")) } - sym, ok := args[0].(*value.Symbol) + sym, ok := args[0].(*lang.Symbol) if !ok { panic(fmt.Errorf("in-ns: expected symbol as namespace name")) } - ns := value.FindOrCreateNamespace(sym) + ns := lang.FindOrCreateNamespace(sym) env.SetCurrentNamespace(ns) return ns })) @@ -92,7 +92,7 @@ func NewEnvironment(opts ...EvalOption) value.Environment { if err != nil { panic(fmt.Sprintf("could not read stdlib core.glj: %v", err)) } - r := reader.New(strings.NewReader(string(core)), reader.WithFilename(path), reader.WithGetCurrentNS(func() *value.Namespace { + r := reader.New(strings.NewReader(string(core)), reader.WithFilename(path), reader.WithGetCurrentNS(func() *lang.Namespace { return env.CurrentNamespace() })) diff --git a/pkg/runtime/environment.go b/pkg/runtime/environment.go index 6b137730..7d858019 100644 --- a/pkg/runtime/environment.go +++ b/pkg/runtime/environment.go @@ -8,16 +8,16 @@ import ( "path/filepath" "sync/atomic" - value "github.com/glojurelang/glojure/pkg/lang" + "github.com/glojurelang/glojure/pkg/lang" ) var ( - SymbolUnquote = value.NewSymbol("clojure.core/unquote") // TODO: rename to glojure.core/unquote - SymbolSpliceUnquote = value.NewSymbol("splice-unquote") - SymbolNamespace = value.NewSymbol("ns") - SymbolInNamespace = value.NewSymbol("in-ns") - SymbolUserNamespace = value.NewSymbol("user") - SymbolDot = value.NewSymbol(".") + SymbolUnquote = lang.NewSymbol("clojure.core/unquote") // TODO: rename to glojure.core/unquote + SymbolSpliceUnquote = lang.NewSymbol("splice-unquote") + SymbolNamespace = lang.NewSymbol("ns") + SymbolInNamespace = lang.NewSymbol("in-ns") + SymbolUserNamespace = lang.NewSymbol("user") + SymbolDot = lang.NewSymbol(".") ) type ( @@ -30,8 +30,8 @@ type ( recurTarget interface{} // some well-known vars - namespaceVar *value.Var // ns - inNamespaceVar *value.Var // in-ns + namespaceVar *lang.Var // ns + inNamespaceVar *lang.Var // in-ns // counter for gensym (symbol generator) symCounter int32 @@ -50,7 +50,7 @@ func newEnvironment(ctx context.Context, stdout, stderr io.Writer) *environment stdout: stdout, stderr: stderr, } - coreNS := value.NSCore + coreNS := lang.NSCore for _, dyn := range []string{ "command-line-args", @@ -64,20 +64,20 @@ func newEnvironment(ctx context.Context, stdout, stderr io.Writer) *environment "print-dup", "read-eval", } { - coreNS.InternWithValue(value.NewSymbol("*"+dyn+"*"), nil, true).SetDynamic() + coreNS.InternWithValue(lang.NewSymbol("*"+dyn+"*"), nil, true).SetDynamic() } // TODO: implement this - coreNS.InternWithValue(value.NewSymbol("load-file"), nil, true) + coreNS.InternWithValue(lang.NewSymbol("load-file"), nil, true) // bootstrap some vars e.namespaceVar = coreNS.InternWithValue(SymbolNamespace, - value.IFnFunc(func(args ...interface{}) interface{} { + lang.IFnFunc(func(args ...interface{}) interface{} { return coreNS }), true) e.namespaceVar.SetMacro() - e.inNamespaceVar = value.NewVarWithRoot(coreNS, SymbolInNamespace, false) + e.inNamespaceVar = lang.NewVarWithRoot(coreNS, SymbolInNamespace, false) return e } @@ -101,11 +101,11 @@ func (env *environment) String() string { // TODO: rename to something else; this isn't for `def`s, it's for // local bindings. -func (env *environment) BindLocal(sym *value.Symbol, val interface{}) { +func (env *environment) BindLocal(sym *lang.Symbol, val interface{}) { env.scope.define(sym, val) } -func (env *environment) DefVar(sym *value.Symbol, val interface{}) *value.Var { +func (env *environment) DefVar(sym *lang.Symbol, val interface{}) *lang.Var { // TODO: match clojure implementation more closely v := env.CurrentNamespace().InternWithValue(sym, val, true /* replace root */) if meta := sym.Meta(); meta != nil { @@ -114,12 +114,12 @@ func (env *environment) DefVar(sym *value.Symbol, val interface{}) *value.Var { return v } -func (env *environment) DefineMacro(name string, fn value.IFn) { - vr := env.DefVar(value.NewSymbol(name), fn) +func (env *environment) DefineMacro(name string, fn lang.IFn) { + vr := env.DefVar(lang.NewSymbol(name), fn) vr.SetMacro() } -func (env *environment) lookup(sym *value.Symbol) (res interface{}, ok bool) { +func (env *environment) lookup(sym *lang.Symbol) (res interface{}, ok bool) { v, ok := env.scope.lookup(sym) if ok { return v, true @@ -127,8 +127,8 @@ func (env *environment) lookup(sym *value.Symbol) (res interface{}, ok bool) { ns := env.CurrentNamespace() if sym.Namespace() != "" { - ns = value.FindNamespace(value.NewSymbol(sym.Namespace())) - sym = value.NewSymbol(sym.Name()) + ns = lang.FindNamespace(lang.NewSymbol(sym.Namespace())) + sym = lang.NewSymbol(sym.Name()) } if ns == nil { return nil, false @@ -138,17 +138,17 @@ func (env *environment) lookup(sym *value.Symbol) (res interface{}, ok bool) { return nil, false } // TODO: can these only be vars? - return vr.(*value.Var).Get(), true + return vr.(*lang.Var).Get(), true } -func (env *environment) WithRecurTarget(rt interface{}) value.Environment { +func (env *environment) WithRecurTarget(rt interface{}) lang.Environment { wrappedEnv := *env newEnv := &wrappedEnv newEnv.recurTarget = rt return newEnv } -func (env *environment) PushScope() value.Environment { +func (env *environment) PushScope() lang.Environment { wrappedEnv := *env newEnv := &wrappedEnv newEnv.scope = newEnv.scope.push() @@ -163,15 +163,15 @@ func (env *environment) Stderr() io.Writer { return env.stderr } -func (env *environment) CurrentNamespace() *value.Namespace { - return value.VarCurrentNS.Get().(*value.Namespace) +func (env *environment) CurrentNamespace() *lang.Namespace { + return lang.VarCurrentNS.Get().(*lang.Namespace) } -func (env *environment) SetCurrentNamespace(ns *value.Namespace) { - value.VarCurrentNS.Set(ns) +func (env *environment) SetCurrentNamespace(ns *lang.Namespace) { + lang.VarCurrentNS.Set(ns) } -func (env *environment) PushLoadPaths(paths []string) value.Environment { +func (env *environment) PushLoadPaths(paths []string) lang.Environment { newEnv := &(*env) newEnv.loadPath = append(paths, newEnv.loadPath...) return newEnv @@ -197,12 +197,12 @@ func (env *environment) Errorf(n interface{}, format string, args ...interface{} func (env *environment) errorf(n interface{}, format string, args ...interface{}) error { var filename, line, col string - var meta value.IPersistentMap - if n, ok := n.(value.IObj); ok { + var meta lang.IPersistentMap + if n, ok := n.(lang.IObj); ok { meta = n.Meta() } - get := func(m value.IPersistentMap, key string) string { - return value.PrintString(value.GetDefault(m, value.NewKeyword(key), "?")) + get := func(m lang.IPersistentMap, key string) string { + return lang.PrintString(lang.GetDefault(m, lang.NewKeyword(key), "?")) } filename = get(meta, "file") diff --git a/pkg/runtime/eval.go b/pkg/runtime/eval.go index ebd2697d..5b99bf78 100644 --- a/pkg/runtime/eval.go +++ b/pkg/runtime/eval.go @@ -5,26 +5,25 @@ import ( "github.com/glojurelang/glojure/pkg/compiler" "github.com/glojurelang/glojure/pkg/lang" - value "github.com/glojurelang/glojure/pkg/lang" ) func (env *environment) Macroexpand1(form interface{}) (interface{}, error) { - seq, ok := form.(value.ISeq) + seq, ok := form.(lang.ISeq) if !ok { return form, nil } - op := value.First(seq) - sym, ok := op.(*value.Symbol) + op := lang.First(seq) + sym, ok := op.(*lang.Symbol) if !ok { return form, nil } symStr := sym.String() if len(symStr) > 1 && symStr[0] == '.' && symStr[1] != '.' { - fieldSym := value.NewSymbol(sym.String()[1:]) + fieldSym := lang.NewSymbol(sym.String()[1:]) // rewrite the expression to a dot expression - dotExpr := value.NewCons(SymbolDot, value.NewCons(seq.Next().First(), value.NewCons(fieldSym, seq.Next().Next()))) + dotExpr := lang.NewCons(SymbolDot, lang.NewCons(seq.Next().First(), lang.NewCons(fieldSym, seq.Next().Next()))) return env.Macroexpand1(dotExpr) } @@ -33,23 +32,23 @@ func (env *environment) Macroexpand1(form interface{}) (interface{}, error) { return form, nil } - applyer, ok := macroVar.Get().(value.IFn) + applyer, ok := macroVar.Get().(lang.IFn) if !ok { return nil, env.errorf(form, "macro %s is not a function (%T)", sym, macroVar.Get()) } - res, err := env.applyMacro(applyer, form.(value.ISeq)) + res, err := env.applyMacro(applyer, form.(lang.ISeq)) if err != nil { return nil, env.errorf(form, "error applying macro: %w", err) } return res, nil } -func (env *environment) applyMacro(fn value.IFn, form value.ISeq) (interface{}, error) { +func (env *environment) applyMacro(fn lang.IFn, form lang.ISeq) (interface{}, error) { argList := form.Next() // two hidden arguments, $form and $env (nil for now). // $form is the form that was passed to the macro // $env is the environment that the macro was called in - return fn.ApplyTo(value.NewCons(form, value.NewCons(nil, argList))), nil + return fn.ApplyTo(lang.NewCons(form, lang.NewCons(nil, argList))), nil } func (env *environment) Eval(n interface{}) (interface{}, error) { @@ -59,22 +58,22 @@ func (env *environment) Eval(n interface{}) (interface{}, error) { func (env *environment) evalInternal(n interface{}) (interface{}, error) { analyzer := &compiler.Analyzer{ Macroexpand1: env.Macroexpand1, - CreateVar: func(sym *value.Symbol, e compiler.Env) (interface{}, error) { + CreateVar: func(sym *lang.Symbol, e compiler.Env) (interface{}, error) { vr := env.CurrentNamespace().Intern(sym) return vr, nil }, IsVar: func(v interface{}) bool { - _, ok := v.(*value.Var) + _, ok := v.(*lang.Var) return ok }, - Gensym: func(prefix string) *value.Symbol { + Gensym: func(prefix string) *lang.Symbol { num := env.nextSymNum() - return value.NewSymbol(fmt.Sprintf("%s%d", prefix, num)) + return lang.NewSymbol(fmt.Sprintf("%s%d", prefix, num)) }, FindNamespace: lang.FindNamespace, } - astNode, err := analyzer.Analyze(n, value.NewMap( - value.KWNS, env.CurrentNamespace().Name(), + astNode, err := analyzer.Analyze(n, lang.NewMap( + lang.KWNS, env.CurrentNamespace().Name(), )) if err != nil { return nil, err @@ -84,16 +83,16 @@ func (env *environment) evalInternal(n interface{}) (interface{}, error) { // Helpers -func (env *environment) lookupVar(sym *value.Symbol, internNew, registerMacro bool) (*value.Var, error) { +func (env *environment) lookupVar(sym *lang.Symbol, internNew, registerMacro bool) (*lang.Var, error) { // Translated from clojure's Compiler.java - var result *value.Var + var result *lang.Var switch { case sym.Namespace() != "": ns := env.namespaceForSymbol(sym) if ns == nil { return nil, env.errorf(sym, "unable to resolve %s", sym) } - nameSym := value.NewSymbol(sym.Name()) + nameSym := lang.NewSymbol(sym.Name()) if internNew && ns == env.CurrentNamespace() { result = ns.Intern(nameSym) } else { @@ -109,9 +108,9 @@ func (env *environment) lookupVar(sym *value.Symbol, internNew, registerMacro bo if v == nil { // introduce a new var in the current ns if internNew { - result = env.CurrentNamespace().Intern(value.NewSymbol(sym.Name())) + result = env.CurrentNamespace().Intern(lang.NewSymbol(sym.Name())) } - } else if v, ok := v.(*value.Var); ok { + } else if v, ok := v.(*lang.Var); ok { result = v } else { return nil, env.errorf(sym, "expecting var, but %s is mapped to %T", sym, v) @@ -123,15 +122,15 @@ func (env *environment) lookupVar(sym *value.Symbol, internNew, registerMacro bo return result, nil } -func (env *environment) namespaceForSymbol(sym *value.Symbol) *value.Namespace { - return value.NamespaceFor(env.CurrentNamespace(), sym) +func (env *environment) namespaceForSymbol(sym *lang.Symbol) *lang.Namespace { + return lang.NamespaceFor(env.CurrentNamespace(), sym) } -func (env *environment) registerVar(v *value.Var) { +func (env *environment) registerVar(v *lang.Var) { // TODO: implement } -func (env *environment) asMacro(sym *value.Symbol) *value.Var { +func (env *environment) asMacro(sym *lang.Symbol) *lang.Var { vr, err := env.lookupVar(sym, false, false) if vr == nil || err != nil { return nil @@ -145,7 +144,7 @@ func (env *environment) asMacro(sym *value.Symbol) *value.Var { // Misc. helpers -func seqToSlice(seq value.ISeq) []interface{} { +func seqToSlice(seq lang.ISeq) []interface{} { if seq == nil { return nil } diff --git a/pkg/runtime/evalast.go b/pkg/runtime/evalast.go index f50f0fdb..9e8d2367 100644 --- a/pkg/runtime/evalast.go +++ b/pkg/runtime/evalast.go @@ -9,7 +9,6 @@ import ( "github.com/glojurelang/glojure/pkg/ast" "github.com/glojurelang/glojure/pkg/lang" - value "github.com/glojurelang/glojure/pkg/lang" "github.com/glojurelang/glojure/pkg/pkgmap" // Make it easier to refer to KW globals @@ -21,8 +20,8 @@ var indent = 0 var ( Debug = false - SymNS = value.NewSymbol("ns") - SymInNS = value.NewSymbol("in-ns") + SymNS = lang.NewSymbol("ns") + SymInNS = lang.NewSymbol("in-ns") ) type EvalError struct { @@ -119,14 +118,14 @@ func (env *environment) EvalAST(x interface{}) (ret interface{}, err error) { case ast.OpThrow: return env.EvalASTThrow(n) default: - panic(fmt.Errorf("unimplemented op: %d. Form: %s", n.Op, value.ToString(n.Form))) + panic(fmt.Errorf("unimplemented op: %d. Form: %s", n.Op, lang.ToString(n.Form))) } } func (env *environment) EvalASTDef(n *ast.Node) (interface{}, error) { defNode := n.Sub.(*ast.DefNode) init := defNode.Init - if value.IsNil(init) { + if lang.IsNil(init) { return defNode.Var, nil } @@ -138,20 +137,20 @@ func (env *environment) EvalASTDef(n *ast.Node) (interface{}, error) { // evaluate symbol metadata if present meta := defNode.Meta - if !value.IsNil(meta) { + if !lang.IsNil(meta) { metaVal, err := env.EvalAST(meta) if err != nil { return nil, err } - s, err := value.WithMeta(sym, metaVal.(value.IPersistentMap)) + s, err := lang.WithMeta(sym, metaVal.(lang.IPersistentMap)) if err != nil { return nil, err } - sym = s.(*value.Symbol) + sym = s.(*lang.Symbol) } vr := env.DefVar(sym, initVal) - if RT.BooleanCast(lang.Get(vr.Meta(), value.KWDynamic)) { + if RT.BooleanCast(lang.Get(vr.Meta(), lang.KWDynamic)) { vr.SetDynamic() } return vr, nil @@ -233,35 +232,35 @@ func (c *evalCompiler) Macroexpand1(form interface{}) interface{} { return res } -func (c *evalCompiler) MaybeResolveIn(ns *value.Namespace, sym *value.Symbol) interface{} { +func (c *evalCompiler) MaybeResolveIn(ns *lang.Namespace, sym *lang.Symbol) interface{} { switch { case sym.Namespace() != "": - n := value.NamespaceFor(ns, sym) + n := lang.NamespaceFor(ns, sym) if n == nil { return nil } - return n.FindInternedVar(value.NewSymbol(sym.Name())) + return n.FindInternedVar(lang.NewSymbol(sym.Name())) case strings.Index(sym.Name(), ".") > 0 && !strings.HasSuffix(sym.Name(), ".") || sym.Name()[0] == '[': // TODO: what case does this correspond to? should we be looking for imports here? // previously: panic(fmt.Errorf("can't resolve class %s in ns %s", sym, ns)) return nil case sym.Equals(SymNS): - return value.VarNS + return lang.VarNS case sym.Equals(SymInNS): - return value.VarInNS + return lang.VarInNS default: return ns.GetMapping(sym) } } func (env *environment) EvalASTMaybeClass(n *ast.Node) (interface{}, error) { - sym := n.Sub.(*ast.MaybeClassNode).Class.(*value.Symbol) + sym := n.Sub.(*ast.MaybeClassNode).Class.(*lang.Symbol) v, ok := pkgmap.Get(sym.FullName()) if ok { return v, nil } - return nil, errors.New("unable to resolve symbol: " + value.ToString(sym)) + return nil, errors.New("unable to resolve symbol: " + lang.ToString(sym)) } func (env *environment) EvalASTMaybeHostForm(n *ast.Node) (interface{}, error) { @@ -274,10 +273,10 @@ func (env *environment) EvalASTMaybeHostForm(n *ast.Node) (interface{}, error) { case "create": return func(keys interface{}) interface{} { var ks []interface{} - for seq := value.Seq(keys); seq != nil; seq = seq.Next() { + for seq := lang.Seq(keys); seq != nil; seq = seq.Next() { ks = append(ks, seq.First()) } - return value.NewSet(ks...) + return lang.NewSet(ks...) }, nil } } @@ -305,16 +304,16 @@ func (env *environment) EvalASTHostCall(n *ast.Node) (interface{}, error) { } argVals = append(argVals, argVal) } - methodVal, ok := value.FieldOrMethod(tgtVal, method.Name()) + methodVal, ok := lang.FieldOrMethod(tgtVal, method.Name()) if !ok { return nil, fmt.Errorf("no such field or method on %v (%T): %s", tgtVal, tgtVal, method) } // if the field is not a function, return an error if reflect.TypeOf(methodVal).Kind() != reflect.Func { - return nil, errors.New("not a method: " + value.ToString(tgtVal) + "." + method.Name()) + return nil, errors.New("not a method: " + lang.ToString(tgtVal) + "." + method.Name()) } - return value.Apply(methodVal, argVals), nil + return lang.Apply(methodVal, argVals), nil } func (env *environment) EvalASTHostInterop(n *ast.Node) (interface{}, error) { @@ -328,7 +327,7 @@ func (env *environment) EvalASTHostInterop(n *ast.Node) (interface{}, error) { return nil, err } - mOrFVal, ok := value.FieldOrMethod(tgtVal, mOrF.Name()) + mOrFVal, ok := lang.FieldOrMethod(tgtVal, mOrF.Name()) if !ok { return nil, fmt.Errorf("no such field or method on %T: %s", tgtVal, mOrF) } @@ -339,7 +338,7 @@ func (env *environment) EvalASTHostInterop(n *ast.Node) (interface{}, error) { } switch reflect.TypeOf(mOrFVal).Kind() { case reflect.Func: - return value.Apply(mOrFVal, nil), nil + return lang.Apply(mOrFVal, nil), nil default: return mOrFVal, nil } @@ -366,7 +365,7 @@ func (env *environment) EvalASTGo(n *ast.Node) (interface{}, error) { argVals = append(argVals, argVal) } - go value.Apply(fnVal, argVals) + go lang.Apply(fnVal, argVals) return nil, nil } @@ -384,7 +383,7 @@ func (env *environment) EvalASTWithMeta(n *ast.Node) (interface{}, error) { return nil, err } - return value.WithMeta(exprVal, metaVal.(value.IPersistentMap)) + return lang.WithMeta(exprVal, metaVal.(lang.IPersistentMap)) } func (env *environment) EvalASTFn(n *ast.Node) (interface{}, error) { @@ -392,7 +391,7 @@ func (env *environment) EvalASTFn(n *ast.Node) (interface{}, error) { } func (env *environment) EvalASTMap(n *ast.Node) (interface{}, error) { - res := value.NewMap() + res := lang.NewMap() mapNode := n.Sub.(*ast.MapNode) @@ -427,7 +426,7 @@ func (env *environment) EvalASTVector(n *ast.Node) (interface{}, error) { } vals = append(vals, itemVal) } - return value.NewVector(vals...), nil + return lang.NewVector(vals...), nil } func (env *environment) EvalASTSet(n *ast.Node) (interface{}, error) { @@ -443,7 +442,7 @@ func (env *environment) EvalASTSet(n *ast.Node) (interface{}, error) { } vals = append(vals, itemVal) } - return value.NewSet(vals...), nil + return lang.NewSet(vals...), nil } func (env *environment) EvalASTIf(n *ast.Node) (interface{}, error) { @@ -457,7 +456,7 @@ func (env *environment) EvalASTIf(n *ast.Node) (interface{}, error) { if err != nil { return nil, err } - if value.IsTruthy(testVal) { + if lang.IsTruthy(testVal) { return env.EvalAST(then) } else { return env.EvalAST(els) @@ -480,7 +479,7 @@ func (env *environment) EvalASTCase(n *ast.Node) (interface{}, error) { if err != nil { return nil, err } - if value.Equals(testVal, caseTestVal) { + if lang.Equals(testVal, caseTestVal) { res, err := env.EvalAST(caseNodeNode.Then) if err != nil { return nil, err @@ -531,14 +530,14 @@ func (env *environment) EvalASTLet(n *ast.Node, isLoop bool) (interface{}, error Recur: for i := 0; i < len(bindNameVals); i += 2 { - name := bindNameVals[i].(*value.Symbol) + name := bindNameVals[i].(*lang.Symbol) val := bindNameVals[i+1] newEnv.BindLocal(name, val) } - rt := value.NewRecurTarget() + rt := lang.NewRecurTarget() recurEnv := newEnv.WithRecurTarget(rt).(*environment) - recurErr := &value.RecurError{Target: rt} + recurErr := &lang.RecurError{Target: rt} res, err := recurEnv.EvalAST(letNode.Body) if isLoop && errors.As(err, &recurErr) { @@ -585,7 +584,7 @@ func (env *environment) EvalASTRecur(n *ast.Node) (interface{}, error) { recurNode := n.Sub.(*ast.RecurNode) exprs := recurNode.Exprs - vals := make([]interface{}, 0, value.Count(exprs)) + vals := make([]interface{}, 0, lang.Count(exprs)) noRecurEnv := env.WithRecurTarget(nil).(*environment) for _, expr := range exprs { val, err := noRecurEnv.EvalAST(expr) @@ -594,7 +593,7 @@ func (env *environment) EvalASTRecur(n *ast.Node) (interface{}, error) { } vals = append(vals, val) } - return nil, &value.RecurError{ + return nil, &lang.RecurError{ Target: env.recurTarget, Args: vals, } @@ -608,7 +607,7 @@ func (env *environment) EvalASTInvoke(n *ast.Node) (res interface{}, err error) if r := recover(); r != nil { // TODO: dynamically set pr-on to nil to avoid infinite // recursion; need to use go-only stringification for errors. - gljFrame = fmt.Sprintf("%s:%d:%d:\t%s", value.Get(meta, KWFile), value.Get(meta, KWLine), value.Get(meta, KWColumn), n.Form) + gljFrame = fmt.Sprintf("%s:%d:%d:\t%s", lang.Get(meta, KWFile), lang.Get(meta, KWLine), lang.Get(meta, KWColumn), n.Form) if rErr, ok := r.(error); ok { if errors.Is(rErr, &EvalError{}) { var evalErr *EvalError @@ -651,7 +650,7 @@ func (env *environment) EvalASTInvoke(n *ast.Node) (res interface{}, err error) argVals = append(argVals, argVal) } - return value.Apply(fnVal, argVals), nil + return lang.Apply(fnVal, argVals), nil } func (env *environment) EvalASTVar(n *ast.Node) (interface{}, error) { diff --git a/pkg/runtime/readeval.go b/pkg/runtime/readeval.go index 96cf58f2..c276823a 100644 --- a/pkg/runtime/readeval.go +++ b/pkg/runtime/readeval.go @@ -4,7 +4,7 @@ import ( "fmt" "strings" - value "github.com/glojurelang/glojure/pkg/lang" + "github.com/glojurelang/glojure/pkg/lang" "github.com/glojurelang/glojure/pkg/reader" ) @@ -15,14 +15,14 @@ type ( readEvalOptions struct { // env is the environment to use for evaluation. If not set, the // global environment is used. - env value.Environment + env lang.Environment // filename is the name of the file being read. filename string } ) // WithEnv sets the environment to use for evaluation. -func WithEnv(env value.Environment) ReadEvalOption { +func WithEnv(env lang.Environment) ReadEvalOption { return func(o *readEvalOptions) { o.env = env } @@ -44,10 +44,10 @@ func ReadEval(code string, options ...ReadEvalOption) interface{} { } env := opts.env if env == nil { - env = value.GlobalEnv + env = lang.GlobalEnv } readerOpts := []reader.Option{ - reader.WithGetCurrentNS(func() *value.Namespace { + reader.WithGetCurrentNS(func() *lang.Namespace { return env.CurrentNamespace() }), } diff --git a/pkg/runtime/rtcompat.go b/pkg/runtime/rtcompat.go index f3fe07ac..7f848693 100644 --- a/pkg/runtime/rtcompat.go +++ b/pkg/runtime/rtcompat.go @@ -10,7 +10,6 @@ import ( "sync/atomic" "github.com/glojurelang/glojure/pkg/lang" - value "github.com/glojurelang/glojure/pkg/lang" "github.com/glojurelang/glojure/pkg/reader" "github.com/glojurelang/glojure/pkg/stdlib" @@ -72,23 +71,23 @@ func (rt *RTMethods) Pop(x interface{}) interface{} { } func (rt *RTMethods) IntCast(x interface{}) int { - return value.IntCast(x) + return lang.IntCast(x) } func (rt *RTMethods) BooleanCast(x interface{}) bool { - return value.BooleanCast(x) + return lang.BooleanCast(x) } func (rt *RTMethods) ByteCast(x interface{}) byte { - return value.ByteCast(x) + return lang.ByteCast(x) } func (rt *RTMethods) CharCast(x interface{}) Char { - return value.CharCast(x) + return lang.CharCast(x) } func (rt *RTMethods) UncheckedCharCast(x interface{}) Char { - return value.UncheckedCharCast(x) + return lang.UncheckedCharCast(x) } func (rt *RTMethods) Dissoc(x interface{}, k interface{}) interface{} { @@ -125,7 +124,7 @@ func (rt *RTMethods) Find(coll, key interface{}) interface{} { func (rt *RTMethods) Load(scriptBase string) { kvs := make([]interface{}, 0, 3) - for _, vr := range []*Var{VarCurrentNS, VarWarnOnReflection, VarUncheckedMath, value.VarDataReaders} { + for _, vr := range []*Var{VarCurrentNS, VarWarnOnReflection, VarUncheckedMath, lang.VarDataReaders} { kvs = append(kvs, vr, vr.Deref()) } PushThreadBindings(NewMap(kvs...)) @@ -228,8 +227,8 @@ func (rt *RTMethods) Munge(name string) string { } func RTReadString(s string) interface{} { - rdr := reader.New(strings.NewReader(s), reader.WithGetCurrentNS(func() *value.Namespace { - return value.VarCurrentNS.Deref().(*value.Namespace) + rdr := reader.New(strings.NewReader(s), reader.WithGetCurrentNS(func() *lang.Namespace { + return lang.VarCurrentNS.Deref().(*lang.Namespace) })) v, err := rdr.ReadOne() if err != nil { diff --git a/pkg/runtime/scope.go b/pkg/runtime/scope.go index 565f3cd9..c09d7065 100644 --- a/pkg/runtime/scope.go +++ b/pkg/runtime/scope.go @@ -1,8 +1,6 @@ package runtime -import ( - value "github.com/glojurelang/glojure/pkg/lang" -) +import "github.com/glojurelang/glojure/pkg/lang" type scope struct { parent *scope @@ -13,7 +11,7 @@ func newScope() *scope { return &scope{syms: make(map[string]interface{})} } -func (s *scope) define(sym *value.Symbol, val interface{}) { +func (s *scope) define(sym *lang.Symbol, val interface{}) { s.syms[sym.String()] = val } @@ -21,7 +19,7 @@ func (s *scope) push() *scope { return &scope{parent: s, syms: make(map[string]interface{})} } -func (s *scope) lookup(sym *value.Symbol) (interface{}, bool) { +func (s *scope) lookup(sym *lang.Symbol) (interface{}, bool) { if v, ok := s.syms[sym.String()]; ok { return v, true }