X-Git-Url: https://git.martlubbers.net/?a=blobdiff_plain;f=gen.icl;h=7ad917653ffa777479976215c029f43445e2be56;hb=a5c9b65860f9af03a7c999f7abd6ab5f12f63523;hp=4bf1bb8fda6853ac980fbf107d0778460c521db6;hpb=a961d52fe0e9269af7d5581e07155f6701c09dbc;p=cc1516.git diff --git a/gen.icl b/gen.icl index 4bf1bb8..7ad9176 100644 --- a/gen.icl +++ b/gen.icl @@ -44,7 +44,10 @@ gen (AST fds) = case evalRWST prog () ('Map'.newMap, labelStream) of 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? @@ -71,7 +74,7 @@ fresh = gets snd >>= \vars-> pure (head vars) class g a :: a -> Gen () -// + instance g Op1 where g UnNegation = tell [Instr "not" [] ""] g UnMinus = tell [Instr "neg" [] ""] @@ -96,7 +99,6 @@ instance g Op2 where 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)] ""] @@ -113,14 +115,24 @@ instance g Expr where >>| 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-> @@ -145,58 +157,33 @@ instance g Expr where // 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) + +addVars :: [String] -> (Addressbook -> Addressbook) +addVars [] = id +addVars [x:xs] = \ab->extend x (ADDR (-2 - (length xs))) (addVars xs ab) instance g FunDecl where - g (FunDecl _ k _ _ vds stms) = + g (FunDecl _ k args _ vds stms) = //varDecls can call the enclosing function, so first reserve a label for it updateAdressbook (extend k (LAB k)) >>| + getAdressbook >>= \oldMap -> + updateAdressbook (addVars args) >>| 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 -//load k = genMap >>= \g-> case 'Map'.member k g of -// False = liftT (Left $ Error $ concat ["PANIC: ", k, " not found in variable mapping"]) -// True = loadP $ 'Map'.find k g -// -//loadP :: LoadPlace -> Gen Instr -//loadP pl = dec pl >>= \(instr, arg)-> pure $ Instr instr [arg] "" -//where -// dec (LDA i) = pure ("lda", Lit i) -// dec (LDC i) = pure ("ldc", Lit i) -// dec (LDH i) = pure ("ldh", Lit i) -// dec (LDL i) = pure ("ldl", Lit i) -// dec (LDR i) = pure ("ldr", Lit i) -// dec (LDS i) = pure ("lds", Lit i) -// dec _ = liftT (Left $ Error "PANIC: trying to load non adres") -// -////Instruction (String), key of function to jump to -//jump :: String String -> Gen Instr -//jump instr k = genMap >>= \g-> case 'Map'.member k g of -// False = liftT (Left $ Error $ concat ["PANIC: ", k, " not found as function"]) -// True = dec ('Map'.find k g) >>= \lbl-> pure $ Instr instr [lbl] (k +++"()") -//where -// dec (FUNC l) = pure (L l) -// dec _ = liftT (Left $ Error "PANIC: trying to jump to non label") class print a :: a -> [String]