New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#4: implement global variables #9

Merged
merged 2 commits into from Jun 16, 2016
File filter...
Filter file types
Jump to file or symbol
Failed to load files and symbols.
+30 −11
Diff settings

Always

Just for now

Next

fixes #4: implement global variables

  • Loading branch information...
nabilhassein committed Jun 16, 2016
commit b20e0a776f587e430f735aa67af87afe009ae0e2
Copy path View file
@@ -55,7 +55,9 @@ pPrintBlock :: Doc -> Block -> Doc
pPrintBlock pre (Block [] e) = sep [pre <+> text "{", nest 4 (maybe empty pPrint e), text "}"]
pPrintBlock pre (Block ss e) = pre <+> text "{" $+$ nest 4 (vcat (map pPrint ss ++ [maybe empty pPrint e])) $+$ text "}"

data Item = Function Visibility String [(Mutable, Var, Type)] Type Block
data Item
= Function Visibility String [(Mutable, Var, Type)] Type Block
| Static Mutable Var Type Expr

instance Pretty Item where
pPrint (Function vis nm args ret body) = pPrintBlock (cat
@@ -64,6 +66,11 @@ instance Pretty Item where
[ sep [case mut of Mutable -> text "mut"; Immutable -> empty, pPrint v, text ":", pPrint t] | (mut, v, t) <- args ]
, text ")" <+> if ret == TypeName "()" then empty else text "->" <+> pPrint ret
]) body
pPrint (Static mut var ty initial) = sep
[ hsep [text "static", if mut == Mutable then text "mut" else empty, pPrint var]
, nest 4 $ text ":" <+> pPrint ty
, nest 4 $ text "=" <+> pPrint initial
] <> text ";"

data Expr
= Lit Lit
Copy path View file
@@ -482,26 +482,37 @@ interpretFunction (CFunDef specs (CDeclr ~(Just ident) ~declarators@(CFunDeclr a
return (Rust.Function vis name formals (toRustType retTy) (Rust.Block (toBlock body') Nothing))

interpretTranslationUnit :: Show a => CTranslationUnit a -> [Rust.Item]
interpretTranslationUnit (CTranslUnit decls _) = catMaybes $ flip evalState [] $ do
interpretTranslationUnit (CTranslUnit decls _) = concat $ flip evalState [] $ do
forM decls $ \ decl -> case decl of
CFDefExt f -> fmap Just (interpretFunction f)
CFDefExt f -> fmap return (interpretFunction f)
CDeclExt (CDecl specs declarators _) -> do
let (storagespecs, [], typequals, typespecs, _inline) = partitionDeclSpecs specs
sequence_ $ case storagespecs of
fmap concat $ sequence $ case storagespecs of
[CTypedef _] ->
[ addType ident =<< cTypeOf typequals typespecs derived
[ do
addType ident =<< cTypeOf typequals typespecs derived
return []
-- Typedefs must have a declarator which must not be
-- abstract, and must not have an initializer or size.
| ~(Just (CDeclr (Just ident) derived _ _ _), Nothing, Nothing) <- declarators
]
_ ->
[ addVar ident =<< cTypeOf typequals typespecs derived
[ do
(mut, ty) <- cTypeOf typequals typespecs derived
addVar ident (mut, ty)
mexpr <- mapM (fmap (castTo ty) . interpretExpr True . (\ (CInitExpr initial _) -> initial)) minit
return $ if isFunc derived || any isExtern storagespecs
then []
else [Rust.Static mut (Rust.VarName (identToString ident)) (toRustType ty) (fromMaybe 0 mexpr)]
-- Top-level declarations must have a declarator
-- which must not be abstract, and must not have a
-- size. They may have an initializer.
-- TODO: emit declarations with optional
-- initializers for non-functions.
| ~(Just (CDeclr (Just ident) derived _ _ _), _, Nothing) <- declarators
| ~(Just (CDeclr (Just ident) derived _ _ _), minit, Nothing) <- declarators
]
return Nothing
_ -> return Nothing -- FIXME: ignore everything but function declarations for now
_ -> return [] -- FIXME: ignore everything but function declarations for now
where
isFunc (CFunDeclr {} : _) = True
isFunc _ = False

isExtern (CExtern _) = True
isExtern _ = False
@@ -39,3 +39,4 @@ tailBlock b = b

itemIdioms :: Rust.Item -> Rust.Item
itemIdioms (Rust.Function vis name formals ret b) = Rust.Function vis name formals ret (tailBlock b)
itemIdioms i = i
ProTip! Use n and p to navigate between commits in a pull request.