{"slug": "rust-like-compiler-pipeline-to-resolve-matlab-language-semantics", "title": "Rust-like compiler pipeline to resolve Matlab language semantics", "summary": "RunMat, a Rust runtime and compiler for MATLAB-family code, uses a staged compiler pipeline to resolve semantic ambiguities in MATLAB's context-dependent syntax, enabling correct execution of real-world engineering programs. The pipeline lowers source code through AST, HIR, MIR, and VM stages to make naming, binding, and output-count decisions explicit before runtime.", "body_md": "If you have only seen MATLAB from the outside, it is easy to think of it as a matrix-oriented scripting language: arrays, plots, numerical routines, and a prompt where engineers try things quickly. That is all true, and it is also why MATLAB is still relevant: it is one of the languages engineers and scientists are taught to think in when they learn applied math, simulation, controls, signal processing, optimization, and numerical computing. A lot of teams keep using it because their models, tools, habits, and domain knowledge are already there.\n\nMATLAB is also a large language and runtime environment for scientific and engineering\nprograms. Real MATLAB code is often split across many files. It uses package folders,\nclass folders, private helper folders, function handles, dynamically resolved calls,\nworkspace state, object-oriented `classdef`\n\nclasses, multiple return values, overloaded\nindexing, and interactive execution. A lot of long-lived engineering code depends on\nthose semantics.\n\nRunMat is a Rust runtime and compiler for that MATLAB-family code.\n\nAs a result, it is not only trying to evaluate simple expressions like `A + B`\n\n. It needs\nto execute real-world programs that look more like this, while preserving the semantics\nthat the original program depends on:\n\n```\nmodel = SignalModel(samples);\n[filtered, stats] = filters.lowpass(model.samples, 30);\nmodel.history{end + 1} = stats;\nplot(filtered);\n```\n\nTo run that correctly, RunMat makes several language questions explicit during compilation and execution:\n\n- Is\n`SignalModel`\n\na variable, a function, a class constructor, or an unresolved external name? If it is a variable, is this an attempted array/object call rather than construction? - Does\n`filters.lowpass`\n\nrefer to a package function, a static method, or a field access followed by a call? - How many outputs did the caller request from\n`lowpass`\n\n, and can the callee observe that through`nargout`\n\n? - Is\n`model.samples`\n\na stored property, a dependent property, or an overloaded member access? - What does\n`end`\n\nmean inside`model.history{end + 1}`\n\n? - Should\n`plot(filtered)`\n\nreturn a value, update figure state, or suppress ordinary output?\n\nThose are not parsing questions. They are semantic questions. For a team trying to run existing engineering code, they are also compatibility questions. If the runtime answers them too late, or answers them differently in the interpreter, language server, JIT, and GPU planner, the system becomes hard to reason about.\n\nRunMat resolves those decisions through a staged compiler pipeline:\n\n``` php\nsource\n  -> AST\n  -> semantic HIR\n  -> MIR\n  -> MIR analysis\n  -> VM layout + bytecode\n  -> runtime/providers\n```\n\nThat staging is the useful connection to Rust: source is lowered into progressively more explicit compiler products before execution. Names, functions, classes, bindings, effects, output counts, indexing contexts, and runtime layout become facts that later stages can reuse.\n\nThis post explains why MATLAB needs that kind of pipeline and how RunMat's runtime is structured today.\n\n## Why MATLAB needs semantic resolution\n\nMATLAB syntax is compact because a lot of meaning is supplied by context. That is part of why the language is productive for numerical work. It is also why MATLAB is hard to execute correctly (and ideally statically): the same surface syntax can mean several different things, and which one is intended depends on the context.\n\nReturn to the opening example:\n\n`SignalModel(samples)`\n\nmight be a class constructor, a function call, a variable being indexed, or an unresolved external name.`filters.lowpass`\n\nmight be a package function, a static method, or a field access followed by a call.`[filtered, stats] = ...`\n\nrequests two outputs, and that output count can affect how the callee behaves through`nargout`\n\nor`varargout`\n\n.`model.samples`\n\nmight be a stored property, a dependent property, or overloaded member access.`model.history{end + 1}`\n\nis not only indexing; it is an assignment target whose`end`\n\ndepends on the current value of`history`\n\n.`plot(filtered)`\n\nis a call with figure and display effects.\n\nThe same surface syntax can therefore mean several different things. RunMat's compiler records which role the program resolved to, so later runtime paths can share the same answer.\n\nThis is why we chose to put a semantic stage in the pipeline. A direct AST-to-bytecode runtime was possible (and was our previous approach), but it tended to scatter these decisions across the interpreter, runtime dispatch, editor tooling, JIT, and acceleration planner. RunMat as of 0.5+ now resolves the source into shared language facts first. That gives the rest of the system one place to ask what the program means, and it lets those facts match what existing MATLAB users expect their code to do.\n\n## Pipeline overview\n\nThe current pipeline is:\n\n``` php\nMATLAB source\n  -> parser AST\n  -> semantic HIR assembly\n  -> MIR assembly\n  -> MIR analysis store\n  -> VM assembly layout\n  -> bytecode\n  -> interpreter/JIT/runtime providers\n```\n\nEach stage has a different job.\n\nThe AST preserves syntactic structure. Semantic HIR says what the source means as a MATLAB program: which functions exist, which names bind to which language entities, which classes are defined, which calls request which outputs, and which bindings should be visible in the workspace. MIR makes control flow, places, calls, and effects easier to analyze and compile. Analysis attaches facts. VM layout maps semantic bindings into executable frame slots. Bytecode is what the interpreter and JIT consume. Runtime providers handle concrete execution services such as builtin dispatch, plotting, filesystem access, workspace materialization, and acceleration.\n\nThe docs version of those layers starts with the [Compilation Pipeline](/docs/runtime/compiler)\noverview, then goes deeper on [High-Level IR (HIR)](/docs/runtime/compiler/hir),\n[Mid-Level IR (MIR)](/docs/runtime/compiler/mir),\n[MIR & Static Analysis](/docs/runtime/compiler/static-analysis), and\n[Bytecode Compilation](/docs/runtime/vm/bytecode).\n\nThe benefit of this separation is that language decisions become reusable. The interpreter can execute them, the language server can explain them, the JIT can compile through them, and the acceleration planner can use them as inputs. The compiler does not have to rediscover from VM stack shape that a call was a two-output call, that an index was a deletion target, or that a function was a nested capture.\n\nThe bytecode product also becomes more useful. It is VM bytecode, not platform-specific machine code, so it can be consumed by the interpreter, the JIT, snapshots, and tooling. That is also the direction that makes future ahead-of-time compilation or static binary packaging plausible: the source can lower into stable semantic and bytecode products before a later target decides how to execute or package them. Static binaries would still need to carry or link the relevant RunMat runtime services, and highly dynamic MATLAB features would still need explicit policies, but the architecture no longer ties execution to reinterpreting source text.\n\n## Semantic HIR: the language product\n\nRunMat's [semantic HIR](/docs/runtime/compiler/hir) is the compiler's record of what the\nMATLAB program means after source layout and names have been resolved. It is represented\nas an assembly.\n\nAn assembly owns tables for:\n\n- modules\n- entrypoints\n- functions\n- classes\n- bindings\n\nThese are semantic IDs, not VM slots. That distinction is important for MATLAB because\nusers think in terms of variables, functions, files, classes, packages, and workspaces,\nnot storage offsets. A binding like `total`\n\nin a nested function has a language identity\nbefore the VM decides where it lives in a frame. A class method belongs to a class before\nthe runtime decides how to dispatch it. A function call can refer to a builtin, bound\nfunction, imported path, dynamic name, or external boundary before bytecode is emitted.\n\nA HIR function carries its MATLAB ABI:\n\n- fixed inputs\n`varargin`\n\n- fixed outputs\n`varargout`\n\n- implicit\n`nargin`\n\n- implicit\n`nargout`\n\n- captures\n- parent function\n- enclosing class, if any\n\nThat lets RunMat represent the opening example as language structure instead of VM stack\nshape: `SignalModel`\n\ncan be resolved as a constructor, `filters.lowpass`\n\ncan be resolved\nas a package function or method-like call, the call can carry an exact requested output\ncount of two, `model.history{end + 1}`\n\ncan be marked as an indexed assignment target, and\n`plot(filtered)`\n\ncan be treated as an effectful plotting call.\n\nThe same structure also covers other MATLAB function behavior that engineers rely on:\nlocal functions, nested functions that share parent scope, anonymous functions, function\nhandles, `nargin`\n\n, `nargout`\n\n, `varargin`\n\n, and `varargout`\n\n. If the compiler loses those\nrelationships, the code may still parse, but it will not behave like MATLAB.\n\nCalls also carry semantic identity. A call target can be a bound function, builtin,\nimported path, dynamic expression, super constructor, super method, or unresolved\nqualified name. The call also carries requested output count and source syntax. That is\nhow later stages know the difference between direct calls, method syntax, dotted calls,\n`feval`\n\n, and output-expanding calls.\n\nIndexing is also semantic. HIR records the index kind and result context: paren or brace, read or assignment, deletion target or comma-list expansion, function-argument expansion or ordinary single read.\n\nThat context becomes critical later because the same surface syntax can mean read, write, deletion, expansion, or overloaded object dispatch.\n\n## MIR: control flow and compiler facts\n\nHIR is still close to MATLAB language structure. MIR is lower-level. It is the form where RunMat turns language meaning into explicit control flow and assignable places.\n\nRunMat's MIR assembly contains bodies keyed by function. A MIR body has locals and basic blocks. Blocks contain statements and a terminator. Places represent assignable locations. Rvalues represent computed values.\n\nMIR can represent:\n\n- local and binding places\n- member places\n- dynamic member places\n- indexed places\n- assignments\n- multi-assignments\n- expression statements\n- workspace effects\n- environment effects\n- branches\n- loops\n- switch\n- try/catch\n- return\n- await\n- future creation\n- spawn\n- tensor, cell, struct, and object literals\n- calls with requested output counts\n\nThis gives the compiler a form that is easier to analyze. For example, initialization analysis is more natural on MIR blocks than on a source syntax tree. So is spawn-safety analysis, fusion candidate detection, and validation that an indexed assignment target was lowered with an assignment context.\n\nMIR also gives RunMat a place to keep \"place\" and \"value\" roles separate. A read from\n`A(i)`\n\nand a write to `A(i)`\n\nshare source syntax but have different roles. MIR can\npreserve that difference explicitly.\n\n## Analysis: facts that feed execution\n\nRunMat's MIR analysis stores facts that later stages can use.\n\nExamples include:\n\n- whether a local is unassigned, maybe assigned, or definitely assigned\n- simple type facts\n- shape facts\n- value-flow facts\n- async/future facts\n- spawn boundary metadata\n- diagnostics\n- fusion eligibility signals\n\nThese facts are not only for error messages. They feed the runtime architecture. The point is not to make MATLAB statically typed; it is to give the runtime enough shared facts that execution, tooling, and acceleration do not each invent their own approximate model of the program.\n\nFor acceleration, semantic and MIR facts give the planner more to work with than a bytecode scan. The compiler can identify MIR regions that are semantically pure enough or structurally suitable enough to be fusion candidates. Runtime planning can then reconcile those candidates with the actual acceleration graph, provider capabilities, and concrete residency of values.\n\nThat split is deliberate. The compiler provides semantic facts. The runtime and provider own physical execution details. This is especially important for numerical code because the same source may run on host arrays, GPU arrays, or a mix of both depending on the session and provider state.\n\n## VM layout: semantic bindings become frame slots\n\nHIR and MIR keep semantic identity separate from VM slot numbers. MATLAB programs have\nworkspace-visible variables, local variables, persistent variables, global variables, and\nimplicit values like `ans`\n\n; keeping those identities intact makes it easier to preserve\nthe user's model of the program while still compiling to efficient execution storage.\n\nInstead, RunMat derives a VM layout after semantic lowering and MIR construction. The layout maps:\n\n- function frame ABI fields to slots\n- semantic bindings to slots\n- MIR locals to slots\n- captures to capture slots\n- entrypoint exports to workspace-visible names\n- global and persistent bindings to storage bindings\n\nThis keeps language semantics separate from execution storage.\n\nFor example, a script entrypoint may export top-level bindings into the workspace. A\nfunction entrypoint may return outputs instead. A local binding may be hidden. An implicit\n`ans`\n\nbinding may have special workspace visibility. Those are semantic/workspace\npolicies first. VM layout later decides which frame slot holds each value.\n\nThis is the same general principle that makes compiler IRs useful: the program's meaning can stay independent from the storage scheme chosen by the final execution engine. For RunMat, that means a workspace variable remains a workspace variable even though the VM eventually stores it in a frame slot.\n\n## Bytecode and callable descriptors\n\nAfter layout, RunMat compiles MIR into [VM bytecode](/docs/runtime/vm/bytecode). This is\nthe point where the program becomes directly executable, but it is not the point where\nRunMat first learns what the program means.\n\nThe VM compiler emits instructions for arithmetic, calls, indexing, stores, object operations, returns, async descriptors, and runtime effects. But by the time bytecode is emitted, many hard semantic decisions have already been made. As a result, the VM is doing a fairly minimal amount of work to translate simple bytecode into machine code.\n\nCalls are compiled from typed callable identities and fallback policies. That means the runtime can distinguish:\n\n- a bound semantic function\n- a builtin\n- a dynamic name\n- an external qualified name\n- a method identity\n- a super call\n- a\n`feval`\n\ntarget\n\nThis is especially important for function handles. MATLAB users pass functions around as values in optimizers, callbacks, event handlers, array operations, and plotting workflows. A function handle should preserve what it points to when possible. If it refers to a semantic function, RunMat can preserve that semantic identity instead of degrading the handle into a string and hoping name lookup finds the same thing later.\n\nRunMat's [callable descriptor path](/docs/runtime/vm/dispatch) keeps the identity,\narguments, requested output count, and fallback policy together. That lets `feval`\n\n,\nclosures, dynamic names, method handles, and external names share one routing model.\n\n## Project manifests and composition\n\nThe semantic pipeline becomes much more useful when RunMat knows the shape of the project\nit is compiling. As of the 0.5 release, that project boundary is explicit. A\n[ runmat.toml project manifest](/docs/runtime/getting-started/projects) can name the\npackage, declare source roots and local dependencies, and define runnable entrypoints.\n\nThe manifest shape is intentionally small and should feel familiar to modern programmers:\n\n```\n[package]\nname = \"signal-demo\"\nversion = \"0.1.0\"\n\n[sources]\nroots = [\"src\", \"examples\"]\n\n[dependencies]\nfilters = { path = \"deps/filters\", version = \"0.1.0\" }\n\n[entrypoints.main]\npath = \"src/main\"\n\n[entrypoints.demo]\npath = \"examples/demo\"\n```\n\nThat manifest can sit next to an existing MATLAB-style source tree:\n\n```\nsignal-demo/\n  runmat.toml\n  src/\n    main.m\n    @SignalModel/\n      SignalModel.m\n    private/\n      normalizeSamples.m\n  examples/\n    demo.m\n  deps/\n    filters/\n      runmat.toml\n      src/\n        +filters/\n          lowpass.m\n```\n\nThe MATLAB parts remain MATLAB parts. `@SignalModel`\n\nis still the class folder.\n`+filters`\n\nis still the package folder. `private/normalizeSamples.m`\n\nis still a private\nhelper. `main.m`\n\ncan still be a normal script or function file. RunMat is not asking the\nproject to become a Rust crate or a new module syntax.\n\nThe added `runmat.toml`\n\ngives that source tree a stable compiler boundary. `[sources]`\n\ntells RunMat which folders are part of the project source index. `[dependencies]`\n\nmakes\nthe local `filters`\n\nproject available to name resolution. `[entrypoints.main]`\n\nand\n`[entrypoints.demo]`\n\ngive users and hosts named workflows instead of relying on whichever\nfile path happened to be executed first.\n\nThe [Module Composition](/docs/runtime/compiler/modules) docs go deeper on the source\nindex, composition graph, package folders, class folders, private helpers, dependencies,\nand entrypoint resolution behind that behavior.\n\nFrom the CLI, those entrypoints are now stable commands:\n\n```\ncd signal-demo\nrunmat run main\nrunmat run demo\n```\n\nThat is the difference between path execution and project composition. Without a manifest, RunMat can still execute a file by path and discover nearby companion source where the runtime can do so safely. With a manifest, the compiler knows the intended source roots, dependency projects, and runnable entrypoints up front.\n\nFor the opening example, that means `SignalModel(samples)`\n\ncan resolve against the\n`@SignalModel`\n\nclass under `src`\n\n, while `filters.lowpass(...)`\n\ncan resolve through the\ndeclared `filters`\n\ndependency. The same composition graph is available to the interpreter,\nbytecode compiler, LSP, JIT boundary, and acceleration planner.\n\n`import`\n\nstill has its MATLAB job: it controls which names are visible and convenient\ninside source files. The dependency declaration makes the `filters`\n\nproject available; an\nimport can then make its package functions convenient inside `main.m`\n\n:\n\n``` python\nimport filters.*\n\nmodel = SignalModel(samples);\n[filtered, stats] = lowpass(model.samples, 30);\n```\n\nDependencies have a different job: they declare which external projects are available to the resolver. Keeping those responsibilities separate lets existing MATLAB code keep its source conventions while giving RunMat a reproducible project graph.\n\n## Builtins as runtime metadata\n\nRunMat's [builtins](/docs/runtime/builtins) are not only function pointers. For MATLAB\nusers, builtins are the standard library surface: `sum`\n\n, `plot`\n\n, `size`\n\n, `zeros`\n\n, `fft`\n\n,\n`table`\n\n, `struct`\n\n, `feval`\n\n, and hundreds of others. Their signatures, output behavior,\nerrors, and editor documentation are part of the language experience.\n\nBuiltins can carry descriptors for:\n\n- signatures\n- input parameters\n- output parameters\n- fixed vs requested-output-dependent behavior\n- completion policy\n- stable errors\n\nThis makes runtime behavior, editor tooling, and generated documentation point at the same source of truth.\n\nFor example, an LSP signature-help request can use builtin descriptors instead of a separate hand-maintained list. Runtime errors can be thrown from descriptor-backed rows instead of duplicating stable identifiers in several files. Generated reference docs can stay aligned with the same metadata that the runtime uses.\n\nThat does not remove the implementation complexity of each builtin. It does make the public contract of a builtin more explicit, and it gives runtime, docs, and tooling the same contract to read from.\n\nIt also makes each builtin an isolated unit of behavior. Each builtin has its own suite of tests, documentation, and error messages that define, constrain, and enforce their contracts.\n\n## Classes and objects\n\nMATLAB [classes](/docs/runtime/classes) add another layer of semantic resolution. If your\npicture of MATLAB is only scripts and matrices, `classdef`\n\ncan look secondary. In real\nengineering code, classes are often how teams package models, hardware abstractions,\nsimulations, and domain-specific APIs.\n\nA `classdef`\n\nsource file defines class metadata: name, superclass, kind, properties,\nmethods, events, enumerations, attributes, defaults, access rules, and method bodies.\nRunMat lowers that into semantic HIR and registers runtime class metadata during\ncompilation/execution.\n\nIn the opening example, `SignalModel(samples)`\n\nmay be constructing an object from a\nsource `classdef`\n\n. RunMat records whether `SignalModel`\n\nis a value class or a handle\nclass, which properties it defines, which methods are static or instance methods, which\naccess rules apply, and whether `model.history{end + 1} = stats`\n\nmutates stored object\nstate or routes through overloaded indexing. Those are language semantics, not bytecode\nconveniences. If they are wrong, the program may run but produce the wrong model state.\n\nCustom indexing adds another example. If a class defines `subsref`\n\nor `subsasgn`\n\n, ordinary\nmember/index syntax may dispatch through that protocol. RunMat's [object indexing\ndescriptor path](/docs/runtime/vm/indexing) keeps those operations explicit so overloaded\nindexing can coexist with normal property access.\n\n## Acceleration and provider boundaries\n\nRunMat's [acceleration model](/docs/runtime/gpu/fusion) separates semantic eligibility\nfrom concrete residency.\n\nThe compiler can identify candidate groups and semantic operation kinds. Builtin metadata can mark operations as elementwise, reductions, shape transforms, sinks, or effectful. MIR analysis can indicate whether a region is structurally suitable for fusion.\n\nBut the runtime/provider decides whether values are actually resident on a GPU, whether a provider supports an operation, whether data must be gathered, whether a fallback is required, and which concrete kernel or host path should run.\n\nThat separation prevents a common mistake: assuming source syntax alone determines GPU execution. In RunMat, compiler facts guide acceleration, but provider state owns physical execution. The user-facing goal is straightforward: preserve MATLAB behavior first, then use acceleration when the runtime can prove the provider path is appropriate.\n\n## JIT status\n\nRunMat has a [JIT path](/docs/runtime/jit/pipeline) through Turbine and Cranelift, but the\nJIT is not complete yet and is not the normal execution path for most programs. Today,\nmost bytecode patterns still fall back to the interpreter. That is the right tradeoff at\nthis stage: the 0.5 work was mostly about making the compiler and runtime agree on MATLAB\nsemantics before compiling more of those semantics to native code.\n\nThe important change is that the JIT now has the right boundary to build on. Semantic function identity, requested output counts, expanded arguments, and non-scalar runtime values can cross through a tagged value ABI instead of being flattened into f64-only lanes or string lookups. That means Turbine can compile from the same bytecode and semantic facts as the interpreter.\n\nFrom here, broader Cranelift lowering is mostly compiler engineering rather than a new language-semantics project. More JIT coverage is planned before 1.0, with the interpreter remaining the fallback whenever a bytecode pattern is not compiled yet.\n\n## What this unlocks\n\nMATLAB remains useful because engineering teams have years of models, scripts, classes, and workflows built around its semantics. That is also what makes a new runtime hard. Workspaces, functions, classes, output counts, indexing, packages, dynamic calls, builtins, GPU residency, and interactive execution all interact.\n\nTrying to handle those interactions directly in an interpreter works for small cases, but it becomes brittle as the language surface grows. Every missing semantic product turns into a runtime heuristic. Every runtime heuristic becomes harder for tooling, diagnostics, JIT, and acceleration to share. For users, that usually shows up as incompatibility: something works in one context, fails in another, or behaves differently once the code moves out of the prompt and into a project.\n\nWith the 0.5 runtime architecture, RunMat can treat more of that code as a real project instead of isolated snippets. Source roots, package folders, class folders, private helpers, function handles, workspace-visible bindings, object metadata, requested output counts, and display effects now have places in the runtime model.\n\nThat means several paths get better at the same time:\n\n- Multi-file MATLAB-family code can resolve companion functions, classes, packages, and private helpers through project-aware source discovery.\n- The interpreter, language server, JIT, and acceleration planner can share semantic facts instead of rediscovering names, output counts, and indexing behavior independently.\n- Hosts such as notebooks, REPLs, desktop integrations, and WebAssembly embeddings can use structured execution outcomes for workspace changes, display events, diagnostics, and figures.\n- Future native execution work has a cleaner target: bytecode plus semantic products, rather than source text plus runtime guesses.\n\nYou can now use RunMat to execute real project-shaped code: folders with helper functions, package directories, classes, callbacks, plotting, and ordinary workspace-driven workflows. Those are exactly the cases this release was built to start handling systematically.\n\nFor the release-focused view of what changed in 0.5, see\n[the 0.5 release post](/blog/runmat-runtime-0-5-release).\n\n## Related docs\n\n[Compilation Pipeline](/docs/runtime/compiler),[High-Level IR (HIR)](/docs/runtime/compiler/hir),[Mid-Level IR (MIR)](/docs/runtime/compiler/mir), and[MIR & Static Analysis](/docs/runtime/compiler/static-analysis)for the compiler stages.[Projects](/docs/runtime/getting-started/projects)and[Module Composition](/docs/runtime/compiler/modules)for`runmat.toml`\n\n, source roots, dependencies, packages, classes, private helpers, and entrypoints.[Bytecode Compilation](/docs/runtime/vm/bytecode),[Callable Resolution & Function Dispatch](/docs/runtime/vm/dispatch), and[Indexing Subsystem](/docs/runtime/vm/indexing)for VM lowering and execution boundaries.[Builtins](/docs/runtime/builtins),[Execution Requests](/docs/runtime/session/execution-requests), and[Editor Features](/docs/runtime/lsp/features)for the metadata shared by runtime execution and tooling.[Fusion Engine & Residency Management](/docs/runtime/gpu/fusion)and[JIT Pipeline](/docs/runtime/jit/pipeline)for acceleration and Turbine status.\n\nWe're excited to see what you build with RunMat!\n\n## Related posts\n\n### Introducing RunMat Desktop: a high-performance MATLAB alternative\n\nRunMat Desktop is a local, GPU-accelerated workspace for MATLAB-syntax code: editor, plots, variables, notebooks, run history, and an agent that can inspect your project.\n\n### RunMat Runtime 0.5 is out: multi-file project support, and resolving MATLAB language semantics like Rust's compiler\n\nRunMat Runtime 0.5 adds manifest-backed multi-file projects, named entrypoints, stronger MATLAB function/class/indexing semantics, and a shared compiler foundation for tooling, acceleration, and JIT work.\n\n### Open-Source MATLAB Alternatives 2026: Speed, Compatibility & Ease of Use\n\nBenchmarks, compatibility, and setup time for four free MATLAB alternatives. Which runs your .m files, which needs a rewrite, and which can you try in 5 seconds?\n\n### Enjoyed this post? Join the newsletter\n\nMonthly updates on RunMat internals, development, and performance tips.\n\n### Download RunMat\n\nDownload RunMat for full performance, or use RunMat in your browser for zero setup.", "url": "https://wpnews.pro/news/rust-like-compiler-pipeline-to-resolve-matlab-language-semantics", "canonical_source": "https://runmat.com/blog/inside-runmat-runtime-compiler-pipeline", "published_at": "2026-06-11 17:39:00+00:00", "updated_at": "2026-06-14 00:29:33.988358+00:00", "lang": "en", "topics": ["developer-tools"], "entities": ["RunMat", "MATLAB", "Rust"], "alternates": {"html": "https://wpnews.pro/news/rust-like-compiler-pipeline-to-resolve-matlab-language-semantics", "markdown": "https://wpnews.pro/news/rust-like-compiler-pipeline-to-resolve-matlab-language-semantics.md", "text": "https://wpnews.pro/news/rust-like-compiler-pipeline-to-resolve-matlab-language-semantics.txt", "jsonld": "https://wpnews.pro/news/rust-like-compiler-pipeline-to-resolve-matlab-language-semantics.jsonld"}}