From 9310e81a8e72cc9b4df238349a6ed56c3fff4509 Mon Sep 17 00:00:00 2001 From: "Norman Nunley, Jr" Date: Thu, 23 Jul 2026 11:39:53 -0400 Subject: [PATCH 1/8] fix(rt): resolve ns alias in LookupOrRegisterNSNoLoad MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit RegisterGeneratedPrimitives (the lginterop-generated //lg:native registrar) Defs primitives via LookupOrRegisterNSNoLoad("clojure.core"), but that path — unlike the loading LookupOrRegisterNS — never resolved the ns alias, so it registered into a DISTINCT "clojure.core" namespace instead of the canonical "core". Hand-registered primitives masked this by also Def'ing into the canonical ns via installLangNS; a primitive hoisted to a pure //lg:native decl has ONLY the generated registration, so it landed in the wrong namespace and was invisible to core.lg's own bootstrap compile ("Can't resolve +"). Resolve the alias as the first step of LookupOrRegisterNSNoLoad, matching the loading variant. This unblocks hoisting native closures in lang.go to named //lg:native primitives for real stack-trace frames. Verified: make check-generated OK (bundle + lowered tree unchanged, this is a Go-only registration fix); clojure.core surface = 807 publics, byte-identical before/after a proof hoist of + - * /. --- pkg/rt/lang.go | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/pkg/rt/lang.go b/pkg/rt/lang.go index 82ab02b16..40c94e48e 100644 --- a/pkg/rt/lang.go +++ b/pkg/rt/lang.go @@ -703,6 +703,18 @@ func LookupOrRegisterNS(name string) *vm.Namespace { } func LookupOrRegisterNSNoLoad(name string) *vm.Namespace { + // Resolve the alias BEFORE touching the registry, as the loading callers do. + // Without this, LookupOrRegisterNSNoLoad("clojure.core") registers a DISTINCT + // "clojure.core" namespace instead of returning the canonical "core" — so the + // generated primitive registrar (RegisterGeneratedPrimitives, which calls this + // with "clojure.core"/"clojure.string"/…) Defs into the wrong namespace, + // invisible to core.lg's own bootstrap compile. Hand-registered primitives + // hid this by also Def'ing into the canonical ns via installLangNS; a primitive + // hoisted to //lg:native has ONLY the generated registration, so it must land + // in the canonical namespace to resolve. + canonical := resolveNSAlias(name) + aliased := canonical != name + name = canonical nsMu.RLock() e := nsRegistry[name] nsMu.RUnlock() @@ -723,6 +735,17 @@ func LookupOrRegisterNSNoLoad(name string) *vm.Namespace { nsRegistry[name] = ns nsMu.Unlock() + // If we just PRE-CREATED a canonical ns from an alias (e.g. clojure.string → + // string) to home a generated native, its .lg source has NOT run — only the + // native being registered now exists. Flag it needs-load so a later + // (require 'clojure.string) still executes the .lg defns (join, split, …) + // instead of short-circuiting on this native-only ns in LookupOrRegisterNS. + // Core is exempt: it is installed eagerly (installLangNS) before any generated + // registrar runs, so it never reaches this newly-created branch. + if aliased { + MarkNSNeedsLoad(name) + } + return ns } From e9dc6a965d032203ec86a1b192f34832034b97e1 Mon Sep 17 00:00:00 2001 From: "Norman Nunley, Jr" Date: Thu, 23 Jul 2026 13:58:27 -0400 Subject: [PATCH 2/8] feat(rt): non-terminating diagnostics for generated-primitive registration MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Hoisting native closures in lang.go to //lg:native primitives means a prim can now have ONLY the generated registration — so a misregistration (wrong namespace, dropped //lg:name) surfaces as a terminating bootstrap panic ("Can't resolve X") that reports one symbol at a time. Add diagnostics so a whole batch of newly hoisted primitives is root-caused in one run: - AuditGeneratedPrimitives(): non-terminating audit returning one line per generated primitive NOT resolvable in its canonical namespace, including where the name actually landed (the exact signature of the alias bug fixed in the parent commit: bound in "clojure.core", absent from "core"). - evalInit bootstrap compile: on failure, append the audit to the panic so every misregistered primitive is listed at once, not one panic per re-run. - LG_REGPRIM_DEBUG: per-primitive registration trace (name, requested ns, canonical ns, landed-canonical) — grep for landed-canonical=false. - TestAuditGeneratedPrimitivesCleanAfterInit: permanent regression guard that every generated primitive resolves in its canonical ns (would have caught the alias bug); the gate to run after each hoist batch. Go-only; no generated artifacts change (check-generated unaffected). --- pkg/compiler/eval.go | 12 ++++- pkg/rt/generated_prim_audit_test.go | 75 +++++++++++++++++++++++++++ pkg/rt/native_prims_lifecycle.go | 79 +++++++++++++++++++++++++++++ 3 files changed, 165 insertions(+), 1 deletion(-) create mode 100644 pkg/rt/generated_prim_audit_test.go diff --git a/pkg/compiler/eval.go b/pkg/compiler/eval.go index 0160e7466..cd6b14a63 100644 --- a/pkg/compiler/eval.go +++ b/pkg/compiler/eval.go @@ -119,7 +119,17 @@ func evalInit() { c.SetSource("") _, _, err := c.CompileMultiple(strings.NewReader(rt.CoreSrc)) if err != nil { - panic("core.lg compilation failed: " + err.Error()) + // A bootstrap resolve failure ("Can't resolve X") usually means a + // generated //lg:native primitive registered into the wrong namespace. + // Attach the non-terminating registration audit so ALL misregistered + // primitives are reported at once (with where each actually landed), + // instead of re-running to discover them one panic at a time. + msg := "core.lg compilation failed: " + err.Error() + if audit := rt.AuditGeneratedPrimitives(); len(audit) > 0 { + msg += fmt.Sprintf("\n\ngenerated-primitive audit (%d not resolvable in canonical ns):\n %s", + len(audit), strings.Join(audit, "\n ")) + } + panic(msg) } // Bundle-path parity (purify-clojure-core ②): the lg baseline namespaces // (let-go.core, …) are auto-refer'd into every namespace but never explicitly diff --git a/pkg/rt/generated_prim_audit_test.go b/pkg/rt/generated_prim_audit_test.go new file mode 100644 index 000000000..ccfeb27af --- /dev/null +++ b/pkg/rt/generated_prim_audit_test.go @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2026 Norman Nunley, Jr + * Part of the let-go project; see CONTRIBUTORS for full list of authors. + * SPDX-License-Identifier: MIT + */ + +package rt + +import ( + "strings" + "testing" + + "github.com/nooga/let-go/pkg/vm" +) + +// TestAuditGeneratedPrimitivesCleanAfterInit is the permanent regression guard +// for the alias-resolution bug (LookupOrRegisterNSNoLoad registering into a +// phantom "clojure.core" instead of canonical "core"): every generated +// primitive MUST be resolvable in its canonical namespace after init. This is +// also the gate to run after hoisting native closures to //lg:native decls — +// if any batch misregisters, this names each offender instead of leaving the +// bootstrap compile to die on the first `Can't resolve X`. +func TestAuditGeneratedPrimitivesCleanAfterInit(t *testing.T) { + if probs := AuditGeneratedPrimitives(); len(probs) > 0 { + t.Fatalf("generated primitives not all resolvable in their canonical namespace:\n %s", + strings.Join(probs, "\n ")) + } +} + +// TestAuditGeneratedPrimitivesFlagsMisregistration proves the audit is a +// non-terminating diagnostic: given a primitive recorded under a canonical ns +// but actually bound in a different ns (the exact shape of the alias bug), it +// reports the miss AND points at where the name actually landed. +func TestAuditGeneratedPrimitivesFlagsMisregistration(t *testing.T) { + const probe = "audit-probe-should-not-collide" + adapter, err := vm.NativeFnType.Wrap(func(_ []vm.Value) (vm.Value, error) { return vm.NIL, nil }) + if err != nil { + t.Fatalf("wrap adapter: %v", err) + } + + // Bind the probe in a phantom namespace (simulating a prim that landed in + // the wrong ns), and register it so whereNameBound can locate it. + phantom := vm.NewNamespace("clojure.audit.phantom") + phantom.Def(probe, adapter) + RegisterNS(phantom) + + // Record it under canonical "core", which does NOT bind the probe. + genPrimMu.Lock() + if genPrimBindings[NameCoreNS] == nil { + genPrimBindings[NameCoreNS] = map[string]vm.Value{} + } + genPrimBindings[NameCoreNS][probe] = adapter + genPrimMu.Unlock() + defer func() { + genPrimMu.Lock() + delete(genPrimBindings[NameCoreNS], probe) + genPrimMu.Unlock() + }() + + var line string + for _, p := range AuditGeneratedPrimitives() { + if strings.Contains(p, probe) { + line = p + } + } + if line == "" { + t.Fatalf("audit did not flag misregistered %q", probe) + } + if !strings.Contains(line, "not bound in canonical ns") { + t.Errorf("audit line missing reason: %s", line) + } + if !strings.Contains(line, "clojure.audit.phantom") { + t.Errorf("audit line did not point at the phantom ns: %s", line) + } +} diff --git a/pkg/rt/native_prims_lifecycle.go b/pkg/rt/native_prims_lifecycle.go index 972c51b40..6aa583846 100644 --- a/pkg/rt/native_prims_lifecycle.go +++ b/pkg/rt/native_prims_lifecycle.go @@ -7,12 +7,22 @@ package rt import ( + "fmt" + "os" + "sort" "strings" "sync" "github.com/nooga/let-go/pkg/vm" ) +// regPrimDebug, when LG_REGPRIM_DEBUG is set, logs every generated-primitive +// registration (name, requested ns, resolved canonical ns, whether it landed +// in the canonical ns). It is the per-primitive trace used to root-cause a +// batch of newly hoisted //lg:native primitives without bisecting the whole +// set: grep the run for `landed-canonical=false`. +var regPrimDebug = os.Getenv("LG_REGPRIM_DEBUG") != "" + // Generated-primitive binding lifecycle. // // RegisterGeneratedPrimitives (zz_primitives_generated.go) Defs each native @@ -85,6 +95,14 @@ func defGeneratedPrimitive(ns *vm.Namespace, nsName, name string, v vm.Value) { // boundaries. setPrimitiveRoot(ns, name, v).GuardRoot() canonical := resolveNSAlias(nsName) + if regPrimDebug { + landed := false + if cns := LookupNS(canonical); cns != nil { + landed = cns.LookupLocal(vm.Symbol(name)) != nil + } + fmt.Fprintf(os.Stderr, "[REGPRIM] %s/%s requested-ns=%s canonical=%s landed-canonical=%v\n", + nsName, name, nsName, canonical, landed) + } genPrimMu.Lock() m := genPrimBindings[canonical] if m == nil { @@ -95,6 +113,67 @@ func defGeneratedPrimitive(ns *vm.Namespace, nsName, name string, v vm.Value) { genPrimMu.Unlock() } +// AuditGeneratedPrimitives verifies that every recorded generated primitive is +// actually bound in its canonical namespace, and returns one human-readable +// line per primitive that is NOT — including where the name IS bound instead, +// if anywhere. It never panics and never stops at the first problem: it is the +// non-terminating diagnostic run around the bootstrap core.lg compile, so a +// batch of newly hoisted //lg:native primitives surfaces ALL its registration +// failures at once (`+ registered under "clojure.core", not canonical "core"`) +// rather than the compile dying on the first `Can't resolve X`. Empty slice = +// every generated primitive resolves in its canonical namespace. +func AuditGeneratedPrimitives() []string { + type binding struct { + ns, name string + } + genPrimMu.RLock() + bindings := make([]binding, 0, len(genPrimBindings)) + for nsName, m := range genPrimBindings { + for name := range m { + bindings = append(bindings, binding{nsName, name}) + } + } + genPrimMu.RUnlock() + + var problems []string + for _, b := range bindings { + ns := LookupNS(b.ns) + if ns == nil { + problems = append(problems, fmt.Sprintf("%s/%s: canonical namespace does not exist", b.ns, b.name)) + continue + } + if v := ns.LookupLocal(vm.Symbol(b.name)); v == nil || !v.IsBound() { + problems = append(problems, fmt.Sprintf("%s/%s: not bound in canonical ns%s", b.ns, b.name, whereNameBound(b.name, resolveNSAlias(b.ns)))) + } + } + sort.Strings(problems) + return problems +} + +// whereNameBound scans the namespace registry for any namespace OTHER than +// exclude that has name bound, returning a " (found bound in: …)" suffix so a +// misregistered primitive points straight at the namespace it landed in (the +// exact signature of the alias-resolution bug: bound in "clojure.core", absent +// from canonical "core"). Empty string when the name is bound nowhere else. +func whereNameBound(name, exclude string) string { + nsMu.RLock() + defer nsMu.RUnlock() + var found []string + for k, ns := range nsRegistry { + if k == exclude { + continue + } + if v := ns.LookupLocal(vm.Symbol(name)); v != nil && v.IsBound() { + found = append(found, k) + } + } + if len(found) == 0 { + return "" + } + sort.Strings(found) + return " (found bound in: " + strings.Join(found, ", ") + ")" +} + // ReapplyGeneratedPrimitives restores the recorded native adapters on a // namespace after one of its chunks executed outside the on-demand loader — // the compiler's eager hybrid-namespace pass (loadPrecompiledBundle) runs From 4d1f0aa049d2e0263cdc5abbd16518c8ab8d9d24 Mon Sep 17 00:00:00 2001 From: "Norman Nunley, Jr" Date: Thu, 23 Jul 2026 01:45:47 -0400 Subject: [PATCH 3/8] =?UTF-8?q?feat(cmd):=20hoist-natives=20codemod=20?= =?UTF-8?q?=E2=80=94=20lift=20lang.go=20closures=20to=20//lg:native=20decl?= =?UTF-8?q?s?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Codemod that lifts the inline anonymous closures registered as clojure.core primitives in pkg/rt/lang.go into named, //lg:native-annotated top-level functions. Three wins: named stack traces (rt.corePlus not installCore.func42), declarative registration (drop ns.Def, lginterop emits from annotations), and the #411 Fn-adapter done as a codemod (no runtime adapter). Only hoists SAFE sites: no genuine enclosing-scope capture (package refs + params are fine; an installCore local like buildArray/asChunked is not) and a discoverable lg-name from ns.Def("name", var). First run on lang.go: 213 safe, 62 capture-blocked (real shared local helpers), 17 no-name. Dry-run by default (report + proposed funcs); -apply rewrites; -only scopes. Converts trailing []vm.Value params to variadic ...vm.Value (lginterop's shape). Analyzer + generator validated (output gofmt-clean, return types preserved); -apply rewrite path implemented but not yet exercised end-to-end. --- cmd/hoist-natives/main.go | 739 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 739 insertions(+) create mode 100644 cmd/hoist-natives/main.go diff --git a/cmd/hoist-natives/main.go b/cmd/hoist-natives/main.go new file mode 100644 index 000000000..72916488b --- /dev/null +++ b/cmd/hoist-natives/main.go @@ -0,0 +1,739 @@ +// Command hoist-natives is a codemod that lifts the inline anonymous closures +// registered as clojure.core primitives in pkg/rt/lang.go into named, +// //lg:native-annotated top-level functions. +// +// Motivation (three wins at once): +// 1. Stack traces read `rt.corePlus` instead of `installCore.func42`. +// 2. Registration becomes declarative — the `ns.Def("+", plus)` call is +// dropped and lginterop emits the registration from the //lg:native + +// //lg:name annotations. +// 3. It is the #411 "Fn-adapter" done as a codemod: hand-built Fn values +// become annotated decls lginterop already consumes, with no runtime +// adapter. +// +// It only hoists closures that are SAFE to lift: no genuine enclosing-scope +// capture (package-level refs and params are fine; an installCore local is +// not), and a discoverable lg-name (an `ns.Def("", )` site). Anything +// else is reported and left untouched — the codemod never guesses. +// +// Default is a dry run: it prints a classification report and the proposed +// hoisted function for each safe site. `-apply` performs the rewrite. +package main + +import ( + "bytes" + "flag" + "fmt" + "go/ast" + "go/format" + "go/parser" + "go/token" + "os" + "path/filepath" + "regexp" + "sort" + "strconv" + "strings" +) + +func main() { + file := flag.String("file", "pkg/rt/lang.go", "Go file to codemod") + pkgDir := flag.String("pkg", "pkg/rt", "package dir (for resolving package-level names)") + only := flag.String("only", "", "regex; limit to lg-names matching it") + helpers := flag.String("helpers", "", "comma-separated installCore-local helper closures to lift to package level (instead of hoisting primitives)") + apply := flag.Bool("apply", false, "apply the rewrite (default: dry run + report)") + flag.Parse() + + var onlyRe *regexp.Regexp + if *only != "" { + onlyRe = regexp.MustCompile(*only) + } + + fset := token.NewFileSet() + f, err := parser.ParseFile(fset, *file, nil, parser.ParseComments) + if err != nil { + die("parse %s: %v", *file, err) + } + + pkgNames, err := packageLevelNames(*pkgDir) + if err != nil { + die("scan package: %v", err) + } + for name := range importNames(f) { + pkgNames[name] = true + } + + if *helpers != "" { + liftHelpers(*file, fset, f, splitSet(*helpers), pkgNames, *apply) + return + } + + defNames := collectNsDefNames(f) // fn-var name -> lg name + + sites := findNativeFnSites(f) + + var safe []*site + skipCap := map[string][]string{} // var -> captured names + var skipNoName []string + for _, s := range sites { + if onlyRe != nil { + lg := defNames[s.varName] + if lg == "" || !onlyRe.MatchString(lg) { + continue + } + } + lg, ok := defNames[s.varName] + if !ok { + skipNoName = append(skipNoName, s.varName) + continue + } + s.lgName = lg + captured := freeVars(s.lit, pkgNames) + if len(captured) > 0 { + skipCap[s.varName] = captured + continue + } + safe = append(safe, s) + } + + report(fset, safe, skipCap, skipNoName, defNames) + + if *apply { + if err := rewrite(*file, fset, f, safe, defNames); err != nil { + die("apply: %v", err) + } + fmt.Printf("\napplied: hoisted %d functions into %s\n", len(safe), *file) + } else { + fmt.Printf("\ndry run — pass -apply to write. proposed hoists for the %d safe sites:\n\n", len(safe)) + for _, s := range safe { + fmt.Println(genFunc(fset, s)) + } + } +} + +// --- site discovery ------------------------------------------------------- + +type site struct { + varName string // the local the closure was assigned to (plus, mul, …) + lgName string // the clojure.core name (from ns.Def) + ctx bool // true for NewCtxNativeFn (first param is ec) + lit *ast.FuncLit // the closure + assign *ast.AssignStmt +} + +// findNativeFnSites finds `X, _ := vm.NativeFnType.Wrap(func…)` / +// `.WrapNoErr(func…)` / `vm.NewCtxNativeFn(func…)` assignments. +func findNativeFnSites(f *ast.File) []*site { + var out []*site + ast.Inspect(f, func(n ast.Node) bool { + as, ok := n.(*ast.AssignStmt) + if !ok || as.Tok != token.DEFINE || len(as.Lhs) != 2 || len(as.Rhs) != 1 { + return true + } + lhs, ok := as.Lhs[0].(*ast.Ident) + if !ok || lhs.Name == "_" { + return true + } + call, ok := as.Rhs[0].(*ast.CallExpr) + if !ok || len(call.Args) != 1 { + return true + } + lit, ok := call.Args[0].(*ast.FuncLit) + if !ok { + return true + } + boxer, ctx := classifyBoxer(call.Fun) + if boxer == "" { + return true + } + out = append(out, &site{varName: lhs.Name, ctx: ctx, lit: lit, assign: as}) + return true + }) + return out +} + +// classifyBoxer returns ("Wrap"|"WrapNoErr"|"NewCtxNativeFn", isCtx) or ("",_). +func classifyBoxer(fun ast.Expr) (string, bool) { + sel, ok := fun.(*ast.SelectorExpr) + if !ok { + return "", false + } + switch sel.Sel.Name { + case "Wrap", "WrapNoErr": + // vm.NativeFnType.Wrap + if inner, ok := sel.X.(*ast.SelectorExpr); ok && inner.Sel.Name == "NativeFnType" { + return sel.Sel.Name, false + } + case "NewCtxNativeFn": + if id, ok := sel.X.(*ast.Ident); ok && id.Name == "vm" { + return sel.Sel.Name, true + } + } + return "", false +} + +// collectNsDefNames maps a registered fn-var to its clojure name from +// `ns.Def("name", fnvar)` call sites. +func collectNsDefNames(f *ast.File) map[string]string { + out := map[string]string{} + ast.Inspect(f, func(n ast.Node) bool { + call, ok := n.(*ast.CallExpr) + if !ok || len(call.Args) != 2 { + return true + } + sel, ok := call.Fun.(*ast.SelectorExpr) + if !ok || sel.Sel.Name != "Def" { + return true + } + nsID, ok := sel.X.(*ast.Ident) + if !ok || nsID.Name != "ns" { + return true + } + lit, ok := call.Args[0].(*ast.BasicLit) + if !ok || lit.Kind != token.STRING { + return true + } + valID, ok := call.Args[1].(*ast.Ident) + if !ok { + return true + } + name, err := strconv.Unquote(lit.Value) + if err == nil { + out[valID.Name] = name + } + return true + }) + return out +} + +// --- free-variable analysis ---------------------------------------------- + +// freeVars returns identifiers used in the closure body that are neither +// declared within it nor package-level nor universe builtins — i.e. genuine +// enclosing-scope captures. Over-reports on shadowing rather than under, so a +// flagged site is skipped for human review, never mis-hoisted. +func freeVars(lit *ast.FuncLit, pkgNames map[string]bool) []string { + declared := map[string]bool{} + for _, fld := range lit.Type.Params.List { + for _, nm := range fld.Names { + declared[nm.Name] = true + } + } + // collect names bound anywhere inside the body + ast.Inspect(lit.Body, func(n ast.Node) bool { + switch x := n.(type) { + case *ast.AssignStmt: + if x.Tok == token.DEFINE { + for _, l := range x.Lhs { + if id, ok := l.(*ast.Ident); ok { + declared[id.Name] = true + } + } + } + case *ast.RangeStmt: + for _, e := range []ast.Expr{x.Key, x.Value} { + if id, ok := e.(*ast.Ident); ok { + declared[id.Name] = true + } + } + case *ast.DeclStmt: + if gd, ok := x.Decl.(*ast.GenDecl); ok { + for _, spec := range gd.Specs { + switch sp := spec.(type) { + case *ast.ValueSpec: + for _, nm := range sp.Names { + declared[nm.Name] = true + } + case *ast.TypeSpec: + declared[sp.Name.Name] = true + } + } + } + case *ast.FuncLit: + for _, fld := range x.Type.Params.List { + for _, nm := range fld.Names { + declared[nm.Name] = true + } + } + } + return true + }) + + // Idents that are NOT value references: a selector's field/method name + // (`x.Type` — `Type` is not a capture) and a struct composite's field key. + skip := map[*ast.Ident]bool{} + ast.Inspect(lit.Body, func(n ast.Node) bool { + switch x := n.(type) { + case *ast.SelectorExpr: + skip[x.Sel] = true + case *ast.CompositeLit: + // keys of a struct composite are field names. (Map/slice keys ARE + // values, so only skip when the type is a struct/named type — being + // conservative and NOT skipping when unsure would just over-flag.) + if isNamedType(x.Type) { + for _, elt := range x.Elts { + if kv, ok := elt.(*ast.KeyValueExpr); ok { + if id, ok := kv.Key.(*ast.Ident); ok { + skip[id] = true + } + } + } + } + } + return true + }) + + freeSet := map[string]bool{} + ast.Inspect(lit.Body, func(n ast.Node) bool { + if id, ok := n.(*ast.Ident); ok && !skip[id] { + considerIdent(id, declared, pkgNames, freeSet) + } + return true + }) + out := make([]string, 0, len(freeSet)) + for nm := range freeSet { + out = append(out, nm) + } + sort.Strings(out) + return out +} + +// isNamedType reports whether a composite-literal type is a named/struct type +// (T{…} or pkg.T{…}), whose keys are field names — as opposed to []T{…} / +// map[K]V{…} whose keys are values. +func isNamedType(e ast.Expr) bool { + switch e.(type) { + case *ast.Ident, *ast.SelectorExpr: + return true + default: + return false + } +} + +func considerIdent(id *ast.Ident, declared, pkg, free map[string]bool) { + nm := id.Name + if nm == "_" || declared[nm] || pkg[nm] || universe[nm] { + return + } + // treat obvious non-values out: capitalized single tokens that are types are + // usually package-level; if unknown, we flag (conservative). + free[nm] = true +} + +var universe = strSet( + "append", "cap", "clear", "close", "complex", "copy", "delete", "imag", + "len", "make", "max", "min", "new", "panic", "print", "println", "real", + "recover", "nil", "true", "false", "iota", + "bool", "byte", "rune", "string", "error", "int", "int8", "int16", "int32", + "int64", "uint", "uint8", "uint16", "uint32", "uint64", "uintptr", + "float32", "float64", "complex64", "complex128", "any", "comparable", +) + +// --- package-level name collection --------------------------------------- + +func packageLevelNames(dir string) (map[string]bool, error) { + names := map[string]bool{} + entries, err := os.ReadDir(dir) + if err != nil { + return nil, err + } + fset := token.NewFileSet() + for _, e := range entries { + if e.IsDir() || !strings.HasSuffix(e.Name(), ".go") || strings.HasSuffix(e.Name(), "_test.go") { + continue + } + f, err := parser.ParseFile(fset, filepath.Join(dir, e.Name()), nil, 0) + if err != nil { + continue // tolerate build-tag / partial parse issues; names union is best-effort + } + for _, d := range f.Decls { + switch decl := d.(type) { + case *ast.FuncDecl: + if decl.Recv == nil { + names[decl.Name.Name] = true + } + case *ast.GenDecl: + for _, spec := range decl.Specs { + switch sp := spec.(type) { + case *ast.ValueSpec: + for _, nm := range sp.Names { + names[nm.Name] = true + } + case *ast.TypeSpec: + names[sp.Name.Name] = true + } + } + } + } + } + return names, nil +} + +func importNames(f *ast.File) map[string]bool { + out := map[string]bool{} + for _, imp := range f.Imports { + if imp.Name != nil { + out[imp.Name.Name] = true + continue + } + p, _ := strconv.Unquote(imp.Path.Value) + base := p + if i := strings.LastIndex(p, "/"); i >= 0 { + base = p[i+1:] + } + out[base] = true + } + return out +} + +// --- generation ----------------------------------------------------------- + +// genFunc renders the hoisted, annotated function for a safe site. +func genFunc(fset *token.FileSet, s *site) string { + name := hoistName(s.varName) + params := convertSignature(fset, s.lit.Type.Params) + results := renderResults(fset, s.lit.Type.Results) + body := nodeString(fset, s.lit.Body) + + var b strings.Builder + b.WriteString("//lg:native\n") + b.WriteString("//lg:name " + s.lgName + "\n") + fmt.Fprintf(&b, "func %s(%s) %s %s", name, params, results, body) + // gofmt the fragment + src := "package rt\n" + b.String() + "\n" + if out, err := format.Source([]byte(src)); err == nil { + return strings.TrimPrefix(string(out), "package rt\n\n") + } + return b.String() +} + +// convertSignature renders params, turning a trailing `vs []vm.Value` into the +// variadic `vs ...vm.Value` shape lginterop's native model consumes. Typed +// params (ec *vm.ExecContext, coll vm.Value, i int) pass through unchanged. +func convertSignature(fset *token.FileSet, params *ast.FieldList) string { + var parts []string + for i, fld := range params.List { + typ := fld.Type + if i == len(params.List)-1 { + if arr, ok := typ.(*ast.ArrayType); ok && arr.Len == nil && nodeString(fset, arr.Elt) == "vm.Value" { + name := "args" + if len(fld.Names) > 0 { + name = fld.Names[0].Name + } + parts = append(parts, name+" ...vm.Value") + continue + } + } + parts = append(parts, renderField(fset, fld)) + } + return strings.Join(parts, ", ") +} + +// renderField renders `[name[, name] ]type` for a param/result field. +// format.Node handles the type (an ast.Expr) but not *ast.Field itself. +func renderField(fset *token.FileSet, fld *ast.Field) string { + typ := nodeString(fset, fld.Type) + if len(fld.Names) == 0 { + return typ + } + names := make([]string, len(fld.Names)) + for i, nm := range fld.Names { + names[i] = nm.Name + } + return strings.Join(names, ", ") + " " + typ +} + +// renderResults renders the result list, parenthesised when needed. +func renderResults(fset *token.FileSet, results *ast.FieldList) string { + if results == nil || len(results.List) == 0 { + return "" + } + parts := make([]string, len(results.List)) + named := false + for i, fld := range results.List { + if len(fld.Names) > 0 { + named = true + } + parts[i] = renderField(fset, fld) + } + joined := strings.Join(parts, ", ") + if len(results.List) > 1 || named { + return "(" + joined + ") " + } + return joined + " " +} + +func hoistName(varName string) string { + // plus -> corePlus, excludeInCurrentNs -> coreExcludeInCurrentNs + if varName == "" { + return "coreFn" + } + return "core" + strings.ToUpper(varName[:1]) + varName[1:] +} + +// --- rewrite (apply) ------------------------------------------------------ + +// rewrite deletes each safe site's `X, _ := …` assignment and its +// `ns.Def("name", X)` statement, then appends the hoisted funcs, at the text +// level (position-based) so formatting elsewhere is untouched. gofmt at the end. +func rewrite(path string, fset *token.FileSet, f *ast.File, safe []*site, defNames map[string]string) error { + src, err := os.ReadFile(path) + if err != nil { + return err + } + type span struct{ start, end int } + var cuts []span + byVar := map[string]*site{} + for _, s := range safe { + byVar[s.varName] = s + cuts = append(cuts, span{fset.Position(s.assign.Pos()).Offset, lineEnd(src, fset.Position(s.assign.End()).Offset)}) + } + // find the ns.Def statements to cut + ast.Inspect(f, func(n ast.Node) bool { + call, ok := n.(*ast.CallExpr) + if !ok || len(call.Args) != 2 { + return true + } + sel, ok := call.Fun.(*ast.SelectorExpr) + if !ok || sel.Sel.Name != "Def" { + return true + } + if id, ok := sel.X.(*ast.Ident); !ok || id.Name != "ns" { + return true + } + valID, ok := call.Args[1].(*ast.Ident) + if !ok || byVar[valID.Name] == nil { + return true + } + cuts = append(cuts, span{lineStart(src, fset.Position(call.Pos()).Offset), lineEnd(src, fset.Position(call.End()).Offset)}) + return true + }) + + sort.Slice(cuts, func(i, j int) bool { return cuts[i].start > cuts[j].start }) + out := append([]byte(nil), src...) + for _, c := range cuts { + out = append(out[:c.start], out[c.end:]...) + } + + var appended bytes.Buffer + appended.WriteString("\n// --- hoisted native primitives (see cmd/hoist-natives) ---\n\n") + for _, s := range safe { + appended.WriteString(genFunc(fset, s)) + appended.WriteString("\n\n") + } + out = append(out, appended.Bytes()...) + + formatted, err := format.Source(out) + if err != nil { + // leave unformatted so the author can inspect; still write + formatted = out + } + return os.WriteFile(path, formatted, 0644) +} + +func lineStart(src []byte, off int) int { + for off > 0 && src[off-1] != '\n' { + off-- + } + return off +} +func lineEnd(src []byte, off int) int { + for off < len(src) && src[off] != '\n' { + off++ + } + if off < len(src) { + off++ // include newline + } + return off +} + +// --- reporting ------------------------------------------------------------ + +func report(fset *token.FileSet, safe []*site, skipCap map[string][]string, skipNoName []string, defNames map[string]string) { + fmt.Printf("hoist-natives report\n====================\n") + fmt.Printf("safe to hoist: %d\n", len(safe)) + fmt.Printf("skipped (captures): %d\n", len(skipCap)) + fmt.Printf("skipped (no lg name): %d\n\n", len(skipNoName)) + + if len(skipCap) > 0 { + fmt.Println("-- skipped: genuine enclosing-scope captures (need ec-threading / manual) --") + keys := sortedKeys(skipCap) + for _, k := range keys { + fmt.Printf(" %-24s captures: %s (lg: %q)\n", k, strings.Join(skipCap[k], ", "), defNames[k]) + } + fmt.Println() + } + if len(skipNoName) > 0 { + sort.Strings(skipNoName) + fmt.Println("-- skipped: no ns.Def(\"name\", var) found (registered differently / internal) --") + fmt.Printf(" %s\n\n", strings.Join(skipNoName, ", ")) + } +} + +// --- helpers -------------------------------------------------------------- + +func nodeString(fset *token.FileSet, n ast.Node) string { + if n == nil { + return "" + } + var b bytes.Buffer + if err := format.Node(&b, fset, n); err != nil { + return "" + } + return b.String() +} + +func strSet(xs ...string) map[string]bool { + m := make(map[string]bool, len(xs)) + for _, x := range xs { + m[x] = true + } + return m +} + +func sortedKeys[V any](m map[string]V) []string { + ks := make([]string, 0, len(m)) + for k := range m { + ks = append(ks, k) + } + sort.Strings(ks) + return ks +} + +// --- helper lift ---------------------------------------------------------- + +type helperSite struct { + name string + lit *ast.FuncLit + assign *ast.AssignStmt +} + +// liftHelpers lifts named installCore-local helper closures (X := func…{…}) to +// package-level funcs. Helpers may call each other, so the requested set is +// treated as already-package-level for the capture check. +func liftHelpers(path string, fset *token.FileSet, f *ast.File, set, pkgNames map[string]bool, apply bool) { + for name := range set { + pkgNames[name] = true + } + sites := findHelperDecls(f, set) + found := map[string]bool{} + var safe []*helperSite + skipCap := map[string][]string{} + for _, h := range sites { + found[h.name] = true + if captured := freeVars(h.lit, pkgNames); len(captured) > 0 { + skipCap[h.name] = captured + continue + } + safe = append(safe, h) + } + + fmt.Printf("lift-helpers report\n===================\n") + fmt.Printf("requested: %d, found: %d, liftable: %d, capture-blocked: %d\n\n", + len(set), len(found), len(safe), len(skipCap)) + for name := range set { + if !found[name] { + fmt.Printf(" NOT FOUND as `%s := func…`\n", name) + } + } + for _, k := range sortedKeys(skipCap) { + fmt.Printf(" capture-blocked %-20s captures: %s\n", k, strings.Join(skipCap[k], ", ")) + } + fmt.Println() + + if apply { + if err := rewriteHelpers(path, fset, safe); err != nil { + die("lift-helpers apply: %v", err) + } + fmt.Printf("applied: lifted %d helpers into %s\n", len(safe), path) + return + } + fmt.Printf("dry run — proposed package-level funcs for the %d liftable helpers:\n\n", len(safe)) + for _, h := range safe { + fmt.Println(genHelper(fset, h)) + } +} + +func findHelperDecls(f *ast.File, set map[string]bool) []*helperSite { + var out []*helperSite + ast.Inspect(f, func(n ast.Node) bool { + as, ok := n.(*ast.AssignStmt) + if !ok || as.Tok != token.DEFINE || len(as.Lhs) != 1 || len(as.Rhs) != 1 { + return true + } + id, ok := as.Lhs[0].(*ast.Ident) + if !ok || !set[id.Name] { + return true + } + lit, ok := as.Rhs[0].(*ast.FuncLit) + if !ok { + return true + } + out = append(out, &helperSite{name: id.Name, lit: lit, assign: as}) + return true + }) + return out +} + +// genHelper renders a lifted helper as a package-level func — no annotations, no +// signature conversion (helpers keep their exact interface). +func genHelper(fset *token.FileSet, h *helperSite) string { + var params []string + for _, fld := range h.lit.Type.Params.List { + params = append(params, renderField(fset, fld)) + } + results := renderResults(fset, h.lit.Type.Results) + body := nodeString(fset, h.lit.Body) + src := fmt.Sprintf("package rt\nfunc %s(%s) %s%s\n", h.name, strings.Join(params, ", "), results, body) + if out, err := format.Source([]byte(src)); err == nil { + return strings.TrimPrefix(string(out), "package rt\n\n") + } + return src +} + +func rewriteHelpers(path string, fset *token.FileSet, safe []*helperSite) error { + src, err := os.ReadFile(path) + if err != nil { + return err + } + type span struct{ start, end int } + var cuts []span + for _, h := range safe { + cuts = append(cuts, span{ + lineStart(src, fset.Position(h.assign.Pos()).Offset), + lineEnd(src, fset.Position(h.assign.End()).Offset), + }) + } + sort.Slice(cuts, func(i, j int) bool { return cuts[i].start > cuts[j].start }) + out := append([]byte(nil), src...) + for _, c := range cuts { + out = append(out[:c.start], out[c.end:]...) + } + var appended bytes.Buffer + appended.WriteString("\n// --- lifted native helpers (see cmd/hoist-natives -helpers) ---\n\n") + for _, h := range safe { + appended.WriteString(genHelper(fset, h)) + appended.WriteString("\n\n") + } + out = append(out, appended.Bytes()...) + formatted, err := format.Source(out) + if err != nil { + formatted = out + } + return os.WriteFile(path, formatted, 0644) +} + +func splitSet(csv string) map[string]bool { + m := map[string]bool{} + for _, p := range strings.Split(csv, ",") { + if p = strings.TrimSpace(p); p != "" { + m[p] = true + } + } + return m +} + +func die(format string, args ...any) { + fmt.Fprintf(os.Stderr, "hoist-natives: "+format+"\n", args...) + os.Exit(1) +} From a21afe97c6aeea7694a7b5da8aa5569b1876f0c5 Mon Sep 17 00:00:00 2001 From: "Norman Nunley, Jr" Date: Thu, 23 Jul 2026 09:40:30 -0400 Subject: [PATCH 4/8] refactor(rt): lift shared native helper closures to package level Lift installCore-local helper closures (buildArray, asChunked, rangeInt, regexSubmatchValue, regexSubmatchVector) to package-level funcs via cmd/hoist-natives -helpers. Unblocks ~14 primitives whose closures captured them, en route to hoisting the native primitives to //lg:native decls. --- pkg/rt/lang.go | 180 +++++++++++++++++++++++++------------------------ 1 file changed, 92 insertions(+), 88 deletions(-) diff --git a/pkg/rt/lang.go b/pkg/rt/lang.go index 40c94e48e..83cc7e722 100644 --- a/pkg/rt/lang.go +++ b/pkg/rt/lang.go @@ -2570,17 +2570,6 @@ func installLangNS() { // AsChunkedSeq, so they resolve through LazySeq wrappers). chunk-cons // builds a ChunkedCons; chunk-buffer / chunk-append / chunk are the // mutable builder API. chunked-seq? answers the type predicate. - asChunked := func(v vm.Value, op string) (vm.IChunkedSeq, error) { - s, err := seqOf(v) - if err != nil { - return nil, fmt.Errorf("%s: not a sequence", op) - } - cs, ok := vm.AsChunkedSeq(s) - if !ok { - return nil, fmt.Errorf("%s: not a chunked seq", op) - } - return cs, nil - } chunkFirst, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { if len(vs) != 1 { @@ -7688,83 +7677,6 @@ func installLangNS() { // --- Array operations --- // Helper: build a typed array from size or seq - buildArray := func(kind vm.ArrayKind, vs []vm.Value) (vm.Value, error) { - if len(vs) == 0 || len(vs) > 2 { - return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) - } - // (x-array n) or (x-array n init) - if n, ok := vs[0].(vm.Int); ok { - size := int(n) - if size < 0 { - return vm.NIL, fmt.Errorf("negative array size: %d", size) - } - var arr *vm.TypedArray - switch kind { - case vm.ArrayByte: - arr = vm.NewByteArray(size) - case vm.ArrayInt: - arr = vm.NewIntArray(size) - case vm.ArrayFloat: - arr = vm.NewFloatArray(size) - case vm.ArrayObject: - arr = vm.NewObjectArray(size) - } - if len(vs) == 2 { - for i := range size { - if err := arr.Set(i, vs[1]); err != nil { - return vm.NIL, err - } - } - } - return arr, nil - } - // (x-array coll) - s, serr := seqOf(vs[0]) - if serr != nil { - return vm.NIL, serr - } - var vals []vm.Value - for ; s != nil; s = s.Next() { - vals = append(vals, s.First()) - } - var arr *vm.TypedArray - switch kind { - case vm.ArrayByte: - data := make([]byte, len(vals)) - for i, v := range vals { - n, ok := v.(vm.Int) - if !ok { - return vm.NIL, fmt.Errorf("byte-array element must be Int, got %s", v.Type().Name()) - } - data[i] = byte(n) - } - arr = vm.NewByteArrayFrom(data) - case vm.ArrayInt: - data := make([]int64, len(vals)) - for i, v := range vals { - switch n := v.(type) { - case vm.Int: - data[i] = int64(n) - default: - return vm.NIL, fmt.Errorf("int-array element must be Int, got %s", v.Type().Name()) - } - } - arr = vm.NewIntArrayFrom(data) - case vm.ArrayFloat: - data := make([]float64, len(vals)) - for i, v := range vals { - f, ok := vm.ToFloat(v) - if !ok { - return vm.NIL, fmt.Errorf("double-array element must be numeric, got %s", v.Type().Name()) - } - data[i] = f - } - arr = vm.NewFloatArrayFrom(data) - case vm.ArrayObject: - arr = vm.NewObjectArrayFrom(vals) - } - return arr, nil - } byteArrayf, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return buildArray(vm.ArrayByte, vs) @@ -8886,3 +8798,95 @@ func strValue(v vm.Value) string { } return v.String() } + +// --- lifted native helpers (see cmd/hoist-natives -helpers) --- + +func asChunked(v vm.Value, op string) (vm.IChunkedSeq, error) { + s, err := seqOf(v) + if err != nil { + return nil, fmt.Errorf("%s: not a sequence", op) + } + cs, ok := vm.AsChunkedSeq(s) + if !ok { + return nil, fmt.Errorf("%s: not a chunked seq", op) + } + return cs, nil +} + +func buildArray(kind vm.ArrayKind, vs []vm.Value) (vm.Value, error) { + if len(vs) == 0 || len(vs) > 2 { + return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) + } + + if n, ok := vs[0].(vm.Int); ok { + size := int(n) + if size < 0 { + return vm.NIL, fmt.Errorf("negative array size: %d", size) + } + var arr *vm.TypedArray + switch kind { + case vm.ArrayByte: + arr = vm.NewByteArray(size) + case vm.ArrayInt: + arr = vm.NewIntArray(size) + case vm.ArrayFloat: + arr = vm.NewFloatArray(size) + case vm.ArrayObject: + arr = vm.NewObjectArray(size) + } + if len(vs) == 2 { + for i := range size { + if err := arr.Set(i, vs[1]); err != nil { + return vm.NIL, err + } + } + } + return arr, nil + } + + s, serr := seqOf(vs[0]) + if serr != nil { + return vm.NIL, serr + } + var vals []vm.Value + for ; s != nil; s = s.Next() { + vals = append(vals, s.First()) + } + var arr *vm.TypedArray + switch kind { + case vm.ArrayByte: + data := make([]byte, len(vals)) + for i, v := range vals { + n, ok := v.(vm.Int) + if !ok { + return vm.NIL, fmt.Errorf("byte-array element must be Int, got %s", v.Type().Name()) + } + data[i] = byte(n) + } + arr = vm.NewByteArrayFrom(data) + case vm.ArrayInt: + data := make([]int64, len(vals)) + for i, v := range vals { + switch n := v.(type) { + case vm.Int: + data[i] = int64(n) + default: + return vm.NIL, fmt.Errorf("int-array element must be Int, got %s", v.Type().Name()) + } + } + arr = vm.NewIntArrayFrom(data) + case vm.ArrayFloat: + data := make([]float64, len(vals)) + for i, v := range vals { + f, ok := vm.ToFloat(v) + if !ok { + return vm.NIL, fmt.Errorf("double-array element must be numeric, got %s", v.Type().Name()) + } + data[i] = f + } + arr = vm.NewFloatArrayFrom(data) + case vm.ArrayObject: + arr = vm.NewObjectArrayFrom(vals) + } + return arr, nil +} From 4654722a23ac17d6456a7fecef3c91b3b43f9965 Mon Sep 17 00:00:00 2001 From: "Norman Nunley, Jr" Date: Thu, 23 Jul 2026 15:00:58 -0400 Subject: [PATCH 5/8] feat(build): runtime-free primitive registrar generator (lgprimgen) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The registrar in pkg/rt/zz_primitives_generated.go is what lets the runtime boot; a generator that boots the runtime to produce it depends on the very artifact it emits (p0 depending on p1). When a primitive is hoisted out of installLangNS into a //lg:native decl, the runtime cannot boot until this file carries its registration — so the generator must run in exactly that state. - Extract the primitives codegen into internal/primgen, a PURE go/ast tool with no pkg/compiler / pkg/rt import (prims_scan, prims_emit, Generate, ScanNativeNames, KebabCase). - Add cmd/lgprimgen, a thin binary over primgen; cmd/lginterop delegates its -primitives mode to the same package (its compiler import is only for the interop-EDN path). - Makefile: regenerate zz_primitives_generated.go via lgprimgen BEFORE the lgbgen bootstrap that consumes it, breaking the boot cycle. generate.lg calls lgprimgen too. - Fix a latent emit bug: variadic-spread adapters (Fn(vs...)) dropped the closing paren — never exercised until the first //lg:native ...vm.Value primitives. gofmt failures now surface stderr + dump the source. --- .gitignore | 1 + Makefile | 16 +- cmd/lginterop/main.go | 123 +----------- cmd/lgprimgen/main.go | 37 ++++ internal/primgen/generate.go | 176 ++++++++++++++++++ .../primgen}/prims_emit.go | 8 +- .../primgen}/prims_scan.go | 4 +- .../primgen}/prims_test.go | 2 +- scripts/generate.lg | 12 +- 9 files changed, 254 insertions(+), 125 deletions(-) create mode 100644 cmd/lgprimgen/main.go create mode 100644 internal/primgen/generate.go rename {cmd/lginterop => internal/primgen}/prims_emit.go (99%) rename {cmd/lginterop => internal/primgen}/prims_scan.go (99%) rename {cmd/lginterop => internal/primgen}/prims_test.go (99%) diff --git a/.gitignore b/.gitignore index cacd30331..37529c034 100644 --- a/.gitignore +++ b/.gitignore @@ -175,6 +175,7 @@ AGENTS.md # AOT codegen tool — built ad-hoc, not checked in /lgbgen /lginterop +/lgprimgen /bench-ratchet /perf-page diff --git a/Makefile b/Makefile index 0f7605832..21934fa5b 100644 --- a/Makefile +++ b/Makefile @@ -69,7 +69,19 @@ build-profile: $(LG-PROFILE) CORE-LG-FILES := $(shell find pkg/rt/core -name '*.lg' -type f 2>/dev/null) LGBGEN-SOURCES := $(shell find cmd/lgbgen -name '*.go' -type f 2>/dev/null) ROOT-GO-FILES := $(shell find . -maxdepth 1 -name '*.go' -type f 2>/dev/null) -pkg/rt/core_compiled.lgb: $(CORE-LG-FILES) $(LGBGEN-SOURCES) $(GO) + +# Primitive registrar. lgprimgen scans pkg/rt's //lg:native-annotated Go sources +# and emits this file. It is a PURE go/ast codegen tool (no pkg/compiler / pkg/rt +# import), so it MUST run before the lgbgen bootstrap that consumes it: when a +# primitive is hoisted out of installLangNS into a //lg:native decl, the bootstrap +# runtime cannot boot until this file carries its registration. A runtime-coupled +# generator here would depend on the very artifact it produces. Making the bundle +# depend on it breaks that cycle. +PRIMGEN-SOURCES := $(shell find pkg/rt -maxdepth 1 -name '*.go' -type f -not -name 'zz_*' -not -name '*_test.go' 2>/dev/null) $(shell find cmd/lgprimgen internal/primgen -name '*.go' -type f 2>/dev/null) +pkg/rt/zz_primitives_generated.go: $(PRIMGEN-SOURCES) $(GO) + go run ./cmd/lgprimgen -primitives pkg/rt -go-pkg github.com/nooga/let-go/pkg/rt -primitives-out pkg/rt/zz_primitives_generated.go + +pkg/rt/core_compiled.lgb: pkg/rt/zz_primitives_generated.go $(CORE-LG-FILES) $(LGBGEN-SOURCES) $(GO) go run -tags bootstrap ./cmd/lgbgen # Lowered-Go target. The -tags gogen_ir build path links these generated @@ -78,7 +90,7 @@ pkg/rt/core_compiled.lgb: $(CORE-LG-FILES) $(LGBGEN-SOURCES) $(GO) # the two engines silently disagree (parity-full diverges on bucket # hashes even when pass/fail counts match). lower_go.go is the timestamp # anchor for the whole tree — every regen rewrites it. -pkg/rt/core_go_lowered/ir/lower_go/lower_go.go: $(CORE-LG-FILES) $(LGBGEN-SOURCES) $(GO) +pkg/rt/core_go_lowered/ir/lower_go/lower_go.go: pkg/rt/zz_primitives_generated.go $(CORE-LG-FILES) $(LGBGEN-SOURCES) $(GO) go run -tags bootstrap ./cmd/lgbgen --target=go # Regenerate every committed code-gen artifact via the let-go orchestrator diff --git a/cmd/lginterop/main.go b/cmd/lginterop/main.go index b90c618a7..b575dc67a 100644 --- a/cmd/lginterop/main.go +++ b/cmd/lginterop/main.go @@ -16,8 +16,8 @@ import ( "sort" "strconv" "strings" - "unicode" + "github.com/nooga/let-go/internal/primgen" "github.com/nooga/let-go/pkg/compiler" "github.com/nooga/let-go/pkg/vm" ) @@ -45,9 +45,12 @@ func main() { goPkg := flag.String("go-pkg", "", "Go import path of the scanned sources (used with -primitives)") flag.Parse() - // Handle -primitives mode (separate from the external interop path) + // Handle -primitives mode (separate from the external interop path). + // Delegates to the runtime-free primgen package — prefer the standalone + // cmd/lgprimgen binary, which does not import pkg/compiler and so can run + // mid-migration when the runtime this binary boots cannot. if *primitivesDir != "" { - if err := generatePrimitives(*primitivesDir, *primitivesOut, *goPkg); err != nil { + if err := primgen.Generate(*primitivesDir, *primitivesOut, *goPkg); err != nil { fmt.Fprintf(os.Stderr, "lginterop: %v\n", err) os.Exit(1) } @@ -123,94 +126,6 @@ func main() { fmt.Printf("lginterop: generated %d/%d package(s) in %s\n", okCount, len(entries), *out) } -// --- primitives generation (-primitives mode) -------------------------------- - -func generatePrimitives(srcDir, outPath, goPkg string) error { - // Walk srcDir and scan all .go files for //lg:native directives - var allSpecs []primSpec - - entries, err := os.ReadDir(srcDir) - if err != nil { - return fmt.Errorf("read directory %s: %w", srcDir, err) - } - - for _, entry := range entries { - // Skip test files and generated output: an //lg:native annotation in - // a _test.go or zz_ file would emit an unconditional reference to a - // symbol the normal build doesn't compile. - if entry.IsDir() || !strings.HasSuffix(entry.Name(), ".go") || - strings.HasSuffix(entry.Name(), "_test.go") || - strings.HasPrefix(entry.Name(), "zz_") { - continue - } - - fpath := filepath.Join(srcDir, entry.Name()) - src, err := os.ReadFile(fpath) - if err != nil { - return fmt.Errorf("read %s: %w", fpath, err) - } - - // Files under a build constraint may reference symbols absent from - // other targets; the registrar compiles unconditionally, so skip them. - if hasBuildConstraint(src) { - continue - } - - specs, err := scanSource(fpath, src) - if err != nil { - return fmt.Errorf("parse %s: %w", fpath, err) - } - allSpecs = append(allSpecs, specs...) - } - - if len(allSpecs) == 0 { - fmt.Printf("lginterop: no //lg:native directives found in %s; generating empty stub\n", srcDir) - // Fall through to generate an empty RegisterGeneratedPrimitives() stub - } - - // Set GoPkg on all specs - for i := range allSpecs { - if goPkg != "" { - allSpecs[i].GoPkg = goPkg - } else if allSpecs[i].GoPkg == "" { - // Fallback default - allSpecs[i].GoPkg = "github.com/nooga/let-go/pkg/rt/builtins" - } - } - - // Generate the file - output := emitFile(allSpecs) - - // Format with gofmt - formatted, err := gofmtCode(output) - if err != nil { - return fmt.Errorf("gofmt: %w", err) - } - - // Write the output file - if err := os.MkdirAll(filepath.Dir(outPath), 0755); err != nil { - return fmt.Errorf("mkdir %s: %w", filepath.Dir(outPath), err) - } - - if err := os.WriteFile(outPath, []byte(formatted), 0644); err != nil { - return fmt.Errorf("write %s: %w", outPath, err) - } - - fmt.Printf("lginterop: generated primitives → %s (%d specs)\n", outPath, len(allSpecs)) - return nil -} - -// gofmtCode formats Go source code using the gofmt command. -func gofmtCode(src string) (string, error) { - cmd := exec.Command("gofmt") - cmd.Stdin = strings.NewReader(src) - output, err := cmd.Output() - if err != nil { - return "", fmt.Errorf("gofmt failed: %w", err) - } - return string(output), nil -} - // --- repo root & lg binary discovery -------------------------------------- func findRepoRoot() (string, error) { @@ -697,7 +612,7 @@ func buildSkeleton(alias string, exports []export, smart bool) string { } if smart { - fmt.Fprintf(b, "(defn- %s\n", kebabCase(ex.name)) + fmt.Fprintf(b, "(defn- %s\n", primgen.KebabCase(ex.name)) fmt.Fprintf(b, " \"Wrapper for %s. Customize as needed.\"\n", qname) if variadic { fmt.Fprintf(b, " [& args]\n") @@ -710,7 +625,7 @@ func buildSkeleton(alias string, exports []export, smart bool) string { fmt.Fprintf(b, " (%s %s))\n\n", qname, strings.Join(argNames, " ")) } } else { - fmt.Fprintf(b, "(defn- %s\n", kebabCase(ex.name)) + fmt.Fprintf(b, "(defn- %s\n", primgen.KebabCase(ex.name)) fmt.Fprintf(b, " \"Wrapper for %s. Customize as needed.\"\n", qname) if variadic { fmt.Fprintf(b, " [& args]\n") @@ -730,33 +645,15 @@ func buildSkeleton(alias string, exports []export, smart bool) string { } case *types.Const: fmt.Fprintf(b, ";; Constant: %s\n", qname) - fmt.Fprintf(b, ";; (def %s %s)\n\n", kebabCase(ex.name), qname) + fmt.Fprintf(b, ";; (def %s %s)\n\n", primgen.KebabCase(ex.name), qname) case *types.Var: fmt.Fprintf(b, ";; Variable: %s\n", qname) - fmt.Fprintf(b, ";; (def %s %s)\n\n", kebabCase(ex.name), qname) + fmt.Fprintf(b, ";; (def %s %s)\n\n", primgen.KebabCase(ex.name), qname) } } return b.String() } -func kebabCase(s string) string { - var b strings.Builder - for i, r := range s { - if i > 0 { - prev := rune(s[i-1]) - if unicode.IsUpper(r) { - if unicode.IsLower(prev) { - b.WriteByte('-') - } else if i+1 < len(s) && unicode.IsLower(rune(s[i+1])) { - b.WriteByte('-') - } - } - } - b.WriteRune(unicode.ToLower(r)) - } - return b.String() -} - // Avoid "declared and not used" for runtime import. var _ = runtime.GOOS diff --git a/cmd/lgprimgen/main.go b/cmd/lgprimgen/main.go new file mode 100644 index 000000000..641b4e018 --- /dev/null +++ b/cmd/lgprimgen/main.go @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2026 Norman Nunley, Jr + * Part of the let-go project; see CONTRIBUTORS for full list of authors. + * SPDX-License-Identifier: MIT + */ + +// Command lgprimgen generates pkg/rt/zz_primitives_generated.go from the +// //lg:native directives in the runtime's Go sources. +// +// It is split out from cmd/lginterop precisely so it imports NOTHING that boots +// the let-go runtime (no pkg/compiler, no pkg/rt). lginterop pulls in +// pkg/compiler for its interop-EDN mode, whose package init compiles core.lg — +// which fails mid-migration, when primitives have been moved out of +// installLangNS but the registrar that replaces them hasn't been generated yet. +// The generator must run in exactly that inconsistent state (it is what makes it +// consistent again), so it stays a pure go/ast → Go codegen tool. +package main + +import ( + "flag" + "fmt" + "os" + + "github.com/nooga/let-go/internal/primgen" +) + +func main() { + srcDir := flag.String("primitives", "pkg/rt", "directory containing //lg:-annotated Go sources") + out := flag.String("primitives-out", "pkg/rt/zz_primitives_generated.go", "output file for the generated registrar") + goPkg := flag.String("go-pkg", "github.com/nooga/let-go/pkg/rt", "Go import path of the scanned sources") + flag.Parse() + + if err := primgen.Generate(*srcDir, *out, *goPkg); err != nil { + fmt.Fprintf(os.Stderr, "lgprimgen: %v\n", err) + os.Exit(1) + } +} diff --git a/internal/primgen/generate.go b/internal/primgen/generate.go new file mode 100644 index 000000000..2a152707b --- /dev/null +++ b/internal/primgen/generate.go @@ -0,0 +1,176 @@ +/* + * Copyright (c) 2026 Norman Nunley, Jr + * Part of the let-go project; see CONTRIBUTORS for full list of authors. + * SPDX-License-Identifier: MIT + */ + +// Package primgen scans //lg:-annotated Go sources and emits the +// zz_primitives_generated.go registrar. It is deliberately a PURE source → +// source code generator: it depends only on go/ast + text templates and does +// NOT import the let-go runtime (pkg/compiler / pkg/rt). +// +// This independence is the whole point. The registrar it emits is what lets the +// NEXT-generation runtime boot; a generator that booted the current runtime +// would depend on the very artifacts it is about to produce (p0 depending on +// p1). During a large primitive migration — closures moved out of installLangNS +// but not yet in the generated registrar — that runtime cannot boot, so a +// runtime-coupled generator would deadlock the regeneration it exists to drive. +package primgen + +import ( + "fmt" + "os" + "os/exec" + "path/filepath" + "strings" + "unicode" +) + +// KebabCase converts a Go identifier (CamelCase) to a let-go kebab name. Used +// both to default a primitive's lg-name during scanning and by lginterop's +// skeleton emitter, so it lives in the shared runtime-free package. +func KebabCase(s string) string { + var b strings.Builder + for i, r := range s { + if i > 0 { + prev := rune(s[i-1]) + if unicode.IsUpper(r) { + if unicode.IsLower(prev) { + b.WriteByte('-') + } else if i+1 < len(s) && unicode.IsLower(rune(s[i+1])) { + b.WriteByte('-') + } + } + } + b.WriteRune(unicode.ToLower(r)) + } + return b.String() +} + +// Generate scans srcDir for //lg:native directives and writes the generated +// primitive registrar to outPath. goPkg is the Go import path of the scanned +// sources (used for cross-package symbol references); empty falls back to the +// per-spec GoPkg or the builtins default. +func Generate(srcDir, outPath, goPkg string) error { + var allSpecs []primSpec + + entries, err := os.ReadDir(srcDir) + if err != nil { + return fmt.Errorf("read directory %s: %w", srcDir, err) + } + + for _, entry := range entries { + // Skip test files and generated output: an //lg:native annotation in + // a _test.go or zz_ file would emit an unconditional reference to a + // symbol the normal build doesn't compile. + if entry.IsDir() || !strings.HasSuffix(entry.Name(), ".go") || + strings.HasSuffix(entry.Name(), "_test.go") || + strings.HasPrefix(entry.Name(), "zz_") { + continue + } + + fpath := filepath.Join(srcDir, entry.Name()) + src, err := os.ReadFile(fpath) + if err != nil { + return fmt.Errorf("read %s: %w", fpath, err) + } + + // Files under a build constraint may reference symbols absent from + // other targets; the registrar compiles unconditionally, so skip them. + if hasBuildConstraint(src) { + continue + } + + specs, err := scanSource(fpath, src) + if err != nil { + return fmt.Errorf("parse %s: %w", fpath, err) + } + allSpecs = append(allSpecs, specs...) + } + + if len(allSpecs) == 0 { + fmt.Printf("lgprimgen: no //lg:native directives found in %s; generating empty stub\n", srcDir) + // Fall through to generate an empty RegisterGeneratedPrimitives() stub + } + + for i := range allSpecs { + if goPkg != "" { + allSpecs[i].GoPkg = goPkg + } else if allSpecs[i].GoPkg == "" { + allSpecs[i].GoPkg = "github.com/nooga/let-go/pkg/rt/builtins" + } + } + + output := emitFile(allSpecs) + + formatted, err := gofmtCode(output) + if err != nil { + return fmt.Errorf("gofmt: %w", err) + } + + if err := os.MkdirAll(filepath.Dir(outPath), 0755); err != nil { + return fmt.Errorf("mkdir %s: %w", filepath.Dir(outPath), err) + } + if err := os.WriteFile(outPath, []byte(formatted), 0644); err != nil { + return fmt.Errorf("write %s: %w", outPath, err) + } + + fmt.Printf("lgprimgen: generated primitives → %s (%d specs)\n", outPath, len(allSpecs)) + return nil +} + +// ScanNativeNames returns the set of let-go names already claimed by //lg:native +// declarations in dir's Go sources, skipping excludeBase (a file basename, e.g. +// "lang.go"). The hoist codemod uses it to avoid hoisting a closure whose +// lg-name a pre-existing native decl already owns — doing so would emit a +// duplicate registration and fail to compile the generated registrar. Reuses +// the same scanner lgprimgen runs, so both agree on what a name is. +func ScanNativeNames(dir, excludeBase string) (map[string]bool, error) { + names := map[string]bool{} + entries, err := os.ReadDir(dir) + if err != nil { + return nil, err + } + for _, entry := range entries { + if entry.IsDir() || !strings.HasSuffix(entry.Name(), ".go") || + strings.HasSuffix(entry.Name(), "_test.go") || + strings.HasPrefix(entry.Name(), "zz_") || + entry.Name() == excludeBase { + continue + } + fpath := filepath.Join(dir, entry.Name()) + src, err := os.ReadFile(fpath) + if err != nil { + return nil, err + } + if hasBuildConstraint(src) { + continue + } + specs, err := scanSource(fpath, src) + if err != nil { + return nil, err + } + for _, s := range specs { + names[s.LgName] = true + } + } + return names, nil +} + +// gofmtCode formats Go source code using the gofmt command. On failure it +// surfaces gofmt's stderr (which carries the :: syntax-error +// location) and dumps the unformatted source to a temp file, so a bad emitted +// registrar is diagnosable instead of a bare "exit status 2". +func gofmtCode(src string) (string, error) { + cmd := exec.Command("gofmt") + cmd.Stdin = strings.NewReader(src) + var stderr strings.Builder + cmd.Stderr = &stderr + output, err := cmd.Output() + if err != nil { + dump := filepath.Join(os.TempDir(), "lgprimgen-unformatted.go") + _ = os.WriteFile(dump, []byte(src), 0644) + return "", fmt.Errorf("gofmt failed: %w\n%s(unformatted source written to %s)", err, stderr.String(), dump) + } + return string(output), nil +} diff --git a/cmd/lginterop/prims_emit.go b/internal/primgen/prims_emit.go similarity index 99% rename from cmd/lginterop/prims_emit.go rename to internal/primgen/prims_emit.go index a73892cdf..74f44f0e0 100644 --- a/cmd/lginterop/prims_emit.go +++ b/internal/primgen/prims_emit.go @@ -1,4 +1,4 @@ -package main +package primgen import ( "fmt" @@ -488,11 +488,11 @@ func generateAritySpecificAdapter(spec *primSpec, arity int, pkgAliasMap map[str fmt.Fprintf(&b, "%s", varName) } - // Add variadic arguments: pass remaining vs elements + // Add variadic arguments: pass remaining vs elements, then close the call. if len(spec.ParamSpecs) > 0 { - fmt.Fprintf(&b, ", vs[%d:]...\n", len(spec.ParamSpecs)) + fmt.Fprintf(&b, ", vs[%d:]...)\n", len(spec.ParamSpecs)) } else { - b.WriteString("vs...\n") + b.WriteString("vs...)\n") } } else { // Non-variadic: standard parameter coercion diff --git a/cmd/lginterop/prims_scan.go b/internal/primgen/prims_scan.go similarity index 99% rename from cmd/lginterop/prims_scan.go rename to internal/primgen/prims_scan.go index 26220a438..c0e320069 100644 --- a/cmd/lginterop/prims_scan.go +++ b/internal/primgen/prims_scan.go @@ -1,4 +1,4 @@ -package main +package primgen import ( "bytes" @@ -90,7 +90,7 @@ func scanSource(path string, src []byte) ([]primSpec, error) { // Determine lg name (default: kebab-cased GoIdent) lgName := name if lgName == "" { - lgName = kebabCase(goIdent) + lgName = KebabCase(goIdent) } // Parse parameters diff --git a/cmd/lginterop/prims_test.go b/internal/primgen/prims_test.go similarity index 99% rename from cmd/lginterop/prims_test.go rename to internal/primgen/prims_test.go index f36d1950d..3d7ac9603 100644 --- a/cmd/lginterop/prims_test.go +++ b/internal/primgen/prims_test.go @@ -1,4 +1,4 @@ -package main +package primgen import ( "go/parser" diff --git a/scripts/generate.lg b/scripts/generate.lg index 0c2a03e4b..21195eca7 100644 --- a/scripts/generate.lg +++ b/scripts/generate.lg @@ -141,9 +141,15 @@ (gen-go "scripts/gen/ir_bridge_generated.head" "pkg/ir/ir_bridge.lg" "pkg/rt/ir_bridge_generated.go") (gen-lisp "pkg/ir/ir_data.lg" "pkg/rt/core/ir/data/generated.lg") -;; Invoke cmd/lginterop -primitives to generate the primitive registrar. -;; Scans pkg/rt for //lg:native-annotated functions and generates adapters + registrations. -(run! go-bin "run" "./cmd/lginterop" "-primitives" "pkg/rt" "-go-pkg" "github.com/nooga/let-go/pkg/rt" "-primitives-out" "pkg/rt/zz_primitives_generated.go") +;; Invoke cmd/lgprimgen to generate the primitive registrar. +;; Scans pkg/rt for //lg:native-annotated functions and generates adapters + +;; registrations. lgprimgen is a PURE go/ast codegen tool that does NOT import +;; the runtime (pkg/compiler / pkg/rt) — so it runs even mid-migration, when +;; primitives have been moved out of installLangNS but the registrar that +;; replaces them has not been generated yet and the runtime cannot boot. Using +;; the runtime-coupled cmd/lginterop here would make this step depend on the +;; very artifact it produces. +(run! go-bin "run" "./cmd/lgprimgen" "-primitives" "pkg/rt" "-go-pkg" "github.com/nooga/let-go/pkg/rt" "-primitives-out" "pkg/rt/zz_primitives_generated.go") ;; One core compile emits BOTH the .lgb bundle and the gogen_ir Go tree. ;; Hermetic generation (clearing the stale lowered-tree before regen) is From 54444ba71835066db13fba57b5beee39afde630b Mon Sep 17 00:00:00 2001 From: "Norman Nunley, Jr" Date: Thu, 23 Jul 2026 15:00:58 -0400 Subject: [PATCH 6/8] feat(cmd/hoist-natives): safety analysis for the //lg:native hoist Harden the codemod so it only lifts closures that are genuinely safe to lift, leaving the rest untouched. Skip / demote a candidate when: - its lg-name is registered under MULTIPLE names (hoisting one //lg:name would drop the others from clojure.core); - its lg-name is already owned by a pre-existing //lg:native decl (duplicate registration, the generated registrar fails to compile); - it is fetched BY lg-name via a .Lookup string arg anywhere in the package, possibly another file, before the generated registrar runs (would be nil); - it is redefined by a stdlib .lg source; the eager core reapply skips it, so a guarded native there would deviate permanently (native-prims-intact? false); - its local var is still referenced by surviving code (a 2nd registration, a helper, a skipped closure body), removing it would leave an undefined ident. Also: strip the dead err-guard(s) left when a hoisted Wrap assignment is cut, emit EXPORTED CoreX names (the gogen_ir lowered tree direct-calls them as rt.Core-prefixed funcs), and reuse internal/primgen scanner so the codemod and lgprimgen agree on what a name is. --- cmd/hoist-natives/main.go | 329 +++++++++++++++++++++++++++++++++++++- 1 file changed, 325 insertions(+), 4 deletions(-) diff --git a/cmd/hoist-natives/main.go b/cmd/hoist-natives/main.go index 72916488b..857f7ec6c 100644 --- a/cmd/hoist-natives/main.go +++ b/cmd/hoist-natives/main.go @@ -34,6 +34,8 @@ import ( "sort" "strconv" "strings" + + "github.com/nooga/let-go/internal/primgen" ) func main() { @@ -68,13 +70,26 @@ func main() { return } - defNames := collectNsDefNames(f) // fn-var name -> lg name + defNames := collectNsDefNames(f) // fn-var name -> lg name (last wins) + allNames := collectNsDefAllNames(f) // fn-var name -> every lg name + lookupNames := lookupNamesInPackage(*pkgDir) // lg-names fetched via .Lookup("…") + // lg-names a pre-existing //lg:native decl already owns (native_prims.go etc.), + // excluding the file we're hoisting into. A candidate colliding with one is a + // redundant second registration; hoisting it would emit a duplicate. + existingNative, err := primgen.ScanNativeNames(*pkgDir, filepath.Base(*file)) + if err != nil { + die("scan existing //lg:native names: %v", err) + } + // lg-names a stdlib .lg source redefines — shadowed at load and not covered + // by the eager core reapply, so hoisting+guarding them would deviate. + lgRedefined := lgRedefinedNames(filepath.Join(*pkgDir, "core")) sites := findNativeFnSites(f) var safe []*site skipCap := map[string][]string{} // var -> captured names var skipNoName []string + var skipMulti []string for _, s := range sites { if onlyRe != nil { lg := defNames[s.varName] @@ -87,6 +102,31 @@ func main() { skipNoName = append(skipNoName, s.varName) continue } + if len(allNames[s.varName]) > 1 { + // Registered under multiple names — hoisting to one //lg:name would + // silently drop the others from clojure.core. Leave it in place. + skipMulti = append(skipMulti, fmt.Sprintf("%s (%s)", s.varName, strings.Join(allNames[s.varName], "/"))) + continue + } + if lookupNames[lg] { + // Fetched by lg-name via `.Lookup("")` somewhere in the package + // (possibly another file) at init time, before the generated + // registrar runs — hoisting would leave that lookup nil. + skipMulti = append(skipMulti, fmt.Sprintf("%s (Lookup %q)", s.varName, lg)) + continue + } + if existingNative[lg] { + // Name already owned by a pre-existing //lg:native decl — hoisting + // this redundant registration would emit a duplicate in the registrar. + skipMulti = append(skipMulti, fmt.Sprintf("%s (dup of //lg:native %q)", s.varName, lg)) + continue + } + if lgRedefined[lg] { + // Shadowed by a stdlib .lg (defn %q) at load; the eager core reapply + // skips it, so a guarded native here deviates permanently. + skipMulti = append(skipMulti, fmt.Sprintf("%s (redefined in .lg %q)", s.varName, lg)) + continue + } s.lgName = lg captured := freeVars(s.lit, pkgNames) if len(captured) > 0 { @@ -95,8 +135,24 @@ func main() { } safe = append(safe, s) } + if len(skipMulti) > 0 { + sort.Strings(skipMulti) + fmt.Printf("-- skipped: registered under multiple lg-names (would drop names) --\n %s\n\n", strings.Join(skipMulti, ", ")) + } + + // Demote any safe var still referenced by code that survives the rewrite. + // The rewrite removes only the var's own `X, err := …Wrap(…)` assignment and + // its single `ns.Def("name", X)` registration; a var referenced anywhere else + // — a second registration (`lgCore.Def("gt", gt)`), a helper, or a skipped + // site's closure body — would become an undefined identifier. freeVars flags + // captures WITHIN a hoisted closure; this flags uses OF the var by others. + safe, skipRef := demoteSurvivingRefs(f, safe) report(fset, safe, skipCap, skipNoName, defNames) + if len(skipRef) > 0 { + sort.Strings(skipRef) + fmt.Printf("-- skipped: still referenced by surviving code (2nd registration / helper / captured by a skip) --\n %s\n\n", strings.Join(skipRef, ", ")) + } if *apply { if err := rewrite(*file, fset, f, safe, defNames); err != nil { @@ -152,6 +208,88 @@ func findNativeFnSites(f *ast.File) []*site { return out } +// demoteSurvivingRefs returns the subset of safe whose local var is referenced +// ONLY by its own assignment target and the single `ns.Def("name", X)` call the +// rewrite cuts, plus the names it demoted. A var referenced by any surviving +// identifier (a second registration, a helper, or a skipped closure body) is +// not hoistable — removing its local would leave that reference undefined. +func demoteSurvivingRefs(f *ast.File, safe []*site) (kept []*site, demoted []string) { + byVar := map[string]*site{} + for _, s := range safe { + byVar[s.varName] = s + } + // Identifiers the rewrite removes: each safe assign's target and the arg of + // the single ns.Def(name, X) it cuts. Every OTHER occurrence survives. + accounted := map[*ast.Ident]bool{} + for _, s := range safe { + if id, ok := s.assign.Lhs[0].(*ast.Ident); ok { + accounted[id] = true + } + } + ast.Inspect(f, func(n ast.Node) bool { + call, ok := n.(*ast.CallExpr) + if !ok || len(call.Args) != 2 { + return true + } + sel, ok := call.Fun.(*ast.SelectorExpr) + if !ok || sel.Sel.Name != "Def" { + return true + } + if id, ok := sel.X.(*ast.Ident); !ok || id.Name != "ns" { + return true + } + if arg, ok := call.Args[1].(*ast.Ident); ok && byVar[arg.Name] != nil { + accounted[arg] = true + } + return true + }) + survives := map[string]bool{} + ast.Inspect(f, func(n ast.Node) bool { + id, ok := n.(*ast.Ident) + if !ok || byVar[id.Name] == nil || accounted[id] { + return true + } + survives[id.Name] = true + return true + }) + + // A primitive is also un-hoistable if surviving code fetches it BY LG-NAME + // via `ns.Lookup("name")` — for post-registration mutation (`.SetMacro()`) + // or to alias it under another name. installLangNS runs before the generated + // registrar, so such a lookup would hit an unregistered var. These references + // are string literals, invisible to the identifier scan above. + byLg := map[string]*site{} + for _, s := range safe { + byLg[s.lgName] = s + } + ast.Inspect(f, func(n ast.Node) bool { + call, ok := n.(*ast.CallExpr) + if !ok || len(call.Args) != 1 { + return true + } + sel, ok := call.Fun.(*ast.SelectorExpr) + if !ok || sel.Sel.Name != "Lookup" { + return true + } + lit, ok := call.Args[0].(*ast.BasicLit) + if !ok || lit.Kind != token.STRING { + return true + } + if name, err := strconv.Unquote(lit.Value); err == nil && byLg[name] != nil { + survives[byLg[name].varName] = true + } + return true + }) + for _, s := range safe { + if survives[s.varName] { + demoted = append(demoted, s.varName) + continue + } + kept = append(kept, s) + } + return kept, demoted +} + // classifyBoxer returns ("Wrap"|"WrapNoErr"|"NewCtxNativeFn", isCtx) or ("",_). func classifyBoxer(fun ast.Expr) (string, bool) { sel, ok := fun.(*ast.SelectorExpr) @@ -172,6 +310,40 @@ func classifyBoxer(fun ast.Expr) (string, bool) { return "", false } +// collectNsDefAllNames maps a registered fn-var to EVERY clojure name it is +// Def'd under. A var registered under several names (`ns.Def("int", intf)`, +// `ns.Def("byte", intf)`, `ns.Def("short", intf)`) can't be hoisted to a single +// //lg:native decl without dropping names, so the caller skips multi-name vars. +func collectNsDefAllNames(f *ast.File) map[string][]string { + out := map[string][]string{} + ast.Inspect(f, func(n ast.Node) bool { + call, ok := n.(*ast.CallExpr) + if !ok || len(call.Args) != 2 { + return true + } + sel, ok := call.Fun.(*ast.SelectorExpr) + if !ok || sel.Sel.Name != "Def" { + return true + } + if nsID, ok := sel.X.(*ast.Ident); !ok || nsID.Name != "ns" { + return true + } + lit, ok := call.Args[0].(*ast.BasicLit) + if !ok || lit.Kind != token.STRING { + return true + } + valID, ok := call.Args[1].(*ast.Ident) + if !ok { + return true + } + if name, err := strconv.Unquote(lit.Value); err == nil { + out[valID.Name] = append(out[valID.Name], name) + } + return true + }) + return out +} + // collectNsDefNames maps a registered fn-var to its clojure name from // `ns.Def("name", fnvar)` call sites. func collectNsDefNames(f *ast.File) map[string]string { @@ -331,6 +503,76 @@ var universe = strSet( // --- package-level name collection --------------------------------------- +// lookupNamesInPackage collects every string literal passed to a `.Lookup("…")` +// call across all non-test .go files in dir. A primitive named by any of these +// lgRedefinedNames collects every name defined by a (def…)/(defn…)/(defmacro…) +// form in the stdlib .lg sources under dir/core. A primitive whose lg-name is +// redefined in core.lg is shadowed by that bootstrap definition at load; the +// eager core-namespace load does NOT reapply the native root over it (see +// coreload.go, which skips NameCoreNS), so a hoisted+guarded native there would +// deviate permanently (native-prims-intact? => false). On main these primitives +// were hand-registered but unguarded, so the .lg definition silently won — the +// behavior-preserving choice is to leave them un-hoisted. +func lgRedefinedNames(coreDir string) map[string]bool { + names := map[string]bool{} + re := regexp.MustCompile(`\(def(?:n|macro)?-?\s+([^\s()]+)`) + entries, err := os.ReadDir(coreDir) + if err != nil { + return names + } + for _, e := range entries { + if e.IsDir() || !strings.HasSuffix(e.Name(), ".lg") { + continue + } + src, err := os.ReadFile(filepath.Join(coreDir, e.Name())) + if err != nil { + continue + } + for _, m := range re.FindAllStringSubmatch(string(src), -1) { + names[m[1]] = true + } + } + return names +} + +// is fetched by lg-name at init time — possibly from ANOTHER file (host_core_fns +// aliases `class` to `ns.Lookup("type")`) before the generated registrar runs — +// so it must not be hoisted. Best-effort union across files. +func lookupNamesInPackage(dir string) map[string]bool { + names := map[string]bool{} + entries, err := os.ReadDir(dir) + if err != nil { + return names + } + fset := token.NewFileSet() + for _, e := range entries { + if e.IsDir() || !strings.HasSuffix(e.Name(), ".go") || strings.HasSuffix(e.Name(), "_test.go") { + continue + } + f, err := parser.ParseFile(fset, filepath.Join(dir, e.Name()), nil, 0) + if err != nil { + continue + } + ast.Inspect(f, func(n ast.Node) bool { + call, ok := n.(*ast.CallExpr) + if !ok || len(call.Args) != 1 { + return true + } + sel, ok := call.Fun.(*ast.SelectorExpr) + if !ok || sel.Sel.Name != "Lookup" { + return true + } + if lit, ok := call.Args[0].(*ast.BasicLit); ok && lit.Kind == token.STRING { + if name, err := strconv.Unquote(lit.Value); err == nil { + names[name] = true + } + } + return true + }) + } + return names +} + func packageLevelNames(dir string) (map[string]bool, error) { names := map[string]bool{} entries, err := os.ReadDir(dir) @@ -464,11 +706,14 @@ func renderResults(fset *token.FileSet, results *ast.FieldList) string { } func hoistName(varName string) string { - // plus -> corePlus, excludeInCurrentNs -> coreExcludeInCurrentNs + // plus -> CorePlus, excludeInCurrentNs -> CoreExcludeInCurrentNs. + // EXPORTED (capital C): the gogen_ir lowered tree lives in sibling packages + // that direct-call these primitives as `rt.Core…`, so an unexported name + // would be invisible there (undefined: rt.corePlus). if varName == "" { - return "coreFn" + return "CoreFn" } - return "core" + strings.ToUpper(varName[:1]) + varName[1:] + return "Core" + strings.ToUpper(varName[:1]) + varName[1:] } // --- rewrite (apply) ------------------------------------------------------ @@ -509,6 +754,60 @@ func rewrite(path string, fset *token.FileSet, f *ast.File, safe []*site, defNam return true }) + // Cut `if err != nil { … }` guards left dead by the removal. An `err` local + // is typically threaded through every Wrap assignment in a block — each with + // its own `if err != nil { panic(err) }`, plus a trailing consolidated + // `if err != nil { panic("… failed") }`. Once every assignment that DECLARES + // that err (via `:=`) is cut and no surviving `:=` redeclares it, the name is + // undefined and all its guards are dead. Work per block: a name declared only + // by cut assigns (and by no surviving `:=`) is orphaned, so cut every + // `if != nil {…}` guard in that block. Scoped this way, a guard whose + // err still has a live declaration is never touched. + safeAssigns := map[*ast.AssignStmt]bool{} + for _, s := range safe { + safeAssigns[s.assign] = true + } + declaredNames := func(as *ast.AssignStmt) []string { + if as.Tok != token.DEFINE { + return nil + } + var ns []string + for _, l := range as.Lhs { + if id, ok := l.(*ast.Ident); ok && id.Name != "_" { + ns = append(ns, id.Name) + } + } + return ns + } + ast.Inspect(f, func(n ast.Node) bool { + blk, ok := n.(*ast.BlockStmt) + if !ok { + return true + } + cutDecl, surviveDecl := map[string]bool{}, map[string]bool{} + for _, st := range blk.List { + as, ok := st.(*ast.AssignStmt) + if !ok { + continue + } + names := declaredNames(as) + target := surviveDecl + if safeAssigns[as] { + target = cutDecl + } + for _, nm := range names { + target[nm] = true + } + } + for _, st := range blk.List { + name := errGuardName(st) + if name != "" && cutDecl[name] && !surviveDecl[name] { + cuts = append(cuts, span{lineStart(src, fset.Position(st.Pos()).Offset), lineEnd(src, fset.Position(st.End()).Offset)}) + } + } + return true + }) + sort.Slice(cuts, func(i, j int) bool { return cuts[i].start > cuts[j].start }) out := append([]byte(nil), src...) for _, c := range cuts { @@ -531,6 +830,28 @@ func rewrite(path string, fset *token.FileSet, f *ast.File, safe []*site, defNam return os.WriteFile(path, formatted, 0644) } +// errGuardName returns the identifier name X for a statement of the exact shape +// `if X != nil { … }` (no init/else), or "" otherwise. The caller decides +// whether X is orphaned before cutting, so this only classifies the shape. +func errGuardName(s ast.Stmt) string { + ifs, ok := s.(*ast.IfStmt) + if !ok || ifs.Init != nil || ifs.Else != nil { + return "" + } + bin, ok := ifs.Cond.(*ast.BinaryExpr) + if !ok || bin.Op != token.NEQ { + return "" + } + x, ok := bin.X.(*ast.Ident) + if !ok { + return "" + } + if y, ok := bin.Y.(*ast.Ident); !ok || y.Name != "nil" { + return "" + } + return x.Name +} + func lineStart(src []byte, off int) int { for off > 0 && src[off-1] != '\n' { off-- From f4be95a89282983195892f13b9e66e9916422a72 Mon Sep 17 00:00:00 2001 From: "Norman Nunley, Jr" Date: Thu, 23 Jul 2026 15:00:58 -0400 Subject: [PATCH 7/8] feat(vm,rt): guard-deviation diagnostics for native primitives Hoisting closures into //lg:native decls adds them to the guarded native-root set, so a primitive shadowed at load (not restored by reapply) trips native-prims-intact? with no clue which one. Add the diagnostics that pinpoint it: - vm.Var.GuardDeviated() + Namespace.AllVars(): read whether a guarded root deviated from its canonical value, and snapshot every interned var. - rt.deviatedGuardedVars() + LG_GUARD_DEBUG: on the off-fast-path branch of NativePrimsIntact(), name the deviated primitive(s) to stderr instead of a bare intact=false. The fast path stays a single atomic load. --- pkg/rt/native_prims_lifecycle.go | 40 +++++++++++++++++++++++++++++++- pkg/vm/namespace.go | 11 +++++++++ pkg/vm/var.go | 5 ++++ 3 files changed, 55 insertions(+), 1 deletion(-) diff --git a/pkg/rt/native_prims_lifecycle.go b/pkg/rt/native_prims_lifecycle.go index 6aa583846..33abefd17 100644 --- a/pkg/rt/native_prims_lifecycle.go +++ b/pkg/rt/native_prims_lifecycle.go @@ -45,7 +45,45 @@ var ( // emitted for native-module callees consult this before taking the baked // direct call; on false they fall back to the var-dispatch trampoline so the // override is observed across lowered function boundaries. -func NativePrimsIntact() bool { return vm.GuardedRootsIntact() } +func NativePrimsIntact() bool { + if vm.GuardedRootsIntact() { + return true + } + // Off the fast path (a root deviated): under LG_GUARD_DEBUG, name the + // offending native primitive(s) — the diagnostic that pinpoints which + // hoisted primitive is being shadowed instead of a bare intact=false. + if guardDebug { + fmt.Fprintf(os.Stderr, "[GUARD] deviated: %v\n", deviatedGuardedVars()) + } + return false +} + +var guardDebug = os.Getenv("LG_GUARD_DEBUG") != "" + +// deviatedGuardedVars lists every interned var whose guarded root has deviated +// from its canonical native root, "/". Diagnostic only. +func deviatedGuardedVars() []string { + nsMu.RLock() + names := make([]string, 0, len(nsRegistry)) + for k := range nsRegistry { + names = append(names, k) + } + nsMu.RUnlock() + var dev []string + for _, nsName := range names { + ns := LookupNS(nsName) + if ns == nil { + continue + } + for sym, v := range ns.AllVars() { + if v.GuardDeviated() { + dev = append(dev, nsName+"/"+string(sym)) + } + } + } + sort.Strings(dev) + return dev +} // guardModuleVars marks the CURRENT root of every var a native module // direct-calls (corefns seq/first/…, builtins vector/cons/…) as canonical, diff --git a/pkg/vm/namespace.go b/pkg/vm/namespace.go index e0ff4c287..5ad4c404c 100644 --- a/pkg/vm/namespace.go +++ b/pkg/vm/namespace.go @@ -518,6 +518,17 @@ func (n *Namespace) PublicVars() map[Symbol]*Var { return out } +// AllVars snapshots every interned var (public and private). Diagnostic use. +func (n *Namespace) AllVars() map[Symbol]*Var { + n.mu.RLock() + defer n.mu.RUnlock() + out := make(map[Symbol]*Var, len(n.registry)) + for k, v := range n.registry { + out[k] = v + } + return out +} + func FuzzySymbolLookup(ns *Namespace, s Symbol, lookupPrivate bool) []Symbol { ret := []Symbol{} for _, r := range ns.refersSnapshot() { diff --git a/pkg/vm/var.go b/pkg/vm/var.go index e89681ccd..770b3e64a 100644 --- a/pkg/vm/var.go +++ b/pkg/vm/var.go @@ -28,6 +28,11 @@ var guardedRootDeviations atomic.Int64 // guards in the lowered tree. func GuardedRootsIntact() bool { return guardedRootDeviations.Load() == 0 } +// GuardDeviated reports whether this guarded var's current root differs from the +// canonical root captured by GuardRoot. Diagnostic use: identify which native +// primitive an intact-check failure attributes to. +func (v *Var) GuardDeviated() bool { return v.guardDeviated.Load() } + type Var struct { // root is atomic so Deref — by far the hottest var operation — is // lock-free. Dynamic (thread-local) bindings no longer live on the Var; From 6162d6c4ef35e6baa7cec9090dc38d98ed4d6b7b Mon Sep 17 00:00:00 2001 From: "Norman Nunley, Jr" Date: Thu, 23 Jul 2026 15:00:58 -0400 Subject: [PATCH 8/8] feat(rt): hoist 222 clojure.core primitives to named //lg:native decls Lift the inline anonymous closures registered as clojure.core primitives in lang.go into named, //lg:native-annotated top-level functions (via cmd/hoist-natives). Three wins: real stack-trace frames (rt.CorePlus, not installLangNS.func42); declarative registration (the ns.Def call is dropped, the generated registrar owns it); and the closures narrow toward typed/ec-threaded signatures. Regenerates zz_primitives_generated.go, the bundle, and the sums. 222 closures were classified safe by the codemod; the analysis skipped the rest (multi-name aliases, //lg:native duplicates, .Lookup-by-name, stdlib-.lg redefinitions, surviving-reference captures). Verified: make check-generated OK on both artifacts; clojure.core surface unchanged at 807 publics; native-prims-intact? true at boot and after (require clojure.string); full go test ./... green. --- pkg/rt/core_compiled.lgb | Bin 259190 -> 262249 bytes pkg/rt/generated.sums | 2 +- pkg/rt/lang.go | 8009 +++++++++++++++-------------- pkg/rt/native_prims.go | 295 -- pkg/rt/zz_primitives_generated.go | 3443 +++++++++++-- 5 files changed, 7282 insertions(+), 4467 deletions(-) diff --git a/pkg/rt/core_compiled.lgb b/pkg/rt/core_compiled.lgb index 405480a5bffa1de7b3f37f3a7cda034798b8b05a..1b22eacff600de4471e3e09019beb6845a4eecf2 100644 GIT binary patch delta 6134 zcmcIod3;qxvhME6xhJT^1P*XR3dUigu!`fBOw>gwg> z{E6x(^VF&%U3h5q(Jm^>f62!fr++_(F3n1AdzqvdlK$(qrG~=PvIe)Cp8DoBlzVw zO@qfr;0Xp#jKGr&o_qryL!;hAvYu#dmx?5&XU-Wgnj6t5mf|{EEHyNGPVyh?xDsb| ziFydC7kBq>dH~6U4rG-~Ge<8GLescTKE-2VPhywi+RE4Ta}5MN<a!@A zv^2tMnXxLdr@tOdTos`$HQKjBt&2w0eut#%qjTC{jAc+N`goZa+F6tw(D`x7&+m2` zuy;e3i;@$=CQ34)H`ZcJsOh3qzE=P4u+G?c+f%Uht_-Y(8!3uyaAnKLK33++wvnUR zpwLQ+RUX<&zc;#ZEA;O+n@rsIh~7B%W`n;Ufp0PR$D!)Q@eQ6Qkh?U0ThX~Jq8T^d)tgWR;&mWD& zIoCo=0On* zKinA<7t+Qd_dvObwXu6mLhtMXN4fCZ*q|#+5yHlIyTWRzuBCvbc|3@a>k0~Lf4zUM_(J@>AmtirRuaTKC8GVFsw!WfzQV5h@b=a` zsalL)O4pNWZDR+To}Nl}cPiJ=9+1gtoK^QhEiS6t*ms8r60Hgxg_CRZ7_=UMroXR! z`v25^`2eKxdYIJ{8e*%SkihF`z6(#s**zguq}!O+7lPR4K}f)pTHnZ1G`g;6#v6NB zFxww_$Zc+O?pwEH_{{($MwXs{YYYTjLMCVKr}wMSY+(b#$oUVoLZ@AGn3{wpjmB z_=UF#Q}@i_yd9Q34z2y|DQBD7=5CzU58|=^CZX_jg^0pG^n;qUZYQlIz1~?3^c#%+ zXJYq$lu`$r*bh4Kj<~xYwBUE3^#rX=IyQa+QhC!QU7rB%4VA`mM1N?>GjUmeNT*@< z^(TueLnOmAY&QUMcpKf;Q?dO(Xy#T@@7ufa*@2Kv)=i(Jj&FxY2I}Z|bs!{*b~d&@ zB!V-6M`6YwxXrUlqk-lOa;?@6f^<8RW&kV}7luVG6i-4Uo*t%Pit{eGZ~|?|Rgdzh z=2f?dUO`>PMlQ8jW0(3^6PMbosY|07E&GDQw5sz5LyN>L0;{fjedH)AmOcz_!&8Hy zQ)2e-sQ-*zhEN^v(bKMhnboM~vxm^KHng!@Ur0jr6isZ~5J(W6Y+U#fAG{*goB zZ@fA79txvHS9|8Sltt$s=`h%Nnv^w%QGk1G+>{}bFmo8p;MLv30xLk7=7U?Ad|3snaT+fLou2tZO4ap+{`R`{8{fpi^J~4H82qQA=}{55yHC zsFix+z7ddJcTj}(Ns{$(r{7lkq#ulTJp;Xe6J&@ElIm|_mZCczeg?7|Mg|)i5p0+{ zn2*KTc>lAoMD(Ylvkgzer03vPF~G)Qk5gGw&x+_kq8pgA;U>MOal&)(nCNHY(8aVO zVk9&RjBumdCe>*64Bj!4=KCzcHeJ$sPjRBp;hd4MCsn^R^}(#4wEDi(Ke{aXB}?6f z-ClrNGuuKG7C#T;rG8FoZLW<|8&FbNqu`WyiAHZjLXQ_dA zDElj<%bNtzn3fCo^2s8*|3cG&1wR!PGHO%ID(l zF%aep!V||*2l0jBrQ@hw0{TU$lO9GVkWOb2ZXXXFe*+g|>PxW6U-eFWLl4;yYfPXn zET#zhRrh9?uyP()VIq3Af~^b>n+RX=z*`acY9zcl;v{J6zQyA4#HB4f$%5V$e5kmSYutuKwKeG_%d z14}fq6HM$xwi6$l0l9oPen~{^p+^6XCVaFjuNhu36aMnwPCDFtmZ`-5Q`XpIE}Zc1 zr`g6*A6CQC2|OMv?i4ZDv5=ky|Fp6608hae3n8EDuYp8Nn+MGU8{P7NDUV>E8fugMqT;C!gfsrOngfZoO_+Bo@*lVoM# zk_8l+mxqro1cw_tY3v+h7ejVYi{Lc>uY9K@VpcKuDA69pkb3hzcd}LAbb8k@c7QO= z9dxN+hj3Og)aQq>j64Dru1D27+G0nrvY7UdR~OEjxPP+|?5OJutPFQArn{`$Vu_XqDfPbqpQ$ zYv^2RM~}V{Z@|mqq_@Y+W>#hitD6p2>?CF_1r*=e_=w^e{1m1vgOz$~=iE^aX1hLiIF&bRHj5om85_dm0DS`HU2@WoSdqky;Wrc7H9xs6h`Dtvo9M*}SY>b%> zS>mjX(<Gl4mGj;fjBUitE1-U@i~ozN0xz$C{`}|g<0~Pyey*BG zkM2CFUhxS{Ci#GEi&ptW#!5ArbXWaq3XzL`HI>K&sS1d^EY&n3$1L?Gkx5d8$o;%u zy-I#WW{`BjuV#`&1j!_yt5O1|NHvyoHchJ8B>n7HzBxqC`Y~q@q~*Tjv)Dozh%1un zUGga+c9B$JALomReO(4ru~chFLu}mCXe$hAElE?O195N404tGd9f`!oEthINvCD~F zL7J7a`6{V45JFO1sZ?b&YALaAOI1$n+hp@fbZ&sXBYp2mwUMBF9*A2jRRytY$#9)i zn}}UU?0Tu*BX&Kp8>HGy>;_`Xqy^So|rZ=58ZtCn-Lc>SJO*C-$(kj!3ng zq{Ac~lj;-CV+WCAgdCUFm(u!5s+|NJC*W&oeIwN_&uX_v_D~jIlkSvk{=HP65_pQF zN(t4}UQ$((a9Re=G?YI|>nCZQmFhG4&?PADoV3nM>w;AK2slT;McMq4RQqx8UZ}_a zi3NKhCHDZW{WvEOH_1^4DfT4Cu4(5x_GBkebBd!5ktY$|3q-!4@rWGu0iQzpd{05- zC@H8C$24)&ank3LezK=0@|CCmnurcu;HYoB$$gtkPys>H9Cd=&X~a%<)Jf0&J0jBw z2|4PNXa7ARAwp(2s?xLhfyfL(UUSsHJmfT)zUJ7$Krk3!vz-8&A=DX~B>{6C^&=V0 zbppXcNBuMbGAvM}8)qqfl(G?j21>4=Oc z9g&wjX@W<#)7hNQt#yu?=mGjKegu5zSRXmoR>#`rs7W^GYbfY0$J*_vd@|TY(jLeD z)UozD_GgZooM{Wbhrs=gnqmXnPwYWQP4z++*uW1Ga>%hickC}5HI0Bn1RQpJM;zZ# XM@_fGE%rmhBz*rgj12cW1Bvh-d?Jpq delta 6074 zcmb_gd3;qxvhME6y(c**m~#W%kcEV0gb_s%FcEPS^$k2X5LXtTh#&&$5Fd)5NI+mz z2oSkSArJ@&Q6K~o0$d2{pbRMD$l?wN0To0*P!R+d=Ie8sWzLNM%uMpjt*Wnt)q8D0-?+pI^8C<&wan#^H1n^@9|1p4{F!)aa z{AVA(Qv4cFoH7nb(In&#EFtSzC!ED&kI%TYbuyAl0;X$VdsGQs6Ddf9po52SJl~K= zjy*LqQ`U>En~_uCo{a+=AtIiQ6sZBczQG#=@P-DD2Jke4X9w^cgE#SU8l7DF?->=44(q*aMY#5R~w%P|DNg ze8@OFY;6AIQ4&KunjrG6*n4+HGafN!|8LA5HD-@lvB~#EBg2gPaibm)ySF5*;0c3{ z1oaP#zl2X2d{h80F!-1N{*GpHi2YbHwc$jFdeVB^o}PALYaFj3*c<A{|jy>dy{~P244*=dM?k!K(xKQiHFIrIe?&(9+py`YXN4 zSgi4=5^q?s?7rDIYdC27rZL?DdhXy`4gNs@|Ipx{>cKD5QZV8+W3fHpxx?T)wP#~3 z1wD5ei#?u&mVy?a8;iYT*OouCwp_;7maC(so$BT2#XW+4s{5;d*C^4=TWtT1QRuJw zN21&6yGDsHcr9DFbNJwGl&!uAbMozUzI`^%v~4OH?|wVEQXLO-zdPu4bu!G|8vyNa zC)G)HEX+Es~sun#4gT*ErogJHfpPiFA%@1nHDPEuO& z^1jqis-MH$_dOK_JsmEAzqyY({+1$zAL>UJ{kC>{Kl+_anbx1KmG$u1iXZNeayH^A z{ZY>_=-f<9JEmbp%w~Ud^c=llIu;#pEFtxLOhm}2Fgt+c*)tJK%Qju)R{2=9F1I9N$ zhzw;*ZuBtyqFVUN9dG?78Yg8dUOEJ$T*zM!p)L(CLJ%7}TkrW6XucAEt+{hPEH36z z`G|4}ug|A;vJIcir; zkJEm2xyAX(D#|wvr^Hr%q6s1$q4hb;@Mu_MdeqNA7qGF#B|EVJUKmd8(mO(V`cBuK z#6?=V2VKB*!>LR9mA|2G%biAGE%Pj%n}$$RMquI7xI|;^Eq8&kN>5g=yri$zq^sR z+Dj$DD{L}8S3;4D+#7l?>;!QQ*B?pa&vcak(H*6|y3XS2nKGMy7>N_mB_4eW3vb`x zRYZy#Ek5;;%H~0%u$gb-AqChpR}v*!`WcO-lqWy}` zjC-5k$?`^1eRZqFDU&J6_l>4DkvlP{&RcIB{aU_@E5=YxQY%yN&b)Cnb!*xqVAT_{ z?)m<93W;9aaSZkOr(nHxu$J;Fet!&gYZVM~cOc0Bd4q(-sW9L4G`*tkKs)V#4wEvL zE?0MAPxZ&r&8--$bDX1%Osa5`tjxC0QU!M;S$!T zR)XHoMdN5|MjtPR6#8+i??e5g3)0o%O_L~_XN;%uwti1)@F9z*v_KZu{h1EPp?t|R zG*3Pf|KJ(ASjypA%;fCnXq$Qx+5QT<(JxRUXHB5n&cIeaCiJg*hGejoQGWi^@pG0vvDL!g4PM(|`pFM?AWu(w#oR2N0lPcmj zis;&Zf~V>wug^zzs06<7d0J=}!B4-=UNkx6AI3oWSvbL=sr0Np)u^Wj)$!M+63f(? zW>`Or60YRYK#MkNyq;cUiy25*zrSZ;bxK=8rF|~|TcrGN0yox7? ziumP>>B<^DGM)0$mqAS;3kmDAGfm6N5;gHoFHxG5%el!+%Ht_B(8OyzK7EDf(%iT- zGcL_V4d>59S6WYYuTf#eIvxuMydy5&LnNzqXYxKj%GO*2kvkQ4OD-@uKrr( za^20cLA-1(-SqFLaHNbL_)k;d=C9CK@~@mcpKeg=(3U<$TN*Z>3S~K7&*_}CfZ9eD zd9@)^8znYyp9R#eLpk8n4}9IN^^XIpuNl43^ow3^&;`JCPxN2-31U8PT!0Ndj}K__ zPTW~Yjis#M3o58jy6==|oRW-_Ef&V-R^Uoi6{gD_T|@_sv2BbUW1I}*6P0vC{#U+J zq+5C}Ld@eEswn6DwO%d!3*hwsN!ELXkm4;H#YusgcMwVr}<>? zm0qaRFXfPUm-kdrUWQ)*DK7S|5GDTRMJ0UU;qI9fz5YE<4tZaQY~1Dg3lpKW`3EH| zHhFqW=zgo;0wB;Q8GWMI?CF!R3{$JAdBp!hrp)&!5txH( zp8g=4@ZcJHR(<3jA#+Au6FS8l8drS8*DWJfAH!@m@{#>2jXR}M7I$4v zkE-PedKWg_lMC^HIJumPbmTLLT4Bx;z{-WP1)nOREIgFY6Y!gG9-4DXDW$s!Df(%k zzvb%Z_Vo#T^%TnB@p0Td+qg20_uFUOb|uxSI*Vm7byd49etr!)?d_|mTf;BlcRn_$ zUIzbFB*Y?Kxr&-M{PJI@D*4DN8YuV0d)89D=6v8YYFSVk4vD#TB(>Cb%aC3v*fQIl z7nZUN>^wW-mfLPQG+@wI)NbD35%kA(A+g${xP)1T$*={A+RWPiz-Nj&Q!LGL5 zC16*BebsiWz`hFhHQTM`EjuZz?NSW$I*@g?TLa}fup8{q1{r$C4sEpEWl(Pb_O9(N z2U{rJ6`Zq+ath**HbJq&c2|Pk0d}Vy+GV?|Ank;-+jeVxkJTW%f$XtEpWC4?Z1+_F zdjNcChxXd;YrfU%KKToh_!7DUcH4uty9VF^NQZ1X&wT@`LlBPGk#Aes-`Sz>?a)!% zeG~5^K&e02p<{OFxb3b5@B@G!?Y1Xu_piKf7d4aX*si1Og7sk%Qu9>~Tp$;r?c`U;T0L4iuVr-|ckg1!*?NxmLri?81b zq5~H>?)(1aJ}3ZG1n7Ck{SfT)V5d6nN51{XAX9>ecPC~EV3ybPJ1gW_u*v76cz=>It{aw3f?9rqygm0%Y;))L1W zBdsdOT9;&1JMN*dl8d2P>R2_7wOm@IDzprY6I$W8-@t9D;~qu^OJTFp39Z5!pv|Gw z-}*y-2OXsEed(xA-bDv2ERdmE$35mF$B|2+487%q-gZJ8oX|Ut`y-C!N<`i4gtj=Y zeo}9SwAHcRcS0XH)`yOJ61i;!_Oavsgz|k1cAMk=>__|sYrGA}cE{S`Sf4rWuK>0K b*y)6KIpI2o+*9Fr lazy seq 0, 1, 2, ... - return vm.NewInfiniteRange(0, 1), nil - } - if len(vs) > 3 { - return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) - } - var start, end, step vm.Int - step = 1 - var err error - var endArg vm.Value - switch len(vs) { - case 1: - endArg = vs[0] - case 2: - endArg = vs[1] - if start, err = rangeInt(vs[0], "start"); err != nil { - return vm.NIL, err - } - case 3: - endArg = vs[1] - if start, err = rangeInt(vs[0], "start"); err != nil { - return vm.NIL, err - } - if step, err = rangeInt(vs[2], "step"); err != nil { - return vm.NIL, err - } - } - // A float end still yields integers, like the JVM: infinite - // for ##Inf toward the step, else every int short of the end - // ((range 2 5.29) => 2 3 4 5). - if f, ok := endArg.(vm.Float); ok { - if math.IsInf(float64(f), 0) { - if (f > 0 && step > 0) || (f < 0 && step < 0) { - return vm.NewInfiniteRange(int(start), int(step)), nil - } - return vm.NewRange(0, 0, 1), nil - } - if step > 0 { - endArg = vm.Int(math.Ceil(float64(f))) - } else { - endArg = vm.Int(math.Floor(float64(f))) - } - } - if end, err = rangeInt(endArg, "end"); err != nil { - return vm.NIL, err - } - return vm.NewRange(start, end, step), nil - }) - - keyword, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - if len(vs) < 1 || len(vs) > 2 { - return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) - } - if len(vs) == 2 { - // (keyword ns name) — both must be strings (or nil ns) - var nsStr, nameStr string - if vs[0] != vm.NIL { - switch n := vs[0].(type) { - case vm.String: - nsStr = string(n) - default: - return vm.NIL, fmt.Errorf("keyword namespace must be a string, got %s", vs[0].Type()) - } - } - switch n := vs[1].(type) { - case vm.String: - nameStr = string(n) - default: - return vm.NIL, fmt.Errorf("keyword name must be a string, got %s", vs[1].Type()) - } - if nsStr == "" && vs[0] == vm.NIL { - return vm.Keyword(nameStr), nil - } - return vm.Keyword(nsStr + "/" + nameStr), nil - } - if vs[0] == vm.NIL { - return vm.NIL, nil - } - if k, ok := vs[0].(vm.Keyword); ok { - return k, nil - } - if k, ok := vs[0].(vm.Symbol); ok { - return vm.Keyword(k), nil - } - if k, ok := vs[0].(vm.String); ok { - return vm.Keyword(k), nil - } - return vm.NIL, fmt.Errorf("keyword expects keyword, symbol, or string, got %s", vs[0].Type()) - }) - - // symbol(name) or symbol(ns, name) - symbolf, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - if len(vs) < 1 || len(vs) > 2 { - return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) - } - toStr := func(v vm.Value) (string, bool) { - switch s := v.(type) { - case vm.String: - return string(s), true - case vm.Symbol: - return string(s), true - case vm.Keyword: - return string(s), true - default: - return "", false - } - } - if len(vs) == 1 { - if vs[0] == vm.NIL { - return vm.NIL, fmt.Errorf("symbol expected String, Symbol, Keyword, or Var") - } - if v, ok := vs[0].(*vm.Var); ok { - return vm.Symbol(externalNSName(v.NS()) + "/" + v.VarName()), nil - } - if s, ok := toStr(vs[0]); ok { - return vm.Symbol(s), nil - } - return vm.NIL, fmt.Errorf("symbol expected String or Symbol") - } - nsStr := "" - if vs[0] != vm.NIL { - ns, ok := vs[0].(vm.String) - if !ok { - return vm.NIL, fmt.Errorf("symbol expected String namespace") - } - nsStr = string(ns) - } - name, ok := vs[1].(vm.String) - if !ok { - return vm.NIL, fmt.Errorf("symbol expected String name") - } - nameStr := string(name) - if nsStr == "" && vs[0] == vm.NIL { - return vm.Symbol(nameStr), nil - } - return vm.Symbol(nsStr + "/" + nameStr), nil - }) - - assoc, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - if len(vs) < 3 || len(vs)%2 == 0 { - return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) - } - coll, ok := vs[0].(vm.Associative) - if !ok { - return vm.NIL, fmt.Errorf("assoc expected Associative") - } - ret := coll - for i := 1; i < len(vs); i += 2 { - ret = ret.Assoc(vs[i], vs[i+1]) - if ret == vm.NIL { - return vm.NIL, fmt.Errorf("assoc failed for key %s", vs[i].String()) - } - } - return ret, nil - }) - - dissoc, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - if len(vs) == 0 { - return vm.NIL, fmt.Errorf("wrong number of arguments 0") - } - if len(vs) == 1 { - return vs[0], nil - } - coll, ok := vs[0].(vm.Associative) - if !ok { - return vm.NIL, fmt.Errorf("dissoc expected Associative") - } - ret := coll - for i := 1; i < len(vs); i++ { - ret = ret.Dissoc(vs[i]) - if vs[0] != vm.NIL && ret == vm.NIL { - return vm.NIL, fmt.Errorf("dissoc failed for key %s", vs[i].String()) - } - } - return ret, nil - }) - update := vm.NewCtxNativeFn("update", func(ec *vm.ExecContext, vs []vm.Value) (vm.Value, error) { if len(vs) < 3 { return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) @@ -2895,13 +2113,6 @@ func installLangNS() { return colla.Assoc(key, v), nil }) - cons, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - if len(vs) != 2 { - return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) - } - return builtins.Cons(vs[0], vs[1]) - }) - conj, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { if len(vs) == 0 { return vm.ArrayVector{}, nil @@ -2941,46 +2152,6 @@ func installLangNS() { return seq, nil }) - disj, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - if len(vs) < 1 { - return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) - } - if vs[0] == vm.NIL { - return vm.NIL, nil - } - if len(vs) == 1 { - return vs[0], nil - } - switch s := vs[0].(type) { - case *vm.PersistentSet: - result := s - for _, v := range vs[1:] { - result = result.Disj(v) - } - return result, nil - case *vm.SortedSet: - result := s - for _, v := range vs[1:] { - result = result.Disj(v) - } - return result, nil - case vm.Set: - for _, v := range vs[1:] { - s = s.Disj(v) - } - return s, nil - default: - return vm.NIL, fmt.Errorf("disj expected Set") - } - }) - - contains, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - if len(vs) != 2 { - return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) - } - return builtins.Contains(vs[0], vs[1]) - }) - first, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { if len(vs) != 1 { return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) @@ -3008,23 +2179,24 @@ func installLangNS() { return vm.NIL, fmt.Errorf("first expected Seq") }) - second, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { + next, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { if len(vs) != 1 { return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) } if vs[0] == vm.NIL { return vm.NIL, nil } - // ArrayVector fast path: index the flat slice directly, no seq alloc. + // ArrayVector fast path: step in with one alloc instead of Seq()+Next(). if av, ok := vs[0].(vm.ArrayVector); ok { - if len(av) < 2 { + n := av.SeqFrom(1) + if n == nil { return vm.NIL, nil } - return av[1], nil + return n, nil } seq, err := seqOf(vs[0]) if err != nil { - return vm.NIL, fmt.Errorf("second expected Seq") + return vm.NIL, fmt.Errorf("next expected Seq") } if seq == nil { return vm.NIL, nil @@ -3033,39 +2205,10 @@ func installLangNS() { if n == nil { return vm.NIL, nil } - return n.First(), nil + return n, nil }) - next, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - if len(vs) != 1 { - return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) - } - if vs[0] == vm.NIL { - return vm.NIL, nil - } - // ArrayVector fast path: step in with one alloc instead of Seq()+Next(). - if av, ok := vs[0].(vm.ArrayVector); ok { - n := av.SeqFrom(1) - if n == nil { - return vm.NIL, nil - } - return n, nil - } - seq, err := seqOf(vs[0]) - if err != nil { - return vm.NIL, fmt.Errorf("next expected Seq") - } - if seq == nil { - return vm.NIL, nil - } - n := seq.Next() - if n == nil { - return vm.NIL, nil - } - return n, nil - }) - - rest, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { + rest, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { if len(vs) != 1 { return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) } @@ -3139,14 +2282,6 @@ func installLangNS() { return vm.Boolean(ok), nil }) - isList, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - if len(vs) != 1 { - return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) - } - _, ok := vs[0].(*vm.List) - return vm.Boolean(ok), nil - }) - isColl, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { if len(vs) != 1 { return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) @@ -3159,26 +2294,6 @@ func installLangNS() { return vm.Boolean(ok), nil }) - empty, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - if len(vs) != 1 { - return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) - } - if vs[0] == vm.NIL || vs[0].Type() == vm.StringType { - return vm.NIL, nil - } - if _, ok := vs[0].(*vm.InfiniteRange); ok { - return vm.EmptyList, nil - } - if _, ok := vs[0].(*vm.Record); ok { - return vm.NIL, fmt.Errorf("empty is not supported on records") - } - coll, ok := vs[0].(vm.Collection) - if !ok { - return vm.NIL, nil - } - return coll.Empty(), nil - }) - get, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { vl := len(vs) if vl < 2 || vl > 3 { @@ -3199,26 +2314,6 @@ func installLangNS() { return as.ValueAtOr(key, vs[2]), nil }) - keyf, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - if len(vs) != 1 { - return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) - } - if e, ok := vs[0].(vm.MapEntry); ok { - return e.Key, nil - } - return vm.NIL, fmt.Errorf("key expects map entry") - }) - - valf, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - if len(vs) != 1 { - return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) - } - if e, ok := vs[0].(vm.MapEntry); ok { - return e.Value, nil - } - return vm.NIL, fmt.Errorf("val expects map entry") - }) - // nth: indexed access that works on any sequential type. // Fast path for vectors (O(1)), linear walk for seqs (O(n)). nthf, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { @@ -3276,23 +2371,6 @@ func installLangNS() { return notFound, nil }) - count, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - if len(vs) != 1 { - return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) - } - if vs[0] == vm.NIL { - return vm.MakeInt(0), nil - } - if s, ok := vs[0].(vm.String); ok { - return vm.MakeInt(len([]rune(string(s)))), nil - } - seq, ok := vs[0].(vm.Counted) - if !ok { - return vm.NIL, fmt.Errorf("count expected Counted") - } - return seq.Count(), nil - }) - // map builtin: always lazy. Clojure semantics require laziness on all // inputs — small counted collections must still defer realization so // consumers (rose trees, short-circuit take, side-effecting f) work. @@ -3624,138 +2702,17 @@ func installLangNS() { return nns, nil }) - excludeInCurrentNs, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - cns := CurrentNS.Deref().(*vm.Namespace) - for _, v := range vs { - sym, ok := v.(vm.Symbol) - if !ok { - return vm.NIL, fmt.Errorf("exclude-in-current-ns expected Symbol, got %s", v.Type().Name()) - } - cns.Exclude(string(sym)) - } - return vm.NIL, nil - }) - - use, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - if len(vs) < 1 { - return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) - } - cns := CurrentNS.Deref().(*vm.Namespace) - for i := range vs { - s, ok := vs[i].(vm.Symbol) - if !ok { - return vm.NIL, fmt.Errorf("use expected Symbol") - } - cns.Refer(NS(string(s)), "", true) - } - return vm.NIL, nil - }) - - aliasf, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - if len(vs) != 2 { - return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) - } - al, ok := vs[0].(vm.Symbol) - if !ok { - return vm.NIL, fmt.Errorf("alias expected Symbol") - } - nsSym, ok := vs[1].(vm.Symbol) - if !ok { - return vm.NIL, fmt.Errorf("alias expected Symbol") - } - cns := CurrentNS.Deref().(*vm.Namespace) - target := NS(string(nsSym)) - cns.Alias(al, target) - return vm.NIL, nil - }) - - referList, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - if len(vs) != 2 { - return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) - } - nsSym, ok := vs[0].(vm.Symbol) - if !ok { - return vm.NIL, fmt.Errorf("refer-list expected ns Symbol") - } - arr, ok := vs[1].(vm.ArrayVector) - if !ok { - return vm.NIL, fmt.Errorf("refer-list expected vector of Symbols") - } - syms := make([]vm.Symbol, 0, len(arr)) - for i := range arr { - if s, ok := arr[i].(vm.Symbol); ok { - syms = append(syms, s) - } - } - cns := CurrentNS.Deref().(*vm.Namespace) - target := NS(string(nsSym)) - // Convert []vm.Symbol to []vm.Symbol type alias in vm - vmSyms := make([]vm.Symbol, len(syms)) - copy(vmSyms, syms) - cns.ReferList(target, vmSyms) - return vm.NIL, nil - }) - // removed resolve-var helper (prefer compile-time resolution) now, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return vm.NewBoxed(time.Now()), nil }) - methodInvoke, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - if len(vs) < 2 { - return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) - } - name, ok := vs[1].(vm.Symbol) - if !ok { - return vm.NIL, fmt.Errorf("method-invoke expected Symbol") - } - rec, ok := vs[0].(vm.Receiver) - if !ok { - return invokeMethodFallback(vs[0], name, vs[2:], fmt.Errorf("method-invoke expected Receiver")) - } - result, err := rec.InvokeMethod(name, vs[2:]) - if err == nil { - return result, nil - } - return invokeMethodFallback(rec, name, vs[2:], err) - }) - // (register-host-method! Type 'name (fn [rec & args] ...)) — register a // handler for `.name` dot-forms on values of Type (the host-method seam). - registerHostMethod, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - if len(vs) != 3 { - return vm.NIL, fmt.Errorf("register-host-method! expected 3 arguments, got %d", len(vs)) - } - t, ok := vs[0].(vm.ValueType) - if !ok { - return vm.NIL, fmt.Errorf("register-host-method! expected a type, got %s", vs[0].Type().Name()) - } - name, ok := vs[1].(vm.Symbol) - if !ok { - return vm.NIL, fmt.Errorf("register-host-method! expected a Symbol method name") - } - fn, ok := vs[2].(vm.Fn) - if !ok { - return vm.NIL, fmt.Errorf("register-host-method! expected a fn") - } - RegisterHostMethod(t, name, fn) - return vm.NIL, nil - }) // (register-host-class! "java.util.Map" value) — make a bare class symbol // resolve to value (typically a let-go type) when used as a value. - registerHostClass, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - if len(vs) != 2 { - return vm.NIL, fmt.Errorf("register-host-class! expected 2 arguments, got %d", len(vs)) - } - name, ok := vs[0].(vm.String) - if !ok { - return vm.NIL, fmt.Errorf("register-host-class! expected a String class name") - } - RegisterHostClass(string(name), vs[1]) - return vm.NIL, nil - }) deref, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { switch len(vs) { @@ -3782,73 +2739,7 @@ func installLangNS() { } }) - concat, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - // Pre-size for the ArrayVector args (flat slices with known length) - // so their direct appends below don't regrow ret. - presize := 0 - for i := range vs { - if av, ok := vs[i].(vm.ArrayVector); ok { - presize += len(av) - } - } - ret := make([]vm.Value, 0, presize) - for i := range vs { - if vs[i] == vm.NIL { - continue - } - // ArrayVector fast path: bulk-append the flat slice — no seq, - // no chunk, no per-element successor allocation. - if av, ok := vs[i].(vm.ArrayVector); ok { - ret = append(ret, av...) - continue - } - vseq, err := seqOf(vs[i]) - if err != nil { - return vm.NIL, fmt.Errorf("concat expected Seq") - } - ret = appendSeqValues(ret, forceSeq(vseq)) - } - r, err := vm.ListType.Box(ret) - if err != nil { - return vm.NIL, fmt.Errorf("concat failed: %w", err) - } - return r, nil - }) - // slurp (reintroduced) - slurp, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - if len(vs) != 1 { - return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) - } - filename, ok := vs[0].(vm.String) - if !ok { - return vm.NIL, fmt.Errorf("slurp expected String") - } - data, err := os.ReadFile(string(filename)) - if err != nil { - return vm.NIL, fmt.Errorf("slurp failed: %w", err) - } - return vm.String(data), nil - }) - - spit, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - if len(vs) != 2 { - return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) - } - filename, ok := vs[0].(vm.String) - if !ok { - return vm.NIL, fmt.Errorf("spit expected String") - } - contents, ok := asBytes(vs[1]) - if !ok { - return vm.NIL, fmt.Errorf("spit expected String or byte-array") - } - err := os.WriteFile(string(filename), contents, 0644) - if err != nil { - return vm.NIL, fmt.Errorf("spit failed: %w", err) - } - return vm.NIL, nil - }) name, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { if len(vs) != 1 { @@ -3879,37 +2770,6 @@ func installLangNS() { return named.Namespace(), nil }) - atom, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - if len(vs) < 1 { - return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) - } - if (len(vs)-1)%2 != 0 { - return vm.NIL, fmt.Errorf("atom options must be key/value pairs") - } - var meta vm.Value - var validator vm.Fn - for i := 1; i < len(vs); i += 2 { - switch vs[i] { - case vm.Keyword("meta"): - if vs[i+1] != vm.NIL && !isMapType(vs[i+1]) { - return vm.NIL, fmt.Errorf("atom :meta must be nil or map") - } - meta = vs[i+1] - case vm.Keyword("validator"): - if vs[i+1] == vm.NIL { - validator = nil - continue - } - fn, ok := vm.AsFn(vs[i+1]) - if !ok { - return vm.NIL, fmt.Errorf("atom :validator must be nil or function") - } - validator = fn - } - } - return vm.NewAtomWithMetaValidator(vs[0], meta, validator) - }) - // (swap! a fn) swap := vm.NewCtxNativeFn("swap!", func(ec *vm.ExecContext, vs []vm.Value) (vm.Value, error) { if len(vs) < 2 { @@ -3927,35 +2787,8 @@ func installLangNS() { }) // (reset! a fn) - reset, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - if len(vs) != 2 { - return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) - } - at, ok := vs[0].(*vm.Atom) - if !ok { - return vm.NIL, fmt.Errorf("reset expected Atom") - } - return at.Reset(vs[1]) - }) // (compare-and-set! a old new): set to new iff current is identical to old. - compareAndSet, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - if len(vs) != 3 { - return vm.NIL, fmt.Errorf("compare-and-set! expected 3 arguments, got %d", len(vs)) - } - at, ok := vs[0].(*vm.Atom) - if !ok { - return vm.NIL, fmt.Errorf("compare-and-set! expected Atom") - } - swapped, err := at.CompareAndSet(vs[1], vs[2]) - if err != nil { - return vm.NIL, err - } - if swapped { - return vm.TRUE, nil - } - return vm.FALSE, nil - }) // swap-vals!: like swap! but returns [old new] swapVals := vm.NewCtxNativeFn("swap-vals!", func(ec *vm.ExecContext, vs []vm.Value) (vm.Value, error) { @@ -3979,20 +2812,6 @@ func installLangNS() { }) // reset-vals!: like reset! but returns [old new] - resetVals, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - if len(vs) != 2 { - return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) - } - at, ok := vs[0].(*vm.Atom) - if !ok { - return vm.NIL, fmt.Errorf("reset-vals! expected Atom") - } - old := at.Deref() - if _, err := at.Reset(vs[1]); err != nil { - return vm.NIL, err - } - return vm.ArrayVector{old, vs[1]}, nil - }) gof := vm.NewCtxNativeFn("go*", func(ec *vm.ExecContext, vs []vm.Value) (vm.Value, error) { if len(vs) != 1 { @@ -4029,13 +2848,6 @@ func installLangNS() { return ret, nil }) - chanf, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - if len(vs) != 0 { - return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) - } - return make(vm.Chan), nil - }) - scopeOpen := vm.NewCtxNativeFn("scope-open", func(ec *vm.ExecContext, vs []vm.Value) (vm.Value, error) { if len(vs) != 0 { return vm.NIL, fmt.Errorf("scope-open expects 0 arguments") @@ -4045,43 +2857,6 @@ func installLangNS() { return vm.OpenChildEC(ec), nil }) - scopeClose, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - if len(vs) != 2 { - return vm.NIL, fmt.Errorf("scope-close! expects 2 arguments (scope timeout-ms)") - } - s, ok := vs[0].(*vm.Scope) - if !ok { - return vm.NIL, fmt.Errorf("scope-close! expected a scope") - } - ms, ok := vs[1].(vm.Int) - if !ok { - return vm.NIL, fmt.Errorf("scope-close! expected an integer timeout-ms") - } - vm.CloseScoped(s, time.Duration(int64(ms))*time.Millisecond) - return vm.NIL, nil - }) - - scopeLive, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - if len(vs) != 1 { - return vm.NIL, fmt.Errorf("scope-live expects 1 argument") - } - s, ok := vs[0].(*vm.Scope) - if !ok { - return vm.NIL, fmt.Errorf("scope-live expected a scope") - } - return vm.Int(s.LiveTree()), nil - }) - - scopeQmark, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - if len(vs) != 1 { - return vm.NIL, fmt.Errorf("scope? expects 1 argument") - } - if _, ok := vs[0].(*vm.Scope); ok { - return vm.TRUE, nil - } - return vm.FALSE, nil - }) - chanput := vm.NewCtxNativeFn(">!", func(ec *vm.ExecContext, vs []vm.Value) (vm.Value, error) { if len(vs) != 2 { return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) @@ -4170,60 +2945,14 @@ func installLangNS() { return vm.MakeInt(i), nil }) - max, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - if len(vs) < 1 { - return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) - } - m := vs[0] - if isNaNValue(m) { - return m, nil - } - for i := 1; i < len(vs); i++ { - if isNaNValue(vs[i]) { - return vs[i], nil - } - gt, err := vm.NumGt(vs[i], m) - if err != nil { - return vm.NIL, err - } - if gt { - m = vs[i] - } - } - return m, nil - }) - - min, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - if len(vs) < 1 { - return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) - } - m := vs[0] - if isNaNValue(m) { - return m, nil - } - for i := 1; i < len(vs); i++ { - if isNaNValue(vs[i]) { - return vs[i], nil - } - lt, err := vm.NumLt(vs[i], m) - if err != nil { - return vm.NIL, err - } - if lt { - m = vs[i] - } - } - return m, nil - }) - - // compareValues delegates to the vm package's DefaultCompare - compareValues := vm.DefaultCompare - - // comparef is defined later (~line 4585); the earlier definition - // that lived here was unused — the later one shadowed it. - - sort := vm.NewCtxNativeFn("sort", func(ec *vm.ExecContext, vs []vm.Value) (vm.Value, error) { - if len(vs) < 1 || len(vs) > 2 { + // compareValues delegates to the vm package's DefaultCompare + compareValues := vm.DefaultCompare + + // comparef is defined later (~line 4585); the earlier definition + // that lived here was unused — the later one shadowed it. + + sort := vm.NewCtxNativeFn("sort", func(ec *vm.ExecContext, vs []vm.Value) (vm.Value, error) { + if len(vs) < 1 || len(vs) > 2 { return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) } var comp vm.Comparator @@ -4313,47 +3042,6 @@ func installLangNS() { return ret, nil }) - strReplace, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - if len(vs) != 3 { - return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) - } - s, ok := vs[0].(vm.String) - if !ok { - return vm.NIL, fmt.Errorf("str-replace expected String") - } - // Function replacement (clojure.string/replace semantics). - if fn, isFn := vs[2].(vm.Fn); isFn { - switch m := vs[1].(type) { - case *vm.Regex: - out, err := m.ReplaceAllFunc(string(s), strReplaceCallback(fn)) - if err != nil { - return vm.NIL, err - } - return vm.String(out), nil - case vm.String: - return literalReplaceFn(string(m), string(s), fn, false) - default: - return vm.NIL, fmt.Errorf("str-replace expected String or Regex") - } - } - r, ok := vs[2].(vm.String) - if !ok { - return vm.NIL, fmt.Errorf("str-replace expected String") - } - switch vs[1].(type) { - case vm.String: - return vm.String(strings.ReplaceAll(string(s), string(vs[1].(vm.String)), string(r))), nil - case *vm.Regex: - out, err := vs[1].(*vm.Regex).ReplaceAll(string(s), string(r)) - if err != nil { - return vm.NIL, err - } - return vm.String(out), nil - default: - return vm.NIL, fmt.Errorf("str-replace expected String or Regex") - } - }) - strReplaceFirst, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { if len(vs) != 3 { return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) @@ -4442,274 +3130,6 @@ func installLangNS() { } }) - longf, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - if len(vs) != 1 { - return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) - } - const minInt64 = float64(-9223372036854775808) - const maxInt64 = float64(9223372036854775807) - coerce := func(f float64) (vm.Value, error) { - if f < minInt64 || f > maxInt64 { - return vm.NIL, fmt.Errorf("%s can't be coerced to long", vs[0]) - } - return vm.Int(int64(math.Trunc(f))), nil - } - switch v := vs[0].(type) { - case vm.Int: - return v, nil - case vm.Float: - return coerce(float64(v)) - case vm.Char: - return vm.Int(int(v)), nil - case *vm.BigInt: - if !v.Val().IsInt64() { - return vm.NIL, fmt.Errorf("%s can't be coerced to long", vs[0]) - } - return vm.Int(v.Val().Int64()), nil - case *vm.BigDecimal: - f, _ := v.Val().Float64() - return coerce(f) - case *vm.Ratio: - f, _ := v.Val().Float64() - return coerce(f) - case vm.Boolean: - if bool(v) { - return vm.MakeInt(1), nil - } - return vm.MakeInt(0), nil - default: - return vm.NIL, fmt.Errorf("%s can't be coerced to long", vs[0]) - } - }) - - floatf, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - if len(vs) != 1 { - return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) - } - f, ok := vm.ToFloat(vs[0]) - if !ok { - return vm.NIL, fmt.Errorf("%s can't be coerced to float", vs[0]) - } - if math.IsInf(f, 0) { - return vm.NIL, fmt.Errorf("%s can't be coerced to float", vs[0]) - } - f32 := float32(f) - if math.IsInf(float64(f32), 0) { - return vm.NIL, fmt.Errorf("%s can't be coerced to float", vs[0]) - } - return vm.Float32(float64(f32)), nil - }) - - doublef, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - if len(vs) != 1 { - return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) - } - f, ok := vm.ToFloat(vs[0]) - if !ok { - return vm.NIL, fmt.Errorf("%s can't be coerced to double", vs[0]) - } - return vm.Float(f), nil - }) - - isNumber, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - if len(vs) != 1 { - return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) - } - return vm.Boolean(vm.IsNumber(vs[0])), nil - }) - - isFloat, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - if len(vs) != 1 { - return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) - } - switch vs[0].(type) { - case vm.Float, vm.Float32: - return vm.TRUE, nil - } - ok := false - return vm.Boolean(ok), nil - }) - - isInt, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - if len(vs) != 1 { - return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) - } - _, ok := vs[0].(vm.Int) - return vm.Boolean(ok), nil - }) - - char, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - if len(vs) != 1 { - return vm.NIL, fmt.Errorf("wrong number of arguments") - } - switch v := vs[0].(type) { - case vm.Int: - if int(v) < 0 || int(v) > 0x10FFFF { - return vm.NIL, fmt.Errorf("value out of range for char: %d", v) - } - return vm.Char(rune(v)), nil - case vm.Char: - return v, nil - case vm.String: - runes := []rune(string(v)) - if len(runes) == 1 { - return vm.Char(runes[0]), nil - } - return vm.NIL, fmt.Errorf("%s can't be coerced to char", vs[0]) - case *vm.BigInt: - n := v.Unbox().(*big.Int).Int64() - if n < 0 || n > 0x10FFFF { - return vm.NIL, fmt.Errorf("value out of range for char: %d", n) - } - return vm.Char(rune(n)), nil - default: - return vm.NIL, fmt.Errorf("%s can't be coerced to char", vs[0]) - } - }) - - regex, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - if len(vs) != 1 { - return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) - } - // (re-pattern p) on an already-compiled regex returns it unchanged, - // matching Clojure where re-pattern accepts a Pattern, not only a String. - if r, ok := vs[0].(*vm.Regex); ok { - return r, nil - } - if s, ok := vs[0].(vm.String); ok { - return vm.NewRegex(string(s)) - } - return vm.NIL, fmt.Errorf("regex expected String") - }) - - peek, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - if len(vs) != 1 { - return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) - } - if vs[0] == vm.NIL { - return vm.NIL, nil - } - switch v := vs[0].(type) { - case vm.ArrayVector: - if len(v) == 0 { - return vm.NIL, nil - } - return v[len(v)-1], nil - case vm.PersistentVector: - if v.RawCount() == 0 { - return vm.NIL, nil - } - return v.ValueAt(vm.Int(v.RawCount() - 1)), nil - case *vm.List: - if v == vm.EmptyList { - return vm.NIL, nil - } - return v.First(), nil - case *vm.PersistentQueue: - return v.Peek(), nil - default: - return vm.NIL, fmt.Errorf("peek not supported on %s", vs[0].Type()) - } - }) - - pop, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - if len(vs) != 1 { - return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) - } - if vs[0] == vm.NIL { - return vm.NIL, nil - } - switch vs[0].(type) { - case vm.PersistentVector: - v := vs[0].(vm.PersistentVector) - if v.RawCount() < 1 { - return vm.NIL, fmt.Errorf("can't pop empty vector") - } - // O(1)-amortized structural pop (was O(n) Unbox()+rebuild). - return v.Pop(), nil - case vm.ArrayVector: - v := vs[0].(vm.ArrayVector) - if v.RawCount() < 1 { - return vm.NIL, fmt.Errorf("can't pop empty vector") - } - return vm.ArrayVector(v[0 : len(v)-1]), nil - case vm.Seq: - s := vs[0].(vm.Seq) - // pop drops the first element and returns the rest. Use More (not - // Next): More yields the empty list () for a one-element seq, - // whereas Next returns nil there — which would wrongly read as - // "empty" and error. Only an already-empty seq is illegal to pop. - if s == vm.EmptyList { - return vm.NIL, fmt.Errorf("can't pop empty seq") - } - if c, ok := vs[0].(vm.Counted); ok && c.RawCount() == 0 { - return vm.NIL, fmt.Errorf("can't pop empty seq") - } - return s.More(), nil - case *vm.PersistentQueue: - return vs[0].(*vm.PersistentQueue).Pop(), nil - default: - return vm.NIL, fmt.Errorf("pop expected Seq or Vec") - } - }) - - iterate, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - if len(vs) != 2 { - return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) - } - f, ok := vm.AsFn(vs[0]) - if !ok { - return vm.NIL, fmt.Errorf("iterate expected a function") - } - return vm.NewIterate(f, vs[1]), nil - }) - - repeat, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - if len(vs) < 1 || len(vs) > 2 { - return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) - } - if len(vs) == 1 { - return vm.NewRepeat(vs[0], -1), nil - } - if _, ok := vs[0].(vm.Boolean); ok { - return vm.NIL, fmt.Errorf("repeat expected an Int") - } - ni, ok := vm.ToInt(vs[0]) - if !ok { - return vm.NIL, fmt.Errorf("repeat expected an Int") - } - n := vm.Int(ni) - if int(n) <= 0 { - return vm.EmptyList, nil - } - return vm.NewRepeat(vs[1], int(n)), nil - }) - - refer, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - if len(vs) < 2 || len(vs) > 3 { - return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) - } - cns := CurrentNS.Deref().(*vm.Namespace) - s, ok := vs[0].(vm.Symbol) - if !ok { - return vm.NIL, fmt.Errorf("refer expected Symbol") - } - alias := "" - if len(vs) > 1 { - if str, ok := vs[1].(vm.String); ok { - alias = string(str) - } - } - all := true - if len(vs) > 2 { - if b, ok := vs[2].(vm.Boolean); ok { - all = bool(b) - } - } - cns.Refer(NS(string(s)), alias, all) - return vm.NIL, nil - }) - // String utility builtins (for string namespace) trimf, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { if len(vs) != 1 { @@ -4879,90 +3299,11 @@ func installLangNS() { }) // format: sprintf-style string formatting - formatf, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - if len(vs) < 1 { - return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) - } - fmtStr, ok := vs[0].(vm.String) - if !ok { - return vm.NIL, fmt.Errorf("format expected String") - } - fmts := string(fmtStr) - args := make([]any, len(vs)-1) - // Scan format string to determine which args need float promotion - vi := 0 - for fi := 0; fi < len(fmts) && vi < len(args); fi++ { - if fmts[fi] != '%' { - continue - } - fi++ // skip % - if fi >= len(fmts) { - break - } - if fmts[fi] == '%' { - continue // %% literal - } - // Skip flags, width, precision - for fi < len(fmts) && (fmts[fi] == '-' || fmts[fi] == '+' || fmts[fi] == ' ' || fmts[fi] == '0' || fmts[fi] == '#' || (fmts[fi] >= '0' && fmts[fi] <= '9') || fmts[fi] == '.') { - fi++ - } - if fi >= len(fmts) { - break - } - verb := fmts[fi] - switch v := vs[vi+1].(type) { - case vm.Int: - if verb == 'f' || verb == 'e' || verb == 'g' || verb == 'E' || verb == 'G' { - args[vi] = float64(v) - } else { - args[vi] = int(v) - } - case vm.Float: - args[vi] = float64(v) - case vm.String: - args[vi] = string(v) - case vm.Boolean: - args[vi] = bool(v) - default: - args[vi] = vs[vi+1].Unbox() - } - vi++ - } - return vm.String(fmt.Sprintf(string(fmtStr), args...)), nil - }) // rand: returns a random float between 0 (inclusive) and 1 (exclusive) // or between 0 and n - randf, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - if len(vs) == 0 { - return vm.Float(rngFloat64()), nil - } - if len(vs) == 1 { - if n, ok := vs[0].(vm.Int); ok { - return vm.Float(rngFloat64() * float64(n)), nil - } - if n, ok := vs[0].(vm.Float); ok { - return vm.Float(rngFloat64() * float64(n)), nil - } - return vm.NIL, fmt.Errorf("rand expected number") - } - return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) - }) // rand-int: returns a random integer between 0 (inclusive) and n (exclusive) - randInt, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - if len(vs) != 1 { - return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) - } - n, ok := vs[0].(vm.Int) - if !ok { - return vm.NIL, fmt.Errorf("rand-int expected Int") - } - if int(n) <= 0 { - return vm.MakeInt(0), nil - } - return vm.MakeInt(rngIntn(int(n))), nil - }) // random-uuid: generate a random UUID v4 randomUUID, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { @@ -4979,490 +3320,59 @@ func installLangNS() { }) // rand-nth: returns a random element from a collection - randNth, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - if len(vs) != 1 { - return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) - } - if vs[0] == vm.NIL { - return vm.NIL, nil - } - coll, ok := vs[0].(vm.Collection) - if !ok { - return vm.NIL, fmt.Errorf("rand-nth expected Collection") - } - n := coll.RawCount() - if n == 0 { - return vm.NIL, fmt.Errorf("rand-nth called on empty collection") - } - idx := rngIntn(n) - if l, ok := vs[0].(vm.Lookup); ok { - return l.ValueAt(vm.Int(idx)), nil - } - // Fallback: iterate - s, _ := seqOf(vs[0]) - for range idx { - s = s.Next() - } - return s.First(), nil - }) // shuffle: returns a random permutation of a collection as a vector - shuffle, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - if len(vs) != 1 { - return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) - } - if vs[0] == vm.NIL { - return vm.NIL, fmt.Errorf("shuffle not supported on nil") - } - switch vs[0].(type) { - case vm.String: - return vm.NIL, fmt.Errorf("shuffle not supported on string") - case *vm.PersistentMap, vm.Map, *vm.SortedMap: - return vm.NIL, fmt.Errorf("shuffle not supported on map") - } - // Collect into slice. forceSeq realizes lazy seqs first, so - // an empty lazy seq yields [] rather than [nil]. - s, err := seqOf(vs[0]) - if err != nil { - return vm.NIL, err - } - vals := appendSeqValues(nil, forceSeq(s)) - // Fisher-Yates shuffle - rngShuffle(len(vals), func(i, j int) { - vals[i], vals[j] = vals[j], vals[i] - }) - return vm.NewArrayVector(vals), nil - }) // set-rand-seed!: seed the shared RNG so rand / rand-int / rand-nth / // shuffle / math/random produce a reproducible sequence. Returns nil. The // bang marks the process-wide mutation. For tests, benchmarks, and bug // repros — NOT a gameplay-determinism mechanism (use explicit state for // that). Reproducible only when rand calls happen in a deterministic order. - setRandSeedFn, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - if len(vs) != 1 { - return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) - } - n, ok := vs[0].(vm.Int) - if !ok { - return vm.NIL, fmt.Errorf("set-rand-seed! expected Int") - } - setRandSeed(int64(n)) - return vm.NIL, nil - }) // transient: create a transient (mutable) version of a persistent collection - transientf, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - if len(vs) != 1 { - return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) - } - switch v := vs[0].(type) { - case *vm.PersistentMap: - return vm.NewTransientMap(v), nil - case *vm.PersistentSet: - return vm.NewTransientSet(v), nil - case vm.ArrayVector: - return vm.NewTransientVector([]vm.Value(v)), nil - case vm.PersistentVector: - vals := v.Unbox().([]vm.Value) - return vm.NewTransientVector(vals), nil - default: - return vm.NIL, fmt.Errorf("transient not supported on %s", vs[0].Type().Name()) - } - }) // persistent!: freeze a transient back to a persistent collection - persistentf, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - if len(vs) != 1 { - return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) - } - switch v := vs[0].(type) { - case *vm.TransientMap: - return v.Persistent() - case *vm.TransientVector: - return v.Persistent() - case *vm.TransientSet: - return v.Persistent() - default: - return vm.NIL, fmt.Errorf("persistent! not supported on %s", vs[0].Type().Name()) - } - }) // conj!: mutating conj on a transient - conjBang, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - if len(vs) == 0 { - return vm.NewTransientVector(nil), nil - } - if len(vs) == 1 { - return vs[0], nil - } - switch t := vs[0].(type) { - case *vm.TransientMap: - var err error - for i := 1; i < len(vs); i++ { - t, err = t.Conj(vs[i]) - if err != nil { - return vm.NIL, err - } - } - return t, nil - case *vm.TransientVector: - var err error - for i := 1; i < len(vs); i++ { - t, err = t.Conj(vs[i]) - if err != nil { - return vm.NIL, err - } - } - return t, nil - case *vm.TransientSet: - var err error - for i := 1; i < len(vs); i++ { - t, err = t.Conj(vs[i]) - if err != nil { - return vm.NIL, err - } - } - return t, nil - default: - return vm.NIL, fmt.Errorf("conj! not supported on %s", vs[0].Type().Name()) - } - }) // assoc!: mutating assoc on a transient - assocBang, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - if len(vs) < 2 { - return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) - } - switch t := vs[0].(type) { - case *vm.TransientMap: - var err error - for i := 1; i < len(vs); i += 2 { - val := vm.Value(vm.NIL) - if i+1 < len(vs) { - val = vs[i+1] - } - t, err = t.Assoc(vs[i], val) - if err != nil { - return vm.NIL, err - } - } - return t, nil - case *vm.TransientVector: - var err error - for i := 1; i < len(vs); i += 2 { - val := vm.Value(vm.NIL) - if i+1 < len(vs) { - val = vs[i+1] - } - t, err = t.Assoc(vs[i], val) - if err != nil { - return vm.NIL, err - } - } - return t, nil - default: - return vm.NIL, fmt.Errorf("assoc! not supported on %s", vs[0].Type().Name()) - } - }) // disj!: mutating disj on a transient set - disjBang, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - if len(vs) < 2 { - return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) - } - t, ok := vs[0].(*vm.TransientSet) - if !ok { - return vm.NIL, fmt.Errorf("disj! expected TransientSet") - } - var err error - for i := 1; i < len(vs); i++ { - t, err = t.Disj(vs[i]) - if err != nil { - return vm.NIL, err - } - } - return t, nil - }) // dissoc!: mutating dissoc on a transient map - dissocBang, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - if len(vs) < 2 { - return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) - } - t, ok := vs[0].(*vm.TransientMap) - if !ok { - return vm.NIL, fmt.Errorf("dissoc! expected TransientMap") - } - var err error - for i := 1; i < len(vs); i++ { - t, err = t.Dissoc(vs[i]) - if err != nil { - return vm.NIL, err - } - } - return t, nil - }) // make-record-type: create a RecordType with name and field keywords - makeRecordType, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - if len(vs) < 1 { - return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) - } - name, ok := vs[0].(vm.String) - if !ok { - return vm.NIL, fmt.Errorf("make-record-type expected String name") - } - fields := make([]vm.Keyword, len(vs)-1) - for i := 1; i < len(vs); i++ { - kw, ok := vs[i].(vm.Keyword) - if !ok { - return vm.NIL, fmt.Errorf("make-record-type expected Keyword fields") - } - fields[i-1] = kw - } - return vm.NewRecordType(string(name), fields), nil - }) // make-record: create a Record from a RecordType and a map - makeRecord, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - if len(vs) != 2 { - return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) - } - rt, ok := vs[0].(*vm.RecordType) - if !ok { - return vm.NIL, fmt.Errorf("make-record expected RecordType") - } - m, ok := vs[1].(*vm.PersistentMap) - if !ok { - return vm.NIL, fmt.Errorf("make-record expected Map") - } - return vm.NewRecord(rt, m), nil - }) // record?: check if a value is a Record - isRecord, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - if len(vs) != 1 { - return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) - } - _, ok := vs[0].(*vm.Record) - return vm.Boolean(ok), nil - }) // make-deftype: create a DType (deftype class) with a name and field symbols. - makeDType, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - if len(vs) < 1 { - return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) - } - name, ok := vs[0].(vm.String) - if !ok { - return vm.NIL, fmt.Errorf("make-deftype expected String name") - } - fields := make([]vm.Symbol, len(vs)-1) - for i := 1; i < len(vs); i++ { - sym, ok := vs[i].(vm.Symbol) - if !ok { - return vm.NIL, fmt.Errorf("make-deftype expected Symbol fields") - } - fields[i-1] = sym - } - return vm.NewDType(string(name), fields), nil - }) // make-deftype-instance: construct an instance of a DType from positional field values. - makeDTypeInstance, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - if len(vs) < 1 { - return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) - } - dt, ok := vs[0].(*vm.DType) - if !ok { - return vm.NIL, fmt.Errorf("make-deftype-instance expected DType, got %s", vs[0].Type().Name()) - } - // Copy to avoid aliasing the VM's args slice (which may be reused). - fields := make([]vm.Value, len(vs)-1) - copy(fields, vs[1:]) - return vm.NewDTypeInstance(dt, fields), nil - }) // set-field!: mutate a deftype instance field in place (backs ^:mutable). // (set-field! instance 'field-name value) -> value - setField, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - if len(vs) != 3 { - return vm.NIL, fmt.Errorf("set-field! expected 3 arguments, got %d", len(vs)) - } - inst, ok := vs[0].(*vm.DTypeInstance) - if !ok { - return vm.NIL, fmt.Errorf("set-field! expected a deftype instance, got %s", vs[0].Type().Name()) - } - name, ok := vs[1].(vm.Symbol) - if !ok { - return vm.NIL, fmt.Errorf("set-field! expected a Symbol field name") - } - if err := inst.SetField(name, vs[2]); err != nil { - return vm.NIL, err - } - return vs[2], nil - }) // defprotocol*: create a protocol (called by defprotocol macro) - defProtocol, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - if len(vs) < 1 { - return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) - } - name, ok := vs[0].(vm.String) - if !ok { - return vm.NIL, fmt.Errorf("defprotocol* expected String name") - } - methods := make([]vm.Symbol, len(vs)-1) - for i := 1; i < len(vs); i++ { - s, ok := vs[i].(vm.Symbol) - if !ok { - return vm.NIL, fmt.Errorf("defprotocol* expected Symbol method names") - } - methods[i-1] = s - } - return vm.NewProtocol(string(name), methods), nil - }) // extend-type*: extend a protocol for a type (called by extend-type macro) - extendType, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - if len(vs) != 3 { - return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) - } - protocol, ok := vs[0].(*vm.Protocol) - if !ok { - return vm.NIL, fmt.Errorf("extend-type* expected Protocol") - } - implMap, ok := vs[2].(*vm.PersistentMap) - if !ok { - return vm.NIL, fmt.Errorf("extend-type* expected map of implementations") - } - // vs[1] is the type to extend — nil, a concrete ValueType, or a - // reusable TypeUnion descriptor for a compatibility interface. - if vs[1] == vm.NIL { - protocol.ExtendNil(implMap) - return vm.NIL, nil - } - if union, ok := vs[1].(*vm.TypeUnion); ok { - // Union fan-out must not clobber an exact extend-type on a member - // (Clojure: exact type beats interface, regardless of order). - for _, valueType := range union.Types() { - protocol.ExtendViaUnion(valueType, implMap) - } - return vm.NIL, nil - } - vt, ok := vs[1].(vm.ValueType) - if !ok { - return vm.NIL, fmt.Errorf("extend-type* expected a type, got %s", vs[1].Type().Name()) - } - protocol.Extend(vt, implMap) - return vm.NIL, nil - }) // make-protocol-fn: create a ProtocolFn for dispatch - makeProtocolFn, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - if len(vs) != 2 { - return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) - } - protocol, ok := vs[0].(*vm.Protocol) - if !ok { - return vm.NIL, fmt.Errorf("make-protocol-fn expected Protocol") - } - methodName, ok := vs[1].(vm.Symbol) - if !ok { - return vm.NIL, fmt.Errorf("make-protocol-fn expected Symbol") - } - return vm.NewProtocolFn(protocol, methodName), nil - }) // -set-invokable-protocol!: wire the VM's "invokable value" support to the // IFn protocol + its -invoke fn (called once from core after defining IFn). // Thereafter any value whose type satisfies IFn can be called like a fn. - setInvokableProtocol, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - if len(vs) != 2 { - return vm.NIL, fmt.Errorf("-set-invokable-protocol! expects 2 args") - } - protocol, ok := vs[0].(*vm.Protocol) - if !ok { - return vm.NIL, fmt.Errorf("-set-invokable-protocol! expected a Protocol") - } - invokeFn, ok := vs[1].(vm.Fn) - if !ok { - return vm.NIL, fmt.Errorf("-set-invokable-protocol! expected the -invoke fn") - } - vm.IFnProtocol = protocol - vm.IFnInvoke = invokeFn - return vm.NIL, nil - }) // -set-deref-protocol!: wire the VM's "derefable value" support to the // IDeref protocol + its -deref fn (called once from core after defining // IDeref). Thereafter any value whose type satisfies IDeref works with @/deref. - setDerefProtocol, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - if len(vs) != 2 { - return vm.NIL, fmt.Errorf("-set-deref-protocol! expects 2 args") - } - protocol, ok := vs[0].(*vm.Protocol) - if !ok { - return vm.NIL, fmt.Errorf("-set-deref-protocol! expected a Protocol") - } - derefFn, ok := vs[1].(vm.Fn) - if !ok { - return vm.NIL, fmt.Errorf("-set-deref-protocol! expected the -deref fn") - } - vm.IDerefProtocol = protocol - vm.IDerefDeref = derefFn - return vm.NIL, nil - }) // satisfies?: check if a value's type implements a protocol - satisfies, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - if len(vs) != 2 { - return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) - } - protocol, ok := vs[0].(*vm.Protocol) - if !ok { - return vm.NIL, fmt.Errorf("satisfies? expected Protocol") - } - return vm.Boolean(protocol.Satisfies(vs[1])), nil - }) // defmulti*: create a multimethod (called by defmulti macro) - defMulti, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - if len(vs) < 2 || len(vs) > 3 { - return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) - } - name, ok := vs[0].(vm.String) - if !ok { - return vm.NIL, fmt.Errorf("defmulti* expected String name") - } - dispatchFn, ok := vs[1].(vm.Fn) - if !ok { - return vm.NIL, fmt.Errorf("defmulti* expected Fn") - } - var defaultVal vm.Value = vm.Keyword("default") - if len(vs) == 3 { - defaultVal = vs[2] - } - return vm.NewMultiFn(string(name), dispatchFn, defaultVal), nil - }) // defmethod*: add a method to a multimethod (called by defmethod macro) - defMethod, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - if len(vs) != 3 { - return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) - } - mf, ok := vs[0].(*vm.MultiFn) - if !ok { - return vm.NIL, fmt.Errorf("defmethod* expected MultiFn") - } - dispatchVal := vs[1] - method, ok := vs[2].(vm.Fn) - if !ok { - return vm.NIL, fmt.Errorf("defmethod* expected Fn") - } - return mf.AddMethod(dispatchVal, method), nil - }) // methods: return the method map of a multimethod methods, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { @@ -5477,9 +3387,6 @@ func installLangNS() { }) // pr-str: print readably to string (with quotes on strings) - prStr, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - return prThroughToString(vs, true) - }) // prn: print readably + newline through *out* prn := vm.NewCtxNativeFn("prn", func(ec *vm.ExecContext, vs []vm.Value) (vm.Value, error) { @@ -5491,213 +3398,25 @@ func installLangNS() { }) // prn-str: print readably + newline to string - prnStr, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - s, err := prThroughToString(vs, true) - if err != nil { - return vm.NIL, err - } - return vm.String(string(s.(vm.String)) + "\n"), nil - }) // print-str: print human-readably to string (no quotes on strings) - printStr, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - return prThroughToString(vs, false) - }) // println-str: print human-readably + newline to string - printlnStr, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - s, err := prThroughToString(vs, false) - if err != nil { - return vm.NIL, err - } - return vm.String(string(s.(vm.String)) + "\n"), nil - }) // re-find: find first match of regex in string - reFind, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - if len(vs) != 2 { - return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) - } - re, ok := vs[0].(*vm.Regex) - if !ok { - return vm.NIL, fmt.Errorf("re-find expected Regex") - } - s, ok := vs[1].(vm.String) - if !ok { - return vm.NIL, fmt.Errorf("re-find expected String") - } - indices := re.FindStringSubmatchIndex(string(s)) - if indices == nil { - return vm.NIL, nil - } - return regexSubmatchValue(string(s), indices), nil - }) // re-matches: match entire string against regex - reMatches, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - if len(vs) != 2 { - return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) - } - re, ok := vs[0].(*vm.Regex) - if !ok { - return vm.NIL, fmt.Errorf("re-matches expected Regex") - } - s, ok := vs[1].(vm.String) - if !ok { - return vm.NIL, fmt.Errorf("re-matches expected String") - } - indices := re.FindStringSubmatchIndex(string(s)) - if indices == nil || indices[0] != 0 || indices[1] != len(s) { - return vm.NIL, nil - } - return regexSubmatchValue(string(s), indices), nil - }) // re-seq: return lazy seq of all matches - reSeq, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - if len(vs) != 2 { - return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) - } - re, ok := vs[0].(*vm.Regex) - if !ok { - return vm.NIL, fmt.Errorf("re-seq expected Regex") - } - s, ok := vs[1].(vm.String) - if !ok { - return vm.NIL, fmt.Errorf("re-seq expected String") - } - // Like Clojure (and re-find above): a groupless pattern yields - // the match string, capture groups yield [full g1 g2 ...]. - all := re.FindAllStringSubmatchIndex(string(s), -1) - if all == nil { - return vm.NIL, nil - } - vals := make([]vm.Value, len(all)) - for i, indices := range all { - vals[i] = regexSubmatchValue(string(s), indices) - } - return vm.ListType.Box(vals) - }) // require loads a namespace by name (like Clojure's require function for REPL use) // Supports: (require 'foo), (require '[foo :as f]), (require '[foo :refer [a b]]) - requiref, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - cns := CurrentNS.Deref().(*vm.Namespace) - for _, v := range vs { - switch arg := v.(type) { - case vm.Symbol: - if _, err := RequireNS(string(arg)); err != nil { - return vm.NIL, err - } - case vm.ArrayVector: - // Vector form: [ns-name :as alias] or [ns-name :refer [syms...]] - if arg.RawCount() < 1 { - return vm.NIL, fmt.Errorf("require: empty vector") - } - nsName, ok := arg.ValueAt(vm.Int(0)).(vm.Symbol) - if !ok { - return vm.NIL, fmt.Errorf("require: first element must be a symbol") - } - target, err := RequireNS(string(nsName)) - if err != nil { - return vm.NIL, err - } - // Parse options - for i := 1; i < arg.RawCount()-1; i += 2 { - opt := arg.ValueAt(vm.Int(int64(i))) - val := arg.ValueAt(vm.Int(int64(i + 1))) - switch opt { - case vm.Keyword("as"): - if alias, ok := val.(vm.Symbol); ok { - cns.Alias(alias, target) - } - case vm.Keyword("refer"): - if val == vm.Keyword("all") { - cns.Refer(target, "", true) - } else if vec, ok := val.(vm.ArrayVector); ok { - syms := make([]vm.Symbol, vec.RawCount()) - for j := 0; j < vec.RawCount(); j++ { - syms[j] = vec.ValueAt(vm.Int(int64(j))).(vm.Symbol) - } - cns.ReferList(target, syms) - } - } - } - default: - return vm.NIL, fmt.Errorf("require expected Symbol or Vector, got %s", v.Type().Name()) - } - } - return vm.NIL, nil - }) // find-ns returns the namespace with the given name, or nil - findNs, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - if len(vs) != 1 { - return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) - } - s, ok := vs[0].(vm.Symbol) - if !ok { - return vm.NIL, fmt.Errorf("find-ns expected Symbol") - } - nsMu.RLock() - ns := nsRegistry[string(s)] - nsMu.RUnlock() - if ns == nil { - return vm.NIL, nil - } - return ns, nil - }) - - resolvef, err := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - if len(vs) != 1 { - return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) - } - sym, ok := vs[0].(vm.Symbol) - if !ok { - return vm.NIL, fmt.Errorf("resolve expected Symbol") - } - cns := CurrentNS.Deref().(*vm.Namespace) - if v := cns.Lookup(sym); v != vm.NIL { - return v, nil - } - return vm.NIL, nil - }) - if err != nil { - panic(err) - } // all-ns returns a list of all loaded namespaces - allNs, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - nsMu.RLock() - var nss []vm.Value - for _, ns := range nsRegistry { - nss = append(nss, ns) - } - nsMu.RUnlock() - return vm.NewList(nss), nil - }) // the-ns returns the namespace for a symbol, throwing if not found - theNs, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - if len(vs) != 1 { - return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) - } - s, ok := vs[0].(vm.Symbol) - if !ok { - // If already a namespace, return it - if ns, ok := vs[0].(*vm.Namespace); ok { - return ns, nil - } - return vm.NIL, fmt.Errorf("the-ns expected Symbol or Namespace") - } - nsMu.RLock() - ns := nsRegistry[string(s)] - nsMu.RUnlock() - if ns == nil { - return vm.NIL, fmt.Errorf("no namespace: %s found", s) - } - return ns, nil - }) // ns-name returns the name of a namespace as a symbol nsName, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { @@ -5714,98 +3433,22 @@ func installLangNS() { // ns-publics returns a map of symbol -> Var for the public (non-private) // interned vars of a namespace, given either the namespace or a symbol // naming it (matching Clojure, which passes its arg through the-ns). - nsPublics, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - if len(vs) != 1 { - return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) - } - var ns *vm.Namespace - switch a := vs[0].(type) { - case *vm.Namespace: - ns = a - case vm.Symbol: - // resolveNSAlias canonicalizes the Clojure-facing names the rest of - // the runtime accepts (clojure.core -> core, clojure.string -> - // string, …); non-aliases pass through unchanged. - nsMu.RLock() - ns = nsRegistry[resolveNSAlias(string(a))] - nsMu.RUnlock() - if ns == nil { - return vm.NIL, fmt.Errorf("no namespace: %s found", a) - } - default: - return vm.NIL, fmt.Errorf("ns-publics expected Symbol or Namespace") - } - pubs := ns.PublicVars() - kvs := make([]vm.Value, 0, len(pubs)*2) - for sym, v := range pubs { - kvs = append(kvs, sym, v) - } - return vm.NewMap(kvs), nil - }) // find-var: (find-var 'ns/name) -> the interned var in that namespace, or // nil if the namespace or the name is not found. integrant's default // init-key resolves a component fn from a qualified keyword via // (some-> (find-var sym) var-get). - findVar, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - if len(vs) != 1 { - return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) - } - sym, ok := vs[0].(vm.Symbol) - if !ok { - return vm.NIL, fmt.Errorf("find-var expected a symbol") - } - nsV, nameV := sym.Namespaced() - nsSym, ok1 := nsV.(vm.Symbol) - nameSym, ok2 := nameV.(vm.Symbol) - if !ok1 || !ok2 { - return vm.NIL, fmt.Errorf("find-var expects a fully-qualified symbol: %s", sym) - } - nsMu.RLock() - targetNS := nsRegistry[resolveNSAlias(string(nsSym))] - nsMu.RUnlock() - if targetNS == nil { - return vm.NIL, nil - } - if v := targetNS.LookupLocal(nameSym); v != nil { - return v, nil - } - return vm.NIL, nil - }) // get-method: (get-method multifn dispatch-val) -> the method fn that value // would select (exact match, else the default method), or nil. integrant's // can-expand-key? uses it to test whether a key has an expand-key method. - getMethod, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - if len(vs) != 2 { - return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) - } - mf, ok := vs[0].(*vm.MultiFn) - if !ok { - return vm.NIL, fmt.Errorf("get-method expected a multimethod") - } - return mf.GetMethod(vs[1]), nil - }) // enumeration-seq: only reached by integrant's JVM-only classpath scanners // (resources/load-hierarchy/load-annotations). let-go has no java.util // Enumeration, so this is a compile-only stub — it lets those :clj defns // load, and fails loudly if actually called. - enumerationSeq, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - return vm.NIL, fmt.Errorf("enumeration-seq is not supported under let-go (no java.util.Enumeration)") - }) // lazy-seq* creates a LazySeq from a thunk function - lazySeq, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - if len(vs) != 1 { - return vm.NIL, fmt.Errorf("lazy-seq* expected 1 argument, got %d", len(vs)) - } - fn, ok := vs[0].(vm.Fn) - if !ok { - return vm.NIL, fmt.Errorf("lazy-seq* expected a function") - } - return vm.NewLazySeq(fn), nil - }) // push-binding!/pop-binding! resolve against the *active* ExecContext // (ec.Invoke routes it in), so a `binding` form inside an isolated child @@ -5857,27 +3500,6 @@ func installLangNS() { return wrapped, nil }) - withMeta, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - if len(vs) != 2 { - return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) - } - if vs[0] == vm.NIL { - return vm.NIL, nil - } - m, ok := vs[0].(vm.IMeta) - if ok { - return m.WithMeta(vs[1]), nil - } - fn, ok := vs[0].(vm.Fn) - if ok { - return vm.NewMetaFn(fn, vs[1]), nil - } - // Other non-IMeta values pass through unchanged. This is - // load-bearing: value-position type hints compile to runtime - // with-meta calls, so hinted scalars must remain valid. - return vs[0], nil - }) - metaf, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { if len(vs) != 1 { return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) @@ -5893,75 +3515,14 @@ func installLangNS() { }) // throw - throwf, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - if len(vs) != 1 { - return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) - } - return vm.NIL, vm.NewThrownError(vs[0]) - }) // ex-info - exInfo, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - if len(vs) < 2 || len(vs) > 3 { - return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) - } - msg, ok := vs[0].(vm.String) - if !ok { - return vm.NIL, fmt.Errorf("ex-info expected String message") - } - data, ok := vs[1].(*vm.PersistentMap) - if !ok { - return vm.NIL, fmt.Errorf("ex-info expected Map data") - } - var cause error - if len(vs) == 3 { - if ei, ok := vs[2].(*vm.ExInfo); ok { - cause = ei - } - } - return vm.NewExInfo(string(msg), data, cause), nil - }) // ex-message - exMessage, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - if len(vs) != 1 { - return vm.NIL, fmt.Errorf("wrong number of arguments") - } - if ei, ok := vs[0].(*vm.ExInfo); ok { - return vm.String(ei.Message()), nil - } - return vm.NIL, nil - }) // ex-data - exData, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - if len(vs) != 1 { - return vm.NIL, fmt.Errorf("wrong number of arguments") - } - if ei, ok := vs[0].(*vm.ExInfo); ok { - // Class-tagged exceptions carry no data map; a nil - // *PersistentMap must surface as NIL, not a typed nil. - if d := ei.Data(); d != nil { - return d, nil - } - } - return vm.NIL, nil - }) // ex-cause - exCause, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - if len(vs) != 1 { - return vm.NIL, fmt.Errorf("wrong number of arguments") - } - if ei, ok := vs[0].(*vm.ExInfo); ok { - if c := ei.Cause(); c != nil { - if cev, ok := c.(*vm.ExInfo); ok { - return cev, nil - } - } - } - return vm.NIL, nil - }) // transformer-seq* — (transformer-seq* xform coll) → lazy seq // Lazily pulls elements from coll through the transducer xform. @@ -6071,73 +3632,16 @@ func installLangNS() { }) // delay — (delay body) is a macro in core.lg, but we need delay* as the constructor - delayStar, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - if len(vs) != 1 { - return vm.NIL, fmt.Errorf("delay* expects 1 arg (thunk fn)") - } - fn, ok := vs[0].(vm.Fn) - if !ok { - return vm.NIL, fmt.Errorf("delay* expected Fn") - } - return vm.NewDelay(fn), nil - }) // force — deref a delay (or return value if not a delay) - force, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - if len(vs) != 1 { - return vm.NIL, fmt.Errorf("force expects 1 arg") - } - if d, ok := vs[0].(*vm.Delay); ok { - return d.Force() - } - return vs[0], nil - }) // delay? — test if value is a Delay - isDelay, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - if len(vs) != 1 { - return vm.FALSE, nil - } - _, ok := vs[0].(*vm.Delay) - return vm.Boolean(ok), nil - }) // realized? — test if a Delay, Promise, Future, or LazySeq has been realized - isRealized, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - if len(vs) != 1 { - return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) - } - if d, ok := vs[0].(*vm.Delay); ok { - return vm.Boolean(d.IsRealized()), nil - } - if p, ok := vs[0].(*vm.Promise); ok { - return vm.Boolean(p.IsRealized()), nil - } - if s, ok := vs[0].(*vm.LazySeq); ok { - return vm.Boolean(s.IsRealized()), nil - } - return vm.NIL, fmt.Errorf("realized? expected delay, promise, future, or lazy seq") - }) // volatile! — create a volatile mutable box - volatilef, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - if len(vs) != 1 { - return vm.NIL, fmt.Errorf("volatile! expects 1 arg") - } - return vm.NewVolatile(vs[0]), nil - }) // vreset! — set volatile value - vreset, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - if len(vs) != 2 { - return vm.NIL, fmt.Errorf("vreset! expects 2 args") - } - v, ok := vs[0].(*vm.Volatile) - if !ok { - return vm.NIL, fmt.Errorf("vreset! expected Volatile") - } - return v.Reset(vs[1]), nil - }) // vswap! — apply fn to volatile value: (vswap! vol f args...) vswap := vm.NewCtxNativeFn("vswap!", func(ec *vm.ExecContext, vs []vm.Value) (vm.Value, error) { @@ -6163,20 +3667,8 @@ func installLangNS() { }) // reduced — wrap a value to signal early termination - reducedf, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - if len(vs) != 1 { - return vm.NIL, fmt.Errorf("reduced expects 1 arg") - } - return vm.NewReduced(vs[0]), nil - }) // reduced? — test if value is Reduced - isReducedf, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - if len(vs) != 1 { - return vm.FALSE, nil - } - return vm.Boolean(vm.IsReduced(vs[0])), nil - }) // compare — generic comparison: -1, 0, 1 comparef, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { @@ -6219,330 +3711,45 @@ func installLangNS() { // --- Bitwise ops --- - bitAnd, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - if len(vs) != 2 { - return vm.NIL, fmt.Errorf("bit-and expects 2 args") - } - a, ok := vs[0].(vm.Int) - if !ok { - return vm.NIL, fmt.Errorf("bit-and expected Int") - } - b, ok := vs[1].(vm.Int) - if !ok { - return vm.NIL, fmt.Errorf("bit-and expected Int") - } - return vm.MakeInt(int(a) & int(b)), nil - }) + // re-groups — find all submatch groups: (re-groups regex str) → vector of [match group1 group2 ...] - bitOr, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - if len(vs) != 2 { - return vm.NIL, fmt.Errorf("bit-or expects 2 args") - } - a, ok := vs[0].(vm.Int) - if !ok { - return vm.NIL, fmt.Errorf("bit-or expected Int") - } - b, ok := vs[1].(vm.Int) - if !ok { - return vm.NIL, fmt.Errorf("bit-or expected Int") - } - return vm.MakeInt(int(a) | int(b)), nil - }) + // promise — create a promise - bitXor, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - if len(vs) != 2 { - return vm.NIL, fmt.Errorf("bit-xor expects 2 args") - } - a, ok := vs[0].(vm.Int) - if !ok { - return vm.NIL, fmt.Errorf("bit-xor expected Int") - } - b, ok := vs[1].(vm.Int) - if !ok { - return vm.NIL, fmt.Errorf("bit-xor expected Int") - } - return vm.MakeInt(int(a) ^ int(b)), nil - }) + // deliver — deliver a value to a promise - bitNot, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { + // future — run body in a goroutine, return a promise that delivers the result + // (future* thunk) — internal, macro wraps body + futureStar := vm.NewCtxNativeFn("future*", func(ec *vm.ExecContext, vs []vm.Value) (vm.Value, error) { if len(vs) != 1 { - return vm.NIL, fmt.Errorf("bit-not expects 1 arg") + return vm.NIL, fmt.Errorf("future* expects 1 arg (thunk fn)") } - a, ok := vs[0].(vm.Int) + fn, ok := vs[0].(vm.Fn) if !ok { - return vm.NIL, fmt.Errorf("bit-not expected Int") + return vm.NIL, fmt.Errorf("future* expected Fn") } - return vm.MakeInt(^int(a)), nil - }) - - bitShiftLeft, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - if len(vs) != 2 { - return vm.NIL, fmt.Errorf("bit-shift-left expects 2 args") - } - a, ok := vs[0].(vm.Int) - if !ok { - return vm.NIL, fmt.Errorf("bit-shift-left expected Int") - } - b, ok := vs[1].(vm.Int) - if !ok { - return vm.NIL, fmt.Errorf("bit-shift-left expected Int") - } - return vm.MakeInt(int(a) << uint(b)), nil - }) - - bitShiftRight, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - if len(vs) != 2 { - return vm.NIL, fmt.Errorf("bit-shift-right expects 2 args") - } - a, ok := vs[0].(vm.Int) - if !ok { - return vm.NIL, fmt.Errorf("bit-shift-right expected Int") - } - b, ok := vs[1].(vm.Int) - if !ok { - return vm.NIL, fmt.Errorf("bit-shift-right expected Int") - } - return vm.MakeInt(int(a) >> uint(b)), nil - }) - - unsignedBitShiftRight, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - if len(vs) != 2 { - return vm.NIL, fmt.Errorf("unsigned-bit-shift-right expects 2 args") - } - a, ok := vs[0].(vm.Int) - if !ok { - return vm.NIL, fmt.Errorf("unsigned-bit-shift-right expected Int") - } - b, ok := vs[1].(vm.Int) - if !ok { - return vm.NIL, fmt.Errorf("unsigned-bit-shift-right expected Int") - } - return vm.MakeInt(int(uint(a) >> uint(b))), nil - }) - - bitTest, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - if len(vs) != 2 { - return vm.NIL, fmt.Errorf("bit-test expects 2 args") - } - a, ok := vs[0].(vm.Int) - if !ok { - return vm.NIL, fmt.Errorf("bit-test expected Int") - } - b, ok := vs[1].(vm.Int) - if !ok { - return vm.NIL, fmt.Errorf("bit-test expected Int") - } - return vm.Boolean(int(a)&(1< — debug tap queue (synchronous) - addTap, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - if len(vs) != 1 { - return vm.NIL, fmt.Errorf("add-tap expects 1 arg") - } - fn, ok := vm.AsFn(vs[0]) - if !ok { - return vm.NIL, fmt.Errorf("add-tap expected Fn") - } - tapsMu.Lock() - taps = append(taps, fn) - tapsMu.Unlock() - return vm.NIL, nil - }) - - removeTap, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - if len(vs) != 1 { - return vm.NIL, fmt.Errorf("remove-tap expects 1 arg") - } - tapsMu.Lock() - for i, t := range taps { - if t == vs[0] { - taps = append(taps[:i], taps[i+1:]...) - break - } - } - tapsMu.Unlock() - return vm.NIL, nil - }) - - tapBang, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - if len(vs) != 1 { - return vm.NIL, fmt.Errorf("tap> expects 1 arg") - } - tapsMu.Lock() - snap := make([]vm.Fn, len(taps)) - copy(snap, taps) - tapsMu.Unlock() - for _, t := range snap { - _, _ = t.Invoke([]vm.Value{vs[0]}) - } - return vm.TRUE, nil - }) // add-watch — (add-watch atom-or-var key fn) - addWatch, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - if len(vs) != 3 { - return vm.NIL, fmt.Errorf("add-watch expects 3 args") - } - fn, ok := vm.AsFn(vs[2]) - if !ok { - return vm.NIL, fmt.Errorf("add-watch expected Fn") - } - switch ref := vs[0].(type) { - case *vm.Atom: - ref.AddWatch(vs[1], fn) - case *vm.Var: - ref.AddWatch(vs[1], fn) - default: - return vm.NIL, fmt.Errorf("add-watch expected Atom or Var") - } - return vs[0], nil - }) // remove-watch — (remove-watch atom-or-var key) - removeWatch, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - if len(vs) != 2 { - return vm.NIL, fmt.Errorf("remove-watch expects 2 args") - } - switch ref := vs[0].(type) { - case *vm.Atom: - ref.RemoveWatch(vs[1]) - case *vm.Var: - ref.RemoveWatch(vs[1]) - default: - return vm.NIL, fmt.Errorf("remove-watch expected Atom or Var") - } - return vs[0], nil - }) // alter-meta! — (alter-meta! ref f & args) alterMeta := vm.NewCtxNativeFn("alter-meta!", func(ec *vm.ExecContext, vs []vm.Value) (vm.Value, error) { @@ -6564,64 +3771,7 @@ func installLangNS() { } }) - getValidator, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - if len(vs) != 1 { - return vm.NIL, fmt.Errorf("get-validator expects 1 arg") - } - a, ok := vs[0].(*vm.Atom) - if !ok { - return vm.NIL, fmt.Errorf("get-validator expected Atom") - } - return a.Validator(), nil - }) - // subvec — (subvec v start) or (subvec v start end) - subvecf, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - if len(vs) < 2 || len(vs) > 3 { - return vm.NIL, fmt.Errorf("subvec expects 2-3 args") - } - s, ok := vm.ToInt(vs[1]) - if !ok { - return vm.NIL, fmt.Errorf("subvec expected Int start") - } - - switch v := vs[0].(type) { - case vm.ArrayVector: - end := len(v) - if len(vs) == 3 { - e, ok := vm.ToInt(vs[2]) - if !ok { - return vm.NIL, fmt.Errorf("subvec expected Int end") - } - end = e - } - if s < 0 || end > len(v) || s > end { - return vm.NIL, fmt.Errorf("subvec: index out of bounds") - } - result := make([]vm.Value, end-s) - copy(result, v[s:end]) - return vm.NewArrayVector(result), nil - case vm.PersistentVector: - end := int(v.Count().(vm.Int)) - if len(vs) == 3 { - e, ok := vm.ToInt(vs[2]) - if !ok { - return vm.NIL, fmt.Errorf("subvec expected Int end") - } - end = e - } - if s < 0 || end > int(v.Count().(vm.Int)) || s > end { - return vm.NIL, fmt.Errorf("subvec: index out of bounds") - } - result := make([]vm.Value, end-s) - for i := s; i < end; i++ { - result[i-s] = v.ValueAt(vm.Int(i)) - } - return vm.NewArrayVector(result), nil - default: - return vm.NIL, fmt.Errorf("subvec expected vector") - } - }) // fn? — test if value is callable isFn, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { @@ -6639,108 +3789,18 @@ func installLangNS() { }) // double? — true only for float64 values; float? accepts float32 and float64. - isDouble, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - if len(vs) != 1 { - return vm.FALSE, nil - } - _, ok := vs[0].(vm.Float) - return vm.Boolean(ok), nil - }) // instance? — type check (simplified: checks if type name matches) - instancep, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - if len(vs) != 2 { - return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) - } - // We accept type objects (e.g. IntType) and check if the value's type matches - if t, ok := vs[0].(vm.ValueType); ok { - if vs[1].Type() == t { - return vm.TRUE, nil - } - // Walk registered ancestry so subclass values answer true for - // parent classes, e.g. (instance? Throwable (Exception. "m")). - // Types with no registered parents keep exact-match semantics. - if anc := directTypeAncestors(vs[1].Type()); anc != nil { - return anc.Contains(t), nil - } - return vm.FALSE, nil - } - if union, ok := vs[0].(*vm.TypeUnion); ok { - return vm.Boolean(union.Contains(vs[1].Type())), nil - } - // Clojure-compat interface markers (e.g. clojure.lang.IEditableCollection) - // are registered as plain symbols by installClojureCompatAliases. Answer - // instance? for them via the type→interface hierarchy so libraries that - // branch on (instance? clojure.lang.IEditableCollection coll) — like - // medley — observe the JVM-equivalent answer. - if marker, ok := vs[0].(vm.Symbol); ok { - if anc := directTypeAncestors(vs[1].Type()); anc != nil { - return vm.Boolean(anc.Contains(marker) == vm.TRUE), nil - } - } - // A protocol behaves like an interface: (instance? SomeProtocol x) is a - // membership test, matching Clojure where defprotocol generates a host - // interface. - if p, ok := vs[0].(*vm.Protocol); ok { - return vm.Boolean(p.Satisfies(vs[1])), nil - } - return vm.FALSE, nil - }) // ifn? — true if value implements Fn (invokable: functions, keywords, maps, sets, vectors) - isIFn, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - if len(vs) != 1 { - return vm.FALSE, nil - } - switch vs[0].(type) { - case vm.Fn, vm.Keyword, vm.Symbol, *vm.PersistentMap, *vm.PersistentSet, - vm.ArrayVector, vm.PersistentVector, *vm.SortedMap, *vm.SortedSet, *vm.Promise: - return vm.TRUE, nil - } - return vm.FALSE, nil - }) // identical? — reference/value identity - identical, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - if len(vs) != 2 { - return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) - } - return vm.Boolean(identicalValue(vs[0], vs[1])), nil - }) // any? — returns true for everything (every value satisfies any?) - anyp, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - if len(vs) != 1 { - return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) - } - return vm.TRUE, nil - }) // unreduced — unwrap Reduced, or return value as-is - unreduced, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - if len(vs) != 1 { - return vm.NIL, fmt.Errorf("unreduced expects 1 arg") - } - if r, ok := vs[0].(*vm.Reduced); ok { - return r.Deref(), nil - } - return vs[0], nil - }) // ensure-reduced — if already Reduced, return as-is; otherwise wrap - ensureReduced, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - if len(vs) != 1 { - return vm.NIL, fmt.Errorf("ensure-reduced expects 1 arg") - } - if _, ok := vs[0].(*vm.Reduced); ok { - return vs[0], nil - } - return vm.NewReduced(vs[0]), nil - }) - - if err != nil { - panic("lang NS init failed") - } ns := vm.NewNamespace(NameCoreNS) @@ -6852,25 +3912,6 @@ func installLangNS() { (ns.Lookup("ns").(*vm.Var)).SetMacro() // primitive fns - ns.Def("+", plus) - ns.Def("*", mul) - ns.Def("-", sub) - ns.Def("/", div) - ns.Def("+'", plusP) - ns.Def("*'", mulP) - ns.Def("-'", subP) - ns.Def("unchecked-add", uncheckedAdd) - ns.Def("unchecked-subtract", uncheckedSubtract) - ns.Def("unchecked-multiply", uncheckedMultiply) - ns.Def("unchecked-negate", uncheckedNegate) - ns.Def("unchecked-divide-int", uncheckedDivideInt) - ns.Def("unchecked-long", uncheckedLong) - ns.Def("unchecked-int", uncheckedInt) - ns.Def("unchecked-short", uncheckedShort) - ns.Def("unchecked-byte", uncheckedByte) - ns.Def("unchecked-char", uncheckedChar) - ns.Def("unchecked-double", uncheckedDouble) - ns.Def("unchecked-float", uncheckedFloat) ns.Def("=", equals) ns.Def("not=", notEq) @@ -6881,78 +3922,38 @@ func installLangNS() { ns.Def("<", lt) ns.Def(">=", ge) ns.Def("<=", le) - ns.Def("mod", mod) - ns.Def("abs", abs) // and/or are now macros in core.lg (short-circuiting) // ns.Def("and", and) // ns.Def("or", or) - ns.Def("not", not) - ns.Def("complement", complement) - ns.Def("set-macro!", setMacro) - ns.Def("gensym", gensym) ns.Def("in-ns", inNs) - ns.Def("exclude-in-current-ns", excludeInCurrentNs) - ns.Def("use", use) - ns.Def("alias", aliasf) ns.Def("name", name) ns.Def("namespace", namespace) - ns.Def("vector", vector) ns.Def("vec", vec) - ns.Def("hash-map", hashMap) - ns.Def("array-map", arrayMap) ns.Def("list", list) - ns.Def("range", rangef) - ns.Def("keyword", keyword) - ns.Def("symbol", symbolf) ns.Def("hash-set", hashSet) - ns.Def("sorted-map", sortedMap) - ns.Def("sorted-set", sortedSet) - ns.Def("sorted-map-by", sortedMapBy) - ns.Def("sorted-set-by", sortedSetBy) ns.Def("seq", seq) ns.Def("seq?", isSeq) - ns.Def("list?", isList) // basic predicates needed during early core bootstrap ns.Def("coll?", isColl) - ns.Def("empty", empty) - - ns.Def("assoc", assoc) - ns.Def("dissoc", dissoc) ns.Def("update", update) - ns.Def("cons", cons) ns.Def("conj", conj) - ns.Def("disj", disj) ns.Def("first", first) - ns.Def("second", second) ns.Def("next", next) ns.Def("rest", rest) ns.Def("get", get) - ns.Def("key", keyf) - ns.Def("val", valf) ns.Def("nth", nthf) - ns.Def("count", count) - ns.Def("contains?", contains) ns.Def("map*", mapf) ns.Def("mapv", mapv) parMapV := vm.NewCtxNativeFn("pmapv", parallelMapV) ns.Def("pmapv", parMapV) - ns.Def("chunk-first", chunkFirst) - ns.Def("chunk-rest", chunkRest) - ns.Def("chunk-next", chunkNext) - ns.Def("chunk-cons", chunkConsF) - ns.Def("chunked-seq?", chunkedSeqP) - ns.Def("chunk-buffer", chunkBufferF) - ns.Def("chunk-append", chunkAppendF) - ns.Def("chunk", chunkF) ns.Def("reduce", reduce) - ns.Def("concat*", concat) ns.Def("some", some) ns.Def("println", printlnf) @@ -6961,61 +3962,34 @@ func installLangNS() { ns.Def("apply*", apply) ns.Def("deref", deref) - ns.Def("register-host-method!", registerHostMethod) - ns.Def("register-host-class!", registerHostClass) - ns.Def("atom", atom) - ns.Def("reset!", reset) ns.Def("swap!", swap) - ns.Def("compare-and-set!", compareAndSet) ns.Def("swap-vals!", swapVals) - ns.Def("reset-vals!", resetVals) // now/lines are lg-isms → let-go.core (see the lgCore block below). - ns.Def("slurp", slurp) - ns.Def("spit", spit) // parse-int is an lg-ism → let-go.core; parse-long is the Clojure name. ns.Def("parse-long", parseInt) - ns.Def("max", max) - ns.Def("min", min) ns.Def("compare", comparef) ns.Def("sort", sort) - ns.Def(".", methodInvoke) - // async ns.Def("go*", gof) - ns.Def("chan", chanf) ns.Def(">!", chanput) ns.Def("!!", chanput) ns.Def("", tapBang) - ns.Def("add-watch", addWatch) - ns.Def("remove-watch", removeWatch) ns.Def("alter-meta!", alterMeta) - ns.Def("get-validator", getValidator) - ns.Def("subvec", subvecf) ns.Def("print", printf) ns.Def("pr", prf) - ns.Def("reduced", reducedf) - ns.Def("reduced?", isReducedf) - ns.Def("unreduced", unreduced) - ns.Def("ensure-reduced", ensureReduced) // quot — integer division (truncated toward zero) - quotf, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - if len(vs) != 2 { - return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) - } - return vm.NumQuot(vs[0], vs[1]) - }) - ns.Def("quot", quotf) // rem — remainder of truncated division (sign follows dividend) - remf, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - if len(vs) != 2 { - return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) - } - return vm.NumRem(vs[0], vs[1]) - }) - ns.Def("rem", remf) // hash — returns the hash code of a value - hashf, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - if len(vs) != 1 { - return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) - } - return vm.MakeInt(int(vm.HashValue(vs[0]))), nil - }) - ns.Def("hash", hashf) // parse-double — parse string to float - parseDouble, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - if len(vs) != 1 { - return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) - } - s, ok := vs[0].(vm.String) - if !ok { - return vm.NIL, fmt.Errorf("parse-double expected String") - } - f, err := strconv.ParseFloat(string(s), 64) - if err != nil { - return vm.NIL, nil // Clojure returns nil for unparseable - } - return vm.Float(f), nil - }) - ns.Def("parse-double", parseDouble) // parse-boolean — parse "true"/"false" to boolean - parseBool, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - if len(vs) != 1 { - return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) - } - s, ok := vs[0].(vm.String) - if !ok { - return vm.NIL, fmt.Errorf("parse-boolean expected String") - } - switch string(s) { - case "true": - return vm.TRUE, nil - case "false": - return vm.FALSE, nil - } - return vm.NIL, nil - }) - ns.Def("parse-boolean", parseBool) // NaN? — test if value is NaN - isNaN, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - if len(vs) != 1 { - return vm.FALSE, nil - } - switch v := vs[0].(type) { - case vm.Float: - return vm.Boolean(math.IsNaN(float64(v))), nil - case vm.Float32: - return vm.Boolean(math.IsNaN(float64(v))), nil - case vm.Int, *vm.BigInt, *vm.Ratio, *vm.BigDecimal: - return vm.FALSE, nil - default: - return vm.NIL, fmt.Errorf("NaN? requires a number, got %s", vs[0].Type().Name()) - } - }) - ns.Def("NaN?", isNaN) // infinite? — test if value is +/-Inf - isInfinite, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - if len(vs) != 1 { - return vm.FALSE, nil - } - if f, ok := vs[0].(vm.Float); ok { - return vm.Boolean(math.IsInf(float64(f), 0)), nil - } - return vm.FALSE, nil - }) - ns.Def("infinite?", isInfinite) // boolean? — test if value is boolean - isBool, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - if len(vs) != 1 { - return vm.FALSE, nil - } - _, ok := vs[0].(vm.Boolean) - return vm.Boolean(ok), nil - }) - ns.Def("boolean?", isBool) // char? — test if value is char - isChar, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - if len(vs) != 1 { - return vm.FALSE, nil - } - _, ok := vs[0].(vm.Char) - return vm.Boolean(ok), nil - }) - ns.Def("char?", isChar) // var? — test if value is a var - isVar, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - if len(vs) != 1 { - return vm.FALSE, nil - } - _, ok := vs[0].(*vm.Var) - return vm.Boolean(ok), nil - }) - ns.Def("var?", isVar) // string/index-of — find first rune index of substring/char indexOf, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { @@ -7678,11 +4197,6 @@ func installLangNS() { // Helper: build a typed array from size or seq - byteArrayf, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - return buildArray(vm.ArrayByte, vs) - }) - ns.Def("byte-array", byteArrayf) - intArrayf, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return buildArray(vm.ArrayInt, vs) }) @@ -7695,131 +4209,15 @@ func installLangNS() { ns.Def("double-array", doubleArrayf) ns.Def("float-array", doubleArrayf) - objectArrayf, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - return buildArray(vm.ArrayObject, vs) - }) - ns.Def("object-array", objectArrayf) - // make-array — (make-array type size) - makeArrayf, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - if len(vs) != 2 { - return vm.NIL, fmt.Errorf("make-array expects 2 args (type, size)") - } - size, ok := vs[1].(vm.Int) - if !ok { - return vm.NIL, fmt.Errorf("make-array size must be Int") - } - n := int(size) - if n < 0 { - return vm.NIL, fmt.Errorf("negative array size: %d", n) - } - switch t := vs[0].(type) { - case vm.Keyword: - switch string(t) { - case "byte": - return vm.NewByteArray(n), nil - case "int", "long": - return vm.NewIntArray(n), nil - case "double", "float": - return vm.NewFloatArray(n), nil - case "object": - return vm.NewObjectArray(n), nil - } - return vm.NIL, fmt.Errorf("unknown array type: %s", t) - default: - // Default to object-array - return vm.NewObjectArray(n), nil - } - }) - ns.Def("make-array", makeArrayf) // aget — (aget arr idx) or (aget arr idx idx2 ...) - agetf, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - if len(vs) < 2 { - return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) - } - arr, ok := vs[0].(*vm.TypedArray) - if !ok { - return vm.NIL, fmt.Errorf("aget expects array, got %s", vs[0].Type().Name()) - } - idx, ok := vs[1].(vm.Int) - if !ok { - return vm.NIL, fmt.Errorf("aget index must be Int") - } - i := int(idx) - if i < 0 || i >= arr.Len() { - return vm.NIL, fmt.Errorf("array index %d out of bounds for length %d", i, arr.Len()) - } - val := arr.Get(i) - // Support nested access: (aget arr i j k ...) - for _, extra := range vs[2:] { - inner, ok := val.(*vm.TypedArray) - if !ok { - return vm.NIL, fmt.Errorf("aget nested: expected array, got %s", val.Type().Name()) - } - idx, ok := extra.(vm.Int) - if !ok { - return vm.NIL, fmt.Errorf("aget index must be Int") - } - j := int(idx) - if j < 0 || j >= inner.Len() { - return vm.NIL, fmt.Errorf("array index %d out of bounds for length %d", j, inner.Len()) - } - val = inner.Get(j) - } - return val, nil - }) - ns.Def("aget", agetf) // aset — (aset arr idx val) - asetf, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - if len(vs) != 3 { - return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) - } - arr, ok := vs[0].(*vm.TypedArray) - if !ok { - return vm.NIL, fmt.Errorf("aset expects array, got %s", vs[0].Type().Name()) - } - idx, ok := vs[1].(vm.Int) - if !ok { - return vm.NIL, fmt.Errorf("aset index must be Int") - } - i := int(idx) - if i < 0 || i >= arr.Len() { - return vm.NIL, fmt.Errorf("array index %d out of bounds for length %d", i, arr.Len()) - } - if err := arr.Set(i, vs[2]); err != nil { - return vm.NIL, err - } - return vs[2], nil - }) - ns.Def("aset", asetf) // alength — (alength arr) - alengthf, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - if len(vs) != 1 { - return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) - } - arr, ok := vs[0].(*vm.TypedArray) - if !ok { - return vm.NIL, fmt.Errorf("alength expects array, got %s", vs[0].Type().Name()) - } - return vm.MakeInt(arr.Len()), nil - }) - ns.Def("alength", alengthf) // aclone — (aclone arr) - aclonef, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - if len(vs) != 1 { - return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) - } - arr, ok := vs[0].(*vm.TypedArray) - if !ok { - return vm.NIL, fmt.Errorf("aclone expects array, got %s", vs[0].Type().Name()) - } - return arr.Clone(), nil - }) - ns.Def("aclone", aclonef) // to-array — (to-array coll) creates object-array from seq toArrayf, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { @@ -7869,22 +4267,6 @@ func installLangNS() { ns.Def("into-array", intoArrayf) // bytes — coerce string to byte-array - bytesf, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - if len(vs) != 1 { - return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) - } - switch v := vs[0].(type) { - case vm.String: - data := []byte(string(v)) - return vm.NewByteArrayFrom(data), nil - case *vm.TypedArray: - if v.Kind() == vm.ArrayByte { - return v, nil - } - } - return vm.NIL, fmt.Errorf("bytes expects String or byte-array, got %s", vs[0].Type().Name()) - }) - ns.Def("bytes", bytesf) // base64-encode — (base64-encode x) → standard padded base64 String. x is a // String or byte-array; pairs with the byte-array sinks and read-bytes. @@ -7965,21 +4347,11 @@ func installLangNS() { ns.Def("longs", intsf) // doubles — coerce seq to double-array - doublesf, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { + + // array? — type predicate + isArrayf, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { if len(vs) != 1 { - return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) - } - if a, ok := vs[0].(*vm.TypedArray); ok && a.Kind() == vm.ArrayFloat { - return a, nil - } - return buildArray(vm.ArrayFloat, vs) - }) - ns.Def("doubles", doublesf) - - // array? — type predicate - isArrayf, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - if len(vs) != 1 { - return vm.FALSE, nil + return vm.FALSE, nil } _, ok := vs[0].(*vm.TypedArray) return vm.Boolean(ok), nil @@ -7989,14 +4361,6 @@ func installLangNS() { // bytes?: true iff the value is a byte-kind TypedArray (backing []byte). // array? doesn't distinguish element kind, and a TypedArray's Kind() is // not reachable from .lg, so this lives in Go alongside array?. - bytesP, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - if len(vs) != 1 { - return vm.FALSE, nil - } - a, ok := vs[0].(*vm.TypedArray) - return vm.Boolean(ok && a.Kind() == vm.ArrayByte), nil - }) - ns.Def("bytes?", bytesP) // alter-var-root — alter a var's root binding via (f root & args). // Reads/writes the root, bypassing any current dynamic binding. @@ -8024,51 +4388,16 @@ func installLangNS() { ns.Def("alter-var-root", alterVarRoot) // var-get — get the value of a Var - varGet, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - if len(vs) != 1 { - return vm.NIL, fmt.Errorf("var-get expects 1 arg") - } - v, ok := vs[0].(*vm.Var) - if !ok { - return vm.NIL, fmt.Errorf("var-get expects a Var") - } - return v.Deref(), nil - }) - ns.Def("var-get", varGet) // bound? — true when the var has a bound value: a root binding or an active // dynamic binding (matching Clojure). Distinguishes a forward-declared/ // compiler-interned var from one that has actually been set, which `defonce` // relies on. - boundQ, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - if len(vs) != 1 { - return vm.NIL, fmt.Errorf("bound? expects 1 arg") - } - v, ok := vs[0].(*vm.Var) - if !ok { - return vm.NIL, fmt.Errorf("bound? expects a Var") - } - if v.IsBound() { - return vm.TRUE, nil - } - return vm.FALSE, nil - }) - ns.Def("bound?", boundQ) // -copy-form-source! carries reader source metadata across macro and IR // rewrites which necessarily allocate a fresh list. It is intentionally a // core implementation detail: ordinary metadata cannot represent the // side-table spans retained by FormSource. - copyFormSource, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - if len(vs) != 2 { - return vm.NIL, fmt.Errorf("-copy-form-source! expects 2 args") - } - if info := vm.FormSource.Get(vs[0]); info != nil { - vm.FormSource.Set(vs[1], *info) - } - return vs[1], nil - }) - ns.Def("-copy-form-source!", copyFormSource) warnReflection := vm.NewCtxNativeFn("-warn-reflection!", func(ec *vm.ExecContext, vs []vm.Value) (vm.Value, error) { if len(vs) != 3 { @@ -8174,50 +4503,10 @@ func installLangNS() { // arity and variadic flag. Used by the IR-compile path of the defn // macro so the embedded function value flows back into the standard // compile pipeline as a constant. - chunkToFnFn, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - if len(vs) != 3 { - return vm.NIL, fmt.Errorf("chunk->fn expects (arity variadic? chunk), got %d args", len(vs)) - } - arityV, ok := vs[0].(vm.Int) - if !ok { - return vm.NIL, fmt.Errorf("chunk->fn: arity must be Int, got %s", vs[0].Type().Name()) - } - variadic := false - if b, ok := vs[1].(vm.Boolean); ok { - variadic = bool(b) - } else if vs[1] != vm.NIL { - return vm.NIL, fmt.Errorf("chunk->fn: variadic? must be Boolean or nil, got %s", vs[1].Type().Name()) - } - boxed, ok := vs[2].(*vm.Boxed) - if !ok { - return vm.NIL, fmt.Errorf("chunk->fn: third arg must be boxed CodeChunk, got %s", vs[2].Type().Name()) - } - chunk, ok := boxed.Unbox().(*vm.CodeChunk) - if !ok { - return vm.NIL, fmt.Errorf("chunk->fn: boxed value is not a CodeChunk") - } - return vm.MakeFunc(int(arityV), variadic, chunk), nil - }) - ns.Def("chunk->fn", chunkToFnFn) // make-multi-arity — combine a list of *Func/*Closure values into a // *MultiArityFn. Used by the IR pipeline to assemble multi-arity // functions at compile time. - makeMultiArityFn, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - if len(vs) != 1 { - return vm.NIL, fmt.Errorf("make-multi-arity expects 1 arg (list of functions)") - } - list, ok := vs[0].(*vm.List) - if !ok { - return vm.NIL, fmt.Errorf("make-multi-arity expects a list, got %s", vs[0].Type().Name()) - } - var fns []vm.Value - for e := vm.Seq(list); e != nil; e = e.Next() { - fns = append(fns, e.First()) - } - return vm.MakeMultiArity(fns) - }) - ns.Def("make-multi-arity", makeMultiArityFn) // with-arity — (with-arity f arity variadic?) wraps callable f in a native // that DECLARES the given arity. ir.direct's invokers are necessarily @@ -8302,89 +4591,15 @@ func installLangNS() { ns.Def("sleep", sleepf) // intern — intern a var in a namespace - internf, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - if len(vs) < 2 || len(vs) > 3 { - return vm.NIL, fmt.Errorf("intern expects 2 or 3 args") - } - var targetNS *vm.Namespace - switch n := vs[0].(type) { - case vm.Symbol: - targetNS = nsRegistry[resolveNSAlias(string(n))] - case *vm.Namespace: - targetNS = n - default: - return vm.NIL, fmt.Errorf("intern expects a namespace or symbol") - } - if targetNS == nil { - return vm.NIL, fmt.Errorf("namespace not found") - } - sym, ok := vs[1].(vm.Symbol) - if !ok { - return vm.NIL, fmt.Errorf("intern expects a symbol name") - } - if len(vs) == 2 { - if existing := targetNS.LookupLocal(sym); existing != nil { - return existing, nil - } - return targetNS.Def(string(sym), vm.NIL), nil - } - // 3-arg form. If the Var already exists, UPDATE its root in - // place; otherwise create a fresh Var. This matters when - // other compiled code holds a captured Var pointer in its - // const pool — recreating the Var would leave those pointers - // referencing the old nil-rooted Var (the chicken-and-egg - // problem from Phase F's data-layer rollout). - if existing := targetNS.LookupLocal(sym); existing != nil { - existing.SetRoot(vs[2]) - return existing, nil - } - v := targetNS.Def(string(sym), vs[2]) - return v, nil - }) - ns.Def("intern", internf) // apply-def-meta! — apply def metadata (and the :dynamic / :private flags it // implies) to a Var, mirroring the bytecode defCompiler. Used by the IR // build-def lowering, which interns the var at build time and so must apply // its meta then, just as defCompiler does at compile time. - applyDefMetaf, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - if len(vs) != 2 { - return vm.NIL, fmt.Errorf("apply-def-meta! expects 2 args") - } - v, ok := vs[0].(*vm.Var) - if !ok { - return vm.NIL, fmt.Errorf("apply-def-meta! expects a Var") - } - ApplyVarMeta(v, vs[1]) - return v, nil - }) - ns.Def("apply-def-meta!", applyDefMetaf) // create-ns — create or return existing namespace - createNsf, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - if len(vs) != 1 { - return vm.NIL, fmt.Errorf("create-ns expects 1 arg") - } - sym, ok := vs[0].(vm.Symbol) - if !ok { - return vm.NIL, fmt.Errorf("create-ns expects a symbol") - } - return NS(string(sym)), nil - }) - ns.Def("create-ns", createNsf) // pop! — pop from a transient vector - popBang, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - if len(vs) != 1 { - return vm.NIL, fmt.Errorf("pop! expects 1 arg") - } - tv, ok := vs[0].(*vm.TransientVector) - if !ok { - return vm.NIL, fmt.Errorf("pop! expects a transient vector") - } - return tv.Pop() - }) - ns.Def("pop!", popBang) // with-out-str* — capture *out* output as string. Binding-based capture // (no process-global os.Stdout swap). Rebinds *out* to a bytes.Buffer- @@ -8428,55 +4643,12 @@ func installLangNS() { ns.Def("with-out-str*", withOutStrf) // uuid? — type predicate for UUID - isUUID, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - if len(vs) != 1 { - return vm.FALSE, nil - } - _, ok := vs[0].(*vm.UUID) - return vm.Boolean(ok), nil - }) - ns.Def("uuid?", isUUID) // inst? — type predicate for Instant - isInst, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - if len(vs) != 1 { - return vm.FALSE, nil - } - _, ok := vs[0].(*vm.Instant) - return vm.Boolean(ok), nil - }) - ns.Def("inst?", isInst) // parse-uuid — parse a string into a UUID - parseUUID, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - if len(vs) != 1 { - return vm.NIL, fmt.Errorf("parse-uuid expects 1 arg") - } - s, ok := vs[0].(vm.String) - if !ok { - return vm.NIL, fmt.Errorf("parse-uuid expects a string, got %s", vs[0].Type().Name()) - } - u := vm.ParseUUID(string(s)) - if u == nil { - return vm.NIL, nil - } - return u, nil - }) - ns.Def("parse-uuid", parseUUID) // == — numeric equality across numeric categories. - numericEq, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { - if len(vs) < 2 { - return vm.TRUE, nil - } - for i := 1; i < len(vs); i++ { - if !vm.NumEquivalent(vs[0], vs[i]) { - return vm.FALSE, nil - } - } - return vm.TRUE, nil - }) - ns.Def("==", numericEq) // IR namespace primitives — declared in pkg/ir/ir_bridge.lg, // generated into pkg/rt/ir_bridge_generated.go via 'make generate-ir-bridge'. @@ -8890,3 +5062,4094 @@ func buildArray(kind vm.ArrayKind, vs []vm.Value) (vm.Value, error) { } return arr, nil } + +// --- hoisted native primitives (see cmd/hoist-natives) --- + +//lg:native +//lg:name + +func CorePlus(vs ...vm.Value) (vm.Value, error) { + if len(vs) == 0 { + return vm.MakeInt(0), nil + } + if len(vs) == 1 { + return vs[0], nil + } + acc := vs[0] + for i := 1; i < len(vs); i++ { + var err error + acc, err = vm.NumAdd(acc, vs[i]) + if err != nil { + return vm.NIL, err + } + } + return acc, nil +} + +//lg:native +//lg:name * +func CoreMul(vs ...vm.Value) (vm.Value, error) { + if len(vs) == 0 { + return vm.MakeInt(1), nil + } + if len(vs) == 1 { + return vs[0], nil + } + acc := vs[0] + for i := 1; i < len(vs); i++ { + var err error + acc, err = vm.NumMul(acc, vs[i]) + if err != nil { + return vm.NIL, err + } + } + return acc, nil +} + +//lg:native +//lg:name - +func CoreSub(vs ...vm.Value) (vm.Value, error) { + if len(vs) < 1 { + return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) + } + if len(vs) == 1 { + return vm.NumNeg(vs[0]) + } + acc := vs[0] + for i := 1; i < len(vs); i++ { + var err error + acc, err = vm.NumSub(acc, vs[i]) + if err != nil { + return vm.NIL, err + } + } + return acc, nil +} + +//lg:native +//lg:name / +func CoreDiv(vs ...vm.Value) (vm.Value, error) { + if len(vs) < 1 { + return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) + } + if len(vs) == 1 { + return vm.NumDiv(vm.MakeInt(1), vs[0]) + } + acc := vs[0] + for i := 1; i < len(vs); i++ { + var err error + acc, err = vm.NumDiv(acc, vs[i]) + if err != nil { + return vm.NIL, err + } + } + return acc, nil +} + +//lg:native +//lg:name +' +func CorePlusP(vs ...vm.Value) (vm.Value, error) { + if len(vs) == 0 { + return vm.MakeInt(0), nil + } + if len(vs) == 1 { + return vs[0], nil + } + acc := vs[0] + for i := 1; i < len(vs); i++ { + var err error + acc, err = vm.NumAddP(acc, vs[i]) + if err != nil { + return vm.NIL, err + } + } + return acc, nil +} + +//lg:native +//lg:name *' +func CoreMulP(vs ...vm.Value) (vm.Value, error) { + if len(vs) == 0 { + return vm.MakeInt(1), nil + } + if len(vs) == 1 { + return vs[0], nil + } + acc := vs[0] + for i := 1; i < len(vs); i++ { + var err error + acc, err = vm.NumMulP(acc, vs[i]) + if err != nil { + return vm.NIL, err + } + } + return acc, nil +} + +//lg:native +//lg:name -' +func CoreSubP(vs ...vm.Value) (vm.Value, error) { + if len(vs) < 1 { + return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) + } + if len(vs) == 1 { + return vm.NumNegP(vs[0]) + } + acc := vs[0] + for i := 1; i < len(vs); i++ { + var err error + acc, err = vm.NumSubP(acc, vs[i]) + if err != nil { + return vm.NIL, err + } + } + return acc, nil +} + +//lg:native +//lg:name unchecked-add +func CoreUncheckedAdd(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 2 { + return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) + } + a, ok := vm.ToInt(vs[0]) + if !ok { + return vm.NIL, fmt.Errorf("unchecked-add expected integer, got %s", vs[0].Type().Name()) + } + b, ok := vm.ToInt(vs[1]) + if !ok { + return vm.NIL, fmt.Errorf("unchecked-add expected integer, got %s", vs[1].Type().Name()) + } + return vm.MakeInt(int(int64(a) + int64(b))), nil +} + +//lg:native +//lg:name unchecked-subtract +func CoreUncheckedSubtract(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 2 { + return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) + } + a, ok := vm.ToInt(vs[0]) + if !ok { + return vm.NIL, fmt.Errorf("unchecked-subtract expected integer, got %s", vs[0].Type().Name()) + } + b, ok := vm.ToInt(vs[1]) + if !ok { + return vm.NIL, fmt.Errorf("unchecked-subtract expected integer, got %s", vs[1].Type().Name()) + } + return vm.MakeInt(int(int64(a) - int64(b))), nil +} + +//lg:native +//lg:name unchecked-multiply +func CoreUncheckedMultiply(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 2 { + return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) + } + a, ok := vm.ToInt(vs[0]) + if !ok { + return vm.NIL, fmt.Errorf("unchecked-multiply expected integer, got %s", vs[0].Type().Name()) + } + b, ok := vm.ToInt(vs[1]) + if !ok { + return vm.NIL, fmt.Errorf("unchecked-multiply expected integer, got %s", vs[1].Type().Name()) + } + return vm.MakeInt(int(int64(a) * int64(b))), nil +} + +//lg:native +//lg:name unchecked-negate +func CoreUncheckedNegate(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 1 { + return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) + } + a, ok := vm.ToInt(vs[0]) + if !ok { + return vm.NIL, fmt.Errorf("unchecked-negate expected integer, got %s", vs[0].Type().Name()) + } + + return vm.MakeInt(int(-int64(a))), nil +} + +//lg:native +//lg:name unchecked-divide-int +func CoreUncheckedDivideInt(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 2 { + return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) + } + a, ok := vm.ToInt(vs[0]) + if !ok { + return vm.NIL, fmt.Errorf("unchecked-divide-int expected integer, got %s", vs[0].Type().Name()) + } + b, ok := vm.ToInt(vs[1]) + if !ok { + return vm.NIL, fmt.Errorf("unchecked-divide-int expected integer, got %s", vs[1].Type().Name()) + } + if b == 0 { + return vm.NIL, fmt.Errorf("divide by zero") + } + + if int64(a) == math.MinInt64 && int64(b) == -1 { + return vm.NIL, fmt.Errorf("integer overflow") + } + return vm.MakeInt(int(int64(a) / int64(b))), nil +} + +//lg:native +//lg:name unchecked-long +func CoreUncheckedLong(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 1 { + return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) + } + switch v := vs[0].(type) { + case vm.Int: + return v, nil + case *vm.BigInt: + + mask := new(big.Int).Lsh(big.NewInt(1), 64) + lo := new(big.Int).Mod(v.Val(), mask) + return vm.MakeInt(int(int64(lo.Uint64()))), nil + case vm.Float: + return vm.MakeInt(int(int64(float64(v)))), nil + default: + return vm.NIL, fmt.Errorf("unchecked-long expected integer or float, got %s", vs[0].Type().Name()) + } +} + +//lg:native +//lg:name unchecked-int +func CoreUncheckedInt(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 1 { + return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) + } + switch v := vs[0].(type) { + case vm.Int: + return vm.MakeInt(int(int32(int64(v)))), nil + case *vm.BigInt: + + mask := new(big.Int).Lsh(big.NewInt(1), 64) + lo := new(big.Int).Mod(v.Val(), mask) + return vm.MakeInt(int(int32(lo.Uint64()))), nil + case vm.Float: + return vm.MakeInt(int(int32(float64(v)))), nil + default: + return vm.NIL, fmt.Errorf("unchecked-int expected integer or float, got %s", vs[0].Type().Name()) + } +} + +//lg:native +//lg:name unchecked-short +func CoreUncheckedShort(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 1 { + return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) + } + switch v := vs[0].(type) { + case vm.Int: + return vm.MakeInt(int(int16(int64(v)))), nil + case *vm.BigInt: + + mask := new(big.Int).Lsh(big.NewInt(1), 64) + lo := new(big.Int).Mod(v.Val(), mask) + return vm.MakeInt(int(int16(lo.Uint64()))), nil + case vm.Float: + return vm.MakeInt(int(int16(float64(v)))), nil + default: + return vm.NIL, fmt.Errorf("unchecked-short expected integer or float, got %s", vs[0].Type().Name()) + } +} + +//lg:native +//lg:name unchecked-byte +func CoreUncheckedByte(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 1 { + return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) + } + switch v := vs[0].(type) { + case vm.Int: + return vm.MakeInt(int(int8(int64(v)))), nil + case *vm.BigInt: + + mask := new(big.Int).Lsh(big.NewInt(1), 64) + lo := new(big.Int).Mod(v.Val(), mask) + return vm.MakeInt(int(int8(lo.Uint64()))), nil + case vm.Float: + return vm.MakeInt(int(int8(float64(v)))), nil + default: + return vm.NIL, fmt.Errorf("unchecked-byte expected integer or float, got %s", vs[0].Type().Name()) + } +} + +//lg:native +//lg:name unchecked-char +func CoreUncheckedChar(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 1 { + return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) + } + switch v := vs[0].(type) { + case vm.Int: + return vm.Char(rune(uint16(int64(v)))), nil + case *vm.BigInt: + + mask := new(big.Int).Lsh(big.NewInt(1), 64) + lo := new(big.Int).Mod(v.Val(), mask) + return vm.Char(rune(uint16(lo.Uint64()))), nil + case vm.Float: + return vm.Char(rune(uint16(int64(float64(v))))), nil + default: + return vm.NIL, fmt.Errorf("unchecked-char expected integer or float, got %s", vs[0].Type().Name()) + } +} + +//lg:native +//lg:name unchecked-double +func CoreUncheckedDouble(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 1 { + return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) + } + switch v := vs[0].(type) { + case vm.Int: + return vm.Float(float64(int64(v))), nil + case *vm.BigInt: + + f, _ := new(big.Float).SetInt(v.Val()).Float64() + return vm.Float(f), nil + case vm.Float: + return v, nil + default: + return vm.NIL, fmt.Errorf("unchecked-double expected numeric, got %s", vs[0].Type().Name()) + } +} + +//lg:native +//lg:name unchecked-float +func CoreUncheckedFloat(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 1 { + return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) + } + switch v := vs[0].(type) { + case vm.Int: + + return vm.Float(float64(float32(int64(v)))), nil + case *vm.BigInt: + f, _ := new(big.Float).SetInt(v.Val()).Float64() + return vm.Float(float64(float32(f))), nil + case vm.Float: + return vm.Float(float64(float32(float64(v)))), nil + default: + return vm.NIL, fmt.Errorf("unchecked-float expected numeric, got %s", vs[0].Type().Name()) + } +} + +//lg:native +//lg:name mod +func CoreMod(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 2 { + return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) + } + return vm.NumMod(vs[0], vs[1]) +} + +//lg:native +//lg:name abs +func CoreAbs(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 1 { + return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) + } + return vm.NumAbs(vs[0]) +} + +//lg:native +//lg:name not +func CoreNot(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 1 { + return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) + } + return builtins.Not(vs[0]) +} + +//lg:native +//lg:name complement +func CoreComplement(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 1 { + return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) + } + f, ok := vm.AsFn(vs[0]) + if !ok { + return vm.NIL, fmt.Errorf("complement expected Fn") + } + + wrapped := vm.NewCtxNativeFn("complemented-fn", func(cec *vm.ExecContext, args []vm.Value) (vm.Value, error) { + v, err := cec.Invoke(f, args) + if err != nil { + return vm.NIL, err + } + return vm.Boolean(!vm.IsTruthy(v)), nil + }) + return wrapped, nil +} + +//lg:native +//lg:name set-macro! +func CoreSetMacro(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 1 { + return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) + } + m := vs[0].(*vm.Var) + m.SetMacro() + return m, nil +} + +//lg:native +//lg:name gensym +func CoreGensym(vs ...vm.Value) (vm.Value, error) { + prefix := "G__" + if len(vs) == 1 { + arg, ok := vs[0].(vm.String) + if !ok { + return vm.NIL, fmt.Errorf("gensym expected String") + } + prefix = string(arg) + } + return vm.Symbol(fmt.Sprintf("%s%d", prefix, nextID())), nil +} + +//lg:native +//lg:name vector +func CoreVector(vs ...vm.Value) (vm.Value, error) { + return builtins.Vector(vs...) +} + +//lg:native +//lg:name hash-map +func CoreHashMap(vs ...vm.Value) (vm.Value, error) { + if len(vs)%2 != 0 { + return vm.NIL, fmt.Errorf("hash-map requires an even number of arguments, got %d", len(vs)) + } + return vm.NewMap(vs), nil +} + +//lg:native +//lg:name array-map +func CoreArrayMap(vs ...vm.Value) (vm.Value, error) { + if len(vs)%2 != 0 { + return vm.NIL, fmt.Errorf("array-map requires an even number of arguments, got %d", len(vs)) + } + return vm.NewArrayMap(vs), nil +} + +//lg:native +//lg:name sorted-map +func CoreSortedMap(vs ...vm.Value) (vm.Value, error) { + if len(vs)%2 != 0 { + return vm.NIL, fmt.Errorf("sorted-map requires even number of arguments, got %d", len(vs)) + } + return vm.NewSortedMap(nil, vs), nil +} + +//lg:native +//lg:name sorted-set +func CoreSortedSet(vs ...vm.Value) (vm.Value, error) { + return vm.NewSortedSet(nil, vs), nil +} + +//lg:native +//lg:name sorted-map-by +func CoreSortedMapBy(vs ...vm.Value) (vm.Value, error) { + if len(vs) < 1 { + return vm.NIL, fmt.Errorf("sorted-map-by requires a comparator") + } + comp, ok := vm.AsFn(vs[0]) + if !ok { + return vm.NIL, fmt.Errorf("sorted-map-by first arg must be a function") + } + kvs := vs[1:] + if len(kvs)%2 != 0 { + return vm.NIL, fmt.Errorf("sorted-map-by requires even number of key-value arguments") + } + return vm.NewSortedMap(fnComparator(comp), kvs), nil +} + +//lg:native +//lg:name sorted-set-by +func CoreSortedSetBy(vs ...vm.Value) (vm.Value, error) { + if len(vs) < 1 { + return vm.NIL, fmt.Errorf("sorted-set-by requires a comparator") + } + comp, ok := vm.AsFn(vs[0]) + if !ok { + return vm.NIL, fmt.Errorf("sorted-set-by first arg must be a function") + } + return vm.NewSortedSet(fnComparator(comp), vs[1:]), nil +} + +//lg:native +//lg:name chunk-first +func CoreChunkFirst(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 1 { + return vm.NIL, fmt.Errorf("chunk-first: wrong number of arguments %d", len(vs)) + } + cs, err := asChunked(vs[0], "chunk-first") + if err != nil { + return vm.NIL, err + } + return cs.ChunkedFirst().(vm.Value), nil +} + +//lg:native +//lg:name chunk-rest +func CoreChunkRest(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 1 { + return vm.NIL, fmt.Errorf("chunk-rest: wrong number of arguments %d", len(vs)) + } + cs, err := asChunked(vs[0], "chunk-rest") + if err != nil { + return vm.NIL, err + } + m := cs.ChunkedMore() + if m == nil { + return vm.EmptyList, nil + } + return m.(vm.Value), nil +} + +//lg:native +//lg:name chunk-next +func CoreChunkNext(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 1 { + return vm.NIL, fmt.Errorf("chunk-next: wrong number of arguments %d", len(vs)) + } + cs, err := asChunked(vs[0], "chunk-next") + if err != nil { + return vm.NIL, err + } + n := cs.ChunkedNext() + if n == nil { + return vm.NIL, nil + } + return n.(vm.Value), nil +} + +//lg:native +//lg:name chunk-cons +func CoreChunkConsF(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 2 { + return vm.NIL, fmt.Errorf("chunk-cons: wrong number of arguments %d", len(vs)) + } + chunk, ok := vs[0].(vm.IChunk) + if !ok { + return vm.NIL, fmt.Errorf("chunk-cons: first arg must be a chunk") + } + var tail vm.Seq + if vs[1] != vm.NIL { + s, err := seqOf(vs[1]) + if err != nil { + return vm.NIL, fmt.Errorf("chunk-cons: second arg must be a seq or nil") + } + tail = s + } + out := vm.ConsChunk(chunk, tail) + if out == nil { + return vm.EmptyList, nil + } + return out.(vm.Value), nil +} + +//lg:native +//lg:name chunked-seq? +func CoreChunkedSeqP(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 1 { + return vm.NIL, fmt.Errorf("chunked-seq?: wrong number of arguments %d", len(vs)) + } + if vs[0] == vm.NIL { + return vm.FALSE, nil + } + s, err := seqOf(vs[0]) + if err != nil || s == nil { + return vm.FALSE, nil + } + _, ok := vm.AsChunkedSeq(s) + return vm.Boolean(ok), nil +} + +//lg:native +//lg:name chunk-buffer +func CoreChunkBufferF(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 1 { + return vm.NIL, fmt.Errorf("chunk-buffer: wrong number of arguments %d", len(vs)) + } + n, ok := vs[0].(vm.Int) + if !ok { + return vm.NIL, fmt.Errorf("chunk-buffer: arg must be Int") + } + return vm.NewChunkBuffer(int(n)), nil +} + +//lg:native +//lg:name chunk-append +func CoreChunkAppendF(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 2 { + return vm.NIL, fmt.Errorf("chunk-append: wrong number of arguments %d", len(vs)) + } + b, ok := vs[0].(*vm.ChunkBuffer) + if !ok { + return vm.NIL, fmt.Errorf("chunk-append: first arg must be a chunk-buffer") + } + b.Append(vs[1]) + return b, nil +} + +//lg:native +//lg:name chunk +func CoreChunkF(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 1 { + return vm.NIL, fmt.Errorf("chunk: wrong number of arguments %d", len(vs)) + } + b, ok := vs[0].(*vm.ChunkBuffer) + if !ok { + return vm.NIL, fmt.Errorf("chunk: arg must be a chunk-buffer") + } + return b.Chunk().(vm.Value), nil +} + +//lg:native +//lg:name range +func CoreRangef(vs ...vm.Value) (vm.Value, error) { + if len(vs) == 0 { + + return vm.NewInfiniteRange(0, 1), nil + } + if len(vs) > 3 { + return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) + } + var start, end, step vm.Int + step = 1 + var err error + var endArg vm.Value + switch len(vs) { + case 1: + endArg = vs[0] + case 2: + endArg = vs[1] + if start, err = rangeInt(vs[0], "start"); err != nil { + return vm.NIL, err + } + case 3: + endArg = vs[1] + if start, err = rangeInt(vs[0], "start"); err != nil { + return vm.NIL, err + } + if step, err = rangeInt(vs[2], "step"); err != nil { + return vm.NIL, err + } + } + + if f, ok := endArg.(vm.Float); ok { + if math.IsInf(float64(f), 0) { + if (f > 0 && step > 0) || (f < 0 && step < 0) { + return vm.NewInfiniteRange(int(start), int(step)), nil + } + return vm.NewRange(0, 0, 1), nil + } + if step > 0 { + endArg = vm.Int(math.Ceil(float64(f))) + } else { + endArg = vm.Int(math.Floor(float64(f))) + } + } + if end, err = rangeInt(endArg, "end"); err != nil { + return vm.NIL, err + } + return vm.NewRange(start, end, step), nil +} + +//lg:native +//lg:name keyword +func CoreKeyword(vs ...vm.Value) (vm.Value, error) { + if len(vs) < 1 || len(vs) > 2 { + return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) + } + if len(vs) == 2 { + // (keyword ns name) — both must be strings (or nil ns) + var nsStr, nameStr string + if vs[0] != vm.NIL { + switch n := vs[0].(type) { + case vm.String: + nsStr = string(n) + default: + return vm.NIL, fmt.Errorf("keyword namespace must be a string, got %s", vs[0].Type()) + } + } + switch n := vs[1].(type) { + case vm.String: + nameStr = string(n) + default: + return vm.NIL, fmt.Errorf("keyword name must be a string, got %s", vs[1].Type()) + } + if nsStr == "" && vs[0] == vm.NIL { + return vm.Keyword(nameStr), nil + } + return vm.Keyword(nsStr + "/" + nameStr), nil + } + if vs[0] == vm.NIL { + return vm.NIL, nil + } + if k, ok := vs[0].(vm.Keyword); ok { + return k, nil + } + if k, ok := vs[0].(vm.Symbol); ok { + return vm.Keyword(k), nil + } + if k, ok := vs[0].(vm.String); ok { + return vm.Keyword(k), nil + } + return vm.NIL, fmt.Errorf("keyword expects keyword, symbol, or string, got %s", vs[0].Type()) +} + +//lg:native +//lg:name symbol +func CoreSymbolf(vs ...vm.Value) (vm.Value, error) { + if len(vs) < 1 || len(vs) > 2 { + return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) + } + toStr := func(v vm.Value) (string, bool) { + switch s := v.(type) { + case vm.String: + return string(s), true + case vm.Symbol: + return string(s), true + case vm.Keyword: + return string(s), true + default: + return "", false + } + } + if len(vs) == 1 { + if vs[0] == vm.NIL { + return vm.NIL, fmt.Errorf("symbol expected String, Symbol, Keyword, or Var") + } + if v, ok := vs[0].(*vm.Var); ok { + return vm.Symbol(externalNSName(v.NS()) + "/" + v.VarName()), nil + } + if s, ok := toStr(vs[0]); ok { + return vm.Symbol(s), nil + } + return vm.NIL, fmt.Errorf("symbol expected String or Symbol") + } + nsStr := "" + if vs[0] != vm.NIL { + ns, ok := vs[0].(vm.String) + if !ok { + return vm.NIL, fmt.Errorf("symbol expected String namespace") + } + nsStr = string(ns) + } + name, ok := vs[1].(vm.String) + if !ok { + return vm.NIL, fmt.Errorf("symbol expected String name") + } + nameStr := string(name) + if nsStr == "" && vs[0] == vm.NIL { + return vm.Symbol(nameStr), nil + } + return vm.Symbol(nsStr + "/" + nameStr), nil +} + +//lg:native +//lg:name assoc +func CoreAssoc(vs ...vm.Value) (vm.Value, error) { + if len(vs) < 3 || len(vs)%2 == 0 { + return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) + } + coll, ok := vs[0].(vm.Associative) + if !ok { + return vm.NIL, fmt.Errorf("assoc expected Associative") + } + ret := coll + for i := 1; i < len(vs); i += 2 { + ret = ret.Assoc(vs[i], vs[i+1]) + if ret == vm.NIL { + return vm.NIL, fmt.Errorf("assoc failed for key %s", vs[i].String()) + } + } + return ret, nil +} + +//lg:native +//lg:name dissoc +func CoreDissoc(vs ...vm.Value) (vm.Value, error) { + if len(vs) == 0 { + return vm.NIL, fmt.Errorf("wrong number of arguments 0") + } + if len(vs) == 1 { + return vs[0], nil + } + coll, ok := vs[0].(vm.Associative) + if !ok { + return vm.NIL, fmt.Errorf("dissoc expected Associative") + } + ret := coll + for i := 1; i < len(vs); i++ { + ret = ret.Dissoc(vs[i]) + if vs[0] != vm.NIL && ret == vm.NIL { + return vm.NIL, fmt.Errorf("dissoc failed for key %s", vs[i].String()) + } + } + return ret, nil +} + +//lg:native +//lg:name cons +func CoreCons(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 2 { + return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) + } + return builtins.Cons(vs[0], vs[1]) +} + +//lg:native +//lg:name disj +func CoreDisj(vs ...vm.Value) (vm.Value, error) { + if len(vs) < 1 { + return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) + } + if vs[0] == vm.NIL { + return vm.NIL, nil + } + if len(vs) == 1 { + return vs[0], nil + } + switch s := vs[0].(type) { + case *vm.PersistentSet: + result := s + for _, v := range vs[1:] { + result = result.Disj(v) + } + return result, nil + case *vm.SortedSet: + result := s + for _, v := range vs[1:] { + result = result.Disj(v) + } + return result, nil + case vm.Set: + for _, v := range vs[1:] { + s = s.Disj(v) + } + return s, nil + default: + return vm.NIL, fmt.Errorf("disj expected Set") + } +} + +//lg:native +//lg:name contains? +func CoreContains(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 2 { + return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) + } + return builtins.Contains(vs[0], vs[1]) +} + +//lg:native +//lg:name second +func CoreSecond(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 1 { + return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) + } + if vs[0] == vm.NIL { + return vm.NIL, nil + } + + if av, ok := vs[0].(vm.ArrayVector); ok { + if len(av) < 2 { + return vm.NIL, nil + } + return av[1], nil + } + seq, err := seqOf(vs[0]) + if err != nil { + return vm.NIL, fmt.Errorf("second expected Seq") + } + if seq == nil { + return vm.NIL, nil + } + n := seq.Next() + if n == nil { + return vm.NIL, nil + } + return n.First(), nil +} + +//lg:native +//lg:name list? +func CoreIsList(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 1 { + return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) + } + _, ok := vs[0].(*vm.List) + return vm.Boolean(ok), nil +} + +//lg:native +//lg:name empty +func CoreEmpty(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 1 { + return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) + } + if vs[0] == vm.NIL || vs[0].Type() == vm.StringType { + return vm.NIL, nil + } + if _, ok := vs[0].(*vm.InfiniteRange); ok { + return vm.EmptyList, nil + } + if _, ok := vs[0].(*vm.Record); ok { + return vm.NIL, fmt.Errorf("empty is not supported on records") + } + coll, ok := vs[0].(vm.Collection) + if !ok { + return vm.NIL, nil + } + return coll.Empty(), nil +} + +//lg:native +//lg:name key +func CoreKeyf(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 1 { + return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) + } + if e, ok := vs[0].(vm.MapEntry); ok { + return e.Key, nil + } + return vm.NIL, fmt.Errorf("key expects map entry") +} + +//lg:native +//lg:name val +func CoreValf(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 1 { + return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) + } + if e, ok := vs[0].(vm.MapEntry); ok { + return e.Value, nil + } + return vm.NIL, fmt.Errorf("val expects map entry") +} + +//lg:native +//lg:name count +func CoreCount(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 1 { + return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) + } + if vs[0] == vm.NIL { + return vm.MakeInt(0), nil + } + if s, ok := vs[0].(vm.String); ok { + return vm.MakeInt(len([]rune(string(s)))), nil + } + seq, ok := vs[0].(vm.Counted) + if !ok { + return vm.NIL, fmt.Errorf("count expected Counted") + } + return seq.Count(), nil +} + +//lg:native +//lg:name exclude-in-current-ns +func CoreExcludeInCurrentNs(vs ...vm.Value) (vm.Value, error) { + cns := CurrentNS.Deref().(*vm.Namespace) + for _, v := range vs { + sym, ok := v.(vm.Symbol) + if !ok { + return vm.NIL, fmt.Errorf("exclude-in-current-ns expected Symbol, got %s", v.Type().Name()) + } + cns.Exclude(string(sym)) + } + return vm.NIL, nil +} + +//lg:native +//lg:name use +func CoreUse(vs ...vm.Value) (vm.Value, error) { + if len(vs) < 1 { + return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) + } + cns := CurrentNS.Deref().(*vm.Namespace) + for i := range vs { + s, ok := vs[i].(vm.Symbol) + if !ok { + return vm.NIL, fmt.Errorf("use expected Symbol") + } + cns.Refer(NS(string(s)), "", true) + } + return vm.NIL, nil +} + +//lg:native +//lg:name alias +func CoreAliasf(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 2 { + return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) + } + al, ok := vs[0].(vm.Symbol) + if !ok { + return vm.NIL, fmt.Errorf("alias expected Symbol") + } + nsSym, ok := vs[1].(vm.Symbol) + if !ok { + return vm.NIL, fmt.Errorf("alias expected Symbol") + } + cns := CurrentNS.Deref().(*vm.Namespace) + target := NS(string(nsSym)) + cns.Alias(al, target) + return vm.NIL, nil +} + +//lg:native +//lg:name refer-list +func CoreReferList(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 2 { + return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) + } + nsSym, ok := vs[0].(vm.Symbol) + if !ok { + return vm.NIL, fmt.Errorf("refer-list expected ns Symbol") + } + arr, ok := vs[1].(vm.ArrayVector) + if !ok { + return vm.NIL, fmt.Errorf("refer-list expected vector of Symbols") + } + syms := make([]vm.Symbol, 0, len(arr)) + for i := range arr { + if s, ok := arr[i].(vm.Symbol); ok { + syms = append(syms, s) + } + } + cns := CurrentNS.Deref().(*vm.Namespace) + target := NS(string(nsSym)) + + vmSyms := make([]vm.Symbol, len(syms)) + copy(vmSyms, syms) + cns.ReferList(target, vmSyms) + return vm.NIL, nil +} + +//lg:native +//lg:name . +func CoreMethodInvoke(vs ...vm.Value) (vm.Value, error) { + if len(vs) < 2 { + return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) + } + name, ok := vs[1].(vm.Symbol) + if !ok { + return vm.NIL, fmt.Errorf("method-invoke expected Symbol") + } + rec, ok := vs[0].(vm.Receiver) + if !ok { + return invokeMethodFallback(vs[0], name, vs[2:], fmt.Errorf("method-invoke expected Receiver")) + } + result, err := rec.InvokeMethod(name, vs[2:]) + if err == nil { + return result, nil + } + return invokeMethodFallback(rec, name, vs[2:], err) +} + +//lg:native +//lg:name register-host-method! +func CoreRegisterHostMethod(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 3 { + return vm.NIL, fmt.Errorf("register-host-method! expected 3 arguments, got %d", len(vs)) + } + t, ok := vs[0].(vm.ValueType) + if !ok { + return vm.NIL, fmt.Errorf("register-host-method! expected a type, got %s", vs[0].Type().Name()) + } + name, ok := vs[1].(vm.Symbol) + if !ok { + return vm.NIL, fmt.Errorf("register-host-method! expected a Symbol method name") + } + fn, ok := vs[2].(vm.Fn) + if !ok { + return vm.NIL, fmt.Errorf("register-host-method! expected a fn") + } + RegisterHostMethod(t, name, fn) + return vm.NIL, nil +} + +//lg:native +//lg:name register-host-class! +func CoreRegisterHostClass(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 2 { + return vm.NIL, fmt.Errorf("register-host-class! expected 2 arguments, got %d", len(vs)) + } + name, ok := vs[0].(vm.String) + if !ok { + return vm.NIL, fmt.Errorf("register-host-class! expected a String class name") + } + RegisterHostClass(string(name), vs[1]) + return vm.NIL, nil +} + +//lg:native +//lg:name concat* +func CoreConcat(vs ...vm.Value) (vm.Value, error) { + + presize := 0 + for i := range vs { + if av, ok := vs[i].(vm.ArrayVector); ok { + presize += len(av) + } + } + ret := make([]vm.Value, 0, presize) + for i := range vs { + if vs[i] == vm.NIL { + continue + } + + if av, ok := vs[i].(vm.ArrayVector); ok { + ret = append(ret, av...) + continue + } + vseq, err := seqOf(vs[i]) + if err != nil { + return vm.NIL, fmt.Errorf("concat expected Seq") + } + ret = appendSeqValues(ret, forceSeq(vseq)) + } + r, err := vm.ListType.Box(ret) + if err != nil { + return vm.NIL, fmt.Errorf("concat failed: %w", err) + } + return r, nil +} + +//lg:native +//lg:name slurp +func CoreSlurp(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 1 { + return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) + } + filename, ok := vs[0].(vm.String) + if !ok { + return vm.NIL, fmt.Errorf("slurp expected String") + } + data, err := os.ReadFile(string(filename)) + if err != nil { + return vm.NIL, fmt.Errorf("slurp failed: %w", err) + } + return vm.String(data), nil +} + +//lg:native +//lg:name spit +func CoreSpit(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 2 { + return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) + } + filename, ok := vs[0].(vm.String) + if !ok { + return vm.NIL, fmt.Errorf("spit expected String") + } + contents, ok := asBytes(vs[1]) + if !ok { + return vm.NIL, fmt.Errorf("spit expected String or byte-array") + } + err := os.WriteFile(string(filename), contents, 0644) + if err != nil { + return vm.NIL, fmt.Errorf("spit failed: %w", err) + } + return vm.NIL, nil +} + +//lg:native +//lg:name atom +func CoreAtom(vs ...vm.Value) (vm.Value, error) { + if len(vs) < 1 { + return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) + } + if (len(vs)-1)%2 != 0 { + return vm.NIL, fmt.Errorf("atom options must be key/value pairs") + } + var meta vm.Value + var validator vm.Fn + for i := 1; i < len(vs); i += 2 { + switch vs[i] { + case vm.Keyword("meta"): + if vs[i+1] != vm.NIL && !isMapType(vs[i+1]) { + return vm.NIL, fmt.Errorf("atom :meta must be nil or map") + } + meta = vs[i+1] + case vm.Keyword("validator"): + if vs[i+1] == vm.NIL { + validator = nil + continue + } + fn, ok := vm.AsFn(vs[i+1]) + if !ok { + return vm.NIL, fmt.Errorf("atom :validator must be nil or function") + } + validator = fn + } + } + return vm.NewAtomWithMetaValidator(vs[0], meta, validator) +} + +//lg:native +//lg:name reset! +func CoreReset(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 2 { + return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) + } + at, ok := vs[0].(*vm.Atom) + if !ok { + return vm.NIL, fmt.Errorf("reset expected Atom") + } + return at.Reset(vs[1]) +} + +//lg:native +//lg:name compare-and-set! +func CoreCompareAndSet(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 3 { + return vm.NIL, fmt.Errorf("compare-and-set! expected 3 arguments, got %d", len(vs)) + } + at, ok := vs[0].(*vm.Atom) + if !ok { + return vm.NIL, fmt.Errorf("compare-and-set! expected Atom") + } + swapped, err := at.CompareAndSet(vs[1], vs[2]) + if err != nil { + return vm.NIL, err + } + if swapped { + return vm.TRUE, nil + } + return vm.FALSE, nil +} + +//lg:native +//lg:name reset-vals! +func CoreResetVals(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 2 { + return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) + } + at, ok := vs[0].(*vm.Atom) + if !ok { + return vm.NIL, fmt.Errorf("reset-vals! expected Atom") + } + old := at.Deref() + if _, err := at.Reset(vs[1]); err != nil { + return vm.NIL, err + } + return vm.ArrayVector{old, vs[1]}, nil +} + +//lg:native +//lg:name chan +func CoreChanf(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 0 { + return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) + } + return make(vm.Chan), nil +} + +//lg:native +//lg:name scope-close! +func CoreScopeClose(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 2 { + return vm.NIL, fmt.Errorf("scope-close! expects 2 arguments (scope timeout-ms)") + } + s, ok := vs[0].(*vm.Scope) + if !ok { + return vm.NIL, fmt.Errorf("scope-close! expected a scope") + } + ms, ok := vs[1].(vm.Int) + if !ok { + return vm.NIL, fmt.Errorf("scope-close! expected an integer timeout-ms") + } + vm.CloseScoped(s, time.Duration(int64(ms))*time.Millisecond) + return vm.NIL, nil +} + +//lg:native +//lg:name scope-live +func CoreScopeLive(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 1 { + return vm.NIL, fmt.Errorf("scope-live expects 1 argument") + } + s, ok := vs[0].(*vm.Scope) + if !ok { + return vm.NIL, fmt.Errorf("scope-live expected a scope") + } + return vm.Int(s.LiveTree()), nil +} + +//lg:native +//lg:name scope? +func CoreScopeQmark(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 1 { + return vm.NIL, fmt.Errorf("scope? expects 1 argument") + } + if _, ok := vs[0].(*vm.Scope); ok { + return vm.TRUE, nil + } + return vm.FALSE, nil +} + +//lg:native +//lg:name max +func CoreMax(vs ...vm.Value) (vm.Value, error) { + if len(vs) < 1 { + return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) + } + m := vs[0] + if isNaNValue(m) { + return m, nil + } + for i := 1; i < len(vs); i++ { + if isNaNValue(vs[i]) { + return vs[i], nil + } + gt, err := vm.NumGt(vs[i], m) + if err != nil { + return vm.NIL, err + } + if gt { + m = vs[i] + } + } + return m, nil +} + +//lg:native +//lg:name min +func CoreMin(vs ...vm.Value) (vm.Value, error) { + if len(vs) < 1 { + return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) + } + m := vs[0] + if isNaNValue(m) { + return m, nil + } + for i := 1; i < len(vs); i++ { + if isNaNValue(vs[i]) { + return vs[i], nil + } + lt, err := vm.NumLt(vs[i], m) + if err != nil { + return vm.NIL, err + } + if lt { + m = vs[i] + } + } + return m, nil +} + +//lg:native +//lg:name str-replace +func CoreStrReplace(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 3 { + return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) + } + s, ok := vs[0].(vm.String) + if !ok { + return vm.NIL, fmt.Errorf("str-replace expected String") + } + + if fn, isFn := vs[2].(vm.Fn); isFn { + switch m := vs[1].(type) { + case *vm.Regex: + out, err := m.ReplaceAllFunc(string(s), strReplaceCallback(fn)) + if err != nil { + return vm.NIL, err + } + return vm.String(out), nil + case vm.String: + return literalReplaceFn(string(m), string(s), fn, false) + default: + return vm.NIL, fmt.Errorf("str-replace expected String or Regex") + } + } + r, ok := vs[2].(vm.String) + if !ok { + return vm.NIL, fmt.Errorf("str-replace expected String") + } + switch vs[1].(type) { + case vm.String: + return vm.String(strings.ReplaceAll(string(s), string(vs[1].(vm.String)), string(r))), nil + case *vm.Regex: + out, err := vs[1].(*vm.Regex).ReplaceAll(string(s), string(r)) + if err != nil { + return vm.NIL, err + } + return vm.String(out), nil + default: + return vm.NIL, fmt.Errorf("str-replace expected String or Regex") + } +} + +//lg:native +//lg:name long +func CoreLongf(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 1 { + return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) + } + const minInt64 = float64(-9223372036854775808) + const maxInt64 = float64(9223372036854775807) + coerce := func(f float64) (vm.Value, error) { + if f < minInt64 || f > maxInt64 { + return vm.NIL, fmt.Errorf("%s can't be coerced to long", vs[0]) + } + return vm.Int(int64(math.Trunc(f))), nil + } + switch v := vs[0].(type) { + case vm.Int: + return v, nil + case vm.Float: + return coerce(float64(v)) + case vm.Char: + return vm.Int(int(v)), nil + case *vm.BigInt: + if !v.Val().IsInt64() { + return vm.NIL, fmt.Errorf("%s can't be coerced to long", vs[0]) + } + return vm.Int(v.Val().Int64()), nil + case *vm.BigDecimal: + f, _ := v.Val().Float64() + return coerce(f) + case *vm.Ratio: + f, _ := v.Val().Float64() + return coerce(f) + case vm.Boolean: + if bool(v) { + return vm.MakeInt(1), nil + } + return vm.MakeInt(0), nil + default: + return vm.NIL, fmt.Errorf("%s can't be coerced to long", vs[0]) + } +} + +//lg:native +//lg:name float +func CoreFloatf(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 1 { + return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) + } + f, ok := vm.ToFloat(vs[0]) + if !ok { + return vm.NIL, fmt.Errorf("%s can't be coerced to float", vs[0]) + } + if math.IsInf(f, 0) { + return vm.NIL, fmt.Errorf("%s can't be coerced to float", vs[0]) + } + f32 := float32(f) + if math.IsInf(float64(f32), 0) { + return vm.NIL, fmt.Errorf("%s can't be coerced to float", vs[0]) + } + return vm.Float32(float64(f32)), nil +} + +//lg:native +//lg:name double +func CoreDoublef(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 1 { + return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) + } + f, ok := vm.ToFloat(vs[0]) + if !ok { + return vm.NIL, fmt.Errorf("%s can't be coerced to double", vs[0]) + } + return vm.Float(f), nil +} + +//lg:native +//lg:name number? +func CoreIsNumber(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 1 { + return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) + } + return vm.Boolean(vm.IsNumber(vs[0])), nil +} + +//lg:native +//lg:name float? +func CoreIsFloat(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 1 { + return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) + } + switch vs[0].(type) { + case vm.Float, vm.Float32: + return vm.TRUE, nil + } + ok := false + return vm.Boolean(ok), nil +} + +//lg:native +//lg:name int? +func CoreIsInt(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 1 { + return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) + } + _, ok := vs[0].(vm.Int) + return vm.Boolean(ok), nil +} + +//lg:native +//lg:name char +func CoreChar(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 1 { + return vm.NIL, fmt.Errorf("wrong number of arguments") + } + switch v := vs[0].(type) { + case vm.Int: + if int(v) < 0 || int(v) > 0x10FFFF { + return vm.NIL, fmt.Errorf("value out of range for char: %d", v) + } + return vm.Char(rune(v)), nil + case vm.Char: + return v, nil + case vm.String: + runes := []rune(string(v)) + if len(runes) == 1 { + return vm.Char(runes[0]), nil + } + return vm.NIL, fmt.Errorf("%s can't be coerced to char", vs[0]) + case *vm.BigInt: + n := v.Unbox().(*big.Int).Int64() + if n < 0 || n > 0x10FFFF { + return vm.NIL, fmt.Errorf("value out of range for char: %d", n) + } + return vm.Char(rune(n)), nil + default: + return vm.NIL, fmt.Errorf("%s can't be coerced to char", vs[0]) + } +} + +//lg:native +//lg:name re-pattern +func CoreRegex(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 1 { + return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) + } + + if r, ok := vs[0].(*vm.Regex); ok { + return r, nil + } + if s, ok := vs[0].(vm.String); ok { + return vm.NewRegex(string(s)) + } + return vm.NIL, fmt.Errorf("regex expected String") +} + +//lg:native +//lg:name peek +func CorePeek(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 1 { + return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) + } + if vs[0] == vm.NIL { + return vm.NIL, nil + } + switch v := vs[0].(type) { + case vm.ArrayVector: + if len(v) == 0 { + return vm.NIL, nil + } + return v[len(v)-1], nil + case vm.PersistentVector: + if v.RawCount() == 0 { + return vm.NIL, nil + } + return v.ValueAt(vm.Int(v.RawCount() - 1)), nil + case *vm.List: + if v == vm.EmptyList { + return vm.NIL, nil + } + return v.First(), nil + case *vm.PersistentQueue: + return v.Peek(), nil + default: + return vm.NIL, fmt.Errorf("peek not supported on %s", vs[0].Type()) + } +} + +//lg:native +//lg:name pop +func CorePop(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 1 { + return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) + } + if vs[0] == vm.NIL { + return vm.NIL, nil + } + switch vs[0].(type) { + case vm.PersistentVector: + v := vs[0].(vm.PersistentVector) + if v.RawCount() < 1 { + return vm.NIL, fmt.Errorf("can't pop empty vector") + } + + return v.Pop(), nil + case vm.ArrayVector: + v := vs[0].(vm.ArrayVector) + if v.RawCount() < 1 { + return vm.NIL, fmt.Errorf("can't pop empty vector") + } + return vm.ArrayVector(v[0 : len(v)-1]), nil + case vm.Seq: + s := vs[0].(vm.Seq) + + if s == vm.EmptyList { + return vm.NIL, fmt.Errorf("can't pop empty seq") + } + if c, ok := vs[0].(vm.Counted); ok && c.RawCount() == 0 { + return vm.NIL, fmt.Errorf("can't pop empty seq") + } + return s.More(), nil + case *vm.PersistentQueue: + return vs[0].(*vm.PersistentQueue).Pop(), nil + default: + return vm.NIL, fmt.Errorf("pop expected Seq or Vec") + } +} + +//lg:native +//lg:name iterate +func CoreIterate(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 2 { + return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) + } + f, ok := vm.AsFn(vs[0]) + if !ok { + return vm.NIL, fmt.Errorf("iterate expected a function") + } + return vm.NewIterate(f, vs[1]), nil +} + +//lg:native +//lg:name repeat +func CoreRepeat(vs ...vm.Value) (vm.Value, error) { + if len(vs) < 1 || len(vs) > 2 { + return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) + } + if len(vs) == 1 { + return vm.NewRepeat(vs[0], -1), nil + } + if _, ok := vs[0].(vm.Boolean); ok { + return vm.NIL, fmt.Errorf("repeat expected an Int") + } + ni, ok := vm.ToInt(vs[0]) + if !ok { + return vm.NIL, fmt.Errorf("repeat expected an Int") + } + n := vm.Int(ni) + if int(n) <= 0 { + return vm.EmptyList, nil + } + return vm.NewRepeat(vs[1], int(n)), nil +} + +//lg:native +//lg:name refer +func CoreRefer(vs ...vm.Value) (vm.Value, error) { + if len(vs) < 2 || len(vs) > 3 { + return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) + } + cns := CurrentNS.Deref().(*vm.Namespace) + s, ok := vs[0].(vm.Symbol) + if !ok { + return vm.NIL, fmt.Errorf("refer expected Symbol") + } + alias := "" + if len(vs) > 1 { + if str, ok := vs[1].(vm.String); ok { + alias = string(str) + } + } + all := true + if len(vs) > 2 { + if b, ok := vs[2].(vm.Boolean); ok { + all = bool(b) + } + } + cns.Refer(NS(string(s)), alias, all) + return vm.NIL, nil +} + +//lg:native +//lg:name format +func CoreFormatf(vs ...vm.Value) (vm.Value, error) { + if len(vs) < 1 { + return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) + } + fmtStr, ok := vs[0].(vm.String) + if !ok { + return vm.NIL, fmt.Errorf("format expected String") + } + fmts := string(fmtStr) + args := make([]any, len(vs)-1) + + vi := 0 + for fi := 0; fi < len(fmts) && vi < len(args); fi++ { + if fmts[fi] != '%' { + continue + } + fi++ + if fi >= len(fmts) { + break + } + if fmts[fi] == '%' { + continue + } + + for fi < len(fmts) && (fmts[fi] == '-' || fmts[fi] == '+' || fmts[fi] == ' ' || fmts[fi] == '0' || fmts[fi] == '#' || (fmts[fi] >= '0' && fmts[fi] <= '9') || fmts[fi] == '.') { + fi++ + } + if fi >= len(fmts) { + break + } + verb := fmts[fi] + switch v := vs[vi+1].(type) { + case vm.Int: + if verb == 'f' || verb == 'e' || verb == 'g' || verb == 'E' || verb == 'G' { + args[vi] = float64(v) + } else { + args[vi] = int(v) + } + case vm.Float: + args[vi] = float64(v) + case vm.String: + args[vi] = string(v) + case vm.Boolean: + args[vi] = bool(v) + default: + args[vi] = vs[vi+1].Unbox() + } + vi++ + } + return vm.String(fmt.Sprintf(string(fmtStr), args...)), nil +} + +//lg:native +//lg:name rand +func CoreRandf(vs ...vm.Value) (vm.Value, error) { + if len(vs) == 0 { + return vm.Float(rngFloat64()), nil + } + if len(vs) == 1 { + if n, ok := vs[0].(vm.Int); ok { + return vm.Float(rngFloat64() * float64(n)), nil + } + if n, ok := vs[0].(vm.Float); ok { + return vm.Float(rngFloat64() * float64(n)), nil + } + return vm.NIL, fmt.Errorf("rand expected number") + } + return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) +} + +//lg:native +//lg:name rand-int +func CoreRandInt(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 1 { + return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) + } + n, ok := vs[0].(vm.Int) + if !ok { + return vm.NIL, fmt.Errorf("rand-int expected Int") + } + if int(n) <= 0 { + return vm.MakeInt(0), nil + } + return vm.MakeInt(rngIntn(int(n))), nil +} + +//lg:native +//lg:name rand-nth +func CoreRandNth(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 1 { + return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) + } + if vs[0] == vm.NIL { + return vm.NIL, nil + } + coll, ok := vs[0].(vm.Collection) + if !ok { + return vm.NIL, fmt.Errorf("rand-nth expected Collection") + } + n := coll.RawCount() + if n == 0 { + return vm.NIL, fmt.Errorf("rand-nth called on empty collection") + } + idx := rngIntn(n) + if l, ok := vs[0].(vm.Lookup); ok { + return l.ValueAt(vm.Int(idx)), nil + } + + s, _ := seqOf(vs[0]) + for range idx { + s = s.Next() + } + return s.First(), nil +} + +//lg:native +//lg:name shuffle +func CoreShuffle(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 1 { + return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) + } + if vs[0] == vm.NIL { + return vm.NIL, fmt.Errorf("shuffle not supported on nil") + } + switch vs[0].(type) { + case vm.String: + return vm.NIL, fmt.Errorf("shuffle not supported on string") + case *vm.PersistentMap, vm.Map, *vm.SortedMap: + return vm.NIL, fmt.Errorf("shuffle not supported on map") + } + + s, err := seqOf(vs[0]) + if err != nil { + return vm.NIL, err + } + vals := appendSeqValues(nil, forceSeq(s)) + + rngShuffle(len(vals), func(i, j int) { + vals[i], vals[j] = vals[j], vals[i] + }) + return vm.NewArrayVector(vals), nil +} + +//lg:native +//lg:name set-rand-seed! +func CoreSetRandSeedFn(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 1 { + return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) + } + n, ok := vs[0].(vm.Int) + if !ok { + return vm.NIL, fmt.Errorf("set-rand-seed! expected Int") + } + setRandSeed(int64(n)) + return vm.NIL, nil +} + +//lg:native +//lg:name transient +func CoreTransientf(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 1 { + return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) + } + switch v := vs[0].(type) { + case *vm.PersistentMap: + return vm.NewTransientMap(v), nil + case *vm.PersistentSet: + return vm.NewTransientSet(v), nil + case vm.ArrayVector: + return vm.NewTransientVector([]vm.Value(v)), nil + case vm.PersistentVector: + vals := v.Unbox().([]vm.Value) + return vm.NewTransientVector(vals), nil + default: + return vm.NIL, fmt.Errorf("transient not supported on %s", vs[0].Type().Name()) + } +} + +//lg:native +//lg:name persistent! +func CorePersistentf(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 1 { + return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) + } + switch v := vs[0].(type) { + case *vm.TransientMap: + return v.Persistent() + case *vm.TransientVector: + return v.Persistent() + case *vm.TransientSet: + return v.Persistent() + default: + return vm.NIL, fmt.Errorf("persistent! not supported on %s", vs[0].Type().Name()) + } +} + +//lg:native +//lg:name conj! +func CoreConjBang(vs ...vm.Value) (vm.Value, error) { + if len(vs) == 0 { + return vm.NewTransientVector(nil), nil + } + if len(vs) == 1 { + return vs[0], nil + } + switch t := vs[0].(type) { + case *vm.TransientMap: + var err error + for i := 1; i < len(vs); i++ { + t, err = t.Conj(vs[i]) + if err != nil { + return vm.NIL, err + } + } + return t, nil + case *vm.TransientVector: + var err error + for i := 1; i < len(vs); i++ { + t, err = t.Conj(vs[i]) + if err != nil { + return vm.NIL, err + } + } + return t, nil + case *vm.TransientSet: + var err error + for i := 1; i < len(vs); i++ { + t, err = t.Conj(vs[i]) + if err != nil { + return vm.NIL, err + } + } + return t, nil + default: + return vm.NIL, fmt.Errorf("conj! not supported on %s", vs[0].Type().Name()) + } +} + +//lg:native +//lg:name assoc! +func CoreAssocBang(vs ...vm.Value) (vm.Value, error) { + if len(vs) < 2 { + return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) + } + switch t := vs[0].(type) { + case *vm.TransientMap: + var err error + for i := 1; i < len(vs); i += 2 { + val := vm.Value(vm.NIL) + if i+1 < len(vs) { + val = vs[i+1] + } + t, err = t.Assoc(vs[i], val) + if err != nil { + return vm.NIL, err + } + } + return t, nil + case *vm.TransientVector: + var err error + for i := 1; i < len(vs); i += 2 { + val := vm.Value(vm.NIL) + if i+1 < len(vs) { + val = vs[i+1] + } + t, err = t.Assoc(vs[i], val) + if err != nil { + return vm.NIL, err + } + } + return t, nil + default: + return vm.NIL, fmt.Errorf("assoc! not supported on %s", vs[0].Type().Name()) + } +} + +//lg:native +//lg:name disj! +func CoreDisjBang(vs ...vm.Value) (vm.Value, error) { + if len(vs) < 2 { + return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) + } + t, ok := vs[0].(*vm.TransientSet) + if !ok { + return vm.NIL, fmt.Errorf("disj! expected TransientSet") + } + var err error + for i := 1; i < len(vs); i++ { + t, err = t.Disj(vs[i]) + if err != nil { + return vm.NIL, err + } + } + return t, nil +} + +//lg:native +//lg:name dissoc! +func CoreDissocBang(vs ...vm.Value) (vm.Value, error) { + if len(vs) < 2 { + return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) + } + t, ok := vs[0].(*vm.TransientMap) + if !ok { + return vm.NIL, fmt.Errorf("dissoc! expected TransientMap") + } + var err error + for i := 1; i < len(vs); i++ { + t, err = t.Dissoc(vs[i]) + if err != nil { + return vm.NIL, err + } + } + return t, nil +} + +//lg:native +//lg:name make-record-type +func CoreMakeRecordType(vs ...vm.Value) (vm.Value, error) { + if len(vs) < 1 { + return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) + } + name, ok := vs[0].(vm.String) + if !ok { + return vm.NIL, fmt.Errorf("make-record-type expected String name") + } + fields := make([]vm.Keyword, len(vs)-1) + for i := 1; i < len(vs); i++ { + kw, ok := vs[i].(vm.Keyword) + if !ok { + return vm.NIL, fmt.Errorf("make-record-type expected Keyword fields") + } + fields[i-1] = kw + } + return vm.NewRecordType(string(name), fields), nil +} + +//lg:native +//lg:name make-record +func CoreMakeRecord(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 2 { + return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) + } + rt, ok := vs[0].(*vm.RecordType) + if !ok { + return vm.NIL, fmt.Errorf("make-record expected RecordType") + } + m, ok := vs[1].(*vm.PersistentMap) + if !ok { + return vm.NIL, fmt.Errorf("make-record expected Map") + } + return vm.NewRecord(rt, m), nil +} + +//lg:native +//lg:name record? +func CoreIsRecord(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 1 { + return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) + } + _, ok := vs[0].(*vm.Record) + return vm.Boolean(ok), nil +} + +//lg:native +//lg:name make-deftype +func CoreMakeDType(vs ...vm.Value) (vm.Value, error) { + if len(vs) < 1 { + return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) + } + name, ok := vs[0].(vm.String) + if !ok { + return vm.NIL, fmt.Errorf("make-deftype expected String name") + } + fields := make([]vm.Symbol, len(vs)-1) + for i := 1; i < len(vs); i++ { + sym, ok := vs[i].(vm.Symbol) + if !ok { + return vm.NIL, fmt.Errorf("make-deftype expected Symbol fields") + } + fields[i-1] = sym + } + return vm.NewDType(string(name), fields), nil +} + +//lg:native +//lg:name make-deftype-instance +func CoreMakeDTypeInstance(vs ...vm.Value) (vm.Value, error) { + if len(vs) < 1 { + return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) + } + dt, ok := vs[0].(*vm.DType) + if !ok { + return vm.NIL, fmt.Errorf("make-deftype-instance expected DType, got %s", vs[0].Type().Name()) + } + + fields := make([]vm.Value, len(vs)-1) + copy(fields, vs[1:]) + return vm.NewDTypeInstance(dt, fields), nil +} + +//lg:native +//lg:name set-field! +func CoreSetField(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 3 { + return vm.NIL, fmt.Errorf("set-field! expected 3 arguments, got %d", len(vs)) + } + inst, ok := vs[0].(*vm.DTypeInstance) + if !ok { + return vm.NIL, fmt.Errorf("set-field! expected a deftype instance, got %s", vs[0].Type().Name()) + } + name, ok := vs[1].(vm.Symbol) + if !ok { + return vm.NIL, fmt.Errorf("set-field! expected a Symbol field name") + } + if err := inst.SetField(name, vs[2]); err != nil { + return vm.NIL, err + } + return vs[2], nil +} + +//lg:native +//lg:name defprotocol* +func CoreDefProtocol(vs ...vm.Value) (vm.Value, error) { + if len(vs) < 1 { + return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) + } + name, ok := vs[0].(vm.String) + if !ok { + return vm.NIL, fmt.Errorf("defprotocol* expected String name") + } + methods := make([]vm.Symbol, len(vs)-1) + for i := 1; i < len(vs); i++ { + s, ok := vs[i].(vm.Symbol) + if !ok { + return vm.NIL, fmt.Errorf("defprotocol* expected Symbol method names") + } + methods[i-1] = s + } + return vm.NewProtocol(string(name), methods), nil +} + +//lg:native +//lg:name extend-type* +func CoreExtendType(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 3 { + return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) + } + protocol, ok := vs[0].(*vm.Protocol) + if !ok { + return vm.NIL, fmt.Errorf("extend-type* expected Protocol") + } + implMap, ok := vs[2].(*vm.PersistentMap) + if !ok { + return vm.NIL, fmt.Errorf("extend-type* expected map of implementations") + } + + if vs[1] == vm.NIL { + protocol.ExtendNil(implMap) + return vm.NIL, nil + } + if union, ok := vs[1].(*vm.TypeUnion); ok { + + for _, valueType := range union.Types() { + protocol.ExtendViaUnion(valueType, implMap) + } + return vm.NIL, nil + } + vt, ok := vs[1].(vm.ValueType) + if !ok { + return vm.NIL, fmt.Errorf("extend-type* expected a type, got %s", vs[1].Type().Name()) + } + protocol.Extend(vt, implMap) + return vm.NIL, nil +} + +//lg:native +//lg:name make-protocol-fn +func CoreMakeProtocolFn(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 2 { + return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) + } + protocol, ok := vs[0].(*vm.Protocol) + if !ok { + return vm.NIL, fmt.Errorf("make-protocol-fn expected Protocol") + } + methodName, ok := vs[1].(vm.Symbol) + if !ok { + return vm.NIL, fmt.Errorf("make-protocol-fn expected Symbol") + } + return vm.NewProtocolFn(protocol, methodName), nil +} + +//lg:native +//lg:name -set-invokable-protocol! +func CoreSetInvokableProtocol(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 2 { + return vm.NIL, fmt.Errorf("-set-invokable-protocol! expects 2 args") + } + protocol, ok := vs[0].(*vm.Protocol) + if !ok { + return vm.NIL, fmt.Errorf("-set-invokable-protocol! expected a Protocol") + } + invokeFn, ok := vs[1].(vm.Fn) + if !ok { + return vm.NIL, fmt.Errorf("-set-invokable-protocol! expected the -invoke fn") + } + vm.IFnProtocol = protocol + vm.IFnInvoke = invokeFn + return vm.NIL, nil +} + +//lg:native +//lg:name -set-deref-protocol! +func CoreSetDerefProtocol(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 2 { + return vm.NIL, fmt.Errorf("-set-deref-protocol! expects 2 args") + } + protocol, ok := vs[0].(*vm.Protocol) + if !ok { + return vm.NIL, fmt.Errorf("-set-deref-protocol! expected a Protocol") + } + derefFn, ok := vs[1].(vm.Fn) + if !ok { + return vm.NIL, fmt.Errorf("-set-deref-protocol! expected the -deref fn") + } + vm.IDerefProtocol = protocol + vm.IDerefDeref = derefFn + return vm.NIL, nil +} + +//lg:native +//lg:name satisfies? +func CoreSatisfies(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 2 { + return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) + } + protocol, ok := vs[0].(*vm.Protocol) + if !ok { + return vm.NIL, fmt.Errorf("satisfies? expected Protocol") + } + return vm.Boolean(protocol.Satisfies(vs[1])), nil +} + +//lg:native +//lg:name defmulti* +func CoreDefMulti(vs ...vm.Value) (vm.Value, error) { + if len(vs) < 2 || len(vs) > 3 { + return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) + } + name, ok := vs[0].(vm.String) + if !ok { + return vm.NIL, fmt.Errorf("defmulti* expected String name") + } + dispatchFn, ok := vs[1].(vm.Fn) + if !ok { + return vm.NIL, fmt.Errorf("defmulti* expected Fn") + } + var defaultVal vm.Value = vm.Keyword("default") + if len(vs) == 3 { + defaultVal = vs[2] + } + return vm.NewMultiFn(string(name), dispatchFn, defaultVal), nil +} + +//lg:native +//lg:name defmethod* +func CoreDefMethod(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 3 { + return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) + } + mf, ok := vs[0].(*vm.MultiFn) + if !ok { + return vm.NIL, fmt.Errorf("defmethod* expected MultiFn") + } + dispatchVal := vs[1] + method, ok := vs[2].(vm.Fn) + if !ok { + return vm.NIL, fmt.Errorf("defmethod* expected Fn") + } + return mf.AddMethod(dispatchVal, method), nil +} + +//lg:native +//lg:name pr-str +func CorePrStr(vs ...vm.Value) (vm.Value, error) { + return prThroughToString(vs, true) +} + +//lg:native +//lg:name prn-str +func CorePrnStr(vs ...vm.Value) (vm.Value, error) { + s, err := prThroughToString(vs, true) + if err != nil { + return vm.NIL, err + } + return vm.String(string(s.(vm.String)) + "\n"), nil +} + +//lg:native +//lg:name print-str +func CorePrintStr(vs ...vm.Value) (vm.Value, error) { + return prThroughToString(vs, false) +} + +//lg:native +//lg:name println-str +func CorePrintlnStr(vs ...vm.Value) (vm.Value, error) { + s, err := prThroughToString(vs, false) + if err != nil { + return vm.NIL, err + } + return vm.String(string(s.(vm.String)) + "\n"), nil +} + +//lg:native +//lg:name re-find +func CoreReFind(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 2 { + return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) + } + re, ok := vs[0].(*vm.Regex) + if !ok { + return vm.NIL, fmt.Errorf("re-find expected Regex") + } + s, ok := vs[1].(vm.String) + if !ok { + return vm.NIL, fmt.Errorf("re-find expected String") + } + indices := re.FindStringSubmatchIndex(string(s)) + if indices == nil { + return vm.NIL, nil + } + return regexSubmatchValue(string(s), indices), nil +} + +//lg:native +//lg:name re-matches +func CoreReMatches(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 2 { + return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) + } + re, ok := vs[0].(*vm.Regex) + if !ok { + return vm.NIL, fmt.Errorf("re-matches expected Regex") + } + s, ok := vs[1].(vm.String) + if !ok { + return vm.NIL, fmt.Errorf("re-matches expected String") + } + indices := re.FindStringSubmatchIndex(string(s)) + if indices == nil || indices[0] != 0 || indices[1] != len(s) { + return vm.NIL, nil + } + return regexSubmatchValue(string(s), indices), nil +} + +//lg:native +//lg:name re-seq +func CoreReSeq(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 2 { + return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) + } + re, ok := vs[0].(*vm.Regex) + if !ok { + return vm.NIL, fmt.Errorf("re-seq expected Regex") + } + s, ok := vs[1].(vm.String) + if !ok { + return vm.NIL, fmt.Errorf("re-seq expected String") + } + + all := re.FindAllStringSubmatchIndex(string(s), -1) + if all == nil { + return vm.NIL, nil + } + vals := make([]vm.Value, len(all)) + for i, indices := range all { + vals[i] = regexSubmatchValue(string(s), indices) + } + return vm.ListType.Box(vals) +} + +//lg:native +//lg:name require +func CoreRequiref(vs ...vm.Value) (vm.Value, error) { + cns := CurrentNS.Deref().(*vm.Namespace) + for _, v := range vs { + switch arg := v.(type) { + case vm.Symbol: + if _, err := RequireNS(string(arg)); err != nil { + return vm.NIL, err + } + case vm.ArrayVector: + + if arg.RawCount() < 1 { + return vm.NIL, fmt.Errorf("require: empty vector") + } + nsName, ok := arg.ValueAt(vm.Int(0)).(vm.Symbol) + if !ok { + return vm.NIL, fmt.Errorf("require: first element must be a symbol") + } + target, err := RequireNS(string(nsName)) + if err != nil { + return vm.NIL, err + } + + for i := 1; i < arg.RawCount()-1; i += 2 { + opt := arg.ValueAt(vm.Int(int64(i))) + val := arg.ValueAt(vm.Int(int64(i + 1))) + switch opt { + case vm.Keyword("as"): + if alias, ok := val.(vm.Symbol); ok { + cns.Alias(alias, target) + } + case vm.Keyword("refer"): + if val == vm.Keyword("all") { + cns.Refer(target, "", true) + } else if vec, ok := val.(vm.ArrayVector); ok { + syms := make([]vm.Symbol, vec.RawCount()) + for j := 0; j < vec.RawCount(); j++ { + syms[j] = vec.ValueAt(vm.Int(int64(j))).(vm.Symbol) + } + cns.ReferList(target, syms) + } + } + } + default: + return vm.NIL, fmt.Errorf("require expected Symbol or Vector, got %s", v.Type().Name()) + } + } + return vm.NIL, nil +} + +//lg:native +//lg:name find-ns +func CoreFindNs(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 1 { + return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) + } + s, ok := vs[0].(vm.Symbol) + if !ok { + return vm.NIL, fmt.Errorf("find-ns expected Symbol") + } + nsMu.RLock() + ns := nsRegistry[string(s)] + nsMu.RUnlock() + if ns == nil { + return vm.NIL, nil + } + return ns, nil +} + +//lg:native +//lg:name resolve +func CoreResolvef(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 1 { + return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) + } + sym, ok := vs[0].(vm.Symbol) + if !ok { + return vm.NIL, fmt.Errorf("resolve expected Symbol") + } + cns := CurrentNS.Deref().(*vm.Namespace) + if v := cns.Lookup(sym); v != vm.NIL { + return v, nil + } + return vm.NIL, nil +} + +//lg:native +//lg:name all-ns +func CoreAllNs(vs ...vm.Value) (vm.Value, error) { + nsMu.RLock() + var nss []vm.Value + for _, ns := range nsRegistry { + nss = append(nss, ns) + } + nsMu.RUnlock() + return vm.NewList(nss), nil +} + +//lg:native +//lg:name the-ns +func CoreTheNs(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 1 { + return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) + } + s, ok := vs[0].(vm.Symbol) + if !ok { + + if ns, ok := vs[0].(*vm.Namespace); ok { + return ns, nil + } + return vm.NIL, fmt.Errorf("the-ns expected Symbol or Namespace") + } + nsMu.RLock() + ns := nsRegistry[string(s)] + nsMu.RUnlock() + if ns == nil { + return vm.NIL, fmt.Errorf("no namespace: %s found", s) + } + return ns, nil +} + +//lg:native +//lg:name ns-publics +func CoreNsPublics(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 1 { + return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) + } + var ns *vm.Namespace + switch a := vs[0].(type) { + case *vm.Namespace: + ns = a + case vm.Symbol: + + nsMu.RLock() + ns = nsRegistry[resolveNSAlias(string(a))] + nsMu.RUnlock() + if ns == nil { + return vm.NIL, fmt.Errorf("no namespace: %s found", a) + } + default: + return vm.NIL, fmt.Errorf("ns-publics expected Symbol or Namespace") + } + pubs := ns.PublicVars() + kvs := make([]vm.Value, 0, len(pubs)*2) + for sym, v := range pubs { + kvs = append(kvs, sym, v) + } + return vm.NewMap(kvs), nil +} + +//lg:native +//lg:name find-var +func CoreFindVar(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 1 { + return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) + } + sym, ok := vs[0].(vm.Symbol) + if !ok { + return vm.NIL, fmt.Errorf("find-var expected a symbol") + } + nsV, nameV := sym.Namespaced() + nsSym, ok1 := nsV.(vm.Symbol) + nameSym, ok2 := nameV.(vm.Symbol) + if !ok1 || !ok2 { + return vm.NIL, fmt.Errorf("find-var expects a fully-qualified symbol: %s", sym) + } + nsMu.RLock() + targetNS := nsRegistry[resolveNSAlias(string(nsSym))] + nsMu.RUnlock() + if targetNS == nil { + return vm.NIL, nil + } + if v := targetNS.LookupLocal(nameSym); v != nil { + return v, nil + } + return vm.NIL, nil +} + +//lg:native +//lg:name get-method +func CoreGetMethod(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 2 { + return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) + } + mf, ok := vs[0].(*vm.MultiFn) + if !ok { + return vm.NIL, fmt.Errorf("get-method expected a multimethod") + } + return mf.GetMethod(vs[1]), nil +} + +//lg:native +//lg:name enumeration-seq +func CoreEnumerationSeq(vs ...vm.Value) (vm.Value, error) { + return vm.NIL, fmt.Errorf("enumeration-seq is not supported under let-go (no java.util.Enumeration)") +} + +//lg:native +//lg:name lazy-seq* +func CoreLazySeq(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 1 { + return vm.NIL, fmt.Errorf("lazy-seq* expected 1 argument, got %d", len(vs)) + } + fn, ok := vs[0].(vm.Fn) + if !ok { + return vm.NIL, fmt.Errorf("lazy-seq* expected a function") + } + return vm.NewLazySeq(fn), nil +} + +//lg:native +//lg:name with-meta +func CoreWithMeta(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 2 { + return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) + } + if vs[0] == vm.NIL { + return vm.NIL, nil + } + m, ok := vs[0].(vm.IMeta) + if ok { + return m.WithMeta(vs[1]), nil + } + fn, ok := vs[0].(vm.Fn) + if ok { + return vm.NewMetaFn(fn, vs[1]), nil + } + + return vs[0], nil +} + +//lg:native +//lg:name throw +func CoreThrowf(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 1 { + return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) + } + return vm.NIL, vm.NewThrownError(vs[0]) +} + +//lg:native +//lg:name ex-info +func CoreExInfo(vs ...vm.Value) (vm.Value, error) { + if len(vs) < 2 || len(vs) > 3 { + return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) + } + msg, ok := vs[0].(vm.String) + if !ok { + return vm.NIL, fmt.Errorf("ex-info expected String message") + } + data, ok := vs[1].(*vm.PersistentMap) + if !ok { + return vm.NIL, fmt.Errorf("ex-info expected Map data") + } + var cause error + if len(vs) == 3 { + if ei, ok := vs[2].(*vm.ExInfo); ok { + cause = ei + } + } + return vm.NewExInfo(string(msg), data, cause), nil +} + +//lg:native +//lg:name ex-message +func CoreExMessage(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 1 { + return vm.NIL, fmt.Errorf("wrong number of arguments") + } + if ei, ok := vs[0].(*vm.ExInfo); ok { + return vm.String(ei.Message()), nil + } + return vm.NIL, nil +} + +//lg:native +//lg:name ex-data +func CoreExData(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 1 { + return vm.NIL, fmt.Errorf("wrong number of arguments") + } + if ei, ok := vs[0].(*vm.ExInfo); ok { + + if d := ei.Data(); d != nil { + return d, nil + } + } + return vm.NIL, nil +} + +//lg:native +//lg:name ex-cause +func CoreExCause(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 1 { + return vm.NIL, fmt.Errorf("wrong number of arguments") + } + if ei, ok := vs[0].(*vm.ExInfo); ok { + if c := ei.Cause(); c != nil { + if cev, ok := c.(*vm.ExInfo); ok { + return cev, nil + } + } + } + return vm.NIL, nil +} + +//lg:native +//lg:name delay* +func CoreDelayStar(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 1 { + return vm.NIL, fmt.Errorf("delay* expects 1 arg (thunk fn)") + } + fn, ok := vs[0].(vm.Fn) + if !ok { + return vm.NIL, fmt.Errorf("delay* expected Fn") + } + return vm.NewDelay(fn), nil +} + +//lg:native +//lg:name force +func CoreForce(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 1 { + return vm.NIL, fmt.Errorf("force expects 1 arg") + } + if d, ok := vs[0].(*vm.Delay); ok { + return d.Force() + } + return vs[0], nil +} + +//lg:native +//lg:name delay? +func CoreIsDelay(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 1 { + return vm.FALSE, nil + } + _, ok := vs[0].(*vm.Delay) + return vm.Boolean(ok), nil +} + +//lg:native +//lg:name realized? +func CoreIsRealized(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 1 { + return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) + } + if d, ok := vs[0].(*vm.Delay); ok { + return vm.Boolean(d.IsRealized()), nil + } + if p, ok := vs[0].(*vm.Promise); ok { + return vm.Boolean(p.IsRealized()), nil + } + if s, ok := vs[0].(*vm.LazySeq); ok { + return vm.Boolean(s.IsRealized()), nil + } + return vm.NIL, fmt.Errorf("realized? expected delay, promise, future, or lazy seq") +} + +//lg:native +//lg:name volatile! +func CoreVolatilef(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 1 { + return vm.NIL, fmt.Errorf("volatile! expects 1 arg") + } + return vm.NewVolatile(vs[0]), nil +} + +//lg:native +//lg:name vreset! +func CoreVreset(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 2 { + return vm.NIL, fmt.Errorf("vreset! expects 2 args") + } + v, ok := vs[0].(*vm.Volatile) + if !ok { + return vm.NIL, fmt.Errorf("vreset! expected Volatile") + } + return v.Reset(vs[1]), nil +} + +//lg:native +//lg:name reduced +func CoreReducedf(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 1 { + return vm.NIL, fmt.Errorf("reduced expects 1 arg") + } + return vm.NewReduced(vs[0]), nil +} + +//lg:native +//lg:name reduced? +func CoreIsReducedf(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 1 { + return vm.FALSE, nil + } + return vm.Boolean(vm.IsReduced(vs[0])), nil +} + +//lg:native +//lg:name bit-and +func CoreBitAnd(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 2 { + return vm.NIL, fmt.Errorf("bit-and expects 2 args") + } + a, ok := vs[0].(vm.Int) + if !ok { + return vm.NIL, fmt.Errorf("bit-and expected Int") + } + b, ok := vs[1].(vm.Int) + if !ok { + return vm.NIL, fmt.Errorf("bit-and expected Int") + } + return vm.MakeInt(int(a) & int(b)), nil +} + +//lg:native +//lg:name bit-or +func CoreBitOr(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 2 { + return vm.NIL, fmt.Errorf("bit-or expects 2 args") + } + a, ok := vs[0].(vm.Int) + if !ok { + return vm.NIL, fmt.Errorf("bit-or expected Int") + } + b, ok := vs[1].(vm.Int) + if !ok { + return vm.NIL, fmt.Errorf("bit-or expected Int") + } + return vm.MakeInt(int(a) | int(b)), nil +} + +//lg:native +//lg:name bit-xor +func CoreBitXor(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 2 { + return vm.NIL, fmt.Errorf("bit-xor expects 2 args") + } + a, ok := vs[0].(vm.Int) + if !ok { + return vm.NIL, fmt.Errorf("bit-xor expected Int") + } + b, ok := vs[1].(vm.Int) + if !ok { + return vm.NIL, fmt.Errorf("bit-xor expected Int") + } + return vm.MakeInt(int(a) ^ int(b)), nil +} + +//lg:native +//lg:name bit-not +func CoreBitNot(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 1 { + return vm.NIL, fmt.Errorf("bit-not expects 1 arg") + } + a, ok := vs[0].(vm.Int) + if !ok { + return vm.NIL, fmt.Errorf("bit-not expected Int") + } + return vm.MakeInt(^int(a)), nil +} + +//lg:native +//lg:name bit-shift-left +func CoreBitShiftLeft(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 2 { + return vm.NIL, fmt.Errorf("bit-shift-left expects 2 args") + } + a, ok := vs[0].(vm.Int) + if !ok { + return vm.NIL, fmt.Errorf("bit-shift-left expected Int") + } + b, ok := vs[1].(vm.Int) + if !ok { + return vm.NIL, fmt.Errorf("bit-shift-left expected Int") + } + return vm.MakeInt(int(a) << uint(b)), nil +} + +//lg:native +//lg:name bit-shift-right +func CoreBitShiftRight(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 2 { + return vm.NIL, fmt.Errorf("bit-shift-right expects 2 args") + } + a, ok := vs[0].(vm.Int) + if !ok { + return vm.NIL, fmt.Errorf("bit-shift-right expected Int") + } + b, ok := vs[1].(vm.Int) + if !ok { + return vm.NIL, fmt.Errorf("bit-shift-right expected Int") + } + return vm.MakeInt(int(a) >> uint(b)), nil +} + +//lg:native +//lg:name unsigned-bit-shift-right +func CoreUnsignedBitShiftRight(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 2 { + return vm.NIL, fmt.Errorf("unsigned-bit-shift-right expects 2 args") + } + a, ok := vs[0].(vm.Int) + if !ok { + return vm.NIL, fmt.Errorf("unsigned-bit-shift-right expected Int") + } + b, ok := vs[1].(vm.Int) + if !ok { + return vm.NIL, fmt.Errorf("unsigned-bit-shift-right expected Int") + } + return vm.MakeInt(int(uint(a) >> uint(b))), nil +} + +//lg:native +//lg:name bit-test +func CoreBitTest(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 2 { + return vm.NIL, fmt.Errorf("bit-test expects 2 args") + } + a, ok := vs[0].(vm.Int) + if !ok { + return vm.NIL, fmt.Errorf("bit-test expected Int") + } + b, ok := vs[1].(vm.Int) + if !ok { + return vm.NIL, fmt.Errorf("bit-test expected Int") + } + return vm.Boolean(int(a)&(1< +func CoreTapBang(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 1 { + return vm.NIL, fmt.Errorf("tap> expects 1 arg") + } + tapsMu.Lock() + snap := make([]vm.Fn, len(taps)) + copy(snap, taps) + tapsMu.Unlock() + for _, t := range snap { + _, _ = t.Invoke([]vm.Value{vs[0]}) + } + return vm.TRUE, nil +} + +//lg:native +//lg:name add-watch +func CoreAddWatch(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 3 { + return vm.NIL, fmt.Errorf("add-watch expects 3 args") + } + fn, ok := vm.AsFn(vs[2]) + if !ok { + return vm.NIL, fmt.Errorf("add-watch expected Fn") + } + switch ref := vs[0].(type) { + case *vm.Atom: + ref.AddWatch(vs[1], fn) + case *vm.Var: + ref.AddWatch(vs[1], fn) + default: + return vm.NIL, fmt.Errorf("add-watch expected Atom or Var") + } + return vs[0], nil +} + +//lg:native +//lg:name remove-watch +func CoreRemoveWatch(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 2 { + return vm.NIL, fmt.Errorf("remove-watch expects 2 args") + } + switch ref := vs[0].(type) { + case *vm.Atom: + ref.RemoveWatch(vs[1]) + case *vm.Var: + ref.RemoveWatch(vs[1]) + default: + return vm.NIL, fmt.Errorf("remove-watch expected Atom or Var") + } + return vs[0], nil +} + +//lg:native +//lg:name get-validator +func CoreGetValidator(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 1 { + return vm.NIL, fmt.Errorf("get-validator expects 1 arg") + } + a, ok := vs[0].(*vm.Atom) + if !ok { + return vm.NIL, fmt.Errorf("get-validator expected Atom") + } + return a.Validator(), nil +} + +//lg:native +//lg:name subvec +func CoreSubvecf(vs ...vm.Value) (vm.Value, error) { + if len(vs) < 2 || len(vs) > 3 { + return vm.NIL, fmt.Errorf("subvec expects 2-3 args") + } + s, ok := vm.ToInt(vs[1]) + if !ok { + return vm.NIL, fmt.Errorf("subvec expected Int start") + } + + switch v := vs[0].(type) { + case vm.ArrayVector: + end := len(v) + if len(vs) == 3 { + e, ok := vm.ToInt(vs[2]) + if !ok { + return vm.NIL, fmt.Errorf("subvec expected Int end") + } + end = e + } + if s < 0 || end > len(v) || s > end { + return vm.NIL, fmt.Errorf("subvec: index out of bounds") + } + result := make([]vm.Value, end-s) + copy(result, v[s:end]) + return vm.NewArrayVector(result), nil + case vm.PersistentVector: + end := int(v.Count().(vm.Int)) + if len(vs) == 3 { + e, ok := vm.ToInt(vs[2]) + if !ok { + return vm.NIL, fmt.Errorf("subvec expected Int end") + } + end = e + } + if s < 0 || end > int(v.Count().(vm.Int)) || s > end { + return vm.NIL, fmt.Errorf("subvec: index out of bounds") + } + result := make([]vm.Value, end-s) + for i := s; i < end; i++ { + result[i-s] = v.ValueAt(vm.Int(i)) + } + return vm.NewArrayVector(result), nil + default: + return vm.NIL, fmt.Errorf("subvec expected vector") + } +} + +//lg:native +//lg:name double? +func CoreIsDouble(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 1 { + return vm.FALSE, nil + } + _, ok := vs[0].(vm.Float) + return vm.Boolean(ok), nil +} + +//lg:native +//lg:name instance? +func CoreInstancep(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 2 { + return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) + } + + if t, ok := vs[0].(vm.ValueType); ok { + if vs[1].Type() == t { + return vm.TRUE, nil + } + + if anc := directTypeAncestors(vs[1].Type()); anc != nil { + return anc.Contains(t), nil + } + return vm.FALSE, nil + } + if union, ok := vs[0].(*vm.TypeUnion); ok { + return vm.Boolean(union.Contains(vs[1].Type())), nil + } + + if marker, ok := vs[0].(vm.Symbol); ok { + if anc := directTypeAncestors(vs[1].Type()); anc != nil { + return vm.Boolean(anc.Contains(marker) == vm.TRUE), nil + } + } + + if p, ok := vs[0].(*vm.Protocol); ok { + return vm.Boolean(p.Satisfies(vs[1])), nil + } + return vm.FALSE, nil +} + +//lg:native +//lg:name ifn? +func CoreIsIFn(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 1 { + return vm.FALSE, nil + } + switch vs[0].(type) { + case vm.Fn, vm.Keyword, vm.Symbol, *vm.PersistentMap, *vm.PersistentSet, + vm.ArrayVector, vm.PersistentVector, *vm.SortedMap, *vm.SortedSet, *vm.Promise: + return vm.TRUE, nil + } + return vm.FALSE, nil +} + +//lg:native +//lg:name identical? +func CoreIdentical(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 2 { + return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) + } + return vm.Boolean(identicalValue(vs[0], vs[1])), nil +} + +//lg:native +//lg:name any? +func CoreAnyp(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 1 { + return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) + } + return vm.TRUE, nil +} + +//lg:native +//lg:name unreduced +func CoreUnreduced(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 1 { + return vm.NIL, fmt.Errorf("unreduced expects 1 arg") + } + if r, ok := vs[0].(*vm.Reduced); ok { + return r.Deref(), nil + } + return vs[0], nil +} + +//lg:native +//lg:name ensure-reduced +func CoreEnsureReduced(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 1 { + return vm.NIL, fmt.Errorf("ensure-reduced expects 1 arg") + } + if _, ok := vs[0].(*vm.Reduced); ok { + return vs[0], nil + } + return vm.NewReduced(vs[0]), nil +} + +//lg:native +//lg:name bigint +func CoreBigintf(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 1 { + return vm.NIL, fmt.Errorf("bigint expects 1 arg") + } + switch v := vs[0].(type) { + case vm.Int: + return vm.NewBigIntFromInt64(int64(v)), nil + case vm.Float: + f := float64(v) + if math.IsNaN(f) || math.IsInf(f, 0) { + return vm.NIL, fmt.Errorf("cannot coerce %s to bigint", vs[0]) + } + decimal := strconv.FormatFloat(f, 'g', -1, 64) + i, _, err := new(big.Float).SetPrec(4096).SetMode(big.ToZero).Parse(decimal, 10) + if err != nil || i == nil { + return vm.NIL, fmt.Errorf("cannot coerce %s to bigint", vs[0]) + } + bi, _ := i.Int(nil) + return vm.NewBigInt(bi), nil + case *vm.BigInt: + return v, nil + case vm.String: + bi, ok := vm.NewBigIntFromString(string(v)) + if !ok { + return vm.NIL, fmt.Errorf("cannot parse bigint: %s", v) + } + return bi, nil + } + return vm.NIL, fmt.Errorf("cannot coerce %s to bigint", vs[0].Type().Name()) +} + +//lg:native +//lg:name ratio? +func CoreIsRatio(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 1 { + return vm.FALSE, nil + } + return vm.Boolean(vm.IsRatio(vs[0])), nil +} + +//lg:native +//lg:name decimal? +func CoreIsDecimal(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 1 { + return vm.FALSE, nil + } + return vm.Boolean(vm.IsBigDecimal(vs[0])), nil +} + +//lg:native +//lg:name sorted? +func CoreIsSorted(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 1 { + return vm.FALSE, nil + } + switch vs[0].(type) { + case *vm.SortedMap, *vm.SortedSet: + return vm.TRUE, nil + } + return vm.FALSE, nil +} + +//lg:native +//lg:name map? +func CoreIsMap(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 1 { + return vm.FALSE, nil + } + switch vs[0].(type) { + case *vm.PersistentMap, *vm.SortedMap: + return vm.TRUE, nil + } + return vm.FALSE, nil +} + +//lg:native +//lg:name set? +func CoreIsSet(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 1 { + return vm.FALSE, nil + } + switch vs[0].(type) { + case *vm.PersistentSet, *vm.SortedSet: + return vm.TRUE, nil + } + return vm.FALSE, nil +} + +//lg:native +//lg:name map-entry? +func CoreIsMapEntry(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 1 { + return vm.FALSE, nil + } + if _, ok := vs[0].(vm.MapEntry); ok { + return vm.TRUE, nil + } + return vm.FALSE, nil +} + +//lg:native +//lg:name lazy-seq? +func CoreIsLazySeq(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 1 { + return vm.FALSE, nil + } + if _, ok := vs[0].(*vm.LazySeq); ok { + return vm.TRUE, nil + } + return vm.FALSE, nil +} + +//lg:native +//lg:name reversible? +func CoreIsReversible(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 1 { + return vm.FALSE, nil + } + switch vs[0].(type) { + case vm.ArrayVector, vm.PersistentVector, *vm.SortedMap, *vm.SortedSet: + return vm.TRUE, nil + } + return vm.FALSE, nil +} + +//lg:native +//lg:name rseq +func CoreRseqf(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 1 { + return vm.NIL, fmt.Errorf("wrong number of arguments") + } + switch v := vs[0].(type) { + case *vm.SortedMap: + s := v.RSeq() + if s == vm.EmptyList { + return vm.NIL, nil + } + return s, nil + case *vm.SortedSet: + s := v.RSeq() + if s == vm.EmptyList { + return vm.NIL, nil + } + return s, nil + case vm.ArrayVector: + n := len(v) + if n == 0 { + return vm.NIL, nil + } + var s vm.Seq = vm.EmptyList + for i := range n { + s = vm.NewCons(v[i], s) + } + return s, nil + case vm.PersistentVector: + n := v.RawCount() + if n == 0 { + return vm.NIL, nil + } + var s vm.Seq = vm.EmptyList + for i := range n { + s = vm.NewCons(v.ValueAt(vm.MakeInt(i)), s) + } + return s, nil + } + return vm.NIL, fmt.Errorf("rseq not supported on: %s", vs[0].Type()) +} + +//lg:native +//lg:name numerator +func CoreNumeratorf(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 1 { + return vm.NIL, fmt.Errorf("wrong number of arguments") + } + if r, ok := vs[0].(*vm.Ratio); ok { + num := r.Val().Num() + return vm.MaybeDowngrade(new(big.Int).Set(num)), nil + } + return vm.NIL, fmt.Errorf("numerator expects a Ratio") +} + +//lg:native +//lg:name denominator +func CoreDenominatorf(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 1 { + return vm.NIL, fmt.Errorf("wrong number of arguments") + } + if r, ok := vs[0].(*vm.Ratio); ok { + den := r.Val().Denom() + return vm.MaybeDowngrade(new(big.Int).Set(den)), nil + } + return vm.NIL, fmt.Errorf("denominator expects a Ratio") +} + +//lg:native +//lg:name bigdec +func CoreBigdecf(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 1 { + return vm.NIL, fmt.Errorf("wrong number of arguments") + } + switch v := vs[0].(type) { + case *vm.BigDecimal: + return v, nil + case vm.Int: + return vm.NewBigDecimalFromInt64(int64(v)), nil + case vm.Float: + f := float64(v) + if math.IsInf(f, 0) || math.IsNaN(f) { + return vm.NIL, fmt.Errorf("cannot coerce non-finite float to bigdec") + } + return vm.NewBigDecimalFromFloat64(f), nil + case *vm.BigInt: + return vm.NewBigDecimalFromBigInt(v.Val()), nil + case *vm.Ratio: + f, _ := v.Val().Float64() + return vm.NewBigDecimalFromFloat64(f), nil + case vm.String: + bd, ok := vm.NewBigDecimalFromString(string(v)) + if !ok { + return vm.NIL, fmt.Errorf("cannot parse bigdec: %s", v) + } + return bd, nil + } + return vm.NIL, fmt.Errorf("cannot coerce %s to bigdec", vs[0].Type().Name()) +} + +//lg:native +//lg:name round-bigdec +func CoreRoundBigdec(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 3 { + return vm.NIL, fmt.Errorf("round-bigdec expects precision, rounding mode, and value") + } + precision, ok := vm.ToInt(vs[0]) + if !ok { + return vm.NIL, fmt.Errorf("round-bigdec expected integer precision") + } + var modeName string + switch m := vs[1].(type) { + case vm.Keyword: + modeName = string(m) + case vm.Symbol: + modeName = string(m) + case vm.String: + modeName = string(m) + default: + return vm.NIL, fmt.Errorf("round-bigdec expected rounding mode") + } + modeName = strings.TrimPrefix(strings.ToLower(modeName), ":") + bd, ok := vs[2].(*vm.BigDecimal) + if !ok { + return vs[2], nil + } + return roundBigDecimalValue(bd, precision, modeName) +} + +//lg:native +//lg:name rationalize +func CoreRationalizef(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 1 { + return vm.NIL, fmt.Errorf("wrong number of arguments") + } + switch v := vs[0].(type) { + case *vm.Ratio: + return v, nil + case vm.Int: + return vm.MaybeSimplifyRatio(big.NewRat(int64(v), 1)), nil + case *vm.BigInt: + return vm.MaybeSimplifyRatio(new(big.Rat).SetInt(v.Val())), nil + case vm.Float: + f := float64(v) + if math.IsInf(f, 0) || math.IsNaN(f) { + return vm.NIL, fmt.Errorf("cannot rationalize %s", vs[0].Type().Name()) + } + if r, ok := new(big.Rat).SetString(strconv.FormatFloat(f, 'f', -1, 64)); ok { + return vm.MaybeSimplifyRatio(r), nil + } + return vm.NIL, fmt.Errorf("cannot rationalize %s", vs[0].Type().Name()) + case *vm.BigDecimal: + if r, ok := new(big.Rat).SetString(v.Val().Text('f', -1)); ok { + return vm.MaybeSimplifyRatio(r), nil + } + return vm.NIL, fmt.Errorf("cannot rationalize %s", vs[0].Type().Name()) + } + return vm.NIL, fmt.Errorf("cannot rationalize %s", vs[0].Type().Name()) +} + +//lg:native +//lg:name quot +func CoreQuotf(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 2 { + return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) + } + return vm.NumQuot(vs[0], vs[1]) +} + +//lg:native +//lg:name rem +func CoreRemf(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 2 { + return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) + } + return vm.NumRem(vs[0], vs[1]) +} + +//lg:native +//lg:name hash +func CoreHashf(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 1 { + return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) + } + return vm.MakeInt(int(vm.HashValue(vs[0]))), nil +} + +//lg:native +//lg:name parse-double +func CoreParseDouble(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 1 { + return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) + } + s, ok := vs[0].(vm.String) + if !ok { + return vm.NIL, fmt.Errorf("parse-double expected String") + } + f, err := strconv.ParseFloat(string(s), 64) + if err != nil { + return vm.NIL, nil + } + return vm.Float(f), nil +} + +//lg:native +//lg:name parse-boolean +func CoreParseBool(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 1 { + return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) + } + s, ok := vs[0].(vm.String) + if !ok { + return vm.NIL, fmt.Errorf("parse-boolean expected String") + } + switch string(s) { + case "true": + return vm.TRUE, nil + case "false": + return vm.FALSE, nil + } + return vm.NIL, nil +} + +//lg:native +//lg:name NaN? +func CoreIsNaN(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 1 { + return vm.FALSE, nil + } + switch v := vs[0].(type) { + case vm.Float: + return vm.Boolean(math.IsNaN(float64(v))), nil + case vm.Float32: + return vm.Boolean(math.IsNaN(float64(v))), nil + case vm.Int, *vm.BigInt, *vm.Ratio, *vm.BigDecimal: + return vm.FALSE, nil + default: + return vm.NIL, fmt.Errorf("NaN? requires a number, got %s", vs[0].Type().Name()) + } +} + +//lg:native +//lg:name infinite? +func CoreIsInfinite(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 1 { + return vm.FALSE, nil + } + if f, ok := vs[0].(vm.Float); ok { + return vm.Boolean(math.IsInf(float64(f), 0)), nil + } + return vm.FALSE, nil +} + +//lg:native +//lg:name boolean? +func CoreIsBool(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 1 { + return vm.FALSE, nil + } + _, ok := vs[0].(vm.Boolean) + return vm.Boolean(ok), nil +} + +//lg:native +//lg:name char? +func CoreIsChar(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 1 { + return vm.FALSE, nil + } + _, ok := vs[0].(vm.Char) + return vm.Boolean(ok), nil +} + +//lg:native +//lg:name var? +func CoreIsVar(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 1 { + return vm.FALSE, nil + } + _, ok := vs[0].(*vm.Var) + return vm.Boolean(ok), nil +} + +//lg:native +//lg:name byte-array +func CoreByteArrayf(vs ...vm.Value) (vm.Value, error) { + return buildArray(vm.ArrayByte, vs) +} + +//lg:native +//lg:name object-array +func CoreObjectArrayf(vs ...vm.Value) (vm.Value, error) { + return buildArray(vm.ArrayObject, vs) +} + +//lg:native +//lg:name make-array +func CoreMakeArrayf(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 2 { + return vm.NIL, fmt.Errorf("make-array expects 2 args (type, size)") + } + size, ok := vs[1].(vm.Int) + if !ok { + return vm.NIL, fmt.Errorf("make-array size must be Int") + } + n := int(size) + if n < 0 { + return vm.NIL, fmt.Errorf("negative array size: %d", n) + } + switch t := vs[0].(type) { + case vm.Keyword: + switch string(t) { + case "byte": + return vm.NewByteArray(n), nil + case "int", "long": + return vm.NewIntArray(n), nil + case "double", "float": + return vm.NewFloatArray(n), nil + case "object": + return vm.NewObjectArray(n), nil + } + return vm.NIL, fmt.Errorf("unknown array type: %s", t) + default: + + return vm.NewObjectArray(n), nil + } +} + +//lg:native +//lg:name aget +func CoreAgetf(vs ...vm.Value) (vm.Value, error) { + if len(vs) < 2 { + return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) + } + arr, ok := vs[0].(*vm.TypedArray) + if !ok { + return vm.NIL, fmt.Errorf("aget expects array, got %s", vs[0].Type().Name()) + } + idx, ok := vs[1].(vm.Int) + if !ok { + return vm.NIL, fmt.Errorf("aget index must be Int") + } + i := int(idx) + if i < 0 || i >= arr.Len() { + return vm.NIL, fmt.Errorf("array index %d out of bounds for length %d", i, arr.Len()) + } + val := arr.Get(i) + + for _, extra := range vs[2:] { + inner, ok := val.(*vm.TypedArray) + if !ok { + return vm.NIL, fmt.Errorf("aget nested: expected array, got %s", val.Type().Name()) + } + idx, ok := extra.(vm.Int) + if !ok { + return vm.NIL, fmt.Errorf("aget index must be Int") + } + j := int(idx) + if j < 0 || j >= inner.Len() { + return vm.NIL, fmt.Errorf("array index %d out of bounds for length %d", j, inner.Len()) + } + val = inner.Get(j) + } + return val, nil +} + +//lg:native +//lg:name aset +func CoreAsetf(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 3 { + return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) + } + arr, ok := vs[0].(*vm.TypedArray) + if !ok { + return vm.NIL, fmt.Errorf("aset expects array, got %s", vs[0].Type().Name()) + } + idx, ok := vs[1].(vm.Int) + if !ok { + return vm.NIL, fmt.Errorf("aset index must be Int") + } + i := int(idx) + if i < 0 || i >= arr.Len() { + return vm.NIL, fmt.Errorf("array index %d out of bounds for length %d", i, arr.Len()) + } + if err := arr.Set(i, vs[2]); err != nil { + return vm.NIL, err + } + return vs[2], nil +} + +//lg:native +//lg:name alength +func CoreAlengthf(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 1 { + return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) + } + arr, ok := vs[0].(*vm.TypedArray) + if !ok { + return vm.NIL, fmt.Errorf("alength expects array, got %s", vs[0].Type().Name()) + } + return vm.MakeInt(arr.Len()), nil +} + +//lg:native +//lg:name aclone +func CoreAclonef(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 1 { + return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) + } + arr, ok := vs[0].(*vm.TypedArray) + if !ok { + return vm.NIL, fmt.Errorf("aclone expects array, got %s", vs[0].Type().Name()) + } + return arr.Clone(), nil +} + +//lg:native +//lg:name bytes +func CoreBytesf(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 1 { + return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) + } + switch v := vs[0].(type) { + case vm.String: + data := []byte(string(v)) + return vm.NewByteArrayFrom(data), nil + case *vm.TypedArray: + if v.Kind() == vm.ArrayByte { + return v, nil + } + } + return vm.NIL, fmt.Errorf("bytes expects String or byte-array, got %s", vs[0].Type().Name()) +} + +//lg:native +//lg:name doubles +func CoreDoublesf(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 1 { + return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) + } + if a, ok := vs[0].(*vm.TypedArray); ok && a.Kind() == vm.ArrayFloat { + return a, nil + } + return buildArray(vm.ArrayFloat, vs) +} + +//lg:native +//lg:name bytes? +func CoreBytesP(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 1 { + return vm.FALSE, nil + } + a, ok := vs[0].(*vm.TypedArray) + return vm.Boolean(ok && a.Kind() == vm.ArrayByte), nil +} + +//lg:native +//lg:name var-get +func CoreVarGet(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 1 { + return vm.NIL, fmt.Errorf("var-get expects 1 arg") + } + v, ok := vs[0].(*vm.Var) + if !ok { + return vm.NIL, fmt.Errorf("var-get expects a Var") + } + return v.Deref(), nil +} + +//lg:native +//lg:name bound? +func CoreBoundQ(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 1 { + return vm.NIL, fmt.Errorf("bound? expects 1 arg") + } + v, ok := vs[0].(*vm.Var) + if !ok { + return vm.NIL, fmt.Errorf("bound? expects a Var") + } + if v.IsBound() { + return vm.TRUE, nil + } + return vm.FALSE, nil +} + +//lg:native +//lg:name -copy-form-source! +func CoreCopyFormSource(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 2 { + return vm.NIL, fmt.Errorf("-copy-form-source! expects 2 args") + } + if info := vm.FormSource.Get(vs[0]); info != nil { + vm.FormSource.Set(vs[1], *info) + } + return vs[1], nil +} + +//lg:native +//lg:name chunk->fn +func CoreChunkToFnFn(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 3 { + return vm.NIL, fmt.Errorf("chunk->fn expects (arity variadic? chunk), got %d args", len(vs)) + } + arityV, ok := vs[0].(vm.Int) + if !ok { + return vm.NIL, fmt.Errorf("chunk->fn: arity must be Int, got %s", vs[0].Type().Name()) + } + variadic := false + if b, ok := vs[1].(vm.Boolean); ok { + variadic = bool(b) + } else if vs[1] != vm.NIL { + return vm.NIL, fmt.Errorf("chunk->fn: variadic? must be Boolean or nil, got %s", vs[1].Type().Name()) + } + boxed, ok := vs[2].(*vm.Boxed) + if !ok { + return vm.NIL, fmt.Errorf("chunk->fn: third arg must be boxed CodeChunk, got %s", vs[2].Type().Name()) + } + chunk, ok := boxed.Unbox().(*vm.CodeChunk) + if !ok { + return vm.NIL, fmt.Errorf("chunk->fn: boxed value is not a CodeChunk") + } + return vm.MakeFunc(int(arityV), variadic, chunk), nil +} + +//lg:native +//lg:name make-multi-arity +func CoreMakeMultiArityFn(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 1 { + return vm.NIL, fmt.Errorf("make-multi-arity expects 1 arg (list of functions)") + } + list, ok := vs[0].(*vm.List) + if !ok { + return vm.NIL, fmt.Errorf("make-multi-arity expects a list, got %s", vs[0].Type().Name()) + } + var fns []vm.Value + for e := vm.Seq(list); e != nil; e = e.Next() { + fns = append(fns, e.First()) + } + return vm.MakeMultiArity(fns) +} + +//lg:native +//lg:name intern +func CoreInternf(vs ...vm.Value) (vm.Value, error) { + if len(vs) < 2 || len(vs) > 3 { + return vm.NIL, fmt.Errorf("intern expects 2 or 3 args") + } + var targetNS *vm.Namespace + switch n := vs[0].(type) { + case vm.Symbol: + targetNS = nsRegistry[resolveNSAlias(string(n))] + case *vm.Namespace: + targetNS = n + default: + return vm.NIL, fmt.Errorf("intern expects a namespace or symbol") + } + if targetNS == nil { + return vm.NIL, fmt.Errorf("namespace not found") + } + sym, ok := vs[1].(vm.Symbol) + if !ok { + return vm.NIL, fmt.Errorf("intern expects a symbol name") + } + if len(vs) == 2 { + if existing := targetNS.LookupLocal(sym); existing != nil { + return existing, nil + } + return targetNS.Def(string(sym), vm.NIL), nil + } + + if existing := targetNS.LookupLocal(sym); existing != nil { + existing.SetRoot(vs[2]) + return existing, nil + } + v := targetNS.Def(string(sym), vs[2]) + return v, nil +} + +//lg:native +//lg:name apply-def-meta! +func CoreApplyDefMetaf(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 2 { + return vm.NIL, fmt.Errorf("apply-def-meta! expects 2 args") + } + v, ok := vs[0].(*vm.Var) + if !ok { + return vm.NIL, fmt.Errorf("apply-def-meta! expects a Var") + } + ApplyVarMeta(v, vs[1]) + return v, nil +} + +//lg:native +//lg:name create-ns +func CoreCreateNsf(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 1 { + return vm.NIL, fmt.Errorf("create-ns expects 1 arg") + } + sym, ok := vs[0].(vm.Symbol) + if !ok { + return vm.NIL, fmt.Errorf("create-ns expects a symbol") + } + return NS(string(sym)), nil +} + +//lg:native +//lg:name pop! +func CorePopBang(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 1 { + return vm.NIL, fmt.Errorf("pop! expects 1 arg") + } + tv, ok := vs[0].(*vm.TransientVector) + if !ok { + return vm.NIL, fmt.Errorf("pop! expects a transient vector") + } + return tv.Pop() +} + +//lg:native +//lg:name uuid? +func CoreIsUUID(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 1 { + return vm.FALSE, nil + } + _, ok := vs[0].(*vm.UUID) + return vm.Boolean(ok), nil +} + +//lg:native +//lg:name inst? +func CoreIsInst(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 1 { + return vm.FALSE, nil + } + _, ok := vs[0].(*vm.Instant) + return vm.Boolean(ok), nil +} + +//lg:native +//lg:name parse-uuid +func CoreParseUUID(vs ...vm.Value) (vm.Value, error) { + if len(vs) != 1 { + return vm.NIL, fmt.Errorf("parse-uuid expects 1 arg") + } + s, ok := vs[0].(vm.String) + if !ok { + return vm.NIL, fmt.Errorf("parse-uuid expects a string, got %s", vs[0].Type().Name()) + } + u := vm.ParseUUID(string(s)) + if u == nil { + return vm.NIL, nil + } + return u, nil +} + +//lg:native +//lg:name == +func CoreNumericEq(vs ...vm.Value) (vm.Value, error) { + if len(vs) < 2 { + return vm.TRUE, nil + } + for i := 1; i < len(vs); i++ { + if !vm.NumEquivalent(vs[0], vs[i]) { + return vm.FALSE, nil + } + } + return vm.TRUE, nil +} diff --git a/pkg/rt/native_prims.go b/pkg/rt/native_prims.go index 824331124..945dbe7b2 100644 --- a/pkg/rt/native_prims.go +++ b/pkg/rt/native_prims.go @@ -439,204 +439,6 @@ func reduceColl(ec *vm.ExecContext, mfn vm.Fn, coll vm.Value, hasInit bool, init return acc, nil } -// symbolToStr accepts the string-like values clojure.core/symbol takes as a -// name or namespace component. -func symbolToStr(v vm.Value) (string, bool) { - switch s := v.(type) { - case vm.String: - return string(s), true - case vm.Symbol: - return string(s), true - case vm.Keyword: - return string(s), true - default: - return "", false - } -} - -// Symbol implements (symbol x): a String/Symbol/Keyword becomes a Symbol of -// the same text, and a Var becomes its qualified name. Lives here rather than -// in pkg/rt/builtins because the Var case needs externalNSName, which reads -// rt's alias table — builtins imports only vm, by design. -// -//lg:native -//lg:name symbol -func Symbol(v vm.Value) (vm.Value, error) { - if v == vm.NIL { - return vm.NIL, fmt.Errorf("symbol expected String, Symbol, Keyword, or Var") - } - if vr, ok := v.(*vm.Var); ok { - return vm.Symbol(externalNSName(vr.NS()) + "/" + vr.VarName()), nil - } - if s, ok := symbolToStr(v); ok { - return vm.Symbol(s), nil - } - return vm.NIL, fmt.Errorf("symbol expected String or Symbol") -} - -// Assoc implements the 3-arity (assoc coll k v). Higher arities stay on the -// trampoline: the variadic form threads pairs left-to-right and is far rarer -// in lowered code than the single-pair case. -// -//lg:native -//lg:name assoc -func Assoc(coll vm.Value, k vm.Value, v vm.Value) (vm.Value, error) { - a, ok := coll.(vm.Associative) - if !ok { - return vm.NIL, fmt.Errorf("assoc expected Associative") - } - ret := a.Assoc(k, v) - if ret == vm.NIL { - return vm.NIL, fmt.Errorf("assoc failed for key %s", k.String()) - } - return ret, nil -} - -// AssocBang implements the 3-arity (assoc! transient k v). The variadic form -// (multiple k/v pairs) stays on the trampoline; the single-pair case is what -// hot loops emit. -// -// Registered as a native because ir.direct's evaluator calls assoc! once per -// INSTRUCTION to store each result into the indexed value table. Without an -// entry here that call lowers to ec.Invoke plus a []vm.Value allocation on -// every instruction executed — the single hottest trampoline in the -// interpreter. -// -//lg:native -//lg:name assoc! -func AssocBang(coll vm.Value, k vm.Value, v vm.Value) (vm.Value, error) { - switch t := coll.(type) { - case *vm.TransientVector: - return t.Assoc(k, v) - case *vm.TransientMap: - return t.Assoc(k, v) - default: - return vm.NIL, fmt.Errorf("assoc! expected a transient, got %s", coll.Type().Name()) - } -} - -// swapAtom is the shared body for the swap! arities: ec.Bind(fn) is what makes -// the atom's retry loop able to re-invoke the user function, which is why this -// lives in rt (with ExecContext) rather than in the vm-only builtins package. -func swapAtom(ec *vm.ExecContext, a vm.Value, f vm.Value, extra []vm.Value) (vm.Value, error) { - at, ok := a.(*vm.Atom) - if !ok { - return vm.NIL, fmt.Errorf("swap expected Atom") - } - fn, ok := vm.AsFn(f) - if !ok { - return vm.NIL, fmt.Errorf("swap expected Fn") - } - return at.Swap(ec.Bind(fn), extra) -} - -// Swap implements (swap! a f). -// -//lg:native -//lg:name swap! -func Swap(ec *vm.ExecContext, a vm.Value, f vm.Value) (vm.Value, error) { - return swapAtom(ec, a, f, nil) -} - -// Swap3 implements (swap! a f x). -// -//lg:native -//lg:name swap! -func Swap3(ec *vm.ExecContext, a vm.Value, f vm.Value, x vm.Value) (vm.Value, error) { - return swapAtom(ec, a, f, []vm.Value{x}) -} - -// NotEq implements the 2-arity (not= a b). It calls rt's own valueEquals — -// NOT vm.ValueEquals / EqValue, which is a different function with different -// nil and numeric handling — so not= stays exactly the negation of =. The NaN -// case mirrors the interpreter path: two NaNs compare not-different here. -// -//lg:native -//lg:name not= -func NotEq(a vm.Value, b vm.Value) (vm.Value, error) { - if isNaNValue(a) && isNaNValue(b) { - return vm.FALSE, nil - } - return vm.Boolean(!valueEquals(a, b)), nil -} - -// assocPairs threads key/value pairs left-to-right, the shared body for the -// fixed assoc arities. -func assocPairs(coll vm.Value, kvs ...vm.Value) (vm.Value, error) { - a, ok := coll.(vm.Associative) - if !ok { - return vm.NIL, fmt.Errorf("assoc expected Associative") - } - ret := a - for i := 0; i+1 < len(kvs); i += 2 { - next := ret.Assoc(kvs[i], kvs[i+1]) - if next == vm.NIL { - return vm.NIL, fmt.Errorf("assoc failed for key %s", kvs[i].String()) - } - // Assoc returns vm.Associative, so next is already that type. - ret = next - } - return ret, nil -} - -// Assoc5 implements (assoc coll k1 v1 k2 v2). -// -//lg:native -//lg:name assoc -func Assoc5(coll, k1, v1, k2, v2 vm.Value) (vm.Value, error) { - return assocPairs(coll, k1, v1, k2, v2) -} - -// Swap4 implements (swap! a f x y). -// -//lg:native -//lg:name swap! -func Swap4(ec *vm.ExecContext, a, f, x, y vm.Value) (vm.Value, error) { - return swapAtom(ec, a, f, []vm.Value{x, y}) -} - -// Swap5 implements (swap! a f x y z). -// -//lg:native -//lg:name swap! -func Swap5(ec *vm.ExecContext, a, f, x, y, z vm.Value) (vm.Value, error) { - return swapAtom(ec, a, f, []vm.Value{x, y, z}) -} - -// IsMap implements (map? x). -// -//lg:native -//lg:name map? -func IsMap(v vm.Value) (vm.Value, error) { - switch v.(type) { - case *vm.PersistentMap, *vm.SortedMap: - return vm.TRUE, nil - } - return vm.FALSE, nil -} - -// Atom implements the 1-arity (atom x). The option-taking arities (:meta, -// :validator) stay on the trampoline — they parse keyword pairs, which the -// fixed-arity direct-call path is not the right shape for. -// -//lg:native -//lg:name atom -func Atom(v vm.Value) (vm.Value, error) { - return vm.NewAtomWithMetaValidator(v, nil, nil) -} - -// Reset implements (reset! a v). -// -//lg:native -//lg:name reset! -func Reset(a vm.Value, v vm.Value) (vm.Value, error) { - at, ok := a.(*vm.Atom) - if !ok { - return vm.NIL, fmt.Errorf("reset expected Atom") - } - return at.Reset(v) -} - // Namespace implements (namespace x) for Named values. // //lg:native @@ -703,27 +505,6 @@ func regexSubmatchValue(s string, indices []int) vm.Value { return regexSubmatchVector(s, indices) } -// ReFind implements (re-find re s), reusing regexSubmatchValue so the -// group-shaped result matches the interpreter path exactly. -// -//lg:native -//lg:name re-find -func ReFind(re vm.Value, s vm.Value) (vm.Value, error) { - r, ok := re.(*vm.Regex) - if !ok { - return vm.NIL, fmt.Errorf("re-find expected Regex") - } - str, ok := s.(vm.String) - if !ok { - return vm.NIL, fmt.Errorf("re-find expected String") - } - indices := r.FindStringSubmatchIndex(string(str)) - if indices == nil { - return vm.NIL, nil - } - return regexSubmatchValue(string(str), indices), nil -} - // Some implements (some pred coll). Body extracted verbatim from lang.go's // closure (including the chunked fast path) rather than retyped, so the // direct-call path cannot drift from the interpreter path. Needs the @@ -839,79 +620,3 @@ func rangeInt(v vm.Value, what string) (vm.Int, error) { return 0, fmt.Errorf("range %s must be an integer, got %s", what, v.Type().Name()) } - -// rangeVals is the shared body of clojure.core/range, extracted verbatim from -// lang.go's closure so the direct-call arities below and the interpreter path -// cannot diverge. -func rangeVals(vs []vm.Value) (vm.Value, error) { - if len(vs) == 0 { - // Infinite range: (range) -> lazy seq 0, 1, 2, ... - return vm.NewInfiniteRange(0, 1), nil - } - if len(vs) > 3 { - return vm.NIL, fmt.Errorf("wrong number of arguments %d", len(vs)) - } - var start, end, step vm.Int - step = 1 - var err error - var endArg vm.Value - switch len(vs) { - case 1: - endArg = vs[0] - case 2: - endArg = vs[1] - if start, err = rangeInt(vs[0], "start"); err != nil { - return vm.NIL, err - } - case 3: - endArg = vs[1] - if start, err = rangeInt(vs[0], "start"); err != nil { - return vm.NIL, err - } - if step, err = rangeInt(vs[2], "step"); err != nil { - return vm.NIL, err - } - } - // A float end still yields integers, like the JVM: infinite - // for ##Inf toward the step, else every int short of the end - // ((range 2 5.29) => 2 3 4 5). - if f, ok := endArg.(vm.Float); ok { - if math.IsInf(float64(f), 0) { - if (f > 0 && step > 0) || (f < 0 && step < 0) { - return vm.NewInfiniteRange(int(start), int(step)), nil - } - return vm.NewRange(0, 0, 1), nil - } - if step > 0 { - endArg = vm.Int(math.Ceil(float64(f))) - } else { - endArg = vm.Int(math.Floor(float64(f))) - } - } - if end, err = rangeInt(endArg, "end"); err != nil { - return vm.NIL, err - } - return vm.NewRange(start, end, step), nil -} - -// Range1 implements (range end). -// -//lg:native -//lg:name range -func Range1(end vm.Value) (vm.Value, error) { return rangeVals([]vm.Value{end}) } - -// Range2 implements (range start end). -// -//lg:native -//lg:name range -func Range2(start, end vm.Value) (vm.Value, error) { - return rangeVals([]vm.Value{start, end}) -} - -// Range3 implements (range start end step). -// -//lg:native -//lg:name range -func Range3(start, end, step vm.Value) (vm.Value, error) { - return rangeVals([]vm.Value{start, end, step}) -} diff --git a/pkg/rt/zz_primitives_generated.go b/pkg/rt/zz_primitives_generated.go index 503b9058c..809b12654 100644 --- a/pkg/rt/zz_primitives_generated.go +++ b/pkg/rt/zz_primitives_generated.go @@ -6,9 +6,2450 @@ package rt import ( "fmt" + "github.com/nooga/let-go/pkg/vm" +) + +func _adapt_CorePlus(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CorePlus(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreMul(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreMul(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreSub(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreSub(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreDiv(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreDiv(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CorePlusP(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CorePlusP(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreMulP(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreMulP(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreSubP(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreSubP(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreUncheckedAdd(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreUncheckedAdd(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreUncheckedSubtract(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreUncheckedSubtract(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreUncheckedMultiply(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreUncheckedMultiply(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreUncheckedNegate(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreUncheckedNegate(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreUncheckedDivideInt(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreUncheckedDivideInt(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreUncheckedLong(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreUncheckedLong(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreUncheckedInt(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreUncheckedInt(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreUncheckedShort(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreUncheckedShort(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreUncheckedByte(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreUncheckedByte(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreUncheckedChar(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreUncheckedChar(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreUncheckedDouble(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreUncheckedDouble(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreUncheckedFloat(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreUncheckedFloat(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreMod(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreMod(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreAbs(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreAbs(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreNot(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreNot(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreComplement(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreComplement(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreSetMacro(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreSetMacro(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreGensym(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreGensym(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreVector(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreVector(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreHashMap(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreHashMap(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreArrayMap(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreArrayMap(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreSortedMap(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreSortedMap(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreSortedSet(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreSortedSet(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreSortedMapBy(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreSortedMapBy(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreSortedSetBy(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreSortedSetBy(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreChunkFirst(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreChunkFirst(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreChunkRest(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreChunkRest(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreChunkNext(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreChunkNext(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreChunkConsF(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreChunkConsF(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreChunkedSeqP(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreChunkedSeqP(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreChunkBufferF(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreChunkBufferF(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreChunkAppendF(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreChunkAppendF(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreChunkF(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreChunkF(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreRangef(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreRangef(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreKeyword(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreKeyword(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreSymbolf(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreSymbolf(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreAssoc(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreAssoc(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreDissoc(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreDissoc(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreCons(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreCons(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreDisj(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreDisj(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreContains(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreContains(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreSecond(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreSecond(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreIsList(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreIsList(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreEmpty(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreEmpty(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreKeyf(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreKeyf(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreValf(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreValf(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreCount(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreCount(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreExcludeInCurrentNs(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreExcludeInCurrentNs(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreUse(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreUse(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreAliasf(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreAliasf(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreReferList(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreReferList(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreMethodInvoke(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreMethodInvoke(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreRegisterHostMethod(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreRegisterHostMethod(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreRegisterHostClass(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreRegisterHostClass(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreConcat(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreConcat(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreSlurp(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreSlurp(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreSpit(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreSpit(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreAtom(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreAtom(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreReset(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreReset(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreCompareAndSet(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreCompareAndSet(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreResetVals(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreResetVals(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreChanf(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreChanf(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreScopeClose(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreScopeClose(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreScopeLive(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreScopeLive(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreScopeQmark(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreScopeQmark(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreMax(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreMax(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreMin(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreMin(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreStrReplace(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreStrReplace(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreLongf(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreLongf(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreFloatf(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreFloatf(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreDoublef(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreDoublef(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreIsNumber(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreIsNumber(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreIsFloat(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreIsFloat(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreIsInt(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreIsInt(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreChar(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreChar(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreRegex(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreRegex(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CorePeek(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CorePeek(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CorePop(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CorePop(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreIterate(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreIterate(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreRepeat(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreRepeat(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreRefer(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreRefer(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreFormatf(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreFormatf(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreRandf(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreRandf(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreRandInt(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreRandInt(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreRandNth(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreRandNth(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreShuffle(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreShuffle(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreSetRandSeedFn(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreSetRandSeedFn(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreTransientf(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreTransientf(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CorePersistentf(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CorePersistentf(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreConjBang(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreConjBang(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreAssocBang(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreAssocBang(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreDisjBang(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreDisjBang(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreDissocBang(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreDissocBang(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreMakeRecordType(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreMakeRecordType(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreMakeRecord(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreMakeRecord(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreIsRecord(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreIsRecord(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreMakeDType(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreMakeDType(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreMakeDTypeInstance(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreMakeDTypeInstance(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreSetField(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreSetField(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreDefProtocol(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreDefProtocol(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreExtendType(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreExtendType(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreMakeProtocolFn(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreMakeProtocolFn(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreSetInvokableProtocol(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreSetInvokableProtocol(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreSetDerefProtocol(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreSetDerefProtocol(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreSatisfies(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreSatisfies(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreDefMulti(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreDefMulti(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreDefMethod(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreDefMethod(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CorePrStr(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CorePrStr(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CorePrnStr(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CorePrnStr(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CorePrintStr(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CorePrintStr(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CorePrintlnStr(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CorePrintlnStr(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreReFind(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreReFind(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreReMatches(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreReMatches(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreReSeq(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreReSeq(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreRequiref(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreRequiref(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreFindNs(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreFindNs(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreResolvef(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreResolvef(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreAllNs(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreAllNs(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreTheNs(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreTheNs(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreNsPublics(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreNsPublics(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreFindVar(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreFindVar(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreGetMethod(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreGetMethod(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreEnumerationSeq(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreEnumerationSeq(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreLazySeq(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreLazySeq(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreWithMeta(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreWithMeta(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreThrowf(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreThrowf(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreExInfo(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreExInfo(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreExMessage(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreExMessage(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreExData(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreExData(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreExCause(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreExCause(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreDelayStar(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreDelayStar(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreForce(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreForce(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreIsDelay(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreIsDelay(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreIsRealized(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreIsRealized(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreVolatilef(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreVolatilef(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreVreset(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreVreset(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreReducedf(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreReducedf(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreIsReducedf(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreIsReducedf(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreBitAnd(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreBitAnd(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreBitOr(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreBitOr(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreBitXor(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreBitXor(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreBitNot(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreBitNot(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreBitShiftLeft(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreBitShiftLeft(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreBitShiftRight(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreBitShiftRight(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreUnsignedBitShiftRight(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreUnsignedBitShiftRight(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreBitTest(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreBitTest(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreBitSet(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreBitSet(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreBitClear(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreBitClear(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreBitAndNot(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreBitAndNot(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreBitFlip(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreBitFlip(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreReGroups(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreReGroups(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CorePromisef(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CorePromisef(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreDeliver(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreDeliver(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreAddTap(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreAddTap(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreRemoveTap(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreRemoveTap(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreTapBang(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreTapBang(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreAddWatch(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreAddWatch(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreRemoveWatch(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreRemoveWatch(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreGetValidator(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreGetValidator(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreSubvecf(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreSubvecf(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreIsDouble(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreIsDouble(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreInstancep(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreInstancep(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreIsIFn(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreIsIFn(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreIdentical(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreIdentical(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreAnyp(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreAnyp(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreUnreduced(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreUnreduced(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreEnsureReduced(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreEnsureReduced(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreBigintf(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreBigintf(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreIsRatio(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreIsRatio(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreIsDecimal(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreIsDecimal(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreIsSorted(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreIsSorted(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreIsMap(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreIsMap(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreIsSet(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreIsSet(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreIsMapEntry(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreIsMapEntry(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreIsLazySeq(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreIsLazySeq(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreIsReversible(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreIsReversible(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreRseqf(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreRseqf(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreNumeratorf(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreNumeratorf(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreDenominatorf(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreDenominatorf(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreBigdecf(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreBigdecf(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreRoundBigdec(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreRoundBigdec(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreRationalizef(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreRationalizef(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreQuotf(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreQuotf(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreRemf(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreRemf(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreHashf(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreHashf(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreParseDouble(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreParseDouble(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreParseBool(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreParseBool(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreIsNaN(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreIsNaN(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreIsInfinite(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreIsInfinite(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreIsBool(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreIsBool(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreIsChar(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreIsChar(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreIsVar(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreIsVar(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreByteArrayf(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreByteArrayf(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreObjectArrayf(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreObjectArrayf(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreMakeArrayf(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreMakeArrayf(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreAgetf(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreAgetf(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreAsetf(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreAsetf(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreAlengthf(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreAlengthf(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreAclonef(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreAclonef(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreBytesf(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreBytesf(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreDoublesf(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreDoublesf(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreBytesP(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreBytesP(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreVarGet(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreVarGet(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreBoundQ(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreBoundQ(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreCopyFormSource(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreCopyFormSource(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreChunkToFnFn(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreChunkToFnFn(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} - "github.com/nooga/let-go/pkg/vm" -) +func _adapt_CoreMakeMultiArityFn(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreMakeMultiArityFn(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreInternf(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreInternf(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreApplyDefMetaf(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreApplyDefMetaf(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreCreateNsf(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreCreateNsf(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CorePopBang(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CorePopBang(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreIsUUID(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreIsUUID(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreIsInst(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreIsInst(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreParseUUID(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreParseUUID(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} + +func _adapt_CoreNumericEq(vs []vm.Value) (vm.Value, error) { + if len(vs) < 0 { + return vm.NIL, fmt.Errorf("wrong number of args (%d), expected at least 0", len(vs)) + } + r, err := CoreNumericEq(vs...) + if err != nil { + return vm.NIL, err + } + return r, nil +} func _adapt_Name(vs []vm.Value) (vm.Value, error) { if len(vs) != 1 { @@ -234,176 +2675,6 @@ func _adapt_Reduce3_arity3(ec *vm.ExecContext, vs []vm.Value) (vm.Value, error) return r, nil } -func _adapt_Symbol(vs []vm.Value) (vm.Value, error) { - if len(vs) != 1 { - return vm.NIL, fmt.Errorf("wrong number of args (%d), expected 1", len(vs)) - } - a0 := vs[0] - r, err := Symbol(a0) - if err != nil { - return vm.NIL, err - } - return r, nil -} - -func _adapt_Assoc(vs []vm.Value) (vm.Value, error) { - switch len(vs) { - case 3: - return _adapt_Assoc_arity3(vs) - case 5: - return _adapt_Assoc5_arity5(vs) - } - return vm.NIL, fmt.Errorf("wrong number of args (%d)", len(vs)) -} - -func _adapt_Assoc_arity3(vs []vm.Value) (vm.Value, error) { - a0 := vs[0] - a1 := vs[1] - a2 := vs[2] - r, err := Assoc(a0, a1, a2) - if err != nil { - return vm.NIL, err - } - return r, nil -} - -func _adapt_Assoc5_arity5(vs []vm.Value) (vm.Value, error) { - a0 := vs[0] - a1 := vs[1] - a2 := vs[2] - a3 := vs[3] - a4 := vs[4] - r, err := Assoc5(a0, a1, a2, a3, a4) - if err != nil { - return vm.NIL, err - } - return r, nil -} - -func _adapt_AssocBang(vs []vm.Value) (vm.Value, error) { - if len(vs) != 3 { - return vm.NIL, fmt.Errorf("wrong number of args (%d), expected 3", len(vs)) - } - a0 := vs[0] - a1 := vs[1] - a2 := vs[2] - r, err := AssocBang(a0, a1, a2) - if err != nil { - return vm.NIL, err - } - return r, nil -} - -func _adapt_Swap(ec *vm.ExecContext, vs []vm.Value) (vm.Value, error) { - switch len(vs) { - case 2: - return _adapt_Swap_arity2(ec, vs) - case 3: - return _adapt_Swap3_arity3(ec, vs) - case 4: - return _adapt_Swap4_arity4(ec, vs) - case 5: - return _adapt_Swap5_arity5(ec, vs) - } - return vm.NIL, fmt.Errorf("wrong number of args (%d)", len(vs)) -} - -func _adapt_Swap_arity2(ec *vm.ExecContext, vs []vm.Value) (vm.Value, error) { - a0 := vs[0] - a1 := vs[1] - r, err := Swap(ec, a0, a1) - if err != nil { - return vm.NIL, err - } - return r, nil -} - -func _adapt_Swap3_arity3(ec *vm.ExecContext, vs []vm.Value) (vm.Value, error) { - a0 := vs[0] - a1 := vs[1] - a2 := vs[2] - r, err := Swap3(ec, a0, a1, a2) - if err != nil { - return vm.NIL, err - } - return r, nil -} - -func _adapt_Swap4_arity4(ec *vm.ExecContext, vs []vm.Value) (vm.Value, error) { - a0 := vs[0] - a1 := vs[1] - a2 := vs[2] - a3 := vs[3] - r, err := Swap4(ec, a0, a1, a2, a3) - if err != nil { - return vm.NIL, err - } - return r, nil -} - -func _adapt_Swap5_arity5(ec *vm.ExecContext, vs []vm.Value) (vm.Value, error) { - a0 := vs[0] - a1 := vs[1] - a2 := vs[2] - a3 := vs[3] - a4 := vs[4] - r, err := Swap5(ec, a0, a1, a2, a3, a4) - if err != nil { - return vm.NIL, err - } - return r, nil -} - -func _adapt_NotEq(vs []vm.Value) (vm.Value, error) { - if len(vs) != 2 { - return vm.NIL, fmt.Errorf("wrong number of args (%d), expected 2", len(vs)) - } - a0 := vs[0] - a1 := vs[1] - r, err := NotEq(a0, a1) - if err != nil { - return vm.NIL, err - } - return r, nil -} - -func _adapt_IsMap(vs []vm.Value) (vm.Value, error) { - if len(vs) != 1 { - return vm.NIL, fmt.Errorf("wrong number of args (%d), expected 1", len(vs)) - } - a0 := vs[0] - r, err := IsMap(a0) - if err != nil { - return vm.NIL, err - } - return r, nil -} - -func _adapt_Atom(vs []vm.Value) (vm.Value, error) { - if len(vs) != 1 { - return vm.NIL, fmt.Errorf("wrong number of args (%d), expected 1", len(vs)) - } - a0 := vs[0] - r, err := Atom(a0) - if err != nil { - return vm.NIL, err - } - return r, nil -} - -func _adapt_Reset(vs []vm.Value) (vm.Value, error) { - if len(vs) != 2 { - return vm.NIL, fmt.Errorf("wrong number of args (%d), expected 2", len(vs)) - } - a0 := vs[0] - a1 := vs[1] - r, err := Reset(a0, a1) - if err != nil { - return vm.NIL, err - } - return r, nil -} - func _adapt_Namespace(vs []vm.Value) (vm.Value, error) { if len(vs) != 1 { return vm.NIL, fmt.Errorf("wrong number of args (%d), expected 1", len(vs)) @@ -441,19 +2712,6 @@ func _adapt_PopBinding(ec *vm.ExecContext, vs []vm.Value) (vm.Value, error) { return r, nil } -func _adapt_ReFind(vs []vm.Value) (vm.Value, error) { - if len(vs) != 2 { - return vm.NIL, fmt.Errorf("wrong number of args (%d), expected 2", len(vs)) - } - a0 := vs[0] - a1 := vs[1] - r, err := ReFind(a0, a1) - if err != nil { - return vm.NIL, err - } - return r, nil -} - func _adapt_Some(ec *vm.ExecContext, vs []vm.Value) (vm.Value, error) { if len(vs) != 2 { return vm.NIL, fmt.Errorf("wrong number of args (%d), expected 2", len(vs)) @@ -479,132 +2737,721 @@ func _adapt_Int(vs []vm.Value) (vm.Value, error) { return r, nil } -func _adapt_Range1(vs []vm.Value) (vm.Value, error) { - switch len(vs) { - case 1: - return _adapt_Range1_arity1(vs) - case 2: - return _adapt_Range2_arity2(vs) - case 3: - return _adapt_Range3_arity3(vs) - } - return vm.NIL, fmt.Errorf("wrong number of args (%d)", len(vs)) -} - -func _adapt_Range1_arity1(vs []vm.Value) (vm.Value, error) { - a0 := vs[0] - r, err := Range1(a0) - if err != nil { - return vm.NIL, err - } - return r, nil -} - -func _adapt_Range2_arity2(vs []vm.Value) (vm.Value, error) { - a0 := vs[0] - a1 := vs[1] - r, err := Range2(a0, a1) - if err != nil { - return vm.NIL, err - } - return r, nil -} - -func _adapt_Range3_arity3(vs []vm.Value) (vm.Value, error) { - a0 := vs[0] - a1 := vs[1] - a2 := vs[2] - r, err := Range3(a0, a1, a2) - if err != nil { - return vm.NIL, err - } - return r, nil -} - func RegisterGeneratedPrimitives() { RegisterNativeModule(&NativeModule{ GoPkg: "github.com/nooga/let-go/pkg/rt", Namespace: "clojure.core", Fns: map[string]NativeDirectFn{ - "name": {GoIdent: "Name", LgName: "name", Arity: 1, ParamSpecs: []string{"vm.Value"}, ResultSpec: "string", NeedsError: true}, - "subs@2": {GoIdent: "Subs", LgName: "subs", Arity: 2, ParamSpecs: []string{"string", "int"}, ResultSpec: "string", NeedsError: true}, - "subs@3": {GoIdent: "Subs3", LgName: "subs", Arity: 3, ParamSpecs: []string{"string", "int", "int"}, ResultSpec: "string", NeedsError: true}, - "nth@2": {GoIdent: "Nth", LgName: "nth", Arity: 2, ParamSpecs: []string{"vm.Value", "int"}, ResultSpec: "vm.Value", NeedsError: true}, - "nth@3": {GoIdent: "Nth3", LgName: "nth", Arity: 3, ParamSpecs: []string{"vm.Value", "int", "vm.Value"}, ResultSpec: "vm.Value", NeedsError: true}, - "deref@1": {GoIdent: "Deref", LgName: "deref", Arity: 1, ParamSpecs: []string{"vm.Value"}, ResultSpec: "vm.Value", NeedsError: true}, - "deref@3": {GoIdent: "Deref3", LgName: "deref", Arity: 3, ParamSpecs: []string{"vm.Value", "int", "vm.Value"}, ResultSpec: "vm.Value", NeedsError: true}, - "str": {GoIdent: "Str", LgName: "str", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "string", NeedsError: true}, - "get@2": {GoIdent: "Get", LgName: "get", Arity: 2, ParamSpecs: []string{"vm.Value", "vm.Value"}, ResultSpec: "vm.Value", NeedsError: true}, - "get@3": {GoIdent: "Get3", LgName: "get", Arity: 3, ParamSpecs: []string{"vm.Value", "vm.Value", "vm.Value"}, ResultSpec: "vm.Value", NeedsError: true}, - "conj": {GoIdent: "Conj", LgName: "conj", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, - "reduce@2": {GoIdent: "Reduce", LgName: "reduce", Arity: 2, ParamSpecs: []string{"vm.Value", "vm.Value"}, ResultSpec: "vm.Value", NeedsError: true, NeedsEC: true}, - "reduce@3": {GoIdent: "Reduce3", LgName: "reduce", Arity: 3, ParamSpecs: []string{"vm.Value", "vm.Value", "vm.Value"}, ResultSpec: "vm.Value", NeedsError: true, NeedsEC: true}, - "symbol": {GoIdent: "Symbol", LgName: "symbol", Arity: 1, ParamSpecs: []string{"vm.Value"}, ResultSpec: "vm.Value", NeedsError: true}, - "assoc@3": {GoIdent: "Assoc", LgName: "assoc", Arity: 3, ParamSpecs: []string{"vm.Value", "vm.Value", "vm.Value"}, ResultSpec: "vm.Value", NeedsError: true}, - "assoc@5": {GoIdent: "Assoc5", LgName: "assoc", Arity: 5, ParamSpecs: []string{"vm.Value", "vm.Value", "vm.Value", "vm.Value", "vm.Value"}, ResultSpec: "vm.Value", NeedsError: true}, - "assoc!": {GoIdent: "AssocBang", LgName: "assoc!", Arity: 3, ParamSpecs: []string{"vm.Value", "vm.Value", "vm.Value"}, ResultSpec: "vm.Value", NeedsError: true}, - "swap!@2": {GoIdent: "Swap", LgName: "swap!", Arity: 2, ParamSpecs: []string{"vm.Value", "vm.Value"}, ResultSpec: "vm.Value", NeedsError: true, NeedsEC: true}, - "swap!@3": {GoIdent: "Swap3", LgName: "swap!", Arity: 3, ParamSpecs: []string{"vm.Value", "vm.Value", "vm.Value"}, ResultSpec: "vm.Value", NeedsError: true, NeedsEC: true}, - "swap!@4": {GoIdent: "Swap4", LgName: "swap!", Arity: 4, ParamSpecs: []string{"vm.Value", "vm.Value", "vm.Value", "vm.Value"}, ResultSpec: "vm.Value", NeedsError: true, NeedsEC: true}, - "swap!@5": {GoIdent: "Swap5", LgName: "swap!", Arity: 5, ParamSpecs: []string{"vm.Value", "vm.Value", "vm.Value", "vm.Value", "vm.Value"}, ResultSpec: "vm.Value", NeedsError: true, NeedsEC: true}, - "not=": {GoIdent: "NotEq", LgName: "not=", Arity: 2, ParamSpecs: []string{"vm.Value", "vm.Value"}, ResultSpec: "vm.Value", NeedsError: true}, - "map?": {GoIdent: "IsMap", LgName: "map?", Arity: 1, ParamSpecs: []string{"vm.Value"}, ResultSpec: "vm.Value", NeedsError: true}, - "atom": {GoIdent: "Atom", LgName: "atom", Arity: 1, ParamSpecs: []string{"vm.Value"}, ResultSpec: "vm.Value", NeedsError: true}, - "reset!": {GoIdent: "Reset", LgName: "reset!", Arity: 2, ParamSpecs: []string{"vm.Value", "vm.Value"}, ResultSpec: "vm.Value", NeedsError: true}, - "namespace": {GoIdent: "Namespace", LgName: "namespace", Arity: 1, ParamSpecs: []string{"vm.Value"}, ResultSpec: "vm.Value", NeedsError: true}, - "push-binding!": {GoIdent: "PushBinding", LgName: "push-binding!", Arity: 2, ParamSpecs: []string{"vm.Value", "vm.Value"}, ResultSpec: "vm.Value", NeedsError: true, NeedsEC: true}, - "pop-binding!": {GoIdent: "PopBinding", LgName: "pop-binding!", Arity: 1, ParamSpecs: []string{"vm.Value"}, ResultSpec: "vm.Value", NeedsError: true, NeedsEC: true}, - "re-find": {GoIdent: "ReFind", LgName: "re-find", Arity: 2, ParamSpecs: []string{"vm.Value", "vm.Value"}, ResultSpec: "vm.Value", NeedsError: true}, - "some": {GoIdent: "Some", LgName: "some", Arity: 2, ParamSpecs: []string{"vm.Value", "vm.Value"}, ResultSpec: "vm.Value", NeedsError: true, NeedsEC: true}, - "int": {GoIdent: "Int", LgName: "int", Arity: 1, ParamSpecs: []string{"vm.Value"}, ResultSpec: "vm.Value", NeedsError: true}, - "range@1": {GoIdent: "Range1", LgName: "range", Arity: 1, ParamSpecs: []string{"vm.Value"}, ResultSpec: "vm.Value", NeedsError: true}, - "range@2": {GoIdent: "Range2", LgName: "range", Arity: 2, ParamSpecs: []string{"vm.Value", "vm.Value"}, ResultSpec: "vm.Value", NeedsError: true}, - "range@3": {GoIdent: "Range3", LgName: "range", Arity: 3, ParamSpecs: []string{"vm.Value", "vm.Value", "vm.Value"}, ResultSpec: "vm.Value", NeedsError: true}, + "+": {GoIdent: "CorePlus", LgName: "+", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "*": {GoIdent: "CoreMul", LgName: "*", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "-": {GoIdent: "CoreSub", LgName: "-", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "/": {GoIdent: "CoreDiv", LgName: "/", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "+'": {GoIdent: "CorePlusP", LgName: "+'", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "*'": {GoIdent: "CoreMulP", LgName: "*'", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "-'": {GoIdent: "CoreSubP", LgName: "-'", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "unchecked-add": {GoIdent: "CoreUncheckedAdd", LgName: "unchecked-add", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "unchecked-subtract": {GoIdent: "CoreUncheckedSubtract", LgName: "unchecked-subtract", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "unchecked-multiply": {GoIdent: "CoreUncheckedMultiply", LgName: "unchecked-multiply", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "unchecked-negate": {GoIdent: "CoreUncheckedNegate", LgName: "unchecked-negate", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "unchecked-divide-int": {GoIdent: "CoreUncheckedDivideInt", LgName: "unchecked-divide-int", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "unchecked-long": {GoIdent: "CoreUncheckedLong", LgName: "unchecked-long", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "unchecked-int": {GoIdent: "CoreUncheckedInt", LgName: "unchecked-int", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "unchecked-short": {GoIdent: "CoreUncheckedShort", LgName: "unchecked-short", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "unchecked-byte": {GoIdent: "CoreUncheckedByte", LgName: "unchecked-byte", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "unchecked-char": {GoIdent: "CoreUncheckedChar", LgName: "unchecked-char", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "unchecked-double": {GoIdent: "CoreUncheckedDouble", LgName: "unchecked-double", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "unchecked-float": {GoIdent: "CoreUncheckedFloat", LgName: "unchecked-float", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "mod": {GoIdent: "CoreMod", LgName: "mod", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "abs": {GoIdent: "CoreAbs", LgName: "abs", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "not": {GoIdent: "CoreNot", LgName: "not", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "complement": {GoIdent: "CoreComplement", LgName: "complement", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "set-macro!": {GoIdent: "CoreSetMacro", LgName: "set-macro!", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "gensym": {GoIdent: "CoreGensym", LgName: "gensym", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "vector": {GoIdent: "CoreVector", LgName: "vector", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "hash-map": {GoIdent: "CoreHashMap", LgName: "hash-map", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "array-map": {GoIdent: "CoreArrayMap", LgName: "array-map", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "sorted-map": {GoIdent: "CoreSortedMap", LgName: "sorted-map", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "sorted-set": {GoIdent: "CoreSortedSet", LgName: "sorted-set", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "sorted-map-by": {GoIdent: "CoreSortedMapBy", LgName: "sorted-map-by", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "sorted-set-by": {GoIdent: "CoreSortedSetBy", LgName: "sorted-set-by", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "chunk-first": {GoIdent: "CoreChunkFirst", LgName: "chunk-first", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "chunk-rest": {GoIdent: "CoreChunkRest", LgName: "chunk-rest", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "chunk-next": {GoIdent: "CoreChunkNext", LgName: "chunk-next", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "chunk-cons": {GoIdent: "CoreChunkConsF", LgName: "chunk-cons", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "chunked-seq?": {GoIdent: "CoreChunkedSeqP", LgName: "chunked-seq?", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "chunk-buffer": {GoIdent: "CoreChunkBufferF", LgName: "chunk-buffer", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "chunk-append": {GoIdent: "CoreChunkAppendF", LgName: "chunk-append", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "chunk": {GoIdent: "CoreChunkF", LgName: "chunk", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "range": {GoIdent: "CoreRangef", LgName: "range", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "keyword": {GoIdent: "CoreKeyword", LgName: "keyword", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "symbol": {GoIdent: "CoreSymbolf", LgName: "symbol", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "assoc": {GoIdent: "CoreAssoc", LgName: "assoc", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "dissoc": {GoIdent: "CoreDissoc", LgName: "dissoc", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "cons": {GoIdent: "CoreCons", LgName: "cons", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "disj": {GoIdent: "CoreDisj", LgName: "disj", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "contains?": {GoIdent: "CoreContains", LgName: "contains?", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "second": {GoIdent: "CoreSecond", LgName: "second", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "list?": {GoIdent: "CoreIsList", LgName: "list?", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "empty": {GoIdent: "CoreEmpty", LgName: "empty", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "key": {GoIdent: "CoreKeyf", LgName: "key", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "val": {GoIdent: "CoreValf", LgName: "val", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "count": {GoIdent: "CoreCount", LgName: "count", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "exclude-in-current-ns": {GoIdent: "CoreExcludeInCurrentNs", LgName: "exclude-in-current-ns", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "use": {GoIdent: "CoreUse", LgName: "use", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "alias": {GoIdent: "CoreAliasf", LgName: "alias", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "refer-list": {GoIdent: "CoreReferList", LgName: "refer-list", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + ".": {GoIdent: "CoreMethodInvoke", LgName: ".", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "register-host-method!": {GoIdent: "CoreRegisterHostMethod", LgName: "register-host-method!", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "register-host-class!": {GoIdent: "CoreRegisterHostClass", LgName: "register-host-class!", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "concat*": {GoIdent: "CoreConcat", LgName: "concat*", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "slurp": {GoIdent: "CoreSlurp", LgName: "slurp", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "spit": {GoIdent: "CoreSpit", LgName: "spit", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "atom": {GoIdent: "CoreAtom", LgName: "atom", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "reset!": {GoIdent: "CoreReset", LgName: "reset!", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "compare-and-set!": {GoIdent: "CoreCompareAndSet", LgName: "compare-and-set!", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "reset-vals!": {GoIdent: "CoreResetVals", LgName: "reset-vals!", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "chan": {GoIdent: "CoreChanf", LgName: "chan", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "scope-close!": {GoIdent: "CoreScopeClose", LgName: "scope-close!", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "scope-live": {GoIdent: "CoreScopeLive", LgName: "scope-live", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "scope?": {GoIdent: "CoreScopeQmark", LgName: "scope?", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "max": {GoIdent: "CoreMax", LgName: "max", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "min": {GoIdent: "CoreMin", LgName: "min", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "str-replace": {GoIdent: "CoreStrReplace", LgName: "str-replace", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "long": {GoIdent: "CoreLongf", LgName: "long", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "float": {GoIdent: "CoreFloatf", LgName: "float", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "double": {GoIdent: "CoreDoublef", LgName: "double", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "number?": {GoIdent: "CoreIsNumber", LgName: "number?", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "float?": {GoIdent: "CoreIsFloat", LgName: "float?", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "int?": {GoIdent: "CoreIsInt", LgName: "int?", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "char": {GoIdent: "CoreChar", LgName: "char", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "re-pattern": {GoIdent: "CoreRegex", LgName: "re-pattern", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "peek": {GoIdent: "CorePeek", LgName: "peek", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "pop": {GoIdent: "CorePop", LgName: "pop", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "iterate": {GoIdent: "CoreIterate", LgName: "iterate", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "repeat": {GoIdent: "CoreRepeat", LgName: "repeat", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "refer": {GoIdent: "CoreRefer", LgName: "refer", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "format": {GoIdent: "CoreFormatf", LgName: "format", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "rand": {GoIdent: "CoreRandf", LgName: "rand", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "rand-int": {GoIdent: "CoreRandInt", LgName: "rand-int", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "rand-nth": {GoIdent: "CoreRandNth", LgName: "rand-nth", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "shuffle": {GoIdent: "CoreShuffle", LgName: "shuffle", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "set-rand-seed!": {GoIdent: "CoreSetRandSeedFn", LgName: "set-rand-seed!", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "transient": {GoIdent: "CoreTransientf", LgName: "transient", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "persistent!": {GoIdent: "CorePersistentf", LgName: "persistent!", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "conj!": {GoIdent: "CoreConjBang", LgName: "conj!", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "assoc!": {GoIdent: "CoreAssocBang", LgName: "assoc!", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "disj!": {GoIdent: "CoreDisjBang", LgName: "disj!", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "dissoc!": {GoIdent: "CoreDissocBang", LgName: "dissoc!", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "make-record-type": {GoIdent: "CoreMakeRecordType", LgName: "make-record-type", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "make-record": {GoIdent: "CoreMakeRecord", LgName: "make-record", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "record?": {GoIdent: "CoreIsRecord", LgName: "record?", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "make-deftype": {GoIdent: "CoreMakeDType", LgName: "make-deftype", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "make-deftype-instance": {GoIdent: "CoreMakeDTypeInstance", LgName: "make-deftype-instance", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "set-field!": {GoIdent: "CoreSetField", LgName: "set-field!", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "defprotocol*": {GoIdent: "CoreDefProtocol", LgName: "defprotocol*", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "extend-type*": {GoIdent: "CoreExtendType", LgName: "extend-type*", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "make-protocol-fn": {GoIdent: "CoreMakeProtocolFn", LgName: "make-protocol-fn", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "-set-invokable-protocol!": {GoIdent: "CoreSetInvokableProtocol", LgName: "-set-invokable-protocol!", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "-set-deref-protocol!": {GoIdent: "CoreSetDerefProtocol", LgName: "-set-deref-protocol!", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "satisfies?": {GoIdent: "CoreSatisfies", LgName: "satisfies?", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "defmulti*": {GoIdent: "CoreDefMulti", LgName: "defmulti*", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "defmethod*": {GoIdent: "CoreDefMethod", LgName: "defmethod*", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "pr-str": {GoIdent: "CorePrStr", LgName: "pr-str", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "prn-str": {GoIdent: "CorePrnStr", LgName: "prn-str", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "print-str": {GoIdent: "CorePrintStr", LgName: "print-str", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "println-str": {GoIdent: "CorePrintlnStr", LgName: "println-str", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "re-find": {GoIdent: "CoreReFind", LgName: "re-find", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "re-matches": {GoIdent: "CoreReMatches", LgName: "re-matches", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "re-seq": {GoIdent: "CoreReSeq", LgName: "re-seq", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "require": {GoIdent: "CoreRequiref", LgName: "require", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "find-ns": {GoIdent: "CoreFindNs", LgName: "find-ns", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "resolve": {GoIdent: "CoreResolvef", LgName: "resolve", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "all-ns": {GoIdent: "CoreAllNs", LgName: "all-ns", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "the-ns": {GoIdent: "CoreTheNs", LgName: "the-ns", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "ns-publics": {GoIdent: "CoreNsPublics", LgName: "ns-publics", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "find-var": {GoIdent: "CoreFindVar", LgName: "find-var", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "get-method": {GoIdent: "CoreGetMethod", LgName: "get-method", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "enumeration-seq": {GoIdent: "CoreEnumerationSeq", LgName: "enumeration-seq", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "lazy-seq*": {GoIdent: "CoreLazySeq", LgName: "lazy-seq*", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "with-meta": {GoIdent: "CoreWithMeta", LgName: "with-meta", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "throw": {GoIdent: "CoreThrowf", LgName: "throw", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "ex-info": {GoIdent: "CoreExInfo", LgName: "ex-info", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "ex-message": {GoIdent: "CoreExMessage", LgName: "ex-message", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "ex-data": {GoIdent: "CoreExData", LgName: "ex-data", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "ex-cause": {GoIdent: "CoreExCause", LgName: "ex-cause", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "delay*": {GoIdent: "CoreDelayStar", LgName: "delay*", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "force": {GoIdent: "CoreForce", LgName: "force", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "delay?": {GoIdent: "CoreIsDelay", LgName: "delay?", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "realized?": {GoIdent: "CoreIsRealized", LgName: "realized?", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "volatile!": {GoIdent: "CoreVolatilef", LgName: "volatile!", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "vreset!": {GoIdent: "CoreVreset", LgName: "vreset!", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "reduced": {GoIdent: "CoreReducedf", LgName: "reduced", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "reduced?": {GoIdent: "CoreIsReducedf", LgName: "reduced?", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "bit-and": {GoIdent: "CoreBitAnd", LgName: "bit-and", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "bit-or": {GoIdent: "CoreBitOr", LgName: "bit-or", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "bit-xor": {GoIdent: "CoreBitXor", LgName: "bit-xor", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "bit-not": {GoIdent: "CoreBitNot", LgName: "bit-not", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "bit-shift-left": {GoIdent: "CoreBitShiftLeft", LgName: "bit-shift-left", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "bit-shift-right": {GoIdent: "CoreBitShiftRight", LgName: "bit-shift-right", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "unsigned-bit-shift-right": {GoIdent: "CoreUnsignedBitShiftRight", LgName: "unsigned-bit-shift-right", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "bit-test": {GoIdent: "CoreBitTest", LgName: "bit-test", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "bit-set": {GoIdent: "CoreBitSet", LgName: "bit-set", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "bit-clear": {GoIdent: "CoreBitClear", LgName: "bit-clear", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "bit-and-not": {GoIdent: "CoreBitAndNot", LgName: "bit-and-not", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "bit-flip": {GoIdent: "CoreBitFlip", LgName: "bit-flip", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "re-groups": {GoIdent: "CoreReGroups", LgName: "re-groups", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "promise": {GoIdent: "CorePromisef", LgName: "promise", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "deliver": {GoIdent: "CoreDeliver", LgName: "deliver", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "add-tap": {GoIdent: "CoreAddTap", LgName: "add-tap", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "remove-tap": {GoIdent: "CoreRemoveTap", LgName: "remove-tap", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "tap>": {GoIdent: "CoreTapBang", LgName: "tap>", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "add-watch": {GoIdent: "CoreAddWatch", LgName: "add-watch", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "remove-watch": {GoIdent: "CoreRemoveWatch", LgName: "remove-watch", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "get-validator": {GoIdent: "CoreGetValidator", LgName: "get-validator", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "subvec": {GoIdent: "CoreSubvecf", LgName: "subvec", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "double?": {GoIdent: "CoreIsDouble", LgName: "double?", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "instance?": {GoIdent: "CoreInstancep", LgName: "instance?", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "ifn?": {GoIdent: "CoreIsIFn", LgName: "ifn?", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "identical?": {GoIdent: "CoreIdentical", LgName: "identical?", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "any?": {GoIdent: "CoreAnyp", LgName: "any?", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "unreduced": {GoIdent: "CoreUnreduced", LgName: "unreduced", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "ensure-reduced": {GoIdent: "CoreEnsureReduced", LgName: "ensure-reduced", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "bigint": {GoIdent: "CoreBigintf", LgName: "bigint", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "ratio?": {GoIdent: "CoreIsRatio", LgName: "ratio?", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "decimal?": {GoIdent: "CoreIsDecimal", LgName: "decimal?", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "sorted?": {GoIdent: "CoreIsSorted", LgName: "sorted?", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "map?": {GoIdent: "CoreIsMap", LgName: "map?", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "set?": {GoIdent: "CoreIsSet", LgName: "set?", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "map-entry?": {GoIdent: "CoreIsMapEntry", LgName: "map-entry?", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "lazy-seq?": {GoIdent: "CoreIsLazySeq", LgName: "lazy-seq?", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "reversible?": {GoIdent: "CoreIsReversible", LgName: "reversible?", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "rseq": {GoIdent: "CoreRseqf", LgName: "rseq", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "numerator": {GoIdent: "CoreNumeratorf", LgName: "numerator", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "denominator": {GoIdent: "CoreDenominatorf", LgName: "denominator", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "bigdec": {GoIdent: "CoreBigdecf", LgName: "bigdec", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "round-bigdec": {GoIdent: "CoreRoundBigdec", LgName: "round-bigdec", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "rationalize": {GoIdent: "CoreRationalizef", LgName: "rationalize", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "quot": {GoIdent: "CoreQuotf", LgName: "quot", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "rem": {GoIdent: "CoreRemf", LgName: "rem", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "hash": {GoIdent: "CoreHashf", LgName: "hash", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "parse-double": {GoIdent: "CoreParseDouble", LgName: "parse-double", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "parse-boolean": {GoIdent: "CoreParseBool", LgName: "parse-boolean", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "NaN?": {GoIdent: "CoreIsNaN", LgName: "NaN?", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "infinite?": {GoIdent: "CoreIsInfinite", LgName: "infinite?", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "boolean?": {GoIdent: "CoreIsBool", LgName: "boolean?", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "char?": {GoIdent: "CoreIsChar", LgName: "char?", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "var?": {GoIdent: "CoreIsVar", LgName: "var?", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "byte-array": {GoIdent: "CoreByteArrayf", LgName: "byte-array", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "object-array": {GoIdent: "CoreObjectArrayf", LgName: "object-array", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "make-array": {GoIdent: "CoreMakeArrayf", LgName: "make-array", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "aget": {GoIdent: "CoreAgetf", LgName: "aget", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "aset": {GoIdent: "CoreAsetf", LgName: "aset", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "alength": {GoIdent: "CoreAlengthf", LgName: "alength", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "aclone": {GoIdent: "CoreAclonef", LgName: "aclone", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "bytes": {GoIdent: "CoreBytesf", LgName: "bytes", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "doubles": {GoIdent: "CoreDoublesf", LgName: "doubles", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "bytes?": {GoIdent: "CoreBytesP", LgName: "bytes?", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "var-get": {GoIdent: "CoreVarGet", LgName: "var-get", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "bound?": {GoIdent: "CoreBoundQ", LgName: "bound?", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "-copy-form-source!": {GoIdent: "CoreCopyFormSource", LgName: "-copy-form-source!", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "chunk->fn": {GoIdent: "CoreChunkToFnFn", LgName: "chunk->fn", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "make-multi-arity": {GoIdent: "CoreMakeMultiArityFn", LgName: "make-multi-arity", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "intern": {GoIdent: "CoreInternf", LgName: "intern", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "apply-def-meta!": {GoIdent: "CoreApplyDefMetaf", LgName: "apply-def-meta!", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "create-ns": {GoIdent: "CoreCreateNsf", LgName: "create-ns", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "pop!": {GoIdent: "CorePopBang", LgName: "pop!", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "uuid?": {GoIdent: "CoreIsUUID", LgName: "uuid?", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "inst?": {GoIdent: "CoreIsInst", LgName: "inst?", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "parse-uuid": {GoIdent: "CoreParseUUID", LgName: "parse-uuid", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "==": {GoIdent: "CoreNumericEq", LgName: "==", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "name": {GoIdent: "Name", LgName: "name", Arity: 1, ParamSpecs: []string{"vm.Value"}, ResultSpec: "string", NeedsError: true}, + "subs@2": {GoIdent: "Subs", LgName: "subs", Arity: 2, ParamSpecs: []string{"string", "int"}, ResultSpec: "string", NeedsError: true}, + "subs@3": {GoIdent: "Subs3", LgName: "subs", Arity: 3, ParamSpecs: []string{"string", "int", "int"}, ResultSpec: "string", NeedsError: true}, + "nth@2": {GoIdent: "Nth", LgName: "nth", Arity: 2, ParamSpecs: []string{"vm.Value", "int"}, ResultSpec: "vm.Value", NeedsError: true}, + "nth@3": {GoIdent: "Nth3", LgName: "nth", Arity: 3, ParamSpecs: []string{"vm.Value", "int", "vm.Value"}, ResultSpec: "vm.Value", NeedsError: true}, + "deref@1": {GoIdent: "Deref", LgName: "deref", Arity: 1, ParamSpecs: []string{"vm.Value"}, ResultSpec: "vm.Value", NeedsError: true}, + "deref@3": {GoIdent: "Deref3", LgName: "deref", Arity: 3, ParamSpecs: []string{"vm.Value", "int", "vm.Value"}, ResultSpec: "vm.Value", NeedsError: true}, + "str": {GoIdent: "Str", LgName: "str", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "string", NeedsError: true}, + "get@2": {GoIdent: "Get", LgName: "get", Arity: 2, ParamSpecs: []string{"vm.Value", "vm.Value"}, ResultSpec: "vm.Value", NeedsError: true}, + "get@3": {GoIdent: "Get3", LgName: "get", Arity: 3, ParamSpecs: []string{"vm.Value", "vm.Value", "vm.Value"}, ResultSpec: "vm.Value", NeedsError: true}, + "conj": {GoIdent: "Conj", LgName: "conj", Arity: -1, Variadic: true, ParamSpecs: []string{}, ResultSpec: "vm.Value", NeedsError: true}, + "reduce@2": {GoIdent: "Reduce", LgName: "reduce", Arity: 2, ParamSpecs: []string{"vm.Value", "vm.Value"}, ResultSpec: "vm.Value", NeedsError: true, NeedsEC: true}, + "reduce@3": {GoIdent: "Reduce3", LgName: "reduce", Arity: 3, ParamSpecs: []string{"vm.Value", "vm.Value", "vm.Value"}, ResultSpec: "vm.Value", NeedsError: true, NeedsEC: true}, + "namespace": {GoIdent: "Namespace", LgName: "namespace", Arity: 1, ParamSpecs: []string{"vm.Value"}, ResultSpec: "vm.Value", NeedsError: true}, + "push-binding!": {GoIdent: "PushBinding", LgName: "push-binding!", Arity: 2, ParamSpecs: []string{"vm.Value", "vm.Value"}, ResultSpec: "vm.Value", NeedsError: true, NeedsEC: true}, + "pop-binding!": {GoIdent: "PopBinding", LgName: "pop-binding!", Arity: 1, ParamSpecs: []string{"vm.Value"}, ResultSpec: "vm.Value", NeedsError: true, NeedsEC: true}, + "some": {GoIdent: "Some", LgName: "some", Arity: 2, ParamSpecs: []string{"vm.Value", "vm.Value"}, ResultSpec: "vm.Value", NeedsError: true, NeedsEC: true}, + "int": {GoIdent: "Int", LgName: "int", Arity: 1, ParamSpecs: []string{"vm.Value"}, ResultSpec: "vm.Value", NeedsError: true}, }, }) // Bind adapters into namespace if ns := LookupOrRegisterNSNoLoad("clojure.core"); ns != nil { - fn0, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_Name(vs) }) - defGeneratedPrimitive(ns, "clojure.core", "name", fn0) - fn1, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_Subs(vs) }) - defGeneratedPrimitive(ns, "clojure.core", "subs", fn1) - fn2, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_Nth(vs) }) - defGeneratedPrimitive(ns, "clojure.core", "nth", fn2) - fn3, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_Deref(vs) }) - defGeneratedPrimitive(ns, "clojure.core", "deref", fn3) - fn4, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_Str(vs) }) - defGeneratedPrimitive(ns, "clojure.core", "str", fn4) - fn5, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_Get(vs) }) - defGeneratedPrimitive(ns, "clojure.core", "get", fn5) - fn6, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_Conj(vs) }) - defGeneratedPrimitive(ns, "clojure.core", "conj", fn6) + fn0, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CorePlus(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "+", fn0) + fn1, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreMul(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "*", fn1) + fn2, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreSub(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "-", fn2) + fn3, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreDiv(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "/", fn3) + fn4, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CorePlusP(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "+'", fn4) + fn5, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreMulP(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "*'", fn5) + fn6, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreSubP(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "-'", fn6) + fn7, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreUncheckedAdd(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "unchecked-add", fn7) + fn8, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreUncheckedSubtract(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "unchecked-subtract", fn8) + fn9, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreUncheckedMultiply(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "unchecked-multiply", fn9) + fn10, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreUncheckedNegate(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "unchecked-negate", fn10) + fn11, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreUncheckedDivideInt(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "unchecked-divide-int", fn11) + fn12, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreUncheckedLong(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "unchecked-long", fn12) + fn13, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreUncheckedInt(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "unchecked-int", fn13) + fn14, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreUncheckedShort(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "unchecked-short", fn14) + fn15, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreUncheckedByte(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "unchecked-byte", fn15) + fn16, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreUncheckedChar(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "unchecked-char", fn16) + fn17, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreUncheckedDouble(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "unchecked-double", fn17) + fn18, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreUncheckedFloat(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "unchecked-float", fn18) + fn19, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreMod(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "mod", fn19) + fn20, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreAbs(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "abs", fn20) + fn21, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreNot(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "not", fn21) + fn22, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreComplement(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "complement", fn22) + fn23, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreSetMacro(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "set-macro!", fn23) + fn24, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreGensym(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "gensym", fn24) + fn25, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreVector(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "vector", fn25) + fn26, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreHashMap(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "hash-map", fn26) + fn27, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreArrayMap(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "array-map", fn27) + fn28, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreSortedMap(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "sorted-map", fn28) + fn29, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreSortedSet(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "sorted-set", fn29) + fn30, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreSortedMapBy(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "sorted-map-by", fn30) + fn31, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreSortedSetBy(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "sorted-set-by", fn31) + fn32, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreChunkFirst(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "chunk-first", fn32) + fn33, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreChunkRest(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "chunk-rest", fn33) + fn34, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreChunkNext(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "chunk-next", fn34) + fn35, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreChunkConsF(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "chunk-cons", fn35) + fn36, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreChunkedSeqP(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "chunked-seq?", fn36) + fn37, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreChunkBufferF(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "chunk-buffer", fn37) + fn38, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreChunkAppendF(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "chunk-append", fn38) + fn39, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreChunkF(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "chunk", fn39) + fn40, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreRangef(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "range", fn40) + fn41, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreKeyword(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "keyword", fn41) + fn42, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreSymbolf(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "symbol", fn42) + fn43, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreAssoc(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "assoc", fn43) + fn44, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreDissoc(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "dissoc", fn44) + fn45, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreCons(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "cons", fn45) + fn46, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreDisj(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "disj", fn46) + fn47, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreContains(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "contains?", fn47) + fn48, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreSecond(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "second", fn48) + fn49, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreIsList(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "list?", fn49) + fn50, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreEmpty(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "empty", fn50) + fn51, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreKeyf(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "key", fn51) + fn52, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreValf(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "val", fn52) + fn53, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreCount(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "count", fn53) + fn54, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreExcludeInCurrentNs(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "exclude-in-current-ns", fn54) + fn55, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreUse(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "use", fn55) + fn56, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreAliasf(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "alias", fn56) + fn57, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreReferList(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "refer-list", fn57) + fn58, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreMethodInvoke(vs) }) + defGeneratedPrimitive(ns, "clojure.core", ".", fn58) + fn59, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreRegisterHostMethod(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "register-host-method!", fn59) + fn60, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreRegisterHostClass(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "register-host-class!", fn60) + fn61, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreConcat(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "concat*", fn61) + fn62, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreSlurp(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "slurp", fn62) + fn63, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreSpit(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "spit", fn63) + fn64, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreAtom(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "atom", fn64) + fn65, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreReset(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "reset!", fn65) + fn66, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreCompareAndSet(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "compare-and-set!", fn66) + fn67, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreResetVals(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "reset-vals!", fn67) + fn68, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreChanf(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "chan", fn68) + fn69, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreScopeClose(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "scope-close!", fn69) + fn70, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreScopeLive(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "scope-live", fn70) + fn71, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreScopeQmark(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "scope?", fn71) + fn72, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreMax(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "max", fn72) + fn73, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreMin(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "min", fn73) + fn74, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreStrReplace(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "str-replace", fn74) + fn75, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreLongf(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "long", fn75) + fn76, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreFloatf(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "float", fn76) + fn77, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreDoublef(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "double", fn77) + fn78, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreIsNumber(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "number?", fn78) + fn79, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreIsFloat(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "float?", fn79) + fn80, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreIsInt(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "int?", fn80) + fn81, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreChar(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "char", fn81) + fn82, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreRegex(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "re-pattern", fn82) + fn83, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CorePeek(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "peek", fn83) + fn84, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CorePop(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "pop", fn84) + fn85, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreIterate(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "iterate", fn85) + fn86, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreRepeat(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "repeat", fn86) + fn87, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreRefer(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "refer", fn87) + fn88, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreFormatf(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "format", fn88) + fn89, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreRandf(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "rand", fn89) + fn90, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreRandInt(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "rand-int", fn90) + fn91, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreRandNth(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "rand-nth", fn91) + fn92, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreShuffle(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "shuffle", fn92) + fn93, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreSetRandSeedFn(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "set-rand-seed!", fn93) + fn94, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreTransientf(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "transient", fn94) + fn95, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CorePersistentf(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "persistent!", fn95) + fn96, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreConjBang(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "conj!", fn96) + fn97, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreAssocBang(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "assoc!", fn97) + fn98, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreDisjBang(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "disj!", fn98) + fn99, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreDissocBang(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "dissoc!", fn99) + fn100, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreMakeRecordType(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "make-record-type", fn100) + fn101, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreMakeRecord(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "make-record", fn101) + fn102, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreIsRecord(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "record?", fn102) + fn103, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreMakeDType(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "make-deftype", fn103) + fn104, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreMakeDTypeInstance(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "make-deftype-instance", fn104) + fn105, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreSetField(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "set-field!", fn105) + fn106, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreDefProtocol(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "defprotocol*", fn106) + fn107, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreExtendType(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "extend-type*", fn107) + fn108, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreMakeProtocolFn(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "make-protocol-fn", fn108) + fn109, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreSetInvokableProtocol(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "-set-invokable-protocol!", fn109) + fn110, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreSetDerefProtocol(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "-set-deref-protocol!", fn110) + fn111, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreSatisfies(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "satisfies?", fn111) + fn112, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreDefMulti(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "defmulti*", fn112) + fn113, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreDefMethod(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "defmethod*", fn113) + fn114, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CorePrStr(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "pr-str", fn114) + fn115, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CorePrnStr(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "prn-str", fn115) + fn116, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CorePrintStr(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "print-str", fn116) + fn117, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CorePrintlnStr(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "println-str", fn117) + fn118, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreReFind(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "re-find", fn118) + fn119, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreReMatches(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "re-matches", fn119) + fn120, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreReSeq(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "re-seq", fn120) + fn121, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreRequiref(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "require", fn121) + fn122, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreFindNs(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "find-ns", fn122) + fn123, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreResolvef(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "resolve", fn123) + fn124, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreAllNs(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "all-ns", fn124) + fn125, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreTheNs(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "the-ns", fn125) + fn126, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreNsPublics(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "ns-publics", fn126) + fn127, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreFindVar(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "find-var", fn127) + fn128, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreGetMethod(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "get-method", fn128) + fn129, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreEnumerationSeq(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "enumeration-seq", fn129) + fn130, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreLazySeq(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "lazy-seq*", fn130) + fn131, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreWithMeta(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "with-meta", fn131) + fn132, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreThrowf(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "throw", fn132) + fn133, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreExInfo(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "ex-info", fn133) + fn134, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreExMessage(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "ex-message", fn134) + fn135, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreExData(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "ex-data", fn135) + fn136, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreExCause(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "ex-cause", fn136) + fn137, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreDelayStar(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "delay*", fn137) + fn138, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreForce(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "force", fn138) + fn139, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreIsDelay(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "delay?", fn139) + fn140, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreIsRealized(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "realized?", fn140) + fn141, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreVolatilef(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "volatile!", fn141) + fn142, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreVreset(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "vreset!", fn142) + fn143, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreReducedf(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "reduced", fn143) + fn144, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreIsReducedf(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "reduced?", fn144) + fn145, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreBitAnd(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "bit-and", fn145) + fn146, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreBitOr(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "bit-or", fn146) + fn147, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreBitXor(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "bit-xor", fn147) + fn148, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreBitNot(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "bit-not", fn148) + fn149, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreBitShiftLeft(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "bit-shift-left", fn149) + fn150, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreBitShiftRight(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "bit-shift-right", fn150) + fn151, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreUnsignedBitShiftRight(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "unsigned-bit-shift-right", fn151) + fn152, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreBitTest(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "bit-test", fn152) + fn153, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreBitSet(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "bit-set", fn153) + fn154, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreBitClear(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "bit-clear", fn154) + fn155, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreBitAndNot(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "bit-and-not", fn155) + fn156, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreBitFlip(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "bit-flip", fn156) + fn157, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreReGroups(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "re-groups", fn157) + fn158, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CorePromisef(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "promise", fn158) + fn159, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreDeliver(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "deliver", fn159) + fn160, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreAddTap(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "add-tap", fn160) + fn161, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreRemoveTap(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "remove-tap", fn161) + fn162, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreTapBang(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "tap>", fn162) + fn163, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreAddWatch(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "add-watch", fn163) + fn164, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreRemoveWatch(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "remove-watch", fn164) + fn165, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreGetValidator(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "get-validator", fn165) + fn166, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreSubvecf(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "subvec", fn166) + fn167, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreIsDouble(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "double?", fn167) + fn168, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreInstancep(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "instance?", fn168) + fn169, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreIsIFn(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "ifn?", fn169) + fn170, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreIdentical(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "identical?", fn170) + fn171, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreAnyp(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "any?", fn171) + fn172, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreUnreduced(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "unreduced", fn172) + fn173, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreEnsureReduced(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "ensure-reduced", fn173) + fn174, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreBigintf(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "bigint", fn174) + fn175, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreIsRatio(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "ratio?", fn175) + fn176, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreIsDecimal(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "decimal?", fn176) + fn177, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreIsSorted(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "sorted?", fn177) + fn178, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreIsMap(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "map?", fn178) + fn179, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreIsSet(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "set?", fn179) + fn180, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreIsMapEntry(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "map-entry?", fn180) + fn181, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreIsLazySeq(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "lazy-seq?", fn181) + fn182, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreIsReversible(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "reversible?", fn182) + fn183, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreRseqf(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "rseq", fn183) + fn184, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreNumeratorf(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "numerator", fn184) + fn185, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreDenominatorf(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "denominator", fn185) + fn186, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreBigdecf(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "bigdec", fn186) + fn187, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreRoundBigdec(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "round-bigdec", fn187) + fn188, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreRationalizef(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "rationalize", fn188) + fn189, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreQuotf(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "quot", fn189) + fn190, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreRemf(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "rem", fn190) + fn191, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreHashf(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "hash", fn191) + fn192, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreParseDouble(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "parse-double", fn192) + fn193, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreParseBool(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "parse-boolean", fn193) + fn194, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreIsNaN(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "NaN?", fn194) + fn195, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreIsInfinite(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "infinite?", fn195) + fn196, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreIsBool(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "boolean?", fn196) + fn197, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreIsChar(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "char?", fn197) + fn198, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreIsVar(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "var?", fn198) + fn199, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreByteArrayf(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "byte-array", fn199) + fn200, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreObjectArrayf(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "object-array", fn200) + fn201, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreMakeArrayf(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "make-array", fn201) + fn202, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreAgetf(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "aget", fn202) + fn203, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreAsetf(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "aset", fn203) + fn204, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreAlengthf(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "alength", fn204) + fn205, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreAclonef(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "aclone", fn205) + fn206, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreBytesf(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "bytes", fn206) + fn207, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreDoublesf(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "doubles", fn207) + fn208, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreBytesP(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "bytes?", fn208) + fn209, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreVarGet(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "var-get", fn209) + fn210, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreBoundQ(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "bound?", fn210) + fn211, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreCopyFormSource(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "-copy-form-source!", fn211) + fn212, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreChunkToFnFn(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "chunk->fn", fn212) + fn213, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreMakeMultiArityFn(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "make-multi-arity", fn213) + fn214, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreInternf(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "intern", fn214) + fn215, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreApplyDefMetaf(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "apply-def-meta!", fn215) + fn216, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreCreateNsf(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "create-ns", fn216) + fn217, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CorePopBang(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "pop!", fn217) + fn218, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreIsUUID(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "uuid?", fn218) + fn219, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreIsInst(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "inst?", fn219) + fn220, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreParseUUID(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "parse-uuid", fn220) + fn221, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_CoreNumericEq(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "==", fn221) + fn222, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_Name(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "name", fn222) + fn223, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_Subs(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "subs", fn223) + fn224, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_Nth(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "nth", fn224) + fn225, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_Deref(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "deref", fn225) + fn226, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_Str(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "str", fn226) + fn227, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_Get(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "get", fn227) + fn228, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_Conj(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "conj", fn228) defGeneratedPrimitive(ns, "clojure.core", "reduce", vm.NewCtxNativeFn("reduce", _adapt_Reduce)) - fn8, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_Symbol(vs) }) - defGeneratedPrimitive(ns, "clojure.core", "symbol", fn8) - fn9, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_Assoc(vs) }) - defGeneratedPrimitive(ns, "clojure.core", "assoc", fn9) - fn10, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_AssocBang(vs) }) - defGeneratedPrimitive(ns, "clojure.core", "assoc!", fn10) - defGeneratedPrimitive(ns, "clojure.core", "swap!", vm.NewCtxNativeFn("swap!", _adapt_Swap)) - fn12, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_NotEq(vs) }) - defGeneratedPrimitive(ns, "clojure.core", "not=", fn12) - fn13, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_IsMap(vs) }) - defGeneratedPrimitive(ns, "clojure.core", "map?", fn13) - fn14, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_Atom(vs) }) - defGeneratedPrimitive(ns, "clojure.core", "atom", fn14) - fn15, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_Reset(vs) }) - defGeneratedPrimitive(ns, "clojure.core", "reset!", fn15) - fn16, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_Namespace(vs) }) - defGeneratedPrimitive(ns, "clojure.core", "namespace", fn16) + fn230, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_Namespace(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "namespace", fn230) defGeneratedPrimitive(ns, "clojure.core", "push-binding!", vm.NewCtxNativeFn("push-binding!", _adapt_PushBinding)) defGeneratedPrimitive(ns, "clojure.core", "pop-binding!", vm.NewCtxNativeFn("pop-binding!", _adapt_PopBinding)) - fn19, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_ReFind(vs) }) - defGeneratedPrimitive(ns, "clojure.core", "re-find", fn19) defGeneratedPrimitive(ns, "clojure.core", "some", vm.NewCtxNativeFn("some", _adapt_Some)) - fn21, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_Int(vs) }) - defGeneratedPrimitive(ns, "clojure.core", "int", fn21) - fn22, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_Range1(vs) }) - defGeneratedPrimitive(ns, "clojure.core", "range", fn22) + fn234, _ := vm.NativeFnType.Wrap(func(vs []vm.Value) (vm.Value, error) { return _adapt_Int(vs) }) + defGeneratedPrimitive(ns, "clojure.core", "int", fn234) } RegisterNativeModule(&NativeModule{ GoPkg: "github.com/nooga/let-go/pkg/rt",