introduce declaration+implementation mechanic for mutual recursive functions definitions
This commit is contained in:
@@ -17,7 +17,7 @@
|
|||||||
module Language.Wasm.Builder (
|
module Language.Wasm.Builder (
|
||||||
GenMod,
|
GenMod,
|
||||||
genMod,
|
genMod,
|
||||||
global, typedef, fun, funRec, table, memory, dataSegment,
|
global, typedef, fun, funRec, declare, implement, table, memory, dataSegment,
|
||||||
importFunction, importGlobal, importMemory, importTable,
|
importFunction, importGlobal, importMemory, importTable,
|
||||||
export,
|
export,
|
||||||
nextFuncIndex, setGlobalInitializer,
|
nextFuncIndex, setGlobalInitializer,
|
||||||
@@ -613,6 +613,29 @@ funRec res generator = do
|
|||||||
fun :: (Returnable res) => res -> GenFun res -> GenMod (Fn res)
|
fun :: (Returnable res) => res -> GenFun res -> GenMod (Fn res)
|
||||||
fun res = funRec res . const
|
fun res = funRec res . const
|
||||||
|
|
||||||
|
declare :: (Returnable res) => res -> [ValueType] -> GenMod (Fn res)
|
||||||
|
declare res args = do
|
||||||
|
st@GenModState { target = m@Module { types, functions }, funcIdx } <- get
|
||||||
|
let t = FuncType args (asResultValue res)
|
||||||
|
let (idx, inserted) = Maybe.fromMaybe (length types, types ++ [t]) $ (\i -> (i, types)) <$> List.findIndex (== t) types
|
||||||
|
put $ st {
|
||||||
|
target = m { functions = functions ++ [Function (fromIntegral idx) [] []], types = inserted },
|
||||||
|
funcIdx = funcIdx + 1
|
||||||
|
}
|
||||||
|
return $ Fn funcIdx
|
||||||
|
|
||||||
|
implement :: (Returnable res) => Fn res -> GenFun res -> GenMod (Fn res)
|
||||||
|
implement (Fn funcIdx) generator = do
|
||||||
|
st@GenModState { target = m@Module { types, functions, imports } } <- get
|
||||||
|
let FuncDef { args, locals, instrs } = execState (runReaderT generator 0) $ FuncDef [] [] [] []
|
||||||
|
let locIdx = fromIntegral funcIdx - (length $ filter isFuncImport imports)
|
||||||
|
let (l, inst : r) = splitAt locIdx functions
|
||||||
|
let typeIdx = funcType inst
|
||||||
|
let FuncType ps _ = types !! fromIntegral typeIdx
|
||||||
|
if args /= ps then error "Arguments list in implementation doesn't match with declared type" else return ()
|
||||||
|
put $ st { target = m { functions = l ++ [Function typeIdx locals instrs] ++ r } }
|
||||||
|
return $ Fn funcIdx
|
||||||
|
|
||||||
nextFuncIndex :: GenMod Natural
|
nextFuncIndex :: GenMod Natural
|
||||||
nextFuncIndex = gets funcIdx
|
nextFuncIndex = gets funcIdx
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user