|
| 1 | +(* |
| 2 | + * Copyright (c) 2025 ARATA Mizuki |
| 3 | + * This file is part of LunarML. |
| 4 | + *) |
| 5 | +structure AlbireoEmit :> sig |
| 6 | +val emit : AlbireoSyntax.dec list -> string |
| 7 | +end = struct |
| 8 | +structure S = AlbireoSyntax |
| 9 | +fun emitHeapTy S.HT_ANY = "any" |
| 10 | + | emitHeapTy S.HT_I31 = "i31" |
| 11 | + | emitHeapTy S.HT_EXTERN = "extern" |
| 12 | +fun emitTy S.I32 = "i32" |
| 13 | + | emitTy S.I64 = "i64" |
| 14 | + | emitTy S.F32 = "f32" |
| 15 | + | emitTy S.F64 = "f64" |
| 16 | + | emitTy S.V128 = "v128" |
| 17 | + | emitTy (S.REF { nullable, to }) = |
| 18 | + if nullable then |
| 19 | + "(ref null " ^ emitHeapTy to ^ ")" |
| 20 | + else |
| 21 | + "(ref " ^ emitHeapTy to ^ ")" |
| 22 | +fun compileExp (S.IntConstExp (i, SOME S.IT_64)) = ["i64.const " ^ CharVector.map (fn #"~" => #"-" | c => c) (Int.toString i)] |
| 23 | + | compileExp (S.IntConstExp (i, _)) = ["i32.const " ^ CharVector.map (fn #"~" => #"-" | c => c) (Int.toString i)] |
| 24 | + | compileExp (S.VarExp id) = ["local.get $" ^ id] |
| 25 | + | compileExp (S.BinExp (p, a, b)) = |
| 26 | + let val insn = case p of |
| 27 | + S.PlusOp => "i32.add" |
| 28 | + | S.MinusOp => "i32.sub" |
| 29 | + | S.TimesOp => "i32.mul" |
| 30 | + | S.DivOp => "i32.div_s" |
| 31 | + in compileExp a @ compileExp b @ [insn] |
| 32 | + end |
| 33 | +fun emitDec (S.FuncDec { name, params, results, body }) = |
| 34 | + let val name' = "(export \"" ^ name ^ "\")" |
| 35 | + val params' = List.map (fn (id, ty) => "(param $" ^ id ^ " " ^ emitTy ty ^ ")") params |
| 36 | + val results' = List.map (fn ty => "(result " ^ emitTy ty ^ ")") results |
| 37 | + val body' = case body of |
| 38 | + [S.ReturnStat exps] => List.concat (List.map compileExp exps) @ ["return"] |
| 39 | + | _ => raise Fail "unsupported function body" |
| 40 | + in "(func " ^ name' ^ "\n" ^ String.concatWith "\n" (params' @ results' @ body') ^ ")" |
| 41 | + end |
| 42 | +fun emit decs = "(module\n" ^ String.concatWith "\n" (List.map emitDec decs) ^ ")" |
| 43 | +end; |
0 commit comments