Commit f459c196 authored by Michael Hanus 's avatar Michael Hanus

Add option --optvardecls

parent 59ff4352
......@@ -9,7 +9,7 @@ The definition of ICurry is inspired by the Curry compiler
[Sprite](http://dx.doi.org/10.1007/978-3-319-63139-4_6)
which compiles Curry programs into LLVM code.
The definition of ICurry implemented in this package follows the
[paper on ICurry](http://arxiv.org/abs/1908.11101).
[paper on ICurry](http://dx.doi.org/10.1007/978-3-030-46714-2_18).
This package contains the definition of ICurry as
Curry data types (module `ICurry.Types`), a simple compiler
......@@ -55,13 +55,6 @@ In the following, we describe various uses of the `icurry` tool.
> icurry -v Prog
As a default, the ICurry compiler lifts all nested case/let expressions,
i.e., it transforms them into auxiliary top-level operations.
This is also necessary for the simple interpreter contained in this
package (see below).
If an implementation of ICurry can deal with nested case/let expressions,
one can use the option `--nolifting` to supress this lifting.
2. One can also use a simple (i.e., not efficient) interpreter
to execute ICurry programs and visualize their behavior.
In this case, one has to provide the name of a 0-ary function `mymain`
......@@ -100,6 +93,33 @@ In the following, we describe various uses of the `icurry` tool.
manually via the operation `ICurry.Interpreter.execProg`.
Explanation of some options:
----------------------------
`--nolifting`:
As a default, the ICurry compiler lifts all nested case/let expressions,
i.e., it transforms them into auxiliary top-level operations.
This is also necessary for the simple interpreter contained in this
package (see below).
If an implementation of ICurry can deal with nested case/let expressions,
one can use the option `--nolifting` to supress this lifting.
`--optvardecls`:
The ICurry compiler generates declaration (`IVarDecl`)
for each variable used in a block in order to support cyclic
data structures (see the paper on ICurry).
For imperative target languages that do not require explicit
variables declaration but allow the introduction of variables
by assignments (see type `IAssign`), one can use the
option `--optvardecls` to suppress the generation of variable
declarations when they are introduced by assignments.
With this options, variable declarations are only generated
for variables which have their first occurrence in an expression
(which is the case when cyclic data structures are used).
Some remarks about the ICurry interpreter:
------------------------------------------
......
......@@ -6,7 +6,7 @@
--- * remove declarations/assignments of unused variables in ICurry code
---
--- @author Michael Hanus
--- @version February 2020
--- @version May 2020
------------------------------------------------------------------------------
module ICurry.Compiler where
......@@ -97,6 +97,7 @@ data ICOptions = ICOptions
, optShowGraph :: Bool -- visualize graph during execution?
, optViewPDF :: String -- command to view graph PDF
, optInteractive :: Bool -- interactive execution?
, optVarDecls :: Bool -- optimize variable declarations?
-- internal options
, optConsMap :: [(QName,(IArity,Int))] -- map: cons. names to arity/position
, optFunMap :: [(QName,Int)] -- map: function names to module indices
......@@ -104,7 +105,8 @@ data ICOptions = ICOptions
}
defaultICOptions :: ICOptions
defaultICOptions = ICOptions 1 False True "" False "evince" False [] [] ("","")
defaultICOptions =
ICOptions 1 False True "" False "evince" False False [] [] ("","")
-- Lookup arity and position index of a constructor.
arityPosOfCons :: ICOptions -> QName -> (IArity,Int)
......@@ -170,9 +172,12 @@ trRule opts (Rule args rhs) = IFuncBody (toIBlock opts args rhs 0)
toIBlock :: ICOptions -> [VarIndex] -> Expr -> Int -> IBlock
toIBlock opts vs e root =
IBlock (map IVarDecl (filter (`elem` evars) vs) ++ varDecls)
IBlock (if optVarDecls opts
then varDecls
else map IVarDecl (filter (`elem` evars) vs) ++ varDecls)
(map (\ (p,i) -> IVarAssign i (IVarAccess root [p]))
(filter ((`elem` evars) . snd) (zip [0..] vs)) ++ varAssigns)
(filter ((`elem` evars) . snd) (zip [0..] vs)) ++
fst varAssigns ++ map fst (snd varAssigns))
(case e of
Case _ ce brs@(Branch (Pattern _ _) _ : _) ->
let carg = trCaseArg ce
......@@ -186,32 +191,41 @@ toIBlock opts vs e root =
evars = allVars e
varDecls = case e of
Free fvs _ -> map IFreeDecl fvs
Let bs _ -> map (IVarDecl .fst) bs
Case _ (Var _) _ -> []
Case _ _ _ -> [IVarDecl caseVar]
_ -> []
Free fvs _ -> map IFreeDecl fvs
Let bs _ -> if optVarDecls opts
then map IVarDecl
(filter (`elem` cyclicVars) (map fst bs))
else map (IVarDecl . fst) bs
Case _ (Var _) _ -> []
Case _ _ _ -> if optVarDecls opts then [] else [IVarDecl caseVar]
_ -> []
-- fresh variable to translate complex case arguments:
caseVar = maximum (0 : evars) + 1
-- the assignments for this block: a pair of direct assignments
-- and subsequent assignments required for recursive lets
-- (where the cyclic variables is returned)
varAssigns = case e of
Let bs _ ->
let assigns = map (\ (v,b) -> (v, (toIExpr opts b))) bs
in map (\ (v,be) -> IVarAssign v be) assigns ++
-- add assignments of recursive occurrences:
recursiveAssigns assigns
Case _ (Var _) _ -> []
Case _ ce _ -> [IVarAssign caseVar (toIExpr opts ce)]
_ -> []
Let bs _ ->
let assigns = map (\ (v,b) -> (v, toIExpr opts b)) bs
in (map (\ (v,be) -> IVarAssign v be) assigns,
-- add assignments of recursive occurrences:
recursiveAssigns assigns)
Case _ (Var _) _ -> ([], [])
Case _ ce _ -> ([IVarAssign caseVar (toIExpr opts ce)], [])
_ -> ([], [])
where
recursiveAssigns [] = []
recursiveAssigns (ve:ves) =
let vps = varPos [] (snd ve)
in map (\ (v,p) -> INodeAssign (fst ve) p (IVar v))
in map (\ (v,p) -> (INodeAssign (fst ve) p (IVar v), v))
(filter (\vp -> fst vp `elem` map fst (ve:ves)) vps) ++
recursiveAssigns ves
-- variables used to implement cyclic data structures
cyclicVars = map snd (snd varAssigns)
trCaseArg ce = case ce of
Var v -> v
_ -> caseVar
......
......@@ -30,7 +30,7 @@ testI p =
banner :: String
banner = unlines [bannerLine,bannerText,bannerLine]
where
bannerText = "ICurry Compiler (Version of 12/05/20)"
bannerText = "ICurry Compiler (Version of 15/05/20)"
bannerLine = take (length bannerText) (repeat '=')
main :: IO ()
......@@ -110,6 +110,9 @@ options =
, Option "" ["nolifting"]
(NoArg (\opts -> opts { optLift = False }))
"do not lift nested case/let expressions"
, Option "" ["optvardecls"]
(NoArg (\opts -> opts { optVarDecls = True }))
"do not generate variable declarations when\nvariables are introduced by assignments"
]
where
safeReadNat opttrans s opts =
......
......@@ -156,7 +156,7 @@ ppAssignments = vcat . map ppAssignment
ppAssignment :: IAssign -> Doc
ppAssignment (IVarAssign v e) = ppVar v <+> equals <+> ppExpr e
ppAssignment (INodeAssign v pos e) =
ppVar v <+> ppPos pos <+> equals <+> ppExpr e
ppVar v <> ppPos pos <+> equals <+> ppExpr e
--- Pretty print comma separated expressions
--- @param exprs the expressions
......@@ -168,15 +168,14 @@ ppExprs = hsep . punctuate comma . map ppExpr
--- @param expr the expression
--- @return the pretty printed expression
ppExpr :: IExpr -> Doc
ppExpr (IVar v) = ppVar v
ppExpr (IVarAccess v pos) = ppVar v <+> ppPos pos
ppExpr (ILit l) = ppLit l
ppExpr (IFCall n es) = ppQName n <+> lparen <+> ppExprs es <+> rparen
ppExpr (ICCall n es) = ppExpr (IFCall n es)
ppExpr (IFPCall n _ es) = ppQName n <+> lparen <+> ppExprs es <+> rparen
ppExpr (ICPCall n m es) = ppExpr (IFPCall n m es)
ppExpr (IOr e1 e2) =
lparen <+> ppExpr e1 <+> char '?' <+> ppExpr e2 <+> rparen
ppExpr (IVar v) = ppVar v
ppExpr (IVarAccess v pos) = ppVar v <> ppPos pos
ppExpr (ILit l) = ppLit l
ppExpr (IFCall n es) = ppQName n <> parens (ppExprs es)
ppExpr (ICCall n es) = ppExpr (IFCall n es)
ppExpr (IFPCall n _ es) = ppQName n <> parens (ppExprs es)
ppExpr (ICPCall n m es) = ppExpr (IFPCall n m es)
ppExpr (IOr e1 e2) = parens (ppExpr e1 <+> char '?' <+> ppExpr e2)
--- Pretty print branches over constructors
--- @param bs the branches
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment