From 14137d45008f6914e8165ddf06663c27795d8ce3 Mon Sep 17 00:00:00 2001 From: Marcin Benke Date: Fri, 28 Nov 2025 13:40:09 +0100 Subject: [PATCH 1/3] Rename mid-level IR to Hull --- runsol.sh | 8 +- sol-core.cabal | 8 +- src/Language/{Core.hs => Hull.hs} | 15 +- src/Language/{Core => Hull}/Parser.hs | 92 +++---- src/Language/{Core => Hull}/Types.hs | 2 +- .../EmitCore.hs => Backend/EmitHull.hs} | 228 +++++++++--------- src/Solcore/Pipeline/Options.hs | 18 +- src/Solcore/Pipeline/SolcorePipeline.hs | 22 +- testsol.sh | 50 ++-- yule/Compress.hs | 2 +- yule/Main.hs | 2 +- yule/TM.hs | 26 +- yule/Translate.hs | 28 +-- 13 files changed, 239 insertions(+), 262 deletions(-) rename src/Language/{Core.hs => Hull.hs} (95%) rename src/Language/{Core => Hull}/Parser.hs (60%) rename src/Language/{Core => Hull}/Types.hs (95%) rename src/Solcore/{Desugarer/EmitCore.hs => Backend/EmitHull.hs} (72%) diff --git a/runsol.sh b/runsol.sh index 30abe741..2e710858 100755 --- a/runsol.sh +++ b/runsol.sh @@ -162,19 +162,19 @@ if [[ -n "$create_arguments_sig" ]] && [[ -n "$create_raw_args" ]]; then fi # Execute compilation pipeline -echo "Compiling to core..." +echo "Compiling to hull..." if ! cabal run sol-core -- -f "$file"; then echo "Error: sol-core compilation failed" exit 1 fi mkdir -p build -if ls ./output*.core 1> /dev/null 2>&1; then - mv ./output*.core build/ +if ls ./output*.hull 1> /dev/null 2>&1; then + mv ./output*.hull build/ fi echo "Generating Yul..." -yule_args=("$core" -o "$yulfile") +yule_args=("$hull" -o "$yulfile") if [[ "$create" == "false" ]]; then yule_args+=(--nodeploy) fi diff --git a/sol-core.cabal b/sol-core.cabal index feff8ae7..db1c262a 100644 --- a/sol-core.cabal +++ b/sol-core.cabal @@ -65,7 +65,7 @@ library Solcore.Desugarer.MatchCompiler Solcore.Desugarer.ReplaceWildcard Solcore.Desugarer.Specialise - Solcore.Desugarer.EmitCore + Solcore.Backend.EmitHull Solcore.Desugarer.ContractDispatch Solcore.Desugarer.ReplaceFunTypeArgs Solcore.Desugarer.UniqueTypeGen @@ -97,9 +97,9 @@ library Solcore.Pipeline.Options Solcore.Pipeline.SolcorePipeline Solcore.Primitives.Primitives - Language.Core - Language.Core.Parser - Language.Core.Types + Language.Hull + Language.Hull.Parser + Language.Hull.Types Language.Yul Language.Yul.Parser Language.Yul.QuasiQuote diff --git a/src/Language/Core.hs b/src/Language/Hull.hs similarity index 95% rename from src/Language/Core.hs rename to src/Language/Hull.hs index 13b9c7de..b399a657 100644 --- a/src/Language/Core.hs +++ b/src/Language/Hull.hs @@ -1,15 +1,14 @@ - {-# OPTIONS_GHC -Wincomplete-patterns #-} {-# LANGUAGE InstanceSigs #-} -module Language.Core +module Language.Hull ( Expr(..), Stmt(..), Arg(..), Alt(..), pattern ConAlt, Pat(..), Con(..), Contract(..), Object(..), Body - , module Language.Core.Types + , module Language.Hull.Types , pattern SAV , Name ) where import Common.Pretty -import Language.Core.Types +import Language.Hull.Types import Language.Yul @@ -64,8 +63,8 @@ data Con = CInl | CInr | CInK Int deriving Show data Contract = Contract { ccName :: Name, ccStmts :: [Stmt] } -newtype Core = Core [Stmt] -instance Show Core where show = render . ppr +newtype Hull = Hull [Stmt] +instance Show Hull where show = render . ppr instance Show Contract where show = render . ppr @@ -150,8 +149,8 @@ instance Pretty Con where instance Pretty Arg where ppr (TArg n t) = text n <+> text ":" <+> ppr t -instance Pretty Core where - ppr (Core stmts) = vcat (map ppr stmts) +instance Pretty Hull where + ppr (Hull stmts) = vcat (map ppr stmts) pprBody :: Body -> Doc pprBody stmts = braces $ nest 2 (vcat (map ppr stmts)) diff --git a/src/Language/Core/Parser.hs b/src/Language/Hull/Parser.hs similarity index 60% rename from src/Language/Core/Parser.hs rename to src/Language/Hull/Parser.hs index 98965209..0741d209 100644 --- a/src/Language/Core/Parser.hs +++ b/src/Language/Hull/Parser.hs @@ -1,5 +1,5 @@ -module Language.Core.Parser where -import Language.Core +module Language.Hull.Parser where +import Language.Hull ( Object(..), Body, Alt(..), @@ -17,7 +17,7 @@ import Language.Yul.Parser(yulBlock) parseObject :: String -> String -> Object -parseObject filename = runMyParser filename coreObject +parseObject filename = runMyParser filename hullObject -- Note: this module repeats some definitions from YulParser.Name -- This is intentional as we may want to make different syntax choices @@ -68,19 +68,19 @@ pKeyword w = try $ lexeme (string w <* notFollowedBy identChar) pPrimaryType :: Parser Type pPrimaryType = choice - [ try $ TNamed <$> identifier <*> braces coreType + [ try $ TNamed <$> identifier <*> braces hullType , TWord <$ pKeyword "word" , TBool <$ pKeyword "bool" , TUnit <$ pKeyword "unit" - , TSumN <$> ( pKeyword "sum" *> parens (commaSep coreType)) - , parens coreType + , TSumN <$> ( pKeyword "sum" *> parens (commaSep hullType)) + , parens hullType ] -coreType :: Parser Type -coreType = makeExprParser pPrimaryType coreTypeTable +hullType :: Parser Type +hullType = makeExprParser pPrimaryType hullTypeTable -coreTypeTable :: [[Operator Parser Type]] -coreTypeTable = [[InfixR (TPair <$ symbol "*")] +hullTypeTable :: [[Operator Parser Type]] +hullTypeTable = [[InfixR (TPair <$ symbol "*")] ,[InfixR (TSum <$ symbol "+")]] pPrimaryExpr :: Parser Expr @@ -89,24 +89,24 @@ pPrimaryExpr = choice , EBool True <$ pKeyword "true" , EBool False <$ pKeyword "false" , pTuple - , try (ECall <$> identifier <*> parens (commaSep coreExpr)) + , try (ECall <$> identifier <*> parens (commaSep hullExpr)) , EVar <$> (identifier <* notFollowedBy (symbol "(")) - , parens coreExpr + , parens hullExpr ] pTuple :: Parser Expr -pTuple = go <$> parens (commaSep coreExpr) where +pTuple = go <$> parens (commaSep hullExpr) where go [] = EUnit go [e] = e go [e1, e2] = EPair e1 e2 go (e:es) = EPair e (go es) -coreExpr :: Parser Expr -coreExpr = choice - [ pKeyword "inl" *> (EInl <$> angles coreType <*> pPrimaryExpr) - , pKeyword "inr" *> (EInr <$> angles coreType <*> pPrimaryExpr) - , pKeyword "in" *> (EInK <$> parens int <*> coreType <*> pPrimaryExpr) +hullExpr :: Parser Expr +hullExpr = choice + [ pKeyword "inl" *> (EInl <$> angles hullType <*> pPrimaryExpr) + , pKeyword "inr" *> (EInr <$> angles hullType <*> pPrimaryExpr) + , pKeyword "in" *> (EInK <$> parens int <*> hullType <*> pPrimaryExpr) , pKeyword "fst" *> (EFst <$> pPrimaryExpr) , pKeyword "snd" *> (ESnd <$> pPrimaryExpr) , condExpr @@ -115,40 +115,40 @@ coreExpr = choice condExpr = do pKeyword "if" - t <- angles coreType - e1 <- coreExpr + t <- angles hullType + e1 <- hullExpr pKeyword "then" - e2 <- coreExpr + e2 <- hullExpr pKeyword "else" - e3 <- coreExpr + e3 <- hullExpr pure (ECond t e1 e2 e3) -coreStmt :: Parser Stmt -coreStmt = choice - [ SAlloc <$> (pKeyword "let" *> identifier) <*> (symbol ":" *> coreType) - , SReturn <$> (pKeyword "return" *> coreExpr) - , SBlock <$> braces(many coreStmt) - , SMatch <$> (pKeyword "match" *> angles coreType) <*> (coreExpr <* pKeyword "with") <*> braces(many coreAlt) - -- , SMatch <$> (pKeyword "match" *> coreExpr <* pKeyword "with") <*> (symbol "{" *> many coreAlt <* symbol "}") - , SFunction <$> (pKeyword "function" *> identifier) <*> (parens (commaSep coreArg)) <*> (symbol "->" *> coreType) - <*> coreBody +hullStmt :: Parser Stmt +hullStmt = choice + [ SAlloc <$> (pKeyword "let" *> identifier) <*> (symbol ":" *> hullType) + , SReturn <$> (pKeyword "return" *> hullExpr) + , SBlock <$> braces(many hullStmt) + , SMatch <$> (pKeyword "match" *> angles hullType) <*> (hullExpr <* pKeyword "with") <*> braces(many hullAlt) + -- , SMatch <$> (pKeyword "match" *> hullExpr <* pKeyword "with") <*> (symbol "{" *> many hullAlt <* symbol "}") + , SFunction <$> (pKeyword "function" *> identifier) <*> (parens (commaSep hullArg)) <*> (symbol "->" *> hullType) + <*> hullBody , SAssembly <$> (pKeyword "assembly" *> yulBlock) , SRevert <$> (pKeyword "revert" *> stringLiteral) - , try (SAssign <$> (coreExpr <* symbol ":=") <*> coreExpr) - , SExpr <$> coreExpr + , try (SAssign <$> (hullExpr <* symbol ":=") <*> hullExpr) + , SExpr <$> hullExpr ] -coreBody :: Parser Body -coreBody = braces(many coreStmt) +hullBody :: Parser Body +hullBody = braces(many hullStmt) -coreArg :: Parser Arg -coreArg = TArg <$> identifier <*> (symbol ":" *> coreType) +hullArg :: Parser Arg +hullArg = TArg <$> identifier <*> (symbol ":" *> hullType) -coreAlt :: Parser Alt -coreAlt = Alt <$> corePat <*> identifier <* symbol "=>" <*> coreBody +hullAlt :: Parser Alt +hullAlt = Alt <$> hullPat <*> identifier <* symbol "=>" <*> hullBody -corePat :: Parser Pat -corePat = choice +hullPat :: Parser Pat +hullPat = choice [ PIntLit <$> integer , PCon CInl <$ pKeyword "inl" , PCon CInr <$ pKeyword "inr" @@ -157,9 +157,9 @@ corePat = choice , PWildcard <$ pKeyword "_" ] -coreObject :: Parser Object -coreObject = sc *> (Object <$> (pKeyword "object" *> identifier <* symbol "{") - <*> coreCode <*> many coreObject) <* symbol "}" +hullObject :: Parser Object +hullObject = sc *> (Object <$> (pKeyword "object" *> identifier <* symbol "{") + <*> hullCode <*> many hullObject) <* symbol "}" -coreCode :: Parser Body -coreCode = sc *> (Object <$> pKeyword "code" *> coreBody) +hullCode :: Parser Body +hullCode = sc *> (Object <$> pKeyword "code" *> hullBody) diff --git a/src/Language/Core/Types.hs b/src/Language/Hull/Types.hs similarity index 95% rename from src/Language/Core/Types.hs rename to src/Language/Hull/Types.hs index 8e6c93d7..0758333c 100644 --- a/src/Language/Core/Types.hs +++ b/src/Language/Hull/Types.hs @@ -1,4 +1,4 @@ -module Language.Core.Types where +module Language.Hull.Types where data Type = TWord diff --git a/src/Solcore/Desugarer/EmitCore.hs b/src/Solcore/Backend/EmitHull.hs similarity index 72% rename from src/Solcore/Desugarer/EmitCore.hs rename to src/Solcore/Backend/EmitHull.hs index f1ec0721..1b317a84 100644 --- a/src/Solcore/Desugarer/EmitCore.hs +++ b/src/Solcore/Backend/EmitHull.hs @@ -1,6 +1,6 @@ -module Solcore.Desugarer.EmitCore(emitCore) where +module Solcore.Backend.EmitHull(emitHull) where import Prelude hiding(catch, product) -import Language.Core qualified as Core +import Language.Hull qualified as Hull import Data.Map qualified as Map import Common.Monad import Control.Monad(when, unless) @@ -21,8 +21,8 @@ import Solcore.Primitives.Primitives import Solcore.Desugarer.Specialise(typeOfTcExp) import System.Exit -emitCore :: Bool -> TcEnv -> CompUnit Id -> IO [Core.Object] -emitCore debugp env cu = fmap concat $ runEM debugp env $ mapM emitTopDecl (contracts cu) +emitHull :: Bool -> TcEnv -> CompUnit Id -> IO [Hull.Object] +emitHull debugp env cu = fmap concat $ runEM debugp env $ mapM emitTopDecl (contracts cu) type EM a = StateT EcState IO a runEM :: Bool -> TcEnv -> EM a -> IO a @@ -35,7 +35,7 @@ errorsEM msgs = do let msg = concat msgs let contextStr = unlines (map ("in: "++) context) writeln contextStr - error "Emit core failed" -- this can be exitFailure eventually + error "Emit hull failed" -- this can be exitFailure eventually data EcState = EcState { ecSubst :: VSubst @@ -43,7 +43,7 @@ data EcState = EcState , ecNest :: Int , ecDebug :: Bool , ecContext :: [String] -- for error handling - , ecDeployer :: Maybe Core.Body + , ecDeployer :: Maybe Hull.Body } initEcState :: Bool -> TcEnv -> EcState @@ -80,7 +80,7 @@ sumDataTy = DataTy builtinDataInfo = [ ("sum", sumDataTy) ] -type VSubst = Map.Map Name Core.Expr +type VSubst = Map.Map Name Hull.Expr emptyVSubst :: VSubst emptyVSubst = Map.empty @@ -101,11 +101,11 @@ withContext s m = pushContext s *> m <* dropContext inContext :: EM a -> String -> EM a inContext = flip withContext -type Translation a = EM (a, [Core.Stmt]) +type Translation a = EM (a, [Hull.Stmt]) -type CoreName = String +type HullName = String -emitTopDecl :: TopDecl Id -> EM [Core.Object] +emitTopDecl :: TopDecl Id -> EM [Hull.Object] emitTopDecl (TContr c) = withLocalState do runtimeObj <- emitContract c pure [runtimeObj] @@ -120,24 +120,24 @@ buildTConInfo :: DataTy -> TConInfo buildTConInfo (DataTy n tvs dcs) = (tvs, map conInfo dcs) where conInfo (Constr n ts) = (n, ts) -} -emitContract :: Contract Id -> EM Core.Object +emitContract :: Contract Id -> EM Hull.Object emitContract c = do let cname = show (name c) - writes ["Emitting core for contract ", cname] + writes ["Emitting hull for contract ", cname] runtimeBody <- concatMapM emitCDecl (decls c) deployer <- gets ecDeployer case deployer of - Nothing -> pure(Core.Object cname runtimeBody []) - Just code -> let runtimeObject = Core.Object cname runtimeBody [] - in pure(Core.Object (cname++"Deploy") code [runtimeObject] ) -emitCDecl :: ContractDecl Id -> EM [Core.Stmt] + Nothing -> pure(Hull.Object cname runtimeBody []) + Just code -> let runtimeObject = Hull.Object cname runtimeBody [] + in pure(Hull.Object (cname++"Deploy") code [runtimeObject] ) +emitCDecl :: ContractDecl Id -> EM [Hull.Stmt] emitCDecl cd@(CFunDecl f) = do -- debug ["!! emitCDecl ", show cd] emitFunDef f emitCDecl (CMutualDecl ds) = case findConstructor ds of Nothing -> do body <- concatMapM emitCDecl ds - pure [Core.SBlock body] + pure [Hull.SBlock body] Just _ -> do -- this is the deployer block depDecls <- concatMapM emitCDecl ds modify (\s -> s { ecDeployer = Just depDecls}) @@ -158,27 +158,27 @@ findConstructor = go where ----------------------------------------------------------------------- -- Translating function definitions ----------------------------------------------------------------------- -emitFunDef :: HasCallStack => FunDef Id -> EM [Core.Stmt] +emitFunDef :: HasCallStack => FunDef Id -> EM [Hull.Stmt] emitFunDef fd@(FunDef sig body) = withContext (shortName fd) do (name, args, typ) <- translateSig sig `inContext` ("function signature " ++ pretty sig) debug ["\n# emitFunDef ", name, " :: ", show typ] - coreBody <- emitStmts body - let coreFun = Core.SFunction name args typ coreBody + hullBody <- emitStmts body + let hullFun = Hull.SFunction name args typ hullBody dropContext - return [coreFun] + return [hullFun] -translateSig :: HasCallStack => Signature Id -> EM (CoreName, [Core.Arg], Core.Type) +translateSig :: HasCallStack => Signature Id -> EM (HullName, [Hull.Arg], Hull.Type) translateSig sig@(Signature vs ctxt n args (Just ret)) = do dataTable <- gets ecDT -- debug ["translateSig ", show sig] let name = show n - coreTyp <- translateType ret - coreArgs <- mapM translateArg args - return (name, coreArgs, coreTyp) + hullTyp <- translateType ret + hullArgs <- mapM translateArg args + return (name, hullArgs, hullTyp) translateSig sig = errorsEM ["No return type in ", show sig] -translateArg :: Param Id -> EM Core.Arg -translateArg p = Core.TArg (show n) <$> translateType t +translateArg :: Param Id -> EM Hull.Arg +translateArg p = Hull.TArg (show n) <$> translateType t where Id n t = getParamId p getParamId :: Param Id -> Id @@ -189,16 +189,16 @@ getParamId (Untyped i) = i -- Translating types and value constructors ----------------------------------------------------------------------- -translateType :: HasCallStack => Ty -> EM Core.Type -translateType (TyCon "word" []) = pure Core.TWord --- translateType _ Fun.TBool = Core.TBool -translateType (TyCon "unit" []) = pure Core.TUnit -translateType (TyCon "()" []) = pure Core.TUnit +translateType :: HasCallStack => Ty -> EM Hull.Type +translateType (TyCon "word" []) = pure Hull.TWord +-- translateType _ Fun.TBool = Hull.TBool +translateType (TyCon "unit" []) = pure Hull.TUnit +translateType (TyCon "()" []) = pure Hull.TUnit translateType t@(u :-> v) = errorsEM ["Cannot translate function type ", show t] translateType (TyCon name tas) = translateTCon name tas translateType t = errorsEM ["Cannot translate type ", show t] -translateTCon :: Name -> [Ty] -> EM Core.Type +translateTCon :: Name -> [Ty] -> EM Hull.Type -- NB "pair" is used for all tuples translateTCon (Name "pair") tas = translateProductType tas translateTCon tycon tas = do @@ -207,41 +207,41 @@ translateTCon tycon tas = do Just (DataTy n tvs cs) -> do let subst = zip tvs tas tys <- mapM (translateDCon subst) cs - Core.TNamed (show tycon) <$> buildSumType tys + Hull.TNamed (show tycon) <$> buildSumType tys Nothing -> errorsEM ["translateTCon: unknown type ", pretty tycon, "\n", show tycon] where - buildSumType :: [Core.Type] -> EM Core.Type - buildSumType [] = errorsEM ["empty sum ", pretty tycon] -- Core.TUnit - buildSumType ts = pure(foldr1 Core.TSum ts) + buildSumType :: [Hull.Type] -> EM Hull.Type + buildSumType [] = errorsEM ["empty sum ", pretty tycon] -- Hull.TUnit + buildSumType ts = pure(foldr1 Hull.TSum ts) -translateDCon :: [(Tyvar, Ty)] -> Constr -> EM Core.Type +translateDCon :: [(Tyvar, Ty)] -> Constr -> EM Hull.Type translateDCon subst (Constr name tas) = translateProductType (insts subst tas) -translateProductType :: [Ty] -> EM Core.Type -translateProductType [] = pure Core.TUnit -translateProductType ts = foldr1 Core.TPair <$> mapM translateType ts +translateProductType :: [Ty] -> EM Hull.Type +translateProductType [] = pure Hull.TUnit +translateProductType ts = foldr1 Hull.TPair <$> mapM translateType ts -emitLit :: Literal -> Core.Expr -emitLit (IntLit i) = Core.EWord i +emitLit :: Literal -> Hull.Expr +emitLit (IntLit i) = Hull.EWord i emitLit (StrLit s) = error "String literals not supported yet" -emitConApp :: Id -> [Exp Id] -> Translation Core.Expr +emitConApp :: Id -> [Exp Id] -> Translation Hull.Expr emitConApp con@(Id n ty) as = do unless (null . fv $ argTypes ty) (errors ["emitConApp: free variables in type ", pretty ty, " in ", pretty (Con con as)]) -- check for free type vars only in args because of phantom types such as Proxy(a) = Proxy case targetType ty of - (TyCon "unit" []) -> pure (Core.EUnit, []) - (TyCon "()" []) -> pure (Core.EUnit, []) + (TyCon "unit" []) -> pure (Hull.EUnit, []) + (TyCon "()" []) -> pure (Hull.EUnit, []) (TyCon "pair" _) -> translateProduct as (TyCon tcname tas) -> do mti <- gets (Map.lookup tcname . ecDT) case mti of Just (DataTy _ tvs allCons) -> do (prod, code) <- translateProduct as - coreTargetType <- translateTCon tcname tas - let result = encodeCon n allCons coreTargetType prod + hullTargetType <- translateTCon tcname tas + let result = encodeCon n allCons hullTargetType prod pure (result, code) Nothing -> errors [ "emitConApp: unknown type ", pretty tcname @@ -260,22 +260,22 @@ emitConApp con@(Id n ty) as = do argTypes (u :-> v) = u : argTypes v argTypes t = [] -translateProduct :: [Exp Id] -> Translation Core.Expr -translateProduct [] = pure (Core.EUnit, []) +translateProduct :: [Exp Id] -> Translation Hull.Expr +translateProduct [] = pure (Hull.EUnit, []) translateProduct es = do - (coreExps, codes) <- unzip <$> mapM emitExp es - let product = foldr1 (Core.EPair) coreExps + (hullExps, codes) <- unzip <$> mapM emitExp es + let product = foldr1 (Hull.EPair) hullExps pure (product, concat codes) -encodeCon :: Name ->[Constr] -> Core.Type -> Core.Expr -> Core.Expr +encodeCon :: Name ->[Constr] -> Hull.Type -> Hull.Expr -> Hull.Expr encodeCon n [c] _ e | constrName c == n = e -encodeCon n cs (Core.TNamed l t) e = label l (encodeCon n cs t e) -- this will change when we compress tags - where label l (Core.EInl t e) = Core.EInl (Core.TNamed l t) e - label l (Core.EInr t e) = Core.EInr (Core.TNamed l t) e +encodeCon n cs (Hull.TNamed l t) e = label l (encodeCon n cs t e) -- this will change when we compress tags + where label l (Hull.EInl t e) = Hull.EInl (Hull.TNamed l t) e + label l (Hull.EInr t e) = Hull.EInr (Hull.TNamed l t) e label l e = e -encodeCon n (con:cons) t@(Core.TSum t1 t2) e - | constrName con == n = Core.EInl t e - | otherwise = Core.EInr t (encodeCon n cons t2 e) +encodeCon n (con:cons) t@(Hull.TSum t1 t2) e + | constrName con == n = Hull.EInl t e + | otherwise = Hull.EInr t (encodeCon n cons t2 e) encodeCon n cons t e = errors [ "encodeCon: no match for ", pretty t , "\n", show t @@ -284,63 +284,63 @@ encodeCon n cons t e = errors -- Translating expressions and statements ----------------------------------------------------------------------- -emitExp :: Exp Id -> Translation Core.Expr +emitExp :: Exp Id -> Translation Hull.Expr emitExp (Lit l) = pure (emitLit l, []) emitExp (Var x) = do subst <- gets ecSubst case Map.lookup (idName x) subst of Just e -> pure (e, []) - Nothing -> pure (Core.EVar (unwrapId x), []) + Nothing -> pure (Hull.EVar (unwrapId x), []) -- special handling of revert -emitExp (Call _ (Id "revert" _) [Lit(StrLit s)]) = pure(Core.EUnit, [Core.SRevert s]) +emitExp (Call _ (Id "revert" _) [Lit(StrLit s)]) = pure(Hull.EUnit, [Hull.SRevert s]) emitExp (Call Nothing f as) = do - (coreArgs, codes) <- unzip <$> mapM emitExp as - let call = Core.ECall (unwrapId f) coreArgs + (hullArgs, codes) <- unzip <$> mapM emitExp as + let call = Hull.ECall (unwrapId f) hullArgs pure (call, concat codes) emitExp e@(Con i as) = emitConApp i as emitExp (TyExp e _) = emitExp e emitExp (Cond e1 e2 e3) = do let ty = typeOfTcExp e3 - coreTy <- translateType ty + hullTy <- translateType ty (ce1, code1) <- emitExp e1 (ce2, code2) <- emitExp e2 (ce3, code3) <- emitExp e3 - pure (Core.ECond coreTy ce1 ce2 ce3, code1 <> code2 <> code3) + pure (Hull.ECond hullTy ce1 ce2 ce3, code1 <> code2 <> code3) emitExp e = errorsEM ["emitExp not implemented for: ", pretty e, "\n", show e] -emitStmt :: Stmt Id -> EM [Core.Stmt] +emitStmt :: Stmt Id -> EM [Hull.Stmt] emitStmt (StmtExp e) = do (e', stmts) <- emitExp e - pure (stmts ++ [Core.SExpr e']) + pure (stmts ++ [Hull.SExpr e']) emitStmt s@(Return e) = do (e', stmts) <- emitExp e - let result = stmts ++ [Core.SReturn e'] - --- debug ["< emitStmt ", show (Core.Core result)] + let result = stmts ++ [Hull.SReturn e'] + --- debug ["< emitStmt ", show (Hull.Hull result)] return result emitStmt (Var i := e) = do (e', stmts) <- emitExp e - let assign = [Core.SAssign (Core.EVar (unwrapId i)) e'] + let assign = [Hull.SAssign (Hull.EVar (unwrapId i)) e'] return (stmts ++ assign) emitStmt (Let (Id name ty) mty mexp ) = do - let coreName = show name - coreTy <- translateType ty - let alloc = [Core.SAlloc coreName coreTy] + let hullName = show name + hullTy <- translateType ty + let alloc = [Hull.SAlloc hullName hullTy] case mexp of Just e -> do (v, estmts) <- emitExp e - let assign = [Core.SAssign (Core.EVar coreName) v] + let assign = [Hull.SAssign (Hull.EVar hullName) v] return (estmts ++ alloc ++ assign) Nothing -> return alloc emitStmt s@(Match [scrutinee] alts) = emitMatch scrutinee alts -emitStmt (Asm ys) = pure [Core.SAssembly ys] +emitStmt (Asm ys) = pure [Hull.SAssembly ys] emitStmt s = errorsEM ["emitStmt not implemented for: ", pretty s, "\n", show s] -emitStmts :: [Stmt Id] -> EM [Core.Stmt] +emitStmts :: [Stmt Id] -> EM [Hull.Stmt] emitStmts = concatMapM emitStmt' where emitStmt' stmt = withContext (pretty stmt) (emitStmt stmt) @@ -365,7 +365,7 @@ General approach to match statement translation: -emitMatch :: Exp Id -> Equations Id -> EM [Core.Stmt] +emitMatch :: Exp Id -> Equations Id -> EM [Hull.Stmt] emitMatch scrutinee alts = do let sty = typeOfTcExp scrutinee @@ -378,7 +378,7 @@ emitMatch scrutinee alts = do "word" -> emitWordMatch scrutinee alts _ -> emitDataMatch scon scrutinee alts -emitDataMatch :: Name -> Exp Id -> Equations Id -> StateT EcState IO [Core.Stmt] +emitDataMatch :: Name -> Exp Id -> Equations Id -> StateT EcState IO [Hull.Stmt] emitDataMatch (Name "pair") scrutinee alts = emitProdMatch scrutinee alts emitDataMatch (Name "()" ) scrutinee alts = emitProdMatch scrutinee alts emitDataMatch scon scrutinee alts = do @@ -390,55 +390,55 @@ emitDataMatch scon scrutinee alts = do [c] -> emitProdMatch scrutinee alts _ -> emitSumMatch allCons scrutinee alts -emitWordMatch :: Exp Id -> Equations Id -> EM [Core.Stmt] +emitWordMatch :: Exp Id -> Equations Id -> EM [Hull.Stmt] emitWordMatch scrutinee alts = do (sVal, sCode) <- emitExp scrutinee - let coreType = Core.TWord - coreAlts <- mapM emitWordAlt alts - return [Core.SMatch coreType sVal coreAlts] + let hullType = Hull.TWord + hullAlts <- mapM emitWordAlt alts + return [Hull.SMatch hullType sVal hullAlts] where - emitWordAlt :: Equation Id -> EM Core.Alt - emitWordAlt ([PLit(IntLit i)], stmts) = Core.Alt (Core.PIntLit i) "$_" <$> emitStmts stmts + emitWordAlt :: Equation Id -> EM Hull.Alt + emitWordAlt ([PLit(IntLit i)], stmts) = Hull.Alt (Hull.PIntLit i) "$_" <$> emitStmts stmts emitWordAlt ([PVar (Id n _)], stmts) = do - coreStmts <- emitStmts stmts - let coreName = show n - return (Core.Alt (Core.PVar coreName) "$_" coreStmts) + hullStmts <- emitStmts stmts + let hullName = show n + return (Hull.Alt (Hull.PVar hullName) "$_" hullStmts) emitWordAlt (pat, _) = errorsEM ["emitWordAlt not implemented for", show pat] -type BranchMap = Map.Map Name [Core.Stmt] +type BranchMap = Map.Map Name [Hull.Stmt] -emitSumMatch :: [Constr] -> Exp Id -> Equations Id -> EM [Core.Stmt] +emitSumMatch :: [Constr] -> Exp Id -> Equations Id -> EM [Hull.Stmt] emitSumMatch allCons scrutinee alts = do (sVal, sCode) <- emitExp scrutinee let sType = typeOfTcExp scrutinee - sCoreType <- translateType sType + sHullType <- translateType sType -- TODO: build branch list in order matching allCons -- by inserting them into a map and then outputting in order -- take default branch from last equation into account - let noMatch c = [Core.SRevert ("no match for: "++ show c)] + let noMatch c = [Hull.SRevert ("no match for: "++ show c)] debug ["emitMatch: allCons ", show allConNames] let defaultBranchMap = Map.fromList [(c, noMatch c) | c <- allConNames] branches <- emitEqns alts let branchMap = foldr insertBranch defaultBranchMap branches let branches = [branchMap Map.! c | c <- allConNames] debug ["emitMatch: branches ", show branches] - let matchCode = buildMatch sVal sCoreType branches + let matchCode = buildMatch sVal sHullType branches return(sCode ++ matchCode) where allConNames = map constrName allCons - insertBranch :: (Pat Id, [Core.Stmt]) -> BranchMap -> BranchMap + insertBranch :: (Pat Id, [Hull.Stmt]) -> BranchMap -> BranchMap insertBranch (PVar (Id n _), stmts) m = Map.fromList [(c, stmts) | c <- allConNames] insertBranch (PCon (Id n _) _, stmts) m = Map.insert n stmts m - emitEqn :: Core.Expr -> Equation Id -> EM (Pat Id, [Core.Stmt]) + emitEqn :: Hull.Expr -> Equation Id -> EM (Pat Id, [Hull.Stmt]) emitEqn expr ([pat], stmts) = withLocalState do let patargs = getPatArgs pat let pvars = translatePatArgs expr patargs extendVSubst pvars - let comment = Core.SComment (pretty pat) - coreStmts <- emitStmts stmts - let coreStmts' = comment : coreStmts - debug ["emitEqn: ", show pat, " / ", show expr, " -> ", show coreStmts'] - return (pat, coreStmts') + let comment = Hull.SComment (pretty pat) + hullStmts <- emitStmts stmts + let hullStmts' = comment : hullStmts + debug ["emitEqn: ", show pat, " / ", show expr, " -> ", show hullStmts'] + return (pat, hullStmts') emitEqn _ _ = error ("emitEqn: multiple patterns should have been desugared by now") getPatArgs(PCon _ patargs) = patargs getPatArgs _ = [] @@ -446,10 +446,10 @@ emitSumMatch allCons scrutinee alts = do -- TODO: emitEqns should process the eqns in constructor declaration order -- e.g. if we have data B = F | T and then match b | T => ... | F => ... -- we should still process the F case first to avoid mixing up inl/inr - emitEqns :: [Equation Id] -> EM [(Pat Id, [Core.Stmt])] - emitEqns [eqn] = (:[]) <$> emitEqn (Core.EVar (altName True)) eqn + emitEqns :: [Equation Id] -> EM [(Pat Id, [Hull.Stmt])] + emitEqns [eqn] = (:[]) <$> emitEqn (Hull.EVar (altName True)) eqn emitEqns (eqn:eqns) = do - b <- emitEqn (Core.EVar (altName False)) eqn + b <- emitEqn (Hull.EVar (altName False)) eqn bs <- emitEqns eqns return (b:bs) @@ -467,24 +467,24 @@ emitSumMatch allCons scrutinee alts = do they can be reused in subsequent branches (no need for unique names as long as they do not clash with user variables) -} - buildMatch :: Core.Expr -> Core.Type ->[[Core.Stmt]] -> [Core.Stmt] + buildMatch :: Hull.Expr -> Hull.Type ->[[Hull.Stmt]] -> [Hull.Stmt] buildMatch _sval sty [] = error "buildMatch: empty branch list" buildMatch sval0 sty branches = go sval0 sty branches where go _sval sty [b] = b -- last branch needs no match - go sval sty (b:bs) = [Core.SMatch sty sval [ alt Core.CInl left b - , alt Core.CInr right (go (Core.EVar right) (rightBranch sty) bs)]] - rightBranch (Core.TSum _ r) = r - rightBranch (Core.TNamed _ t) = rightBranch t + go sval sty (b:bs) = [Hull.SMatch sty sval [ alt Hull.CInl left b + , alt Hull.CInr right (go (Hull.EVar right) (rightBranch sty) bs)]] + rightBranch (Hull.TSum _ r) = r + rightBranch (Hull.TNamed _ t) = rightBranch t rightBranch t = error ("rightBranch: not a sum type: " ++ show t) left = altName False right = altName True - alt con n stmts = Core.ConAlt con n stmts + alt con n stmts = Hull.ConAlt con n stmts -- Would be clearer with $left/$right, but simpler with $alt for now altName False = "$alt" altName True = "$alt" -emitProdMatch :: Exp Id -> Equations Id -> EM [Core.Stmt] +emitProdMatch :: Exp Id -> Equations Id -> EM [Hull.Stmt] emitProdMatch scrutinee (eqn:_) = do (sexpr, scode) <- emitExp scrutinee mcode <- translateSingleEquation sexpr eqn @@ -494,7 +494,7 @@ emitProdMatch scrutinee (eqn:_) = do -- | translateSingleEquation handles the special case for product types -- there is only one match branch, just transform to projections -- takes a translated scrutinee and a single equation -translateSingleEquation :: Core.Expr -> Equation Id -> EM [Core.Stmt] +translateSingleEquation :: Hull.Expr -> Equation Id -> EM [Hull.Stmt] translateSingleEquation expr ([PCon _con patargs], stmts) = withLocalState do let pvars = translatePatArgs expr patargs extendVSubst pvars @@ -506,11 +506,11 @@ translateSingleEquation _ eqn = error $ -- p@(Just x) ~> [x -> p] -- p@(Pair x y) ~> [x -> fst p, y -> snd p] -- p@(Triple x y z) ~> [x -> fst p, y -> fst (snd p), z -> snd (snd p)] -translatePatArgs :: Core.Expr -> [Pat Id] -> VSubst +translatePatArgs :: Hull.Expr -> [Pat Id] -> VSubst translatePatArgs e = Map.fromList . go e where go _ [] = [] go s [PVar i] = [(idName i, s)] - go s (PVar i:as) = let (s1, s2) = (Core.EFst s, Core.ESnd s) in + go s (PVar i:as) = let (s1, s2) = (Hull.EFst s, Hull.ESnd s) in (idName i, s1) : go s2 as go s (PCon _ []:as) = go s as go _ (pat:_) = error ("Unimplemented: translatePatArgs _ " ++ pretty pat) @@ -535,5 +535,5 @@ dumpDT = do concatMapM :: (Monad f) => (a -> f [b]) -> [a] -> f [b] concatMapM f xs = concat <$> mapM f xs -unwrapId :: Id -> CoreName +unwrapId :: Id -> HullName unwrapId = show . idName diff --git a/src/Solcore/Pipeline/Options.hs b/src/Solcore/Pipeline/Options.hs index e0d84a57..bf93236b 100644 --- a/src/Solcore/Pipeline/Options.hs +++ b/src/Solcore/Pipeline/Options.hs @@ -17,10 +17,10 @@ data Option , optDumpDS :: !Bool , optDumpDF :: !Bool , optDumpSpec :: !Bool - , optDumpCore :: !Bool + , optDumpHull :: !Bool -- Options controlling diagnostic output , optDebugSpec :: !Bool - , optDebugCore :: !Bool + , optDebugHull :: !Bool , optTiming :: !Bool } deriving (Eq, Show) @@ -40,10 +40,10 @@ emptyOption path = Option , optDumpDS = False , optDumpDF = False , optDumpSpec = False - , optDumpCore = False + , optDumpHull = False -- Options controlling diagnostic output , optDebugSpec = False - , optDebugCore = False + , optDebugHull = False , optTiming = False } @@ -64,7 +64,7 @@ options <> help "This flag appends a colon-separated list of dirs to the search path.") <*> switch ( long "no-specialise" <> short 'n' - <> help "Skip specialisation and core emission phases") + <> help "Skip specialisation and hull emission phases") <*> switch ( long "no-desugar-calls" <> short 's' <> help "Skip indirect call desugaring") @@ -91,13 +91,13 @@ options <> help "Dump defunctionalised contract") <*> switch ( long "dump-spec" <> help "Dump specialised contract") - <*> switch ( long "dump-core" - <> help "Dump low-level core") + <*> switch ( long "dump-hull" + <> help "Dump low-level hull") -- Options controlling diagnostic output <*> switch ( long "debug-spec" <> help "Debug specialisation") - <*> switch ( long "debug-core" - <> help "Debug core emission") + <*> switch ( long "debug-hull" + <> help "Debug hull emission") <*> switch ( long "timing" <> help "Measure time of some phases") diff --git a/src/Solcore/Pipeline/SolcorePipeline.hs b/src/Solcore/Pipeline/SolcorePipeline.hs index 03696d24..cd59963c 100644 --- a/src/Solcore/Pipeline/SolcorePipeline.hs +++ b/src/Solcore/Pipeline/SolcorePipeline.hs @@ -11,7 +11,7 @@ import System.FilePath import qualified System.TimeIt as TimeIt import Text.Pretty.Simple -import qualified Language.Core as Core +import qualified Language.Hull as Hull import Solcore.Desugarer.ContractDispatch (contractDispatchDesugarer) import Solcore.Desugarer.IndirectCall (indirectCall) import Solcore.Desugarer.MatchCompiler (matchCompiler) @@ -28,7 +28,7 @@ import Solcore.Frontend.TypeInference.SccAnalysis import Solcore.Frontend.TypeInference.TcContract import Solcore.Frontend.TypeInference.TcEnv import Solcore.Desugarer.Specialise(specialiseCompUnit) -import Solcore.Desugarer.EmitCore(emitCore) +import Solcore.Backend.EmitHull(emitHull) import Solcore.Pipeline.Options(Option(..), argumentsParser) -- main compiler driver function @@ -43,12 +43,12 @@ pipeline = do exitWith (ExitFailure 1) Right contracts -> do forM_ (zip [(1::Int)..] contracts) $ \(i, c) -> do - let filename = "output" <> show i <> ".core" + let filename = "output" <> show i <> ".hull" putStrLn ("Writing to " ++ filename) writeFile filename (show c) -- Version that returns Either for testing -compile :: Option -> IO (Either String [Core.Object]) +compile :: Option -> IO (Either String [Hull.Object]) compile opts = runExceptT $ do let verbose = optVerbose opts noDesugarCalls = optNoDesugarCalls opts @@ -145,7 +145,7 @@ compile opts = runExceptT $ do putStrLn "> Match compilation result:" putStrLn (pretty matchless) - -- Specialization & Core Generation + -- Specialization & Hull Generation if optNoSpec opts then pure [] else do @@ -156,14 +156,14 @@ compile opts = runExceptT $ do putStrLn "> Specialised contract:" putStrLn (pretty specialized) - core <- liftIO $ timeItNamed "Emit Core " $ - emitCore (optDebugCore opts) env specialized + hull <- liftIO $ timeItNamed "Emit Hull " $ + emitHull (optDebugHull opts) env specialized - liftIO $ when (optDumpCore opts) $ do - putStrLn "> Core contract(s):" - forM_ core (putStrLn . pretty) + liftIO $ when (optDumpHull opts) $ do + putStrLn "> Hull contract(s):" + forM_ hull (putStrLn . pretty) - pure core + pure hull -- add declarations generated in the previous step -- and moving data types inside contracts to the diff --git a/testsol.sh b/testsol.sh index 5b075a2e..e0f861cd 100644 --- a/testsol.sh +++ b/testsol.sh @@ -10,21 +10,21 @@ function runsol() { file=$1 echo $file shift - rm -f -v output1.core Output.sol + rm -f -v output1.hull Output.sol /usr/bin/time -f "Compilation time: %E" cabal run sol-core -- -f $file $* && \ - cabal exec yule -- output1.core -w -O --nodeploy > /dev/null && \ + cabal exec yule -- output1.hull -w -O --nodeploy > /dev/null && \ forge script --via-ir Output.sol | egrep '(Gas|RESULT)' } -function runcore() { +function runhull() { echo $1 rm -f -v Output.sol cabal exec yule -- $1 -w --nodeploy -O && forge script --via-ir Output.sol | egrep '(Gas|RESULT)' } -function hevmcore() { - local base=$(basename $1 .core) +function hevmhull() { + local base=$(basename $1 .hull) local yulfile=$base.yul echo $yulfile local hexfile=$base.hex @@ -40,13 +40,13 @@ function hevmsol() { file=$1 echo $file local base=$(basename $1 .solc) - local core=output1.core + local hull=output1.hull local hexfile=$base.hex local yulfile=$base.yul echo Hex: $hexfile shift cabal exec sol-core -- -f $file $* && \ - cabal exec yule -- $core --nodeploy -O -o $yulfile && \ + cabal exec yule -- $hull --nodeploy -O -o $yulfile && \ solc --strict-assembly --bin --optimize $yulfile | tail -1 > $hexfile && \ hevm exec --code $(cat $hexfile) | awk -f parse_hevm_output.awk @@ -57,21 +57,21 @@ function deploysol() { shift echo "Solc: $file" local base=$(basename $file .solc) - local core=output1.core - echo "Sail: $core" + local hull=output1.hull + echo "Hull: $hull" local yulfile=$base.yul echo "Yul: $yulfile" rm -f -v $yulfile cabal exec sol-core -- -f $file $* && \ - cabal exec yule -- $core -o $yulfile + cabal exec yule -- $hull -o $yulfile hex=$(solc --strict-assembly --bin --optimize --optimize-yul $yulfile | tail -1) rawtx=$(cast mktx --private-key=$DEPLOYER_KEY --create $hex) addr=$(cast publish $rawtx | jq .contractAddress | tr -d '"') echo $addr } -function deploycore() { - local base=$(basename $1 .core) +function deployhull() { + local base=$(basename $1 .hull) local yulfile=$base.yul echo $yulfile local hexfile=$base.hex @@ -83,28 +83,6 @@ function deploycore() { echo $addr } -# function deployyul() { -# local yulfile=$1 -# local base=$(basename $1 .yul) -# hex=$(solc --strict-assembly --bin --optimize --optimize-yul $yulfile | tail -1) -# rawtx=$(cast mktx --private-key=$DEPLOYER_KEY --create $hex) -# addr=$(cast publish $rawtx | jq .contractAddress | tr -d '"') -# echo $addr -# } - -function deploysail() { - local sail=$1 - local base=$(basename $1 .core) - shift - local yulfile=$base.yul - echo $yulfile - local hexfile=$base.hex - rm -f -v $yulfile #$hexfile - echo cabal exec yule -- $sail -o $yulfile - cabal exec yule -- $sail -o $yulfile - #deployyul $1 $* -} - function deployyul() { local yulfile=$1 shift @@ -137,8 +115,8 @@ function deployyul1() { echo $contractAddress } -function sail() { - local base=$(basename $1 .core) +function hull() { + local base=$(basename $1 .hull) local yulfile=$base.yul rm -f -v $yulfile cabal exec yule -- $1 -o $yulfile diff --git a/yule/Compress.hs b/yule/Compress.hs index f10d79bc..1c34cab1 100644 --- a/yule/Compress.hs +++ b/yule/Compress.hs @@ -1,5 +1,5 @@ module Compress where -import Language.Core +import Language.Hull class Compress a where compress :: a -> a diff --git a/yule/Main.hs b/yule/Main.hs index 1c8bcb8b..b6d116ea 100644 --- a/yule/Main.hs +++ b/yule/Main.hs @@ -1,7 +1,7 @@ {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE QuasiQuotes #-} module Main where -import Language.Core.Parser(parseObject) +import Language.Hull.Parser(parseObject) import Solcore.Frontend.Syntax.Name -- FIXME: move Name to Common import Common.Pretty -- (Doc, Pretty(..), nest, render) import Builtins(yulBuiltins) diff --git a/yule/TM.hs b/yule/TM.hs index 9327dd0c..3ee4a9be 100644 --- a/yule/TM.hs +++ b/yule/TM.hs @@ -24,13 +24,13 @@ import qualified Data.Map as Map import Data.Map(Map) import Locus -import Language.Core qualified as Core +import Language.Hull qualified as Hull import qualified Options import Options(Options) type VarEnv = Map String Location type FunEnv = Map String FunInfo -data FunInfo = FunInfo { fun_args :: [Core.Type], fun_result :: Core.Type} +data FunInfo = FunInfo { fun_args :: [Hull.Type], fun_result :: Hull.Type} data CEnv = CEnv { env_counter :: IORef Int , env_vars :: IORef VarEnv @@ -121,15 +121,15 @@ withLocalEnv m = do builtinFuns :: [(String, FunInfo)] builtinFuns = - [ ("stop", FunInfo [] Core.TUnit) - , ("add", FunInfo [Core.TWord, Core.TWord] Core.TWord) - , ("mul", FunInfo [Core.TWord, Core.TWord] Core.TWord) - , ("sub", FunInfo [Core.TWord, Core.TWord] Core.TWord) - , ("div", FunInfo [Core.TWord, Core.TWord] Core.TWord) - , ("sdiv", FunInfo [Core.TWord, Core.TWord] Core.TWord) - , ("mod", FunInfo [Core.TWord, Core.TWord] Core.TWord) - , ("smod", FunInfo [Core.TWord, Core.TWord] Core.TWord) - , ("addmod", FunInfo [Core.TWord, Core.TWord, Core.TWord] Core.TWord) - , ("mulmod", FunInfo [Core.TWord, Core.TWord, Core.TWord] Core.TWord) - , ("exp", FunInfo [Core.TWord, Core.TWord] Core.TWord) + [ ("stop", FunInfo [] Hull.TUnit) + , ("add", FunInfo [Hull.TWord, Hull.TWord] Hull.TWord) + , ("mul", FunInfo [Hull.TWord, Hull.TWord] Hull.TWord) + , ("sub", FunInfo [Hull.TWord, Hull.TWord] Hull.TWord) + , ("div", FunInfo [Hull.TWord, Hull.TWord] Hull.TWord) + , ("sdiv", FunInfo [Hull.TWord, Hull.TWord] Hull.TWord) + , ("mod", FunInfo [Hull.TWord, Hull.TWord] Hull.TWord) + , ("smod", FunInfo [Hull.TWord, Hull.TWord] Hull.TWord) + , ("addmod", FunInfo [Hull.TWord, Hull.TWord, Hull.TWord] Hull.TWord) + , ("mulmod", FunInfo [Hull.TWord, Hull.TWord, Hull.TWord] Hull.TWord) + , ("exp", FunInfo [Hull.TWord, Hull.TWord] Hull.TWord) ] diff --git a/yule/Translate.hs b/yule/Translate.hs index bb82ec97..e1d8c1ca 100644 --- a/yule/Translate.hs +++ b/yule/Translate.hs @@ -4,8 +4,8 @@ module Translate where import Data.List(nub, union) import GHC.Stack -import Language.Core hiding(Name) -import qualified Language.Core as Core +import Language.Hull hiding(Name) +import qualified Language.Hull as Hull import Language.Yul import Solcore.Frontend.Syntax.Name import Data.String @@ -61,7 +61,7 @@ genExpr (ECall name args) = do let argsCode = concat argCodes let yulArgs = concatMap flattenRhs argLocs funInfo <- lookupFun name - (resultCode, resultLoc) <- coreAlloc (fun_result funInfo) + (resultCode, resultLoc) <- hullAlloc (fun_result funInfo) let callExpr = YCall (yulFunName name) yulArgs let callCode = case sizeOf(resultLoc) of -- handle void functions 0 -> [YExp callExpr] @@ -70,7 +70,7 @@ genExpr (ECall name args) = do genExpr e@(ECond ty cond e1 e2) = do debug ["genExpr: ", show e] - (resultCode, resultLoc) <- coreAlloc ty + (resultCode, resultLoc) <- hullAlloc ty (condCode, condLoc) <- genExpr cond -- Bools are complex(False ~ inr ()) to get something we can switch on let tag = normalizeLoc condLoc @@ -85,10 +85,10 @@ genExpr e@(ECond ty cond e1 e2) = do genExpr e = error ("genExpr: not implemented for "++show e) -yulFunName :: Core.Name -> Name +yulFunName :: Hull.Name -> Name yulFunName = fromString . ("usr$" ++) -yulVarName :: Core.Name -> Name +yulVarName :: Hull.Name -> Name yulVarName = fromString flattenRhs :: Location -> [YulExp] @@ -119,7 +119,7 @@ genStmt (SAssembly stmts) = do pure stmts genStmt (SAlloc name typ) = allocVar name typ -genStmt (SAssign name expr) = coreAssign name expr +genStmt (SAssign name expr) = hullAssign name expr genStmt (SReturn expr) = do debug [">SReturn: ", show expr] @@ -177,7 +177,7 @@ genStmt (SFunction name args ret stmts) = withLocalEnv do let resultLoc = LocNamed "_result" insertVar "_result" resultLoc return ["_result"] - place :: Core.Name -> Type -> TM [Name] + place :: Hull.Name -> Type -> TM [Name] place name typ = do loc <- buildLoc typ insertVar name loc @@ -240,12 +240,12 @@ genAlt payload (Alt (PVar name) _ body) = do genAlt _ alt = error ("genAlt unimplemented for: " ++ show alt) -allocVar :: Core.Name -> Type -> TM [YulStmt] +allocVar :: Hull.Name -> Type -> TM [YulStmt] allocVar name TWord = do insertVar name (LocNamed name) pure [YulAlloc (yulVarName name)] allocVar name typ = do - (stmts, loc) <- coreAlloc typ + (stmts, loc) <- hullAlloc typ insertVar name loc return stmts @@ -265,8 +265,8 @@ buildLoc (TNamed n ty) = buildLoc ty buildLoc t = error ("cannot build location for "++show t) -coreAlloc :: Type -> TM ([YulStmt], Location) -coreAlloc t = do +hullAlloc :: Type -> TM ([YulStmt], Location) +hullAlloc t = do loc <- buildLoc t let stmts = allocLoc loc pure (stmts, loc) @@ -286,8 +286,8 @@ allocWord = do pure ([YulAlloc (stkLoc n)], loc) -coreAssign :: Expr -> Expr -> TM [YulStmt] -coreAssign lhs rhs = do +hullAssign :: Expr -> Expr -> TM [YulStmt] +hullAssign lhs rhs = do (stmtsLhs, locLhs) <- genExpr lhs (stmtsRhs, locRhs) <- genExpr rhs if sizeOf locLhs == 0 then pure stmtsRhs From d20c4c445e476bf7ac7d697fcb30d992ee4c39ff Mon Sep 17 00:00:00 2001 From: Marcin Benke Date: Fri, 28 Nov 2025 13:49:22 +0100 Subject: [PATCH 2/3] Move Specialise module to Backend subdir --- sol-core.cabal | 4 ++-- src/Solcore/Backend/EmitHull.hs | 2 +- src/Solcore/{Desugarer => Backend}/Specialise.hs | 2 +- src/Solcore/Pipeline/SolcorePipeline.hs | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) rename src/Solcore/{Desugarer => Backend}/Specialise.hs (99%) diff --git a/sol-core.cabal b/sol-core.cabal index db1c262a..e03870cb 100644 --- a/sol-core.cabal +++ b/sol-core.cabal @@ -60,12 +60,12 @@ library -- cabal-fmt: expand src exposed-modules: + Solcore.Backend.EmitHull + Solcore.Backend.Specialise Solcore.Desugarer.IfDesugarer Solcore.Desugarer.IndirectCall Solcore.Desugarer.MatchCompiler Solcore.Desugarer.ReplaceWildcard - Solcore.Desugarer.Specialise - Solcore.Backend.EmitHull Solcore.Desugarer.ContractDispatch Solcore.Desugarer.ReplaceFunTypeArgs Solcore.Desugarer.UniqueTypeGen diff --git a/src/Solcore/Backend/EmitHull.hs b/src/Solcore/Backend/EmitHull.hs index 1b317a84..cf6fbdd1 100644 --- a/src/Solcore/Backend/EmitHull.hs +++ b/src/Solcore/Backend/EmitHull.hs @@ -18,7 +18,7 @@ import Solcore.Frontend.TypeInference.TcMonad (insts) import Solcore.Frontend.TypeInference.TcSubst import Solcore.Frontend.TypeInference.TcUnify import Solcore.Primitives.Primitives -import Solcore.Desugarer.Specialise(typeOfTcExp) +import Solcore.Backend.Specialise(typeOfTcExp) import System.Exit emitHull :: Bool -> TcEnv -> CompUnit Id -> IO [Hull.Object] diff --git a/src/Solcore/Desugarer/Specialise.hs b/src/Solcore/Backend/Specialise.hs similarity index 99% rename from src/Solcore/Desugarer/Specialise.hs rename to src/Solcore/Backend/Specialise.hs index 59d9e61b..6dee19e7 100644 --- a/src/Solcore/Desugarer/Specialise.hs +++ b/src/Solcore/Backend/Specialise.hs @@ -1,5 +1,5 @@ -- {-# LANGUAGE DefaultSignatures #-} -module Solcore.Desugarer.Specialise where --(specialiseCompUnit, typeOfTcExp) where +module Solcore.Backend.Specialise where --(specialiseCompUnit, typeOfTcExp) where {- * Specialisation Create specialised versions of polymorphic and overloaded functions. This is meant to be run on typed and defunctionalised code, so no higher-order functions. diff --git a/src/Solcore/Pipeline/SolcorePipeline.hs b/src/Solcore/Pipeline/SolcorePipeline.hs index cd59963c..280ab074 100644 --- a/src/Solcore/Pipeline/SolcorePipeline.hs +++ b/src/Solcore/Pipeline/SolcorePipeline.hs @@ -27,7 +27,7 @@ import Solcore.Frontend.Syntax import Solcore.Frontend.TypeInference.SccAnalysis import Solcore.Frontend.TypeInference.TcContract import Solcore.Frontend.TypeInference.TcEnv -import Solcore.Desugarer.Specialise(specialiseCompUnit) +import Solcore.Backend.Specialise(specialiseCompUnit) import Solcore.Backend.EmitHull(emitHull) import Solcore.Pipeline.Options(Option(..), argumentsParser) From afafbe4d567971bfda1669c3f54ae76eb7762c77 Mon Sep 17 00:00:00 2001 From: Marcin Benke Date: Thu, 8 Jan 2026 11:54:43 +0100 Subject: [PATCH 3/3] rename doc/core.md -> doc/hull.md --- doc/{core.md => hull.md} | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) rename doc/{core.md => hull.md} (93%) diff --git a/doc/core.md b/doc/hull.md similarity index 93% rename from doc/core.md rename to doc/hull.md index 69ef3fe2..0fab56c2 100644 --- a/doc/core.md +++ b/doc/hull.md @@ -1,12 +1,17 @@ -# Core language (low level) +# Hull language (low level) ## Introduction -The Core language is an intermediate step before Yul generation. +The Hull language is an intermediate step before Yul generation. It is basically Yul with algebraic types (sums/products) +### Naming + +Hull was initially named Core, but once it was decided that the whole language should be called "Core Solidity", +it was renamed to Hull. + ## Abstract syntax -See `src/Language/Core.hs` +See `src/Language/Hull.hs` ### Types @@ -82,12 +87,12 @@ data Contract = Contract { ccName :: Name, ccStmts :: [Stmt] } ## Concrete Syntax -See `src/Language/Core/Parser.hs` +See `src/Language/Hull/Parser.hs` -Although Core is not meant to be written manually, it has concrete syntax, mostly for diagnostic purposes. +Although Hull is not meant to be written manually, it has concrete syntax, mostly for diagnostic purposes. ``` -Block = "{" coreStmt* "}" +Block = "{" hullStmt* "}" Contract = "contract" identifier Stmt = "let" identifier ":" Type | "return" Expr @@ -199,7 +204,7 @@ contract Food { } ``` -yields the following Core: +yields the following Hull: ``` contract Food {