X-Git-Url: https://git.martlubbers.net/?a=blobdiff_plain;f=gen.icl;h=d139804acf681111aa45a4279e72d4fc7bc3de00;hb=f081c2c5e248331eb6e2f090f4afe818fd8259eb;hp=a00275d6b5d14047dc2e2d8f7173061d2d7b7562;hpb=8472f6d9507fd0116ac85d02e8ed5566ef8e7980;p=cc1516.git diff --git a/gen.icl b/gen.icl index a00275d..d139804 100644 --- a/gen.icl +++ b/gen.icl @@ -39,24 +39,45 @@ FALSE :== 0 labelStream :: [Label] labelStream = ["lbl_" +++ toString i\\i<-[1..]] +defaultAddressBook :: Addressbook +defaultAddressBook = extend "print" (LAB "print") + $ extend "read" (LAB "read") + $ extend "isEmpty" (LAB "isEmpty") + 'Map'.newMap + gen :: AST -> Either String String -gen (AST fds) = case evalRWST prog () ('Map'.newMap, labelStream) of +gen (AST fds) = case evalRWST prog () (defaultAddressBook, labelStream) of Left (Error e) = Left e Right (_, p) = Right $ toString p where prog = tell [ Instr "bsr" [L "main"] "", Instr "halt" [] "" - ] >>| mapM_ g fds - -//Current issues: -//All VarDecls are added as function, how to deal with assignments? -// (And when we deal with assignments, how to deal with assignments to higher order functions?) -//Dealing with arguments -//Dealing with types that do not fit on the Stack -// Probably completely change LoadPlace to a Type and a position relative to *something* -// And where the type determines if this position is a pointer to the heap or an -// unboxed value + ] >>| tell programContext + >>| mapM_ g fds + +programContext :: SSMProgram +programContext = [Lab "print" //there is no actual IO in SSM + ,Instr "link" [Lit 0] "" + ,Instr "unlink" [] "" + ,Instr "ret" [] "" + ,Lab "read" //there is no actual IO in SSM + ,Instr "link" [Lit 0] "" + ,Instr "ldc" [Lit 0] "" + ,Instr "sth" [] "" + ,Instr "str" [Raw "RR"] "" + ,Instr "unlink" [] "" + ,Instr "ret" [] "" + ,Lab "isEmpty" + ,Instr "link" [Lit 0] "" + ,Instr "ldl" [Lit -2] "load prt to list" + ,Instr "lda" [Lit 0] "derefrence ptr" + ,Instr "ldc" [Lit 0] "" + ,Instr "eq" [] "test for null pointer" + ,Instr "str" [Raw "RR"] "" + ,Instr "unlink" [] "" + ,Instr "ret" [] "" + ] //helper functions for the gen monad getAdressbook :: Gen Addressbook @@ -121,8 +142,9 @@ instance g Expr where 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) = - mapM g es + mapM_ g es >>| jump "bsr" k + >>| mapM_ (const $ tell [Instr "ajs" [Lit -1] ""]) es //clean up args >>| tell [Instr "ldr" [Raw "RR"] ""] jump :: String String -> Gen () @@ -156,7 +178,10 @@ instance g Stmt where Nothing = liftT (Left $ Error $ concat ["PANIC: ", k, " not found as var"]) Just (LAB t) = liftT (Left $ Error $ "PANIC: cannot assign to function") Just (ADDR t) = tell [Instr "stl" [Lit t] ""] - g (FunStmt k es) = mapM g es >>| jump "bsr" k + g (FunStmt k es) = mapM_ g es + >>| jump "bsr" k + >>| mapM_ (const $ tell [Instr "ajs" [Lit -1] ""]) es //clean up args + >>| pure () g (ReturnStmt Nothing) = tell [Instr "unlink" [] ""] >>| tell [Instr "ret" [] ""] g (ReturnStmt (Just e)) = g e @@ -165,6 +190,7 @@ instance g Stmt where foldVarDecl :: Int VarDecl -> Gen Int foldVarDecl x (VarDecl _ _ k e) = g e + >>| annote x k >>| updateAdressbook (extend k (ADDR x)) >>| pure (x + 1) addVars :: [String] -> (Addressbook -> Addressbook) @@ -179,12 +205,16 @@ instance g FunDecl where updateAdressbook (addVars args) >>| tell [Lab k] >>| tell [Instr "link" [Lit 0] ""] >>| - //then generate functions for the VarDecls + //add the vars foldM foldVarDecl 1 vds >>| - //then the main function + //and the statements mapM_ g stms >>| updateAdressbook (const oldMap) >>| pure () +annote :: Int String -> Gen () +annote pos key = + tell [Instr "annote" [Raw "MP", Lit pos, Lit pos, Raw "green", Raw key] ""] + class print a :: a -> [String] instance print Instr where