module Language.Pascal.Builtin (i, push, builtinFunctions, lookupBuiltin ) where import Control.Monad.State import Language.SSVM.Types import Language.Pascal.Types -- | Add any stack item to the code putItem :: StackItem -> Generate () putItem x = do st <- get let gen = generated st code = x: cCode (generated st) put $ st {generated = gen {cCode = code}} -- | Generate instruction i :: Instruction -> Generate () i x = do q <- gets quoteMode if q then putItem (Quote $ SInstruction x) else putItem (SInstruction x) -- | Generate PUSH instruction push :: StackType a => a -> Generate () push x = i (PUSH $ toStack x) -- | List of builtin functions builtinFunctions :: [(Id, Type, Generate ())] builtinFunctions = [("write", TFunction [TAny] TVoid, write), ("writeln", TFunction [TAny] TVoid, writeln), ("readln", TFunction [] TAny, readln) ] -- | If named symbol is builtin, return it's definition lookupBuiltin :: Id -> Maybe (Generate ()) lookupBuiltin name = look builtinFunctions where look [] = Nothing look ((s, _, code):other) | s == name = Just code | otherwise = look other write :: Generate () write = i PRINT writeln :: Generate () writeln = do i PRINT push "\n" i PRINT readln :: Generate () readln = i INPUT