-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathEModule.hs
63 lines (54 loc) · 2.15 KB
/
EModule.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE RecordWildCards #-}
module EModule where
-- hp
import qualified Data.ByteString as B
import Data.Int
-- 3rd party
import Data.Generics.Uniplate.Data
import Data.Vector (Vector)
import qualified Data.Vector as V
-- this project
import AtomTable (AtomTable)
import qualified AtomTable as AT
import Beam
import ETerm
data EModule =
EModule
{ emodName :: B.ByteString
, emodModNameAtom :: AtomNo
, emodCode :: Code
, emodImports :: Vector (AtomNo {- mod -}, AtomNo {- fun -}, Arity)
, emodExports :: [(AtomNo {- fun -}, Arity, Int32 {- label -})]
, emodLabelToIp :: [(Int32, Int)]
, emodLiteralTable :: [Literal]
, emodFunctions :: [Lambda]
} deriving (Show)
newtype Code = Code { unCode :: Vector Op }
instance Show Code where
show (Code v) = show (V.toList v)
showsPrec i (Code v) = showsPrec i (V.toList v)
showList vs = showList (map unCode vs)
opAtIp :: Code -> Int -> Op
opAtIp (Code v) ix = v V.! ix
makeCode :: [Op] -> Code
makeCode ops = Code (V.fromList ops)
beamToModule :: Beam -> AtomTable -> (EModule, AtomTable, Beam)
beamToModule bm0@(Beam _ new_atom_names0 _ _ _ _ _ _) at = (emod, at', bm')
where
bm'@(Beam modName _ ops _ imps exps lambdas literal) = transformBi updateAtoms bm0
new_atom_names = [ name | AtomName name <- new_atom_names0 ]
at' = AT.merge at (AT.fromList new_atom_names)
emod = EModule
{ emodName = modName
, emodModNameAtom = AT.lookupByName at' modName
, emodCode = makeCode ops
, emodImports = V.fromList [ (emod, fun, arity) | Import emod fun arity <- imps ]
, emodExports = [ (fun, arity, label) | Export fun arity label <- exps ]
, emodLabelToIp = [ (label, ip) | (Label label, ip) <- zip ops [0..] ]
, emodLiteralTable = literal
, emodFunctions = lambdas
}
updateAtoms (AtomNo nr) = AT.lookupByName at' (new_atom_names !! (fromIntegral nr - 1))