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
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
- >>| mapM_ (const $ tell [Instr "ajs" [Lit -1] ""]) es //clean up args
>>| 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
variableStream :: [TVar]
variableStream = map toString [1..]
+defaultGamma :: Gamma //includes all default functions
+defaultGamma = extend "print" (Forall ["a"] ((IdType "a") ->> VoidType))
+ $ extend "isEmpty" (Forall ["a"] (ListType (IdType "a") ->> BoolType))
+ $ extend "read" (Forall [] (IntType ->> (ListType CharType)))
+ zero
+
sem :: AST -> Either [SemError] AST
sem (AST fd) = case foldM (const $ hasNoDups fd) () fd
>>| foldM (const isNiceMain) () fd
>>| hasMain fd
- >>| evalStateT (type fd) (zero, variableStream) of
+ >>| evalStateT (type fd) (defaultGamma, variableStream) of
Left e = Left [e]
Right (_,fds) = Right (AST fds)
where