Skip to content

Commit

Permalink
removed type table dependencies from backend
Browse files Browse the repository at this point in the history
  • Loading branch information
clifordjoshy committed Feb 4, 2022
1 parent 0bc8a84 commit 596ab97
Show file tree
Hide file tree
Showing 6 changed files with 84 additions and 77 deletions.
98 changes: 45 additions & 53 deletions Stage6/CodeGen.hs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import qualified Data.Map as Map
import LabelLink (replaceLabels)
import SymbolTable
import SyntaxTree
import TypeTable
import XsmGen

allRegs :: [String]
Expand All @@ -26,42 +25,38 @@ getRegsUsed freeRegs = allRegs \\ freeRegs

-- | resolves a symbol name and returns the address in a register
-- | symName -> reg -> globalSymbolT -> localSymbolT -> (code, sym)
symbolResolve :: String -> String -> GSymbolTable -> LSymbolTable -> (String, String)
symbolResolve :: String -> String -> GSymbolTable -> LSymbolTable -> String
symbolResolve name r gst lst = case Map.lookup name lst of
Just (lType, lAddr) -> (lType, genMovXsm r "BP" ++ genArmcXsm '+' r (show lAddr))
Nothing -> let sym = gst Map.! name in (getSymbolType sym, genMovXsm r (show $ getSymbolAddress sym))
Just (lType, lAddr) -> genMovXsm r "BP" ++ genArmcXsm '+' r (show lAddr)
Nothing -> let sym = gst Map.! name in genMovXsm r (show $ getSymbolAddress sym)

-- | Resolves a dot field and returns code. Stores final address in passed register
-- | tTable -> startType -> reg(with sym address) -> dotlist -> tempReg -> Code
dotResolve :: TypeTable -> String -> String -> [String] -> String -> String
dotResolve _ _ _ [] _ = ""
dotResolve tTable p r (c : ds) tempReg = code ++ dotResolve tTable cType r ds tempReg
-- | dotlist -> reg(with sym address) -> tempReg -> Code
dotResolve :: [Int] -> String -> String -> String
dotResolve [] _ _ = ""
dotResolve (c : ds) r tempReg = code ++ dotResolve ds r tempReg
where
pFields = tTable Map.! p
(childIndex, (cType, _)) = case findIndex ((c ==) . snd) pFields of
Just i -> (i, pFields !! i)
Nothing -> error "Shouldn't be an error"
code = genMovXsm tempReg (accessMem r) ++ genArmcXsm '+' tempReg (show childIndex) ++ genMovXsm r tempReg
code = genMovXsm tempReg (accessMem r) ++ genArmcXsm '+' tempReg (show c) ++ genMovXsm r tempReg

-- | varName -> resolver -> freeRegs -> GSymbolTable -> LSymbolTable -> (code, reg, remainingRegs)
-- | Returns code to resolve a variable address and stores the address in a register
genAddrResolveCode :: String -> VarResolve -> [String] -> GSymbolTable -> LSymbolTable -> TypeTable -> (String, String, [String])
genAddrResolveCode name Simple regs gst lst _ = (symCode, symReg, regs2)
genAddrResolveCode :: String -> VarResolve -> [String] -> GSymbolTable -> LSymbolTable -> (String, String, [String])
genAddrResolveCode name Simple regs gst lst = (symCode, symReg, regs2)
where
(symReg, regs2) = getReg regs
(_, symCode) = symbolResolve name symReg gst lst
genAddrResolveCode name Deref regs gst lst _ = (symCode ++ genMovXsm valReg (accessMem symReg), valReg, regs2)
symCode = symbolResolve name symReg gst lst
genAddrResolveCode name Deref regs gst lst = (symCode ++ genMovXsm valReg (accessMem symReg), valReg, regs2)
where
(valReg, regs2) = getReg regs
(symReg, regs3) = getReg regs2
(_, symCode) = symbolResolve name symReg gst lst
genAddrResolveCode name (Dot dotList) regs gst lst tTable = (symCode ++ dotCode, valReg, regs2)
symCode = symbolResolve name symReg gst lst
genAddrResolveCode name (Dot dotList) regs gst lst = (symCode ++ dotCode, valReg, regs2)
where
(valReg, regs2) = getReg regs
(tempReg, _) = getReg regs2
(symType, symCode) = symbolResolve name valReg gst lst
dotCode = dotResolve tTable symType valReg dotList tempReg
genAddrResolveCode name (Index i) regs gst lst _ =
symCode = symbolResolve name valReg gst lst
dotCode = dotResolve dotList valReg tempReg
genAddrResolveCode name (Index i) regs gst lst =
( symCode
++ iCode
++ genArmcXsm '+' symReg iReg,
Expand All @@ -71,8 +66,8 @@ genAddrResolveCode name (Index i) regs gst lst _ =
where
(symReg, regs2) = getReg regs
(iCode, iReg, _, _) = genCode Args {node = i, regsFree = regs2, gSymTable = gst, lSymTable = lst}
(_, symCode) = symbolResolve name symReg gst lst
genAddrResolveCode name (Index2D i j) regs gst lst _ =
symCode = symbolResolve name symReg gst lst
genAddrResolveCode name (Index2D i j) regs gst lst =
( symCode
++ iCode
++ jCode
Expand All @@ -85,26 +80,25 @@ genAddrResolveCode name (Index2D i j) regs gst lst _ =
where
(symReg, regs2) = getReg regs
(iCode, iReg, regs3, _) = genCode Args {node = i, regsFree = regs2, gSymTable = gst, lSymTable = lst, labels = [], blockLabels = Nothing}
(_, symCode) = symbolResolve name symReg gst lst
symCode = symbolResolve name symReg gst lst
(Arr2 _ m n _) = gst Map.! name
(jCode, jReg, _, _) = genCode Args {node = j, regsFree = regs3, gSymTable = gst, lSymTable = lst, labels = [], blockLabels = Nothing}

-- | varName -> resolver -> freeRegs -> GSymbolTable -> LSymbolTable -> TypeTable -> (code, reg, remainingRegs)
-- | varName -> resolver -> freeRegs -> GSymbolTable -> LSymbolTable -> (code, reg, remainingRegs)
-- | Returns code to resolve a variable value and stores the value in a register
genValResolveCode :: String -> VarResolve -> [String] -> GSymbolTable -> LSymbolTable -> TypeTable -> (String, String, [String])
genValResolveCode name resolv regs gst lst tt = (addrCode ++ genMovXsm valReg (accessMem addrReg), valReg, rs)
genValResolveCode :: String -> VarResolve -> [String] -> GSymbolTable -> LSymbolTable -> (String, String, [String])
genValResolveCode name resolv regs gst lst = (addrCode ++ genMovXsm valReg (accessMem addrReg), valReg, rs)
where
(valReg, rs) = getReg regs
(addrCode, addrReg, _) = genAddrResolveCode name resolv rs gst lst tt
(addrCode, addrReg, _) = genAddrResolveCode name resolv rs gst lst

data CodeArgs = Args
{ node :: SyntaxTree,
regsFree :: [String],
labels :: [String],
blockLabels :: Maybe (String, String),
gSymTable :: GSymbolTable,
lSymTable :: LSymbolTable,
tTable :: TypeTable
lSymTable :: LSymbolTable
}

-- | syntaxTree -> freeRegisters -> labels -> Maybe (startLabel, endLabel) -> (code, usedregister, remainingRegisters, remainingLabels)
Expand All @@ -125,8 +119,8 @@ genCode a@Args {node = LeafNull} = (genMovXsm r "0", r, remainingRegs, labels)
Args {regsFree = regsFree, labels = labels} = a
genCode a@Args {node = (LeafVar var resolver)} = (code, r, rs, labels)
where
Args {regsFree = regsFree, labels = labels, gSymTable = gst, lSymTable = lst, tTable = tt} = a
(code, r, rs) = genValResolveCode var resolver regsFree gst lst tt
Args {regsFree = regsFree, labels = labels, gSymTable = gst, lSymTable = lst} = a
(code, r, rs) = genValResolveCode var resolver regsFree gst lst
genCode a@Args {node = (LeafFn name params)} = (genFnCallXsm usedRegs fnLabel argCodes returnReg, returnReg, rs, labels)
where
Args {regsFree = regsFree, labels = labels, gSymTable = gst} = a
Expand All @@ -139,8 +133,8 @@ genCode a@Args {node = (LeafFn name params)} = (genFnCallXsm usedRegs fnLabel ar
-- Operator Nodes
genCode a@Args {node = (NodeRef (LeafVar var resolver))} = (argCode, r, rem, labels)
where
Args {regsFree = regsFree, labels = labels, gSymTable = gst, lSymTable = lst, tTable = tt} = a
(argCode, r, rem) = genAddrResolveCode var resolver regsFree gst lst tt
Args {regsFree = regsFree, labels = labels, gSymTable = gst, lSymTable = lst} = a
(argCode, r, rem) = genAddrResolveCode var resolver regsFree gst lst
genCode a@Args {node = (NodeArmc op l r)} = (lCode ++ rCode ++ genArmcXsm op lReg rReg, lReg, regRemaining, labels)
where
(lCode, lReg, regRemaining, _) = genCode a {node = l}
Expand Down Expand Up @@ -209,9 +203,9 @@ genCode a@Args {node = NodeCont, regsFree = fr, labels = lb, blockLabels = bl} =
genCode a@Args {node = (NodeAssign (LeafVar var varResolver) r)} = (code, "", regsFree, labels)
where
(rCode, rReg, regs2, _) = genCode a {node = r}
(lCode, lReg, _) = genAddrResolveCode var varResolver regs2 gst lst tt
(lCode, lReg, _) = genAddrResolveCode var varResolver regs2 gst lst
code = rCode ++ lCode ++ genMovXsm (accessMem lReg) rReg
Args {regsFree = regsFree, labels = labels, gSymTable = gst, lSymTable = lst, tTable = tt} = a
Args {regsFree = regsFree, labels = labels, gSymTable = gst, lSymTable = lst} = a
genCode a@Args {node = (NodeConn l r)} = (lCode ++ rCode, rReg, regsFree, remainingLabels)
where
(lCode, _, _, labels2) = genCode a {node = l}
Expand All @@ -232,10 +226,10 @@ genCode a@Args {node = (NodeWrite arg)} = (argCode ++ genLibXsm usedRegs "Write"
(retReg, regsRem) = getReg regsFree
genCode a@Args {node = (NodeRead arg)} = (argCode ++ genLibXsm usedRegs "Read" libArgs retReg, retReg, regsRem, labels)
where
Args {regsFree = regsFree, labels = labels, gSymTable = gst, lSymTable = lst, tTable = tt} = a
Args {regsFree = regsFree, labels = labels, gSymTable = gst, lSymTable = lst} = a
usedRegs = getRegsUsed regsFree
(LeafVar var varResolver) = arg
(argCode, argReg, regRem) = genAddrResolveCode var varResolver regsRem gst lst tt
(argCode, argReg, regRem) = genAddrResolveCode var varResolver regsRem gst lst
libArgs = (ValInt $ -1, Reg argReg, None)
(retReg, regsRem) = getReg regsFree
genCode a@Args {node = NodeInitialize} = (genLibXsm usedRegs "Heapset" libArgs retReg, retReg, regsRem, labels)
Expand All @@ -244,14 +238,13 @@ genCode a@Args {node = NodeInitialize} = (genLibXsm usedRegs "Heapset" libArgs r
usedRegs = getRegsUsed regsFree
libArgs = (None, None, None)
(retReg, regsRem) = getReg regsFree
genCode a@Args {node = (NodeAlloc var@(LeafVar vName vRes))} = (code, "", regsFree, labels)
genCode a@Args {node = (NodeAlloc var@(LeafVar vName vRes) size)} = (code, "", regsFree, labels)
where
Args {regsFree = regsFree, labels = labels, gSymTable = gst, lSymTable = lst, tTable = tTable} = a
Args {regsFree = regsFree, labels = labels, gSymTable = gst, lSymTable = lst} = a
usedRegs = getRegsUsed regsFree
varSize = getTypeSize tTable $ findVarType gst lst tTable var
libArgs = (ValInt varSize, None, None)
libArgs = (ValInt size, None, None)
(retReg, regsRem) = getReg regsFree
(lCode, lReg, _) = genAddrResolveCode vName vRes regsRem gst lst tTable
(lCode, lReg, _) = genAddrResolveCode vName vRes regsRem gst lst
code = genLibXsm usedRegs "Alloc" libArgs retReg ++ lCode ++ genMovXsm (accessMem lReg) retReg
genCode a@Args {node = (NodeFree var)} = (varCode ++ genLibXsm usedRegs "Free" libArgs retReg, retReg, regsRem, labels)
where
Expand All @@ -270,8 +263,8 @@ type FDef = (String, String, [String], LSymbolTable, SyntaxTree)

-- Generates code for a function
-- FDef -> GSymbolTable -> labels -> (remainingLabels, code)
genFnCode :: FDef -> GSymbolTable -> TypeTable -> [String] -> ([String], String)
genFnCode (_, name, params, lSym, ast) gSym tTable labels =
genFnCode :: FDef -> GSymbolTable -> [String] -> ([String], String)
genFnCode (_, name, params, lSym, ast) gSym labels =
( remainingLabels,
genLabelXsm label
++ genStackXsm PUSH "BP"
Expand All @@ -297,19 +290,18 @@ genFnCode (_, name, params, lSym, ast) gSym tTable labels =
labels = labels,
blockLabels = Nothing,
gSymTable = gSym,
lSymTable = lSym,
tTable = tTable
lSymTable = lSym
}
lVarRelCode = concat $ replicate lVarCount (genStackXsm POP "R0")

-- GSymbolTable -> sp -> typetable -> fDecls -> mainBlock -> code
codeGen :: GSymbolTable -> Int -> TypeTable -> [FDef] -> (LSymbolTable, SyntaxTree) -> String
codeGen gTable sp tTable fDecls main = header ++ code
-- GSymbolTable -> sp -> fDecls -> mainBlock -> code
codeGen :: GSymbolTable -> Int -> [FDef] -> (LSymbolTable, SyntaxTree) -> String
codeGen gTable sp fDecls main = header ++ code
where
header = unlines $ map show [0, 2056, 0, 0, 0, 0, 0, 0]
(labelsRem, codeList) = mapAccumL (\a b -> genFnCode b gTable tTable a) ["L" ++ show i | i <- [0, 1 ..]] fDecls
(labelsRem, codeList) = mapAccumL (\a b -> genFnCode b gTable a) ["L" ++ show i | i <- [0, 1 ..]] fDecls
(mainLSym, mainAst) = main
(_, mainCode) = genFnCode ("int", "main", [], mainLSym, mainAst) gTable tTable labelsRem
(_, mainCode) = genFnCode ("int", "main", [], mainLSym, mainAst) gTable labelsRem
(initCode, _, _, _) = genCode Args {node = LeafFn "main" [], regsFree = allRegs, gSymTable = gTable}
labelledCode = genMovXsm "SP" (show sp) ++ initCode ++ "INT 10\n" ++ concat codeList ++ mainCode
-- code = labelledCode
Expand Down
5 changes: 2 additions & 3 deletions Stage6/Compiler.hs
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,10 @@ main = do
args <- getArgs
inputFile <- openFile (head args) ReadMode
fileContents <- hGetContents inputFile
let (tTable, gTable, sp, fDecl, main) = parseTokens (scanTokens fileContents)
let (gTable, sp, fDecl, main) = parseTokens (scanTokens fileContents)
-- print gTable
-- print tTable
-- print fDecl
-- let (_, mainAst) = main in putStr $ prettyPrint mainAst
let code = codeGen gTable sp tTable fDecl main
let code = codeGen gTable sp fDecl main
createOutputFile code
hClose inputFile
6 changes: 3 additions & 3 deletions Stage6/Parser.y
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ Stmt : Variable '=' RVal ';' {% let (t, v) = $3 in
| BREAK ';' { NodeBreak }
| CONTINUE ';' { NodeCont }
| FnCall ';' { $1 }
| Variable '=' ALLOC '(' ')' ';' {% varType $1 >>= userTypeCheck >> return (NodeAlloc $1) }
| Variable '=' ALLOC '(' ')' ';' {% varType $1 >>= \t -> (userTypeCheck t >> typeSize t) >>= \s -> return (NodeAlloc $1 s) }

E2 : E '+' E { NodeArmc '+' $1 $3 }
| E '-' E { NodeArmc '-' $1 $3 }
Expand Down Expand Up @@ -202,7 +202,7 @@ Variable : id {% symCheck (isUnit) $1 >> return (LeafV
| id '[' E ']' {% symCheck (isArr) $1 >> return (LeafVar $1 (Index $3)) }
| id '['E']' '['E']' {% symCheck (isArr2) $1 >> return (LeafVar $1 (Index2D $3 $6)) }
| '*' id {% symCheck (isPtr) $2 >> return (LeafVar $2 Deref) }
| DotField {% let n:d = $1 in (dotSymCheck n d >> return(LeafVar n (Dot d))) }
| DotField {% (let n:ds = $1 in dotSymCheck n ds >>= \di -> return (LeafVar n (Dot di))) }

DotField : DotField '.' id { $1 ++ [$3] }
| id '.' id { [$1, $3] }
Expand All @@ -219,7 +219,7 @@ Main: MAIN {% saveMainFn }

parseError t = error $ "Parse error: " ++ show t

parseTokens tokenStream = (tTable, gSymFull, sp, fDecl, main)
parseTokens tokenStream = (gSymFull, sp, fDecl, main)
where
((sp, fDecl, main), (tTable, gSymTable, _, _)) = runState (parse tokenStream) startState
gSymFull = Map.insertWith (error "Main function declared twice") "main" (Func "int" [] "main") gSymTable
Expand Down
22 changes: 14 additions & 8 deletions Stage6/ParserState.hs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module ParserState where

import Control.Monad.State (MonadState (get, put), State, unless)
import Control.Monad.State (MonadState (get, put), State)
import Data.Bifunctor (second)
import qualified Data.Map as Map
import SymbolTable
Expand Down Expand Up @@ -110,6 +110,14 @@ fnCallTypeCheck name params = do
else error $ "Function call doesnt match definition: " ++ name ++ show (map fst params)
_ -> error $ "Function call is invalid: " ++ name

-- Typechecks and returns modified index dotfields
dotSymCheck :: String -> [String] -> State ParserState [Int]
dotSymCheck symName dots = do
(tTable, _, _, symTab) <- get
case Map.lookup symName symTab of
Just s -> return $ dotStrToIndex tTable (getSymbolType s) dots
Nothing -> error $ "Variable does not exist : " ++ symName

retTypeCheck :: String -> State ParserState ()
retTypeCheck t = do
(_, _, cFn, _) <- get
Expand All @@ -128,13 +136,6 @@ userTypeCheck tName = do
Just _ -> return ()
Nothing -> error $ "Cannot do heap operations on " ++ tName

dotSymCheck :: String -> [String] -> State ParserState ()
dotSymCheck symName dots = do
(tTable, _, _, symTab) <- get
case Map.lookup symName symTab of
Just s -> unless (null (resolveDotType tTable (getSymbolType s) dots)) (return ())
Nothing -> error $ "Variable does not exist : " ++ symName

intCheck :: SyntaxTree -> State ParserState SyntaxTree
intCheck n = do
(tt, _, _, symTab) <- get
Expand All @@ -152,6 +153,11 @@ varType n = do
(tt, _, _, symTab) <- get
return $ getVarType symTab tt n

typeSize :: String -> State ParserState Int
typeSize tName = do
(tt, _, _, _) <- get
return $ getTypeSize tt tName

fnType :: SyntaxTree -> State ParserState String
fnType n = do
(_, _, _, symTab) <- get
Expand Down
8 changes: 4 additions & 4 deletions Stage6/SyntaxTree.hs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ data VarResolve
| Deref
| Index SyntaxTree
| Index2D SyntaxTree SyntaxTree
| Dot [String]
| Dot [Int]
deriving (Show)

data SyntaxTree
Expand All @@ -22,7 +22,7 @@ data SyntaxTree
| NodeRead SyntaxTree
| NodeWrite SyntaxTree
| NodeInitialize
| NodeAlloc SyntaxTree
| NodeAlloc SyntaxTree Int
| NodeFree SyntaxTree
| NodeArmc Char SyntaxTree SyntaxTree
| NodeBool String SyntaxTree SyntaxTree
Expand Down Expand Up @@ -65,7 +65,7 @@ getFnType st (NodeRead _) = "int"
getFnType st (NodeWrite _) = "int"
getFnType st NodeInitialize = "int"
getFnType st (NodeFree _) = "int"
getFnType st (NodeAlloc _) = "int"
getFnType st (NodeAlloc _ _) = "int"
getFnType _ _ = error "Not a function"

toDataTree :: SyntaxTree -> Tree String
Expand All @@ -79,7 +79,7 @@ toDataTree t = case t of
NodeWhile cond bl -> Node "While" [toDataTree cond, toDataTree bl]
NodeRead t -> Node "Read" [toDataTree t]
NodeWrite t -> Node "Write" [toDataTree t]
NodeAlloc t -> Node "Alloc" [toDataTree t]
NodeAlloc t s -> Node ("Alloc " ++ show s) [toDataTree t]
NodeFree t -> Node "Free" [toDataTree t]
_ -> Node (show t) []

Expand Down
22 changes: 16 additions & 6 deletions Stage6/TypeTable.hs
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,23 @@ type TypeTable = Map.Map String [Field] -- Name -> TypeInfo

-- | Check if a list of dot access is valid on a given type and returns final type
-- | TypeTable -> startType -> [DotList] -> FinalType
resolveDotType :: TypeTable -> String -> [String] -> String
resolveDotType tTable = foldl' childType
resolveDotType :: TypeTable -> String -> [Int] -> String
resolveDotType tTable = foldl' (\pType cIndex -> fst ((tTable Map.! pType) !! cIndex))

-- | Converts a dot list of strings to field indices
-- | TypeTable -> startType -> stringFields -> indexFields
dotStrToIndex :: TypeTable -> String -> [String] -> [Int]
dotStrToIndex tTable startType fields = intFields
where
childType :: String -> String -> String
childType pType cName = case find ((cName ==) . snd) (tTable Map.! pType) of
Just (tName, _) -> tName
Nothing -> error $ "Type " ++ pType ++ " does not contain child " ++ cName
mapFn :: String -> String -> (String, Int)
mapFn pType cName = (cType, childIndex)
where
pFields = tTable Map.! pType
(childIndex, (cType, _)) = case findIndex ((cName ==) . snd) pFields of
Just i -> (i, pFields !! i)
Nothing -> error $ "Type " ++ pType ++ " does not contain child " ++ cName

(_, intFields) = mapAccumL mapFn startType fields

-- | Returns the size of a given type string
getTypeSize :: TypeTable -> String -> Int
Expand Down

0 comments on commit 596ab97

Please sign in to comment.