eval

MoonBit Eval Package

moonbit
eval
moon add oboard/eval@0.9.4
Download zip
Author
Version
0.9.4
License
Apache-2.0
Last updated
last month
Downloads
29
README

#MoonBit Eval

Version GitHub Workflow Status (with event) License

#Demo

🚀 REPL Demo

#Introduction

MoonBit Eval is an interpreter for the MoonBit language.

Built on top of the @moonbitlang/parser library, it provides comprehensive and accurate MoonBit syntax support, capable of correctly parsing and executing complex MoonBit code structures including functions, structs, lambdas, loops, and more.

#Quick Start

let vm = MoonBitVM()

// Basic expressions
inspect(vm.eval("1 + 2 * 3"), content="7")
inspect(vm.eval("\"hello\" + \" world\""), content="hello world")

// Variables and functions
inspect(vm.eval("let x = 42"), content="()")
inspect(vm.eval("fn double(n: Int) -> Int { n * 2 }"), content="(n: Int) -> Int")
inspect(vm.eval("double(x)"), content="84")

// Control flow
inspect(vm.eval("if x > 40 { \"big\" } else { \"small\" }"), content="big")

// Pattern matching
inspect(vm.eval("match (1, 2) { (a, b) => a + b }"), content="3")

// Using aliases (new parser style)
inspect(vm.eval("using @int {abs}"), content="()")
inspect(vm.eval("abs(-5)"), content="5")

#Compile and Run

Use compile when the same code needs to run repeatedly. Parsing happens once, and each run executes the compiled code against the VM you pass in.

let vm = MoonBitVM()
let expr = vm.compile("x + y * 2", params=["x", "y"])

inspect(
expr.run(vm, args=[3, 4]),
content="11",
)
inspect(
expr.run(vm, args=[10, 1]),
content="12",
)

Compiled parameters are bound in a temporary scope, so they do not leak into the VM global environment after execution.

#Imports and Package Loading

eval accepts top-level expressions directly, with or without fn main. Import declarations can appear before either form.

let vm = MoonBitVM()

inspect(
vm.eval(
(
#|import {
#| "moonbitlang/core/list"
#|}
#|@list.from_array([1, 2, 3])
),
),
content="More(1, tail=More(2, tail=More(3, tail=Empty)))",
)

Core packages are loaded on demand. moonbitlang/core/builtin is always available, but other core packages such as moonbitlang/core/list must be imported explicitly before using their package aliases.

#Runtime Modules

Optional runtime modules can be injected when constructing a VM. They register packages and embedded runtime functions without loading every package into the current eval scope.

let vm = MoonBitVM(modules=[@eval/async.module()])

The async module makes the root @async package available. Subpackages are lazy-loaded and must be imported explicitly:

inspect(
vm.test_all(
(
#|import { "moonbitlang/async/http" }
#|async test "https request" {
#| let (response, body) = @async.retry(FixedDelay(250), max_retry=3, () => {
#| @async.with_timeout(3000, () => @http.get("https://www.moonbitlang.com"))
#| })
#| assert_true(response.code is (200..<300), msg=response.code.to_string())
#| assert_true(body.text().to_lower().has_prefix("<!doctype html>"), msg=body.text())
#|}
),
),
content="TestResult(total=1, passed=1, failed=0)",
)

vm.test_all(code) runs top-level test and async test blocks and returns a TestResult summary instead of swallowing assertion failures.

#Parser Notes

  • eval parses code through a compatibility wrapper around moonbitlang/parser.
  • Top-level expressions are supported directly, so users do not need to wrap snippets in fn main.
  • Full top-level code with declarations and fn main remains supported.
  • Diagnostics from parser reports are preserved and returned in Err(...) when parse fails.

#✨ Features

  • ✅ đŸĨŽ Mooncakes Loader: Load Mooncakes packages at runtime
  • ✅ Builtin FileSystem Library: Provides basic file system operations.
  • ✅ Eval Function: Allows dynamic evaluation of MoonBit code strings.

#MoonBit Language Support

FeatureStatusDescription
Core Language
Basic Types (Int, Bool, String, Double, Char)✅Full support for primitive types
Expressions (arithmetic, logical, comparison)✅Complete expression evaluation
Variables (let, let mut)✅Immutable and mutable variables
Assignment✅Variable reassignment and shadowing
Multiline strings✅#|syntax for multiline string literals
String interpolation✅{variable} syntax in string literals
Type constraints✅(value : Type) syntax for explicit typing
Control Flow
If-else✅Conditional expressions
For loops✅C-style for loops with continue/break
While loops✅While loop constructs with else clause
Loop control✅Continue and break statements
Guard expressions✅guard condition else { action } syntax
Is expressions✅Pattern matching with 'is' operator
Defer expressions✅defer statement for cleanup code
Return expressions✅Early return from functions
Raise expressions✅Exception throwing with raise
Try-catch expressions✅Exception handling with try-catch
Loop expressions✅loop pattern matching with break/continue
Functions
Function definitions✅Named functions with parameters
Named parameters✅Named and optional parameters
Lambda expressions✅Anonymous functions (x => x * 2)
Closures✅Proper closure environment capture
Recursive functions✅Self-referencing function calls
Currying✅Higher-order function composition
External functions✅Integration with external calls
Embedded functions✅Native function integration
Data Structures
Arrays✅Array creation, indexing, assignment
Array methods✅length, get, push, pop, contains, slice, concat, join
Array boolean methods✅any, all operations
Array spread syntax✅[..array1, ..array2] syntax
Array slice operations✅arr[start:end], arr[start:], arr[:end] syntax
Array augmented assignment✅arr[i] += value, arr[i] *= value syntax
Tuples✅Tuple creation, access, destructuring
Structs✅Custom data types with methods
Mutable struct fields✅Field mutation support
Nested struct references✅Reference semantics for nested structures
Record update syntax✅{ ..record, field: new_value } syntax
Map literals✅{ "key": value } syntax for map creation
Pattern Matching
Basic patterns✅Constants, variables, wildcards
Tuple patterns✅Destructuring tuples
Array patterns✅Array destructuring
Record patterns✅Struct field matching
Range patterns✅Range expressions (_..<x, 'a'..='z')
Constructor patterns✅Constant constructor matching
Or patterns✅Multiple pattern alternatives
Nested patterns✅Complex nested pattern matching
Enums and Generics
Basic enums✅Simple enumeration types
Enums with data✅Algebraic data types
Enum pattern matching✅Pattern matching on enum variants
Generic types✅Generic enums and functions
Generic functions✅Polymorphic function definitions
Option Type
Option basics✅Some/None construction
Option pattern matching✅Pattern matching on Option
Option methods✅unwrap, unwrap_or, is_empty, map, filter
Built-in Methods
Bool methods✅compare, default
Int methods✅Bitwise ops, comparisons, bit manipulation
String methods✅length, get, unsafe_get, to_string
Double methods✅compare, to_int64
Char methods✅compare, to_int
Advanced Features
Type system✅Basic type checking and inference
Static method calls✅Class::method() syntax
Pipe operator✅|> operator for function chaining
Function aliases✅using @pkg {name} alias support
Cross-package method calls✅Method calls across different packages
Error handling✅Result type error handling
Group expressions✅Parenthesized expressions for precedence
For-in loops✅Iterator-based loops
Iterator methods✅iter, map, filter, reduce, for_each
Nested iteration✅Complex nested loop structures
Iterator control flow✅break/continue in iterator contexts
Package System
Module imports✅Explicit import { "package/path" } declarations and @package.function syntax
Cross-package types✅Using types from other packages
Built-in packages✅Builtin package is always loaded; other core packages load through explicit imports
Package method calling✅Method calls across package boundaries
Runtime modules✅Optional injected modules such as @eval/async.module()
IO and FFI
Print functions✅println and print support
Embedded functions✅Native function integration via FFI
External function binding✅Custom function registration
Sorting and Collections
List sorting✅Built-in sort methods for collections
Array sorting✅Sorting operations on arrays
Collection methods✅Comprehensive collection manipulation
Comparison Operations
Equality operators✅== and != operators
Relational operators✅, <=, >= operators
Type-aware comparison✅Proper type checking in comparisons
Constructor Patterns
Single argument matching✅Constructor pattern with single args
Named field matching✅Constructor patterns with named fields
Wildcard patterns✅_ patterns in constructor matching
Functional Programming
Higher-order functions✅Functions as first-class values
Function composition✅Combining functions effectively
Closure environments✅Proper variable capture in closures
Literal Overloading
Numeric literal overloading✅Automatic conversion between numeric types
Character literal overloading✅Char to Int conversion in pattern matching
String literal overloading✅String to Bytes conversion
Array literal overloading✅Array to various types (Bytes, String) conversion
Double literal overloading✅Double to Float precision conversion
Map literal overloading✅Map to Json object conversion
Complex overloading scenarios✅Multi-step type conversions
Traits🟡Interface definitions
Trait as expressions🟡(value as Trait) syntax for trait casting
Packages🟡Module system with @package.function syntax (no trait, trait derive, operator overloading)
Attribute
#alias✅Function alias
#external❌External function binding
#callsite❌Call site information
#skip❌Skipping compilation of a function
#cfg❌Conditional compilation based on configuration
Not Yet Supported
Async/await🟡Async tests and selected moonbitlang/async APIs through explicit runtime module injection

#Contributing

We welcome contributions to the MoonBit Eval project! Whether it's bug fixes, feature additions, or documentation improvements, your contributions are valuable.

#Community

Join our community for discussions and support:
  • QQ Group: 949886784

QQ įž¤

#
CompiledCode

pub(all) struct CompiledCode {
// private fields
}

#
CompiledCode::run

fn CompiledCode::run(self : CompiledCode, vm : MoonBitVM, args? : Array[&ToRuntime], log? : Bool) -> EvalResult

#
MoonBitVM

pub(all) struct MoonBitVM {
interpreter :
ClosureInterpreter

log : Bool
// private fields
}
#alias(new)
fn MoonBitVM::MoonBitVM(log? : Bool, modules? : Array[
RuntimeModule
]) -> MoonBitVM

#
MoonBitVM::compile

fn MoonBitVM::compile(self : MoonBitVM, code : String, params? : Array[String]) -> CompiledCode

#
MoonBitVM::create

#
MoonBitVM::eval

fn MoonBitVM::eval(self : MoonBitVM, code : String, log? : Bool) -> EvalResult

#
MoonBitVM::run

fn MoonBitVM::run(self : MoonBitVM, code : String, log? : Bool) -> Unit

#
MoonBitVM::test_all

fn MoonBitVM::test_all(self : MoonBitVM, code : String, log? : Bool) -> TestResult

#
TestFailure

pub(all) struct TestFailure {
name : String
message : String
} derive(ToJson)

impl Show for TestFailure

#
TestResult

pub(all) struct TestResult {
total : Int
passed : Int
failed : Int
failures : Array[TestFailure]
} derive(ToJson)

impl Show for TestResult

#
code_to_ast

fn code_to_ast(code : String) -> String

#
compile

fn compile(vm : MoonBitVM, code : String, params? : Array[String]) -> CompiledCode

#
eval_result_to_string

fn eval_result_to_string(result : EvalResult) -> String

#
expr_to_string

fn expr_to_string(expr :
Expr
) -> String

#
run_compiled

fn run_compiled(vm : MoonBitVM, compiled : CompiledCode, args? : Array[&ToRuntime], log? : Bool) -> EvalResult

#
test_all

fn test_all(vm : MoonBitVM, code : String, log? : Bool) -> TestResult

#
test_result_to_string

fn test_result_to_string(result : TestResult) -> String

#
value_to_json

fn value_to_json(value :
RuntimeValue
) -> String

#
value_to_string

fn value_to_string(value :
RuntimeValue
) -> String

Powered by MoonBit

Site sourceReport issuePackagesBuild queueSkillsStatistics

Š 2026 mooncakes.io