moon-wit

A dependency-free WIT parser and MoonBit API scaffold generator

wit
wasm
component-model
bindgen
codegen
moon add pei0331/moon-wit@0.1.0
Download zip
Author
Version
0.1.0
License
Apache-2.0
Last updated
4 days ago
Downloads
2
README

#pei0331/moon-wit

A WIT core-subset parser and MoonBit API scaffold generator. It emits typed declarations and compiling function stubs. Version 0.1.0 does not yet implement the Component Model Canonical ABI, so the generated functions are not callable Wasm import/export bindings. Design inspired by bytecodealliance/wit-bindgen.

The module has no third-party runtime dependencies beyond MoonBit core.

#Usage

The library exposes the parse → generate pipeline used by the moon-wit CLI:

///|
let pkg = @moon_wit.parse(src) // WIT text → WitPackage (raises WitError)

///|
let bindings = @moon_wit.generate(pkg) // → bindings.mbt content

///|
let moon_pkg = @moon_wit.generate_moon_pkg(
@moon_wit.needs_list_import(pkg), // → moon.pkg content
)

Checked-in CLI outputs are compiled by CI. They cover inline interfaces, escaped identifiers, direct world-level functions, resources, composition, versioned WASI paths, async scaffold handles and official-style attributes. Versioned external paths such as wasi:io/streams@0.2.0 are preserved across parse/render and code generation. Flags use UInt bitmasks, while future<T> and stream<T> generate opaque typed scaffold handles.

#Public API

  • parse(String) -> WitPackage raise WitError — lex + parse a WIT document.
  • generate(WitPackage) -> String — render MoonBit bindings.
  • needs_list_import(WitPackage) -> Bool — whether list<T> appears.
  • generate_moon_pkg(Bool) -> String — contents of the generated moon.pkg.
  • type_str(WitType) -> String — WIT type → MoonBit type.
  • type_name / case_name / field_name — kebab-case → Pascal/snake_case.

Errors carry 1-based line:column positions. The implementation is pure logic with no I/O, so the lexer/parser/codegen run unchanged on the Wasm targets; file I/O lives only in the moon-wit CLI (cmd/moon-wit).

#
WitError

pub(all) suberror WitError {
At(Int, Int, String)
}

A lexer/parser error with 1-based line and column position.

#
WitError::make

fn WitError::make(line : Int, col : Int, message : String) -> WitError

#
WitError::to_string

fn WitError::to_string(self : WitError) -> String

Formats as line:col: message.

#
Case

pub struct Case {
name : String
ty : WitType?
}

A variant case. ty is None for a unit case.

#
Case::to_string

fn Case::to_string(self : Case) -> String

#
Field

pub struct Field {
name : String
ty : WitType
}

A named field with its type (record field or function parameter).

#
Field::to_string

fn Field::to_string(self : Field) -> String

#
FuncResult

pub enum FuncResult {
Unnamed(WitType)
Named(Field)
}

A single unnamed result, or a named result (WIT named results).

#
FuncResult::to_string

fn FuncResult::to_string(self : FuncResult) -> String

#
FuncSig

pub struct FuncSig {
name : String
params : Array[Field]
results : Array[FuncResult]
}

A func signature with parameters and results.

#
FuncSig::to_string

fn FuncSig::to_string(self : FuncSig) -> String

#
ImpExp

pub struct ImpExp {
name : String
asName : String?
inline : Interface?
}

An import foo [as bar] [: interface {...}] or export ... item.

#
ImpExp::to_string

fn ImpExp::to_string(self : ImpExp) -> String

#
Interface

pub struct Interface {
name : String
items : Array[InterfaceItem]
}

An interface definition.

#
Interface::to_string

fn Interface::to_string(self : Interface) -> String

#
InterfaceItem

pub enum InterfaceItem {
Use(UseDecl)
Type(TypeDef)
Func(FuncSig)
}

An item inside an interface (or an inline interface in a world).

#
InterfaceItem::to_string

fn InterfaceItem::to_string(self : InterfaceItem) -> String

#
ResourceFunc

pub struct ResourceFunc {
kind : ResourceFuncKind
sig : FuncSig
}

#
ResourceFuncKind

pub enum ResourceFuncKind {
Constructor
Static
Method
}

#
Token

pub struct Token {
kind : TokenKind
line : Int
col : Int
} derive(Eq)

#
Token::to_string

fn Token::to_string(self : Token) -> String

#
TokenKind

pub enum TokenKind {
Ident(String)
Version(String)
LBrace
RBrace
LParen
RParen
Lt
Gt
Comma
Semi
Colon
Arrow
Eq
Dot
Slash
At
Star
Eof
} derive(Eq)

#
TypeDef

pub struct TypeDef {
name : String
kind : TypeDefKind
}

A named type definition.

#
TypeDef::to_string

fn TypeDef::to_string(self : TypeDef) -> String

#
TypeDefKind

pub enum TypeDefKind {
Record(Array[Field])
Variant(Array[Case])
Enum(Array[String])
Flags(Array[String])
Resource(Array[ResourceFunc])
Alias(WitType)
}

The kind of a named type definition.

#
UseDecl

pub struct UseDecl {
path : String
names : Array[UseName]
}

use <path>.{a, b as c} — re-exports types from an interface.

#
UseDecl::to_string

fn UseDecl::to_string(self : UseDecl) -> String

#
UseName

pub struct UseName {
name : String
asName : String?
}

use path.{a, b as c} declaration.

#
UseName::to_string

fn UseName::to_string(self : UseName) -> String

#
WitItem

pub enum WitItem {
Interface(Interface)
World(World)
Use(UseDecl)
}

An item at the top level of a WIT document.

#
WitItem::to_string

fn WitItem::to_string(self : WitItem) -> String

#
WitPackage

pub struct WitPackage {
ns : String
name : String
version : String?
items : Array[WitItem]
}

A parsed WIT document (the result of parse).

#
WitPackage::to_string

fn WitPackage::to_string(self : WitPackage) -> String

#
WitType

pub enum WitType {
Name(String)
U8
U16
U32
U64
S8
S16
S32
S64
F32
F64
TChar
TString
TBool
List(WitType)
Option(WitType)
Result(WitType?, WitType?)
Tuple(Array[WitType])
Own(String)
Borrow(String)
Future(WitType?)
Stream(WitType?)
}

A reference to a WIT type.

#
WitType::to_string

fn WitType::to_string(self : WitType) -> String

Renders a WIT type reference back to WIT syntax.

#
World

pub struct World {
name : String
items : Array[WorldItem]
}

A world definition.

#
World::to_string

fn World::to_string(self : World) -> String

#
WorldItem

pub enum WorldItem {
Import(ImpExp)
Export(ImpExp)
ImportFunc(FuncSig)
ExportFunc(FuncSig)
Include(String, Array[UseName])
Use(UseDecl)
}

An item inside a world.

#
WorldItem::to_string

fn WorldItem::to_string(self : WorldItem) -> String

#
case_name

fn case_name(name : String) -> String

first-nameFirstName (MoonBit enum case naming).

#
field_name

fn field_name(name : String) -> String

first-namefirst_name (MoonBit field/function naming).

#
generate

fn generate(pkg : WitPackage) -> String

Generate the contents of a bindings.mbt file for pkg.

#
generate_moon_pkg

fn generate_moon_pkg(use_list : Bool) -> String

Contents of the moon.pkg for a generated package.

#
needs_list_import

fn needs_list_import(pkg : WitPackage) -> Bool

Whether any generated type needs moonbitlang/core/list.

#
parse

fn parse(src : String) -> WitPackage raise WitError

Parse a WIT document into a [WitPackage].

#
tokenize

fn tokenize(src : String) -> Array[Token] raise WitError

Tokenize a full WIT document. Raises WitError on an unexpected character or an unterminated block comment.

#
type_name

fn type_name(name : String) -> String

hello-worldHelloWorld (MoonBit type/case naming).

#
type_str

fn type_str(t : WitType) -> String

WIT type → MoonBit type.