Skip to content

Commit

Permalink
♻️ register globals in env before compilation
Browse files Browse the repository at this point in the history
  • Loading branch information
laendoor committed Dec 15, 2021
1 parent d12f62d commit 9230178
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 31 deletions.
25 changes: 17 additions & 8 deletions src/Mamarracho.hs
Original file line number Diff line number Diff line change
Expand Up @@ -17,18 +17,27 @@ compile :: Program -> MamCode
compile prog = showCode $ getCode $ execState (compile' prog) initState

compile' :: Program -> Mam ()
compile' [] = return ()
compile' (def:program) = do
compile' prog = registerGlobals prog >> compile'' prog

registerGlobals :: Program -> Mam ()
registerGlobals [] = return ()
registerGlobals ((Def x _):program) = do
extendEnv (x, BRegister $ Global $ "G_" ++ x)
registerGlobals program

compile'' :: Program -> Mam ()
compile'' [] = return ()
compile'' (def:program) = do
compileDef def
compile' program

compileDef :: Definition -> Mam ()
compileDef (Def _id e) = do
let greg = Global $ "G_" ++ _id
compileExpr e greg
extendEnv (_id, BRegister greg)
return ()

compileDef (Def x e) = do
res <- lookupEnv x
case res of
Just (BRegister reg) -> compileExpr e reg
_ -> error $ "GLOBAL " ++ x ++ " SHOULD BE DEFINED"
compileExpr :: Expr -> Reg -> Mam ()
compileExpr (ExprVar _id) reg = compileVariable _id reg
compileExpr (ExprNumber n) reg = compilePrimitiveValue tagNumber n reg
Expand Down
23 changes: 1 addition & 22 deletions src/State.hs
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
module State where

import Control.Monad.State (State, MonadState(get, put), gets)
import Types (Instruction (Comment), StackEnv, ID, Binding(..), Env, Reg(Local), Label)
import Data.List (intercalate)
import Types (Instruction(..), StackEnv, ID, Binding(..), Env, Label)

type Mam = State MamState

Expand Down Expand Up @@ -48,16 +47,6 @@ getEnv = gets (head . env)
lookupEnv :: ID -> Mam (Maybe Binding)
lookupEnv x = lookup x <$> getEnv

lookupEnvRegister :: ID -> Mam Reg
lookupEnvRegister x = do
env' <- getEnv
let regEnv = filter (isReg . snd) env'
case lookup x regEnv of
Just (BRegister reg) -> return reg
_ -> do
_ <- lookupEnvError x
return $ Local "_err"

isReg :: Binding -> Bool
isReg (BRegister _) = True
isReg (BEnclosed _) = False
Expand All @@ -81,16 +70,6 @@ popEnv = do
put $ mam { env = tail $ env mam }
return $ head $ env mam

lookupEnvError :: ID -> Mam String
lookupEnvError x = do
env' <- getEnv
stackEnv' <- getStackEnv
let stackEnv'' = map show stackEnv'
error $ "'" ++ show x ++ "' is not defined in "
++ show env'
++ "\nStackEnv: \n"
++ intercalate "\n" stackEnv''

-- Code Stack

getStack :: Mam Stack
Expand Down
2 changes: 1 addition & 1 deletion src/Types.hs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ type StackEnv = [Env]

type NumOp = (Reg, Reg, Reg) -> Instruction

data VarType = TPrinter | TOper | TVar
data VarType = TPrinter | TOper | TVar deriving Show

data Reg = Global String
| Local String
Expand Down

0 comments on commit 9230178

Please sign in to comment.