Skip to content

Commit

Permalink
finished stage 6 backend
Browse files Browse the repository at this point in the history
  • Loading branch information
clifordjoshy committed Feb 3, 2022
1 parent 8ae9651 commit 983cd6a
Show file tree
Hide file tree
Showing 9 changed files with 165 additions and 150 deletions.
225 changes: 113 additions & 112 deletions Stage6/CodeGen.hs

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions Stage6/Compiler.hs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module Main where

-- import CodeGen (codeGen)
import CodeGen (codeGen)
import Parser (parseTokens)
import SymbolTable
import SyntaxTree
Expand All @@ -24,6 +24,6 @@ main = do
print tTable
-- print fDecl
let (_, mainAst) = main in putStr $ prettyPrint mainAst
-- let code = codeGen gTable sp fDecl main
-- createOutputFile code
let code = codeGen gTable sp tTable fDecl main
createOutputFile code
hClose inputFile
2 changes: 1 addition & 1 deletion Stage6/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ Parser.hs : Parser.y
LabelLink.hs : LabelLink.x
alex LabelLink.x

Compiler : Tokens.hs Parser.hs ParserState.hs Compiler.hs SyntaxTree.hs SymbolTable.hs LabelLink.hs XsmGen.hs TypeTable.hs
Compiler : Tokens.hs Parser.hs ParserState.hs Compiler.hs SyntaxTree.hs SymbolTable.hs LabelLink.hs XsmGen.hs TypeTable.hs CodeGen.hs
ghc --make Compiler -outputdir=__intermediate__

clean:
Expand Down
25 changes: 7 additions & 18 deletions Stage6/Parser.y
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,7 @@ RVal : Variable {% varType $1 >>= \t -> return (t, $1) }
| String { ("str", $1) }
| E2 { ("int", $1) }
| '&' Variable {% varType $2 >>= \t -> return (t++"*", NodeRef $2) }
| NULL { ("null", LeafNull) }

Slist : Slist Stmt { NodeConn $1 $2 }
| Stmt { $1 }
Expand All @@ -167,7 +168,6 @@ Stmt : Variable '=' RVal ';' {% let (t, v) = $3 in
| CONTINUE ';' { NodeCont }
| FnCall ';' { $1 }
| Variable '=' ALLOC '(' ')' ';' {% varType $1 >>= userTypeCheck >> return (NodeAlloc $1) }
| Variable '=' NULL ';' {% varType $1 >>= userTypeCheck >> return (NodeAssign $1 LeafNull) }

E2 : E '+' E { NodeArmc '+' $1 $3 }
| E '-' E { NodeArmc '-' $1 $3 }
Expand All @@ -191,17 +191,12 @@ ArgList : ArgList ',' RVal { $1 ++ [$3] }
| RVal { [$1] }
| {- empty -} { [] }

B : E '<' E { NodeBool "<" $1 $3 }
| E '>' E { NodeBool ">" $1 $3 }
| E '<=' E { NodeBool "<=" $1 $3 }
| E '>=' E { NodeBool ">=" $1 $3 }
| Eq { $1 }

Eq : EqVal '==' EqVal { getEqNode True $1 $3 }
| EqVal '!=' EqVal { getEqNode False $1 $3 }

EqVal : RVal { $1 }
| NULL { ("null", LeafNull) }
B : RVal '<' RVal { NodeBool "<" (snd $1) (snd $3) }
| RVal '>' RVal { NodeBool ">" (snd $1) (snd $3) }
| RVal '<=' RVal { NodeBool "<=" (snd $1) (snd $3) }
| RVal '>=' RVal { NodeBool ">=" (snd $1) (snd $3) }
| RVal '==' RVal { NodeBool "==" (snd $1) (snd $3) }
| RVal '!=' RVal { NodeBool "!=" (snd $1) (snd $3) }

Variable : id {% symCheck (isUnit) $1 >> return (LeafVar $1 Simple) }
| id '[' E ']' {% symCheck (isArr) $1 >> return (LeafVar $1 (Index $3)) }
Expand All @@ -222,12 +217,6 @@ Main: MAIN {% saveMainFn }

{

getEqNode :: Bool -> (String, SyntaxTree) -> (String, SyntaxTree) -> SyntaxTree
getEqNode eqOp (t1, v1) (t2, v2) = case (t1, t2) of
("int", "int") -> NodeBool (if eqOp then "==" else "!=") v1 v2
("str", "str") -> NodeBool (if eqOp then "==" else "!=") v1 v2
_ -> NodeTEq eqOp v1 v2

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

parseTokens tokenStream = (tTable, gSymFull, sp, fDecl, main)
Expand Down
18 changes: 14 additions & 4 deletions Stage6/ParserState.hs
Original file line number Diff line number Diff line change
Expand Up @@ -89,27 +89,37 @@ fnTypeCheck (t, name, params, lSym, tree) = do
then return (t, name, params2, lSym, tree)
else error "Function definition does not match declaration"

tEq :: String -> String -> Bool
tEq t1 t2 = case (t1, t2) of
("null", t) -> isUserType t
(t, "null") -> isUserType t
(ta, tb) -> ta == tb
where
isUserType "int" = False
isUserType "str" = False
isUserType _ = True

-- Typechecks and returns given fn defn with modified params
fnCallTypeCheck :: String -> [(String, SyntaxTree)] -> State ParserState [SyntaxTree]
fnCallTypeCheck name params = do
(_, gSymT, _, _) <- get
case Map.lookup name gSymT of
Just (Func _ p2 _) ->
if map fst params == map fst p2
if (length params == length p2) && and (zipWith (\(t1, _) (t2, _) -> tEq t1 t2) params p2)
then return (map snd params)
else error $ "Function call doesnt match definition: " ++ name ++ show (map fst params) ++ show ()
else error $ "Function call doesnt match definition: " ++ name ++ show (map fst params)
_ -> error $ "Function call is invalid: " ++ name

retTypeCheck :: String -> State ParserState ()
retTypeCheck t = do
(_, _, cFn, _) <- get
let (Func td _ _) = cFn
if t == td then return () else error $ "Function returns " ++ t ++ " instead of " ++ td
if t `tEq` td then return () else error $ "Function returns " ++ t ++ " instead of " ++ td

assignTypeCheck :: SyntaxTree -> String -> State ParserState ()
assignTypeCheck n tc = do
t <- varType n
if t == tc then return () else error $ "Cannot assign " ++ tc ++ " to " ++ t
if t `tEq` tc then return () else error $ "Cannot assign " ++ tc ++ " to " ++ t

userTypeCheck :: String -> State ParserState ()
userTypeCheck tName = do
Expand Down
5 changes: 5 additions & 0 deletions Stage6/SymbolTable.hs
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,11 @@ getSymbolAddress (Arr _ _ a) = a
getSymbolAddress (Arr2 _ _ _ a) = a
getSymbolAddress _ = error "No address for function"

findSymbolType :: String -> LSymbolTable -> GSymbolTable -> String
findSymbolType name lst gst = case Map.lookup name lst of
Just (t, _) -> t
Nothing -> getSymbolType (gst Map.! name)

-- | Base declarations -> typetable -> startAddress -> mapFunction -> errorMsg -> (SymbolTable, Size)
symbolTableHelper :: forall tVal. [(String, [SymbolBase])] -> Int -> (String -> SymbolBase -> Int -> (String, tVal)) -> String -> (Map.Map String tVal, Int)
symbolTableHelper decls sa toTableEntry eMsg = (Map.fromListWith (error eMsg) symList, size)
Expand Down
12 changes: 9 additions & 3 deletions Stage6/SyntaxTree.hs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
module SyntaxTree (SyntaxTree (..), VarResolve (..), prettyPrint, isInteger, getVarType, getFnType) where
module SyntaxTree (SyntaxTree (..), VarResolve (..), prettyPrint, isInteger, getVarType, getFnType, findVarType) where

import qualified Data.Map as Map
import Data.Tree (Tree (Node), drawTree)
Expand Down Expand Up @@ -26,7 +26,6 @@ data SyntaxTree
| NodeFree SyntaxTree
| NodeArmc Char SyntaxTree SyntaxTree
| NodeBool String SyntaxTree SyntaxTree
| NodeTEq Bool SyntaxTree SyntaxTree
| NodeAssign SyntaxTree SyntaxTree
| NodeConn SyntaxTree SyntaxTree
| NodeIf SyntaxTree SyntaxTree
Expand All @@ -47,12 +46,20 @@ isInteger _ LeafValInt {} = True
isInteger _ NodeArmc {} = True
isInteger _ _ = False

-- Used in ParserState. Takes merged sym table
getVarType :: GSymbolTable -> TypeTable -> SyntaxTree -> String
getVarType st _ (LeafVar var Deref) = init $ getSymbolType (st Map.! var) -- Remove "*" from the end
getVarType st tt (LeafVar var (Dot dotList)) = resolveDotType tt (getSymbolType (st Map.! var)) dotList
getVarType st _ (LeafVar var _) = getSymbolType (st Map.! var)
getVarType _ _ _ = error "Not a variable"

-- Takes lsym and gsym separately
findVarType :: GSymbolTable -> LSymbolTable -> TypeTable -> SyntaxTree -> String
findVarType gst lst _ (LeafVar var Deref) = init $ findSymbolType var lst gst -- Remove "*" from the end
findVarType gst lst tt (LeafVar var (Dot dotList)) = resolveDotType tt (findSymbolType var lst gst) dotList
findVarType gst lst _ (LeafVar var _) = findSymbolType var lst gst
findVarType _ _ _ _ = error "Not a variable. (shouldn't be thrown)"

getFnType :: GSymbolTable -> SyntaxTree -> String
getFnType st (LeafFn name _) = getSymbolType (st Map.! name)
getFnType st (NodeRead _) = "int"
Expand All @@ -66,7 +73,6 @@ toDataTree :: SyntaxTree -> Tree String
toDataTree t = case t of
NodeArmc c l r -> Node ("Arithmetic " ++ [c]) [toDataTree l, toDataTree r]
NodeBool c l r -> Node ("Boolean " ++ c) [toDataTree l, toDataTree r]
NodeTEq e l r -> Node ("Type Eq-" ++ show e) [toDataTree l, toDataTree r]
NodeConn l r -> Node "NodeConn" [toDataTree l, toDataTree r]
NodeAssign l r -> Node "Assign" [toDataTree l, toDataTree r]
NodeIf cond bl -> Node "If" [toDataTree cond, toDataTree bl]
Expand Down
4 changes: 2 additions & 2 deletions Stage6/TypeTable.hs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ type Field = (String, String) -- TypeName, VarName

type TypeTable = Map.Map String [Field] -- Name -> TypeInfo

-- | Check if a list of dot access is valid on a given type
-- | TypeTable -> startType -> [DotList] -> String
-- | 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
where
Expand Down
18 changes: 11 additions & 7 deletions Stage6/XsmGen.hs
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@ genMovXsm :: String -> String -> String
genMovXsm dest source = "MOV " ++ dest ++ ", " ++ source ++ "\n"

-- | Surrounds a given string in [] for memory access
genMemAccXsm :: String -> String
genMemAccXsm v = "[" ++ v ++ "]"
accessMem :: String -> String
accessMem v = "[" ++ v ++ "]"

-- Appends : to the end defining a label
genLabelXsm :: String -> String
Expand Down Expand Up @@ -68,13 +68,16 @@ genCallXsm lbl = "CALL " ++ lbl ++ "\n"
genRetXsm :: String
genRetXsm = "RET\n"

genIncSpXsm :: String
genIncSpXsm = "INR SP\n"

-- | Generates xsm for a fn call
-- | usedRegs -> FunctionLabel(accessed) -> [code for pushing each arg] -> returnReg -> Code
genFnCallXsm :: [String] -> String -> [String] -> String -> String
genFnCallXsm usedRegs fnLabel argCodes returnReg =
pushRegCode
++ pushArgCode
++ genStackXsm PUSH "R0"
++ genIncSpXsm
++ genCallXsm fnLabel
++ genStackXsm POP returnReg
++ popArgCode
Expand All @@ -95,8 +98,9 @@ genLibXsm usedRegs fnCode (a1, a2, a3) retReg = genFnCallXsm usedRegs "0" argCod
where
evalArg :: LibCallArg -> String
evalArg argType = case argType of
(ValInt val) -> genMovXsm retReg $show val ++ genStackXsm PUSH retReg
(ValString val) -> genMovXsm retReg $show val ++ genStackXsm PUSH retReg
(ValInt val) -> genMovXsm retReg (show val) ++ genStackXsm PUSH retReg
(ValString val) -> genMovXsm retReg (show val) ++ genStackXsm PUSH retReg
(Reg r) -> genStackXsm PUSH r
None -> ""
argCodes = [evalArg a1, evalArg a2, evalArg a3]
None -> genIncSpXsm
fnCodeCode = genMovXsm retReg (show fnCode) ++ genStackXsm PUSH retReg
argCodes = [fnCodeCode, evalArg a1, evalArg a2, evalArg a3]

0 comments on commit 983cd6a

Please sign in to comment.