1
1
{-# LANGUAGE OverloadedStrings #-}
2
2
module Main where
3
- import Language.Core (Contract (.. ))
4
- import Language.Core.Parser (parseContract )
3
+ import Language.Core (Object (.. ))
4
+ import Language.Core.Parser (parseObject )
5
5
import Solcore.Frontend.Syntax.Name -- FIXME: move Name to Common
6
6
import Common.Pretty -- (Doc, Pretty(..), nest, render)
7
7
import Builtins (yulBuiltins )
@@ -21,54 +21,62 @@ main = do
21
21
-- print options
22
22
let filename = Options. input options
23
23
src <- readFile filename
24
- let coreContract = parseContract filename src
25
- let core = ccStmts coreContract
26
- when (Options. verbose options) $ do
27
- putStrLn " /* Core:"
28
- putStrLn (render (nest 2 (ppr coreContract)))
29
- putStrLn " */"
24
+ let (Object name code inners) = parseObject filename src
30
25
let oCompress = Options. compress options
31
- let source = if oCompress then compress core else core
32
26
when oCompress $ do
33
27
putStrLn " Compressing sums"
28
+ let source = if oCompress then compress code else code
34
29
generatedYul <- runTM options (translateStmts source)
35
- let name = fromString (ccName coreContract)
36
-
30
+ let withDeployment = not (Options. runOnce options)
37
31
let doc = if Options. wrap options
38
- then wrapInSol name generatedYul
39
- else wrapInObject name generatedYul
32
+ then wrapInSol ( Name name) generatedYul
33
+ else wrapInObject ( Name name) withDeployment generatedYul
40
34
putStrLn (" writing output to " ++ Options. output options)
41
35
writeFile (Options. output options) (render doc)
42
36
43
37
-- wrap in a Yul object with the given name
44
- wrapInObject :: Name -> Yul -> Doc
45
- wrapInObject name yul = ppr object where
46
- object = YulObject (show name) (YulCode stmts) []
47
- stmts = yulStmts yul ++ retcode
38
+ wrapInObject :: Name -> Bool -> [YulStmt ] -> Doc
39
+ wrapInObject name deploy yul
40
+ | deploy = ppr nested
41
+ | otherwise = ppr runtime
42
+ where
43
+ nested = YulObject " Deployable" deploycode [InnerObject runtime]
44
+ runtime = YulObject (show name) (YulCode stmts) []
45
+ cname = yulString (show name)
46
+ stmts = yul ++ retcode
48
47
retcode =
49
- [ call " mstore" [yulInt (0 :: Integer ), YIdent " _mainresult" ]
50
- , call " return" [yulInt (0 :: Integer ), yulInt (32 :: Integer )]
48
+ [ calls " mstore" [yulInt 0 , YIdent " _mainresult" ]
49
+ , calls " return" [yulInt 0 , yulInt 32 ]
50
+ ]
51
+ deploycode = YulCode
52
+ [ calls " mstore" [yulInt 64 , YCall " memoryguard" [yulInt 128 ]]
53
+ , ylva " memPtr" (YCall " mload" [yulInt 64 ])
54
+ -- call constructor here
55
+ , calls " datacopy" [yulInt 0 , dataoffset, datasize]
56
+ , calls " return" [yulInt 0 , datasize]
51
57
]
52
- call f args = YExp (YCall f args)
58
+ calls f args = YExp (YCall f args)
59
+ ylva x e = YLet [Name x] (Just e)
60
+ datasize = YCall " datasize" [cname]
61
+ dataoffset = YCall " dataoffset" [cname]
53
62
54
63
{- | wrap a Yul chunk in a Solidity function with the given name
55
64
assumes result is in a variable named "_result"
56
65
-}
57
- wrapInSol :: Name -> Yul -> Doc
66
+ wrapInSol :: Name -> [ YulStmt ] -> Doc
58
67
wrapInSol name yul = wrapInContract name " wrapper()" wrapper
59
68
where
60
69
wrapper = wrapInSolFunction " wrapper" (yulBuiltins <> yul)
61
70
62
- wrapInSolFunction :: Name -> Yul -> Doc
71
+ wrapInSolFunction :: Name -> [ YulStmt ] -> Doc
63
72
wrapInSolFunction name yul =
64
73
text " function" <+> ppr name <+> prettyargs <+> text " public returns (uint256 _wrapresult)" <+> lbrace
65
74
$$ nest 2 assembly
66
75
$$ rbrace
67
76
where
68
- yul' = yul <> Yul [YAssign1 " _wrapresult" (YIdent " _mainresult" )]
69
- assembly = text " assembly" <+> lbrace
70
- $$ nest 2 (ppr yul')
71
- $$ rbrace
77
+ yul' = yul <> [YAssign1 " _wrapresult" (YIdent " _mainresult" )]
78
+ assembly = text " assembly" <+> braces (nest 2 prettybody)
79
+ prettybody = vcat (map ppr yul')
72
80
prettyargs = parens empty
73
81
74
82
wrapInContract :: Name -> Name -> Doc -> Doc
0 commit comments