reuse string lits
This commit is contained in:
@@ -50,6 +50,9 @@ import Control.Lens.Unsound
|
|||||||
import qualified Data.Bits
|
import qualified Data.Bits
|
||||||
import qualified GHC.IO.Encoding as T
|
import qualified GHC.IO.Encoding as T
|
||||||
import qualified Data.Text.Encoding as T
|
import qualified Data.Text.Encoding as T
|
||||||
|
import Data.HashMap.Strict (HashMap)
|
||||||
|
import Effectful.State.Static.Local
|
||||||
|
import qualified Data.HashMap.Strict as HM
|
||||||
|
|
||||||
|
|
||||||
data Val
|
data Val
|
||||||
@@ -277,18 +280,23 @@ lowerInt = QBE.ValConst . QBE.CInt
|
|||||||
. fromIntegral
|
. fromIntegral
|
||||||
|
|
||||||
lowerString
|
lowerString
|
||||||
:: forall es. (GenSym :> es, Writer (Vector QBE.DataDef) :> es)
|
:: forall es. (GenSym :> es, State StringLiterals :> es)
|
||||||
=> Text -> (QBE.Val -> Eff es BlockBuilder) -> Eff es BlockBuilder
|
=> Text -> (QBE.Val -> Eff es BlockBuilder) -> Eff es BlockBuilder
|
||||||
lowerString s k = do
|
lowerString s k = do
|
||||||
rawString <- gensym
|
let len = lengthOf each $ T.encodeUtf8 s
|
||||||
|
rawString <- getRawString
|
||||||
r <- gensym
|
r <- gensym
|
||||||
let bs = T.encodeUtf8 s
|
|
||||||
len = lengthOf each bs
|
|
||||||
tell . pure $
|
|
||||||
QBE.DataDef [] rawString Nothing
|
|
||||||
[QBE.FieldExtTy QBE.Byte [QBE.String bs]]
|
|
||||||
Emit (alloc r rawString len) <$> k (QBE.ValTemporary r)
|
Emit (alloc r rawString len) <$> k (QBE.ValTemporary r)
|
||||||
where
|
where
|
||||||
|
-- getRawString
|
||||||
|
-- :: forall es. (GenSym :> es, State StringLiterals :> es)
|
||||||
|
-- => Eff es _
|
||||||
|
getRawString = do
|
||||||
|
x <- get
|
||||||
|
case x ^. at s of
|
||||||
|
Just s' -> pure s'
|
||||||
|
Nothing -> do r <- gensym
|
||||||
|
state \lits -> (r, HM.insert s r lits)
|
||||||
alloc r rs len =
|
alloc r rs len =
|
||||||
[ QBE.Call
|
[ QBE.Call
|
||||||
(Just (r, QBE.AbiBaseTy QBE.Long))
|
(Just (r, QBE.AbiBaseTy QBE.Long))
|
||||||
@@ -302,8 +310,10 @@ lowerString s k = do
|
|||||||
[]
|
[]
|
||||||
]
|
]
|
||||||
|
|
||||||
|
type StringLiterals = HashMap Text (QBE.Ident QBE.Global)
|
||||||
|
|
||||||
lowerVal
|
lowerVal
|
||||||
:: forall es. (GenSym :> es, Writer (Vector QBE.DataDef) :> es)
|
:: forall es. (GenSym :> es, State StringLiterals :> es)
|
||||||
=> Val
|
=> Val
|
||||||
-> (QBE.Val -> Eff es BlockBuilder)
|
-> (QBE.Val -> Eff es BlockBuilder)
|
||||||
-> Eff es BlockBuilder
|
-> Eff es BlockBuilder
|
||||||
@@ -353,7 +363,7 @@ sizeofScm :: Integral a => a
|
|||||||
sizeofScm = 8
|
sizeofScm = 8
|
||||||
|
|
||||||
lowerCons
|
lowerCons
|
||||||
:: (GenSym :> es, Writer (Vector QBE.DataDef) :> es)
|
:: (GenSym :> es, State StringLiterals :> es)
|
||||||
=> Name -> QBE.Val -> QBE.Val -> Exp
|
=> Name -> QBE.Val -> QBE.Val -> Exp
|
||||||
-> (QBE.Val -> Eff es BlockBuilder)
|
-> (QBE.Val -> Eff es BlockBuilder)
|
||||||
-> Eff es BlockBuilder
|
-> Eff es BlockBuilder
|
||||||
@@ -442,7 +452,7 @@ smallIntMask :: Integer
|
|||||||
smallIntMask = 2 ^ (sizeofScm * 8) - 2
|
smallIntMask = 2 ^ (sizeofScm * 8) - 2
|
||||||
|
|
||||||
lowerCar
|
lowerCar
|
||||||
:: (GenSym :> es, Writer (Vector QBE.DataDef) :> es)
|
:: (GenSym :> es, State StringLiterals :> es)
|
||||||
=> Name -> QBE.Val -> _
|
=> Name -> QBE.Val -> _
|
||||||
-> (QBE.Val -> Eff es BlockBuilder) -> Eff es BlockBuilder
|
-> (QBE.Val -> Eff es BlockBuilder) -> Eff es BlockBuilder
|
||||||
lowerCar r x e k = do
|
lowerCar r x e k = do
|
||||||
@@ -451,7 +461,7 @@ lowerCar r x e k = do
|
|||||||
<$> lower' e k
|
<$> lower' e k
|
||||||
|
|
||||||
lowerCdr
|
lowerCdr
|
||||||
:: (GenSym :> es, Writer (Vector QBE.DataDef) :> es)
|
:: (GenSym :> es, State StringLiterals :> es)
|
||||||
=> Name -> QBE.Val -> Exp
|
=> Name -> QBE.Val -> Exp
|
||||||
-> (QBE.Val -> Eff es BlockBuilder) -> Eff es BlockBuilder
|
-> (QBE.Val -> Eff es BlockBuilder) -> Eff es BlockBuilder
|
||||||
lowerCdr r x e k = do
|
lowerCdr r x e k = do
|
||||||
@@ -472,7 +482,7 @@ lowerNewline r k =
|
|||||||
<$> k (QBE.ValTemporary (lowerName r))
|
<$> k (QBE.ValTemporary (lowerName r))
|
||||||
|
|
||||||
lowerPrim
|
lowerPrim
|
||||||
:: forall es. (GenSym :> es, Writer (Vector QBE.DataDef) :> es)
|
:: forall es. (GenSym :> es, State StringLiterals :> es)
|
||||||
=> Name -> Prim Val -> Exp
|
=> Name -> Prim Val -> Exp
|
||||||
-> (QBE.Val -> Eff es BlockBuilder)
|
-> (QBE.Val -> Eff es BlockBuilder)
|
||||||
-> Eff es BlockBuilder
|
-> Eff es BlockBuilder
|
||||||
@@ -491,7 +501,7 @@ lowerPrim r p e k =
|
|||||||
PrimNewline -> lowerNewline r k
|
PrimNewline -> lowerNewline r k
|
||||||
|
|
||||||
lower'
|
lower'
|
||||||
:: forall es. (GenSym :> es, Writer (Vector QBE.DataDef) :> es)
|
:: forall es. (GenSym :> es, State StringLiterals :> es)
|
||||||
=> Exp
|
=> Exp
|
||||||
-> (QBE.Val -> Eff es BlockBuilder)
|
-> (QBE.Val -> Eff es BlockBuilder)
|
||||||
-> Eff es BlockBuilder
|
-> Eff es BlockBuilder
|
||||||
@@ -517,12 +527,17 @@ lower' (ExpBegin (x:xs)) k = fold1 <$> traverse low (x:|xs)
|
|||||||
lower' _ k = _
|
lower' _ k = _
|
||||||
|
|
||||||
lower
|
lower
|
||||||
:: (GenSym :> es, Writer (Vector QBE.DataDef) :> es)
|
:: (GenSym :> es, State StringLiterals :> es)
|
||||||
=> QBE.Ident QBE.Label
|
=> QBE.Ident QBE.Label
|
||||||
-> Exp
|
-> Exp
|
||||||
-> Eff es QBE.Block
|
-> Eff es QBE.Block
|
||||||
lower n e = buildBlock n <$> lower' e (pure . Exit . QBE.Ret . Just)
|
lower n e = buildBlock n <$> lower' e (pure . Exit . QBE.Ret . Just)
|
||||||
|
|
||||||
|
lowerStringLiterals =
|
||||||
|
ifoldMapOf itraversed \s v ->
|
||||||
|
[ QBE.DataDef [] v Nothing
|
||||||
|
[QBE.FieldExtTy QBE.Byte [QBE.String (T.encodeUtf8 s)]]]
|
||||||
|
|
||||||
lowerProgram
|
lowerProgram
|
||||||
:: (GenSym :> es, Traversable t)
|
:: (GenSym :> es, Traversable t)
|
||||||
=> t Exp -> Eff es QBE.Program
|
=> t Exp -> Eff es QBE.Program
|
||||||
@@ -531,17 +546,18 @@ lowerProgram anfs =
|
|||||||
-- hack for dev convenience: if there's only one expression, let
|
-- hack for dev convenience: if there's only one expression, let
|
||||||
-- it be the entry point.
|
-- it be the entry point.
|
||||||
[e] -> do
|
[e] -> do
|
||||||
(b,dataDefs) <- runWriter . lower "start" $ e
|
(b,stringLits) <- runState mempty . lower "start" $ e
|
||||||
let f = wrapFunction @NonEmpty "main" [b]
|
let f = wrapFunction @NonEmpty "main" [b]
|
||||||
pure $ QBE.Program [] (dataDefs ^.. each) [f]
|
dataDefs = lowerStringLiterals stringLits
|
||||||
|
pure $ QBE.Program [] dataDefs [f]
|
||||||
_ -> do
|
_ -> do
|
||||||
let low e = do
|
let low e = do
|
||||||
bl <- gensym' "b"
|
bl <- gensym' "b"
|
||||||
fl <- gensym' "f"
|
fl <- gensym' "f"
|
||||||
b <- lower bl e
|
b <- lower bl e
|
||||||
pure $ wrapFunction @NonEmpty fl [b]
|
pure $ wrapFunction @NonEmpty fl [b]
|
||||||
(fs,dataDefs) <- runWriter $ traverse low anfs
|
(fs,stringLits) <- runState mempty $ traverse low anfs
|
||||||
pure $ QBE.Program [] (dataDefs ^.. each) (fs ^.. traversed)
|
pure $ QBE.Program [] (lowerStringLiterals stringLits) (fs ^.. traversed)
|
||||||
|
|
||||||
wrapFunction
|
wrapFunction
|
||||||
:: Foldable1 t
|
:: Foldable1 t
|
||||||
|
|||||||
@@ -193,7 +193,7 @@ impl std::hash::Hash for Symbol {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn make_symbol_off_heap (name : scm_bits) -> Symbol {
|
fn make_symbol_off_heap (name : scm_bits) -> Symbol {
|
||||||
Symbol ([ tc7_symbol, name ])
|
Symbol ([ tc7_symbol, name ])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +0,0 @@
|
|||||||
use gyehoek::scm::*;
|
|
||||||
|
|
||||||
pub fn main () {
|
|
||||||
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user