1+ /*--------------------------------------------------------------------------
2+
3+ ParseBox
4+
5+ The MIT License (MIT)
6+
7+ Copyright (c) 2024-2026 Haydn Paterson
8+
9+ Permission is hereby granted, free of charge, to any person obtaining a copy
10+ of this software and associated documentation files (the "Software"), to deal
11+ in the Software without restriction, including without limitation the rights
12+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13+ copies of the Software, and to permit persons to whom the Software is
14+ furnished to do so, subject to the following conditions:
15+
16+ The above copyright notice and this permission notice shall be included in
17+ all copies or substantial portions of the Software.
18+
19+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25+ THE SOFTWARE.
26+
27+ ---------------------------------------------------------------------------*/
28+
29+ export function test ( math : Math ) {
30+ const a = math . $add ( 1 , 2 )
31+ const b = math . $sub ( 1 , 2 )
32+ const c = math . $mul ( 1 , 2 )
33+ const d = math . $div ( 1 , 2 )
34+
35+ const expr = math . $add ( // (1 - 2) + (3 + ((4 * 5) / 6))
36+ math . $sub ( 1 , 2 ) ,
37+ math . $add ( 3 ,
38+ math . $div (
39+ math . $mul ( 4 , 5 ) ,
40+ 6
41+ )
42+ )
43+ )
44+ }
45+
46+ type Math = Wat < `(module
47+ (func $add (param $x f32) (param $y f32) (result f32)
48+ local.get $x
49+ local.get $y
50+ f32.add
51+ )
52+ (func $sub (param $x f32) (param $y f32) (result f32)
53+ local.get $x
54+ local.get $y
55+ f32.sub
56+ )
57+ (func $mul (param $x f32) (param $y f32) (result f32)
58+ local.get $x
59+ local.get $y
60+ f32.mul
61+ )
62+ (func $div (param $x f32) (param $y f32) (result f32)
63+ local.get $x
64+ local.get $y
65+ f32.div
66+ )
67+ )`>
68+
69+ import { Static } from '@sinclair/parsebox'
70+
71+ // ---------------------------------------------------
72+ // Wat: Parse
73+ // ---------------------------------------------------
74+ export type Wat < Code extends string ,
75+ Parsed extends unknown = Static . Parse < Module , Code > [ 0 ] ,
76+ Ast extends TModule = Parsed extends TModule ? Parsed : TModule < [ ] > ,
77+ Exports extends Record < PropertyKey , unknown > = GetExports < Ast >
78+ > = Exports
79+
80+ // ---------------------------------------------------
81+ // Query: Exports
82+ // ---------------------------------------------------
83+ type GetExportsParams < Params extends TParam [ ] , Result extends unknown [ ] = [ ] > = (
84+ Params extends [ infer _ extends TParam , ...infer Right extends TParam [ ] ]
85+ ? GetExportsParams < Right , [ ...Result , number ] > // i32, i64, f32, f64
86+ : Result
87+ )
88+ type GetExportsFunc < Func extends TFunc ,
89+ Params extends unknown [ ] = GetExportsParams < Func [ 'params' ] > ,
90+ Return extends unknown = number , // single return type
91+ Result extends Record < PropertyKey , unknown > = {
92+ [ K in Func [ 'name' ] ] : ( ...args : [ ...Params ] ) => Return
93+ }
94+ > = Result
95+ type GetExportsQuery < Funcs extends TFunc [ ] , Result extends Record < PropertyKey , unknown > = { } > = (
96+ Funcs extends [ infer Left extends TFunc , ...infer Right extends TFunc [ ] ]
97+ ? GetExportsQuery < Right , Result & GetExportsFunc < Left > >
98+ : { [ K in keyof Result ] : Result [ K ] }
99+ )
100+ type GetExports < Module extends TModule > = GetExportsQuery < Module [ 'funcs' ] >
101+
102+ // ---------------------------------------------------
103+ // NativeType
104+ // ---------------------------------------------------
105+ type NativeType = Static . Union < [
106+ Static . Const < 'i32' > ,
107+ Static . Const < 'i64' > ,
108+ Static . Const < 'f32' > ,
109+ Static . Const < 'i64' >
110+ ] >
111+ // ---------------------------------------------------
112+ // Param
113+ // ---------------------------------------------------
114+ interface TParam < Name extends string = string , Type extends string = string > {
115+ kind : 'Param'
116+ name : Name
117+ type : Type
118+ }
119+ interface ParamMapping extends Static . IMapping {
120+ output : this[ 'input' ] extends [ '(' , 'param' , infer Name extends string , infer Type extends string , ')' ]
121+ ? TParam < Name , Type >
122+ : never
123+ }
124+ type Param = Static . Tuple < [
125+ Static . Const < '(' > ,
126+ Static . Const < 'param' > ,
127+ Static . Ident ,
128+ NativeType ,
129+ Static . Const < ')' >
130+ ] , ParamMapping >
131+ type Params = Static . Array < Param >
132+ // ---------------------------------------------------
133+ // Result
134+ // ---------------------------------------------------
135+ interface TResult < Type extends string = string > {
136+ kind : 'Result'
137+ type : Type
138+ }
139+ interface ResultMapping extends Static . IMapping {
140+ output : this[ 'input' ] extends [ '(' , 'result' , infer Type extends string , ')' ]
141+ ? TResult < Type >
142+ : never
143+ }
144+ type Result = Static . Tuple < [
145+ Static . Const < '(' > ,
146+ Static . Const < 'result' > ,
147+ NativeType ,
148+ Static . Const < ')' > ,
149+ ] , ResultMapping >
150+ // ---------------------------------------------------
151+ // Instruction
152+ // ---------------------------------------------------
153+ type Oprand = Static . Union < [
154+ Static . Ident ,
155+ Static . Number
156+ ] >
157+ interface TInstruction <
158+ Namespace extends string = string ,
159+ Operator extends string = string ,
160+ Operand extends string [ ] = string [ ]
161+ > {
162+ kind : 'Instruction'
163+ namespace : Namespace
164+ operator : Operator
165+ operand : Operand
166+ }
167+ interface InstructionMapping extends Static . IMapping {
168+ output : this[ 'input' ] extends [ infer Namespace extends string , '.' , infer Operator extends string , infer Operand extends string [ ] ]
169+ ? TInstruction < Namespace , Operator , Operand >
170+ : never
171+ }
172+ type Instruction = Static . Tuple < [
173+ Static . Union < [ NativeType , Static . Const < 'local' > ] > ,
174+ Static . Const < '.' > ,
175+ Static . Ident ,
176+ Static . Optional < Oprand >
177+ ] , InstructionMapping >
178+ type Instructions = Static . Array < Instruction >
179+ // ---------------------------------------------------
180+ // Func
181+ // ---------------------------------------------------
182+ interface TFunc <
183+ Name extends string = string ,
184+ Params extends TParam [ ] = TParam [ ] ,
185+ Result extends TResult = TResult ,
186+ Instructions extends TInstruction [ ] = TInstruction [ ] > {
187+ kind : 'Func'
188+ name : Name
189+ params : Params
190+ result : Result
191+ instructions : Instructions
192+ }
193+ interface FuncMapping extends Static . IMapping {
194+ output : this[ 'input' ] extends [ '(' , 'func' , infer Name extends string , infer Params extends TParam [ ] , infer Result extends TResult , infer Instructions extends TInstruction [ ] , ')' ]
195+ ? TFunc < Name , Params , Result , Instructions >
196+ : never
197+ }
198+ type Func = Static . Tuple < [
199+ Static . Const < '(' > ,
200+ Static . Const < 'func' > ,
201+ Static . Ident ,
202+ Params ,
203+ Result ,
204+ Instructions ,
205+ Static . Const < ')' >
206+ ] , FuncMapping >
207+ type Funcs = Static . Array < Func >
208+ // ---------------------------------------------------
209+ // Module
210+ // ---------------------------------------------------
211+ interface TModule < Funcs extends TFunc [ ] = TFunc [ ] > {
212+ kind : 'Module'
213+ funcs : Funcs
214+ }
215+ interface ModuleMapping extends Static . IMapping {
216+ output : this[ 'input' ] extends [ '(' , 'module' , infer Funcs extends TFunc [ ] , ')' ]
217+ ? TModule < Funcs >
218+ : never
219+ }
220+ type Module = Static . Tuple < [
221+ Static . Const < '(' > ,
222+ Static . Const < 'module' > ,
223+ Funcs ,
224+ Static . Const < ')' >
225+ ] , ModuleMapping >
0 commit comments