@@ -35,9 +35,15 @@ data Module =
35
35
Module [TopLevel ]
36
36
BytesAllocated
37
37
38
+ data WasmType
39
+ = I32
40
+ | F32
41
+ deriving (Show , Eq , G.Generic )
42
+
38
43
data Declaration =
39
44
Declaration F. Ident
40
45
[F. Ident ]
46
+ WasmType
41
47
Expression
42
48
deriving (Show , Eq , G.Generic )
43
49
@@ -59,7 +65,7 @@ data Expression
59
65
| If Expression
60
66
Expression
61
67
(Maybe Expression )
62
- | Sequence (NE. NonEmpty Expression )
68
+ | Sequence WasmType (NE. NonEmpty Expression )
63
69
deriving (Show , Eq )
64
70
65
71
data Locals =
@@ -163,29 +169,38 @@ allocateBytes (Module topLevel bytes) extraBytes =
163
169
Module topLevel (bytes + extraBytes)
164
170
165
171
compileDeclaration :: Module -> TypedDeclaration -> Module
166
- compileDeclaration m (TypedDeclaration name args _ fexpr) =
172
+ compileDeclaration m (TypedDeclaration name args fType fexpr) =
167
173
let parameters = concatMap (fst <$> assignments) (fst <$> args)
168
174
deconstruction = concatMap (snd <$> assignments) (fst <$> args)
169
175
locals = Locals (Set. fromList parameters)
170
176
(m', expr') = compileExpression m locals fexpr
177
+ wasmType = forestTypeToWasmType fType
171
178
func =
172
179
Func $
173
180
Declaration
174
181
name
175
182
parameters
176
- (Sequence $ NE. fromList (deconstruction <> [expr']))
183
+ wasmType
184
+ (Sequence wasmType $ NE. fromList (deconstruction <> [expr']))
177
185
in addTopLevel m' [func]
178
186
179
187
compileInlineDeclaration ::
180
188
Module -> Locals -> TypedDeclaration -> (Maybe Expression , Module )
181
- compileInlineDeclaration m (Locals l) (TypedDeclaration name args _ fexpr) =
189
+ compileInlineDeclaration m (Locals l) (TypedDeclaration name args forestType fexpr) =
182
190
let parameters = concatMap (fst <$> assignments) (fst <$> args)
183
191
locals = Locals (Set. union l (Set. fromList parameters))
184
192
(m', expr') = compileExpression m locals fexpr
185
193
in case args of
186
194
[] -> (Just $ SetLocal name expr', m')
187
195
_ ->
188
- (Nothing , addTopLevel m' [Func $ Declaration name parameters expr'])
196
+ (Nothing , addTopLevel m' [Func $ Declaration name parameters (forestTypeToWasmType forestType) expr'])
197
+
198
+ forestTypeToWasmType :: T. Type -> WasmType
199
+ forestTypeToWasmType fType =
200
+ case fType of
201
+ Num -> I32
202
+ Float' -> F32
203
+ _ -> I32
189
204
190
205
compileExpressions ::
191
206
Module -> NonEmpty TypedExpression -> (Module , [Expression ])
@@ -221,9 +236,9 @@ compileInfix m locals operator a b =
221
236
let (m', aExpr) = compileExpression m locals a
222
237
(m'', bExpr) = compileExpression m' locals b
223
238
name = (F. Ident $ F. NonEmptyString ' s' " tring_add" )
224
- in case operator of
225
- F. StringAdd -> (m'', NamedCall name [aExpr, bExpr])
226
- _ -> (m'', Call (funcForOperator operator) [aExpr, bExpr])
239
+ in case ( operator, T. typeOf b) of
240
+ ( F. StringAdd, T. Str ) -> (m'', NamedCall name [aExpr, bExpr])
241
+ (_, t) -> (m'', Call (funcForOperator operator t ) [aExpr, bExpr])
227
242
228
243
compileApply ::
229
244
Module
@@ -235,7 +250,7 @@ compileApply m locals left right =
235
250
case left of
236
251
T. Apply _ (T. Identifier _ name _) r' ->
237
252
let (m', exprs) = compileExpressions m [right, r']
238
- in (m', Sequence $ NE. fromList (exprs <> [NamedCall name [] ]))
253
+ in (m', Sequence I32 $ NE. fromList (exprs <> [NamedCall name [] ]))
239
254
T. Identifier _ name _ ->
240
255
let (m', r) = compileExpression m locals right
241
256
in (m', NamedCall name [r])
@@ -261,7 +276,7 @@ compileLet m locals@(Locals l) declarations fexpr =
261
276
NE. toList $ (\ (TypedDeclaration name _ _ _) -> name) <$> declarations
262
277
locals' = Locals $ Set. union l (Set. fromList names)
263
278
(m'', expr') = compileExpression m' locals' fexpr
264
- in (m'', Sequence $ NE. fromList (declarationExpressions <> [expr']))
279
+ in (m'', Sequence I32 $ NE. fromList (declarationExpressions <> [expr']))
265
280
266
281
compileCase ::
267
282
Module
@@ -305,7 +320,7 @@ compileCase m locals caseFexpr patterns =
305
320
compileADTConstruction ::
306
321
(Functor t , Foldable t ) => Int -> t (F. Argument , b ) -> Expression
307
322
compileADTConstruction tag args =
308
- Sequence
323
+ Sequence I32
309
324
(NE. fromList
310
325
([ SetLocal
311
326
(ident " address" )
@@ -361,7 +376,7 @@ compileDeconstructionAssignment i a n =
361
376
(Call
362
377
(ident " i32.load" )
363
378
[Call (ident " i32.add" ) [GetLocal i, Const $ n * 4 ]]))
364
- _ -> Sequence []
379
+ _ -> Sequence I32 []
365
380
366
381
compileCaseExpression ::
367
382
Module -> Locals -> T. TypedExpression -> (Module , Expression )
@@ -397,7 +412,7 @@ compileArgument m caseFexpr arg =
397
412
localName (TAIdentifier _ ident') = Just ident'
398
413
localName _ = Nothing
399
414
locals = addLocals (mapMaybe localName args) noLocals
400
- in (m, Sequence (NE. fromList (assignments <> [Const tag])), locals)
415
+ in (m, Sequence I32 (NE. fromList (assignments <> [Const tag])), locals)
401
416
where
402
417
caseLocal =
403
418
case caseFexpr of
@@ -407,15 +422,24 @@ compileArgument m caseFexpr arg =
407
422
eq32 :: F. Ident
408
423
eq32 = F. Ident $ F. NonEmptyString ' i' " 32.eq"
409
424
410
- funcForOperator :: F. OperatorExpr -> F. Ident
411
- funcForOperator operator =
412
- F. Ident . uncurry F. NonEmptyString $
413
- case operator of
414
- F. Add -> (' i' , " 32.add" )
415
- F. Subtract -> (' i' , " 32.sub" )
416
- F. Multiply -> (' i' , " 32.mul" )
417
- F. Divide -> (' i' , " 32.div_s" )
418
- F. StringAdd -> (' s' , " tring_add" )
425
+ funcForOperator :: F. OperatorExpr -> T. Type -> F. Ident
426
+ funcForOperator operator t =
427
+ let
428
+ wasmType =
429
+ case t of
430
+ Num -> " i32"
431
+ Float' -> " f32"
432
+ _ -> error $ " tried to get a funcForOperator for a non numeric type: " <> (Text. unpack $ T. printType t)
433
+ op =
434
+ case (operator, t) of
435
+ (F. Add , _) -> " add"
436
+ (F. Subtract , _) -> " sub"
437
+ (F. Multiply , _) -> " mul"
438
+ (F. Divide , Float' ) -> " div"
439
+ (F. Divide , _) -> " div_s"
440
+ _ -> error $ " tried to get a funcForOperator for a non numeric type: " <> (Text. unpack $ T. printType t)
441
+ in
442
+ ident (wasmType <> " ." <> op)
419
443
420
444
printWasm :: Module -> Text
421
445
printWasm (Module expressions bytesAllocated) =
@@ -439,10 +463,10 @@ printMemory bytes =
439
463
printWasmTopLevel :: TopLevel -> Text
440
464
printWasmTopLevel topLevel =
441
465
case topLevel of
442
- Func (Declaration name args body) ->
466
+ Func (Declaration name args wasmType body) ->
443
467
Text. unlines
444
468
[ " (export \" " <> F. s name <> " \" (func $" <> F. s name <> " ))"
445
- , printDeclaration (Declaration name args body)
469
+ , printDeclaration (Declaration name args wasmType body)
446
470
]
447
471
Data offset str ->
448
472
" (data (i32.const " <> showT offset <> " ) \" " <>
@@ -459,8 +483,8 @@ printWasmTopLevel topLevel =
459
483
printWasmExpr :: Expression -> Text
460
484
printWasmExpr expr =
461
485
case expr of
462
- Sequence exprs ->
463
- " (block (result i32 )\n " <> indent2 (Text. intercalate " \n " $ NE. toList (printWasmExpr <$> exprs)) <> " \n )"
486
+ Sequence wasmType exprs ->
487
+ " (block (result " <> printWasmType wasmType <> " )\n " <> indent2 (Text. intercalate " \n " $ NE. toList (printWasmExpr <$> exprs)) <> " \n )"
464
488
Const n -> " (i32.const " <> showT n <> " )"
465
489
FloatConst n -> " (f32.const " <> showT n <> " )"
466
490
GetLocal name -> " (get_local $" <> F. s name <> " )"
@@ -482,13 +506,20 @@ printWasmExpr expr =
482
506
] <>
483
507
[indent2 $ maybe " (i32.const 0)" printWasmExpr b, " )" ])
484
508
509
+
510
+ printWasmType :: WasmType -> Text
511
+ printWasmType wasmType =
512
+ case wasmType of
513
+ I32 -> " i32"
514
+ F32 -> " f32"
515
+
485
516
printDeclaration :: Declaration -> Text
486
- printDeclaration (Declaration name args body) =
517
+ printDeclaration (Declaration name args wasmType body) =
487
518
Text. intercalate
488
519
" \n "
489
520
[ " (func $" <> F. s name <>
490
521
Text. unwords (fmap (\ x -> " (param $" <> x <> " i32)" ) (F. s <$> args)) <>
491
- " (result i32 ) " <>
522
+ " (result " <> printWasmType wasmType <> " ) " <>
492
523
Text. unwords (printLocal <$> locals body)
493
524
, indent2 $ Text. unlines [" (return" , indent2 $ printWasmExpr body, " )" ]
494
525
, " )"
@@ -498,7 +529,7 @@ printDeclaration (Declaration name args body) =
498
529
locals expr' =
499
530
case expr' of
500
531
SetLocal name _ -> [F. s name]
501
- Sequence exprs -> concatMap locals $ NE. toList exprs
532
+ Sequence _ exprs -> concatMap locals $ NE. toList exprs
502
533
If expr expr' mexpr ->
503
534
locals expr <> locals expr' <> maybe [] locals mexpr
504
535
Call _ exprs -> concatMap locals exprs
0 commit comments