Left (Error e) = Left e
Right (_, p) = Right $ toString p
where
- prog = tell [Instr "bra" [L "main"] ""] >>| mapM_ g fds
+ prog = tell [
+ Instr "bsr" [L "main"] "",
+ Instr "halt" [] ""
+ ] >>| mapM_ g fds
//Current issues:
//All VarDecls are added as function, how to deal with assignments?
BiCons = abort "Shit, Cons, how to deal with this?"
instance g Expr where
-// g (VarExpr _ (VarDef k fs)) = load k >>= \instr-> tell [instr] //note: pure is pure for list, i.e. []
g (IntExpr _ i) = tell [Instr "ldc" [Lit i] ""]
g (CharExpr _ c) = tell [Instr "ldc" [Lit (toInt c)] ""]
g (BoolExpr _ b) = tell [Instr "ldc" [Lit (if b TRUE FALSE)] ""]
>>| g e2
>>| tell [Instr "sth" [] ""]
>>| tell [Instr "ajs" [Lit -1] ""]
- g _ = abort "hoi"
- g (FunExpr _ k es fs) = abort "FunExpr unsupported modderfokker"
- // mapM g es >>| //put all arguments on the stack (todo: fix argument handling!)
- // jump "bsr" k >>= \instr->
- // tell [instr] >>| //actually branch to function
- // tell [Instr "ldr" [Raw "RR"] ""] //push return value on stack, todo: check for VOID
-//
-//instance g Stmt where
+ g (VarExpr _ (VarDef k fs)) = getAdressbook >>= \ab->case 'Map'.get k ab of
+ Nothing = liftT (Left $ Error "PANIC: undefined variable")
+ Just (ADDR t) = tell [Instr "ldl" [Lit t] ""]
+ Just (LAB t) = liftT (Left $ Error "PANIC: variable and function name clash")
+ //load k >>= \instr-> tell [instr] //note: pure is pure for list, i.e. []
+ g (FunExpr _ k es fs) =
+// tell [Instr "ldr" [Raw "MP"] ("old frame pointer")]
+ mapM g es
+ >>| jump "bsr" k
+ >>| tell [Instr "ldr" [Raw "RR"] ""]
+
+jump :: String String -> Gen ()
+jump instr k = getAdressbook >>= \ab->case 'Map'.get k ab of
+ Nothing = liftT (Left $ Error $ concat ["PANIC: ", k, " not found as function"])
+ Just (LAB t) = tell [Instr instr [L t] (k +++"()")]
+ Just (ADDR t) = liftT (Left $ Error $ "PANIC: jump should go to label")
+
+instance g Stmt where
// g (IfStmt cond th el) =
// fresh >>= \elseLabel->
// fresh >>= \endLabel->
// abort "Shit, an assignment, figure out something with storing vars or something"
// //vars will be on stack in locals (possible pointers to heap)
// g (FunStmt _ _) = abort "CodeGen, FunStmt unused" //not used
-// g (ReturnStmt Nothing) = tell [Instr "ret" [] ""] //NOTE! Assumes only return address on stack, safe?
-// g (ReturnStmt (Just e)) =
-// g e >>|
-// tell [Instr "str" [Raw "RR"] ""] >>|
-// g (ReturnStmt Nothing)
-
-instance g VarDecl where
- g (VarDecl _ Nothing _ _) = liftT (Left $ Error "PANIC: untyped vardecl")
- g (VarDecl _ (Just t) k e) = g e
-// TupleType (t1, t2) = g e
-// ListType t = abort "listtype"
-// IdType _ = liftT (Left $ Error "PANIC: unresolved typevariable")
-// t1 ->> t2 = abort "funtype"
-// VoidType = liftT (Left $ Error "PANIC: Void vardecl")
-// _ = g e
+ g (ReturnStmt Nothing) = tell [Instr "unlink" [] ""]
+ >>| tell [Instr "ret" [] ""]
+ g (ReturnStmt (Just e)) = g e
+ >>| tell [Instr "str" [Raw "RR"] ""]
+ >>| g (ReturnStmt Nothing)
+
+foldVarDecl :: Int VarDecl -> Gen Int
+foldVarDecl x (VarDecl _ _ k e) = g e
+ >>| updateAdressbook (extend k (ADDR x)) >>| pure (x + 1)
instance g FunDecl where
g (FunDecl _ k _ _ vds stms) =
//varDecls can call the enclosing function, so first reserve a label for it
updateAdressbook (extend k (LAB k)) >>|
tell [Lab k] >>|
+ tell [Instr "link" [Lit 0] ""] >>|
//then generate functions for the VarDecls
getAdressbook >>= \oldMap ->
- mapM_ g vds >>|
+ foldM foldVarDecl 1 vds >>|
//then the main function
-// mapM_ g stms >>|
+ mapM_ g stms >>|
updateAdressbook (const oldMap) >>| pure ()
//
//load :: String -> Gen Instr
parseBasicExpr :: Parser Token Expr
parseBasicExpr = peekPos >>= \pos ->
(TupleExpr pos <$> (parseTuple parseExpr)) <|>
- (parseFunCall >>= \(ident, args)->parseFieldSelectors >>= \fs->
- pure $ FunExpr pos ident args fs) <|>
parseBBraces parseExpr <|>
trans1 EmptyListToken (EmptyListExpr pos) <|>
trans1 TrueToken (BoolExpr pos True) <|>
trans2 (NumberToken zero) (\(NumberToken i)->IntExpr pos i) <|>
trans2 (CharToken zero) (\(CharToken c)->CharExpr pos c) <|>
(Op1Expr pos <$> parseOp1 <*> parseExpr) <|>
+ (parseFunCall >>= \(ident, args)->parseFieldSelectors >>= \fs->
+ pure $ FunExpr pos ident args fs) <|>
(VarExpr pos <$> parseVarDef)
parseFunCall :: Parser Token (String, [Expr])
-parseFunCall = tuple <$> parseIdent <*> (
- (parseBBraces $ parseSepList CommaToken parseExpr) <|> pure [])
+parseFunCall = liftM2 tuple
+ parseIdent
+ (parseBBraces $ parseSepList CommaToken parseExpr)
parseVarDef :: Parser Token VarDef
parseVarDef = liftM2 VarDef parseIdent parseFieldSelectors