Conversation
catch-throw-compiler recompiled the thrown expression with a stale captured compilers map instead of the threaded cmplrs, dropping let/loop locals introduced inside the catch. Thread cmplrs through. Closes #7
ex-info and ex-data were ported but ex-message and ex-cause were not. Add both using the stdlib's .NET idiom: .getMessage maps to .Message, .getCause to .InnerException. Add regression tests in magic.test.control. Closes nasser/magic#238
…asser/magic#238) Recompiled clojure.core.clj.dll deployed to nostrand/references and magic-unity Export.
CaptureString starts buffering every char read; GetString returns and clears the buffer. Buffered chars are dropped on unread. Enables read+string in clojure.core.
…lojure.core symbol arity-1 now converts Vars (qualified) and Keywords, throwing ArgumentException on anything else. add-tap, remove-tap and tap> back a tap set with a BlockingCollection worker thread started lazily on first use. BlockingCollection is in System.dll on net471, so no assembly-load is needed. read+string returns the object read plus the trimmed source text. Tests live in magic.test.stdlib (compiler suite) and smoke.stdlib-1-10 (IL2CPP regression).
…stdlib additions Rebuilt Clojure.dll (reader capture) and clojure.core.clj.dll (symbol, tap>, read+string).
PrintWriter-on returns a TextWriter that buffers writes and calls flush-fn with the accumulated string on Flush, and close-fn (when non-nil) on Close. Implemented as a proxy over System.IO.StringWriter. Closes #8
Make :message and :cause conditional, add the :phase key read from :clojure.error/phase ex-data, and derive each stack frame's class symbol from the method's declaring type instead of the StackFrame type itself. Refs #10.
) Rebuilt clojure.core_print.clj.dll in nostrand/references and the Unity Export dir for the 1.10 Throwable->map shape. Refs #10.
Port the 1.10 ex-triage and ex-str error-triage pair and rewire repl-caught to the 1.10 form (Throwable->map -> ex-triage -> ex-str). err->msg and :clojure.error/path are post-1.10 and are intentionally not ported. Tests mirror clojure.test-clojure.main from ClojureCLR. Refs #10
…server (#10) Port the 1.10 prepl trio. Drop three post-1.10 details from the ClojureCLR reference: the 3-arity PrintWriter-on autoflush call (our PrintWriter-on is 2-arity), the read+string :read-cond opts form, and the valf wrap in the io-prepl catch. prepl evaluates at runtime, so it runs under Mono/nostrand only, never under IL2CPP AOT. Closes #10
bb pipeline shows the compiled IL for a form but never runs it, so there was
no way to see what a form returns at runtime. These tasks add that, as the
runtime complement to pipeline:
bb prepl-server [port] start a socket prepl on a warm nostrand-hosted
MAGIC runtime (the MAGIC analogue of an nREPL)
bb prepl-eval '<form>' send a form to it and print the structured reply:
{:tag :ret :val .. :ms ..}, separate {:tag :out ..},
or an :exception true :ret with Throwable->map data
The server is MAGIC Clojure (clojure.core.server/io-prepl, from #10) running
on the CLR; the client is plain babashka, so each eval is fast. Global defs
persist across calls because Vars live in the runtime. Mono/nostrand only:
prepl needs runtime eval, so it has no IL2CPP path. Binds the listener to
IPAddress/Loopback so start-server skips the Dns resolution that can otherwise
bind off 127.0.0.1.
Closes #11
…ader
MetaReader unconditionally overwrote a read seq's :line/:column/:source-span
with the reader's positional values, clobbering explicit ^{:line N} metadata.
JVM 1.10.0 and ClojureCLR keep the explicit value and use the positional value
only as a default via RT.get. Match that.
renumbering-read (clojure.main, 1.10) depends on this: it re-reads a captured
form to stabilize line numbers, which requires explicit :line metadata to
survive the read.
Refs #12
Add renumbering-read and rewire repl-read to use it, matching Clojure 1.10.0.
repl-read previously read directly via (read {:read-cond :allow} *in*); 1.10
wraps that in renumbering-read, which captures the form via read+string then
re-reads it from a fresh LineNumberingTextReader with the line number reset,
giving REPL-read forms stable :line metadata.
Closes #12
…ng-read Rebuilt Clojure.dll (MetaReader explicit-meta fix) and clojure.main.clj.dll (renumbering-read, repl-read). Refs #12
…ta (#13) Clojure 1.10 :extend-via-metadata needs the protocol method's fully-qualified symbol as the metadata lookup key. Add it as a sym field with sym-carrying constructors, matching ClojureCLR. Keep the sym-less constructors as a bootstrap bridge: the checked-in core_deftype.clj.dll still emits newobj against them. Dropped once the bootstrap DLLs are rebuilt.
Port the Clojure 1.10 :extend-via-metadata weave. When a protocol opts in, emit-method-builder checks the target's metadata for the fully-qualified protocol-fn symbol before the external extend table, giving the order: direct definitions, then metadata, then extend. Thread the method symbol through expand-method-impl-cache and -reset-methods, and pass :extend-via-metadata from emit-protocol. Closes #13
…or :extend-via-metadata (#13) Regenerate the core_deftype and clojure.core.protocols bootstrap DLLs and the Export Clojure.dll for the metadata dispatch weave. Clojure.dll still carries the transitional sym-less constructors; dropped in the follow-up.
…gic#233) Spells become flags. magic.flags gains *lift-vars*, *lift-keywords*, and *sparse-case*; magic.core/active-spells derives the active spell set from them and get-compilers uses it. This replaces the externally-set *spells* list and the global bind-spells!/alter-var-root mutation, so a spell is toggled like any other flag. Delete bind-spells!/bind-basic-spells! and the dead magic.spells.protocols spell. build.clj enables an extra spell by binding its flag and loading its namespace. Existing binding-based callers are unaffected: the flag names and the default spells are unchanged. Document the flag surface in the root and compiler READMEs, and cover active-spells in magic.test.flags (spell identity and order, the sparse-case branch, and a standalone require of the spell namespaces). Closes nasser/magic#233
…ic#233) Regenerate the magic.flags, magic.core, and magic.api compiler DLLs in nostrand/references for the flag-based spell configuration. Compiler-only namespaces, so not part of the magic-unity Export set.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
v0.3.0 - 2026-06-01
Completes the Clojure 1.10 stdlib surface and unifies the compiler config behind
magic.flags.Clojure 1.10 stdlib (the marked-1.10 port is now complete)
ex-message/ex-causeadded toclojure.core- Fix nasser/magic#238symbolarity-1 now converts a Var (qualified) or Keywordtap>/add-tap/remove-tap(the tap system) ported toclojure.coreread+stringported toclojure.core, backed by string capture inLineNumberingTextReaderPrintWriter-onported toclojure.core- Closes #8Throwable->mapbrought to the 1.10 shape: conditional:message/:causeand the:phasekey;StackTraceElement->vecand the StackFrame print-method derive the class from the frame's declaring type - part of #10ex-triage/ex-strported toclojure.main;repl-caughtrewired to the 1.10Throwable->map->ex-triage->ex-strpath - part of #10prepl/io-prepl/remote-preplported toclojure.core.server- Closes #10renumbering-readported toclojure.main;repl-readrewired to it - Closes #12defprotocol :extend-via-metadatadispatch implemented (direct defs -> fully-qualified-symbol metadata -> extend table) - Closes #13Compiler
magic.flagsis now the single config surface: every compilation knob is a dynamic var there, and spells (*lift-vars*,*lift-keywords*,*sparse-case*) are flags too. Removedmagic.core/*spells*,bind-spells!, the load-time global mutation, and the deadmagic.spells.protocolsspell;active-spellsderives the spell fns from the flags - Fix nasser/magic#233throwof alet/loop-local introduced inside acatchnow compiles (the thrown expression was recompiled with a stale captured compilers map) - Closes #7Runtime
LineNumberingTextReadercaptures read text forread+stringLispReaderMetaReaderpreserves an explicit:line/:column/:source-spaninstead of clobbering it with positional values (uses positional only as a default), matching JVM 1.10 and ClojureCLR - part of #12MethodImplCachecarries the protocol fn symbol needed for:extend-via-metadatadispatch - part of #13Tooling
bb prepl-server/bb prepl-eval: live runtime eval against a warm nostrand-hosted MAGIC runtime (a socket io-prepl), the runtime complement tobb pipeline- Closes #11Deps & docs
deps.ednswitched to monorepo paths andflybot-sg/clr.test.checkmagic-unity/package.jsonmetadata fixed and version synced fromversion.edn