Add LVal to AST
This commit is contained in:
@@ -35,6 +35,14 @@ instance Arbitrary AssignOp where
|
|||||||
arbitrary = elements [BaseAssign, AddAssign, SubAssign, MulAssign, DivAssign,
|
arbitrary = elements [BaseAssign, AddAssign, SubAssign, MulAssign, DivAssign,
|
||||||
ModAssign, BitAndAssign, BitOrAssign, BitXorAssign, ShiftLAssign, ShiftRAssign]
|
ModAssign, BitAndAssign, BitOrAssign, BitXorAssign, ShiftLAssign, ShiftRAssign]
|
||||||
|
|
||||||
|
instance Arbitrary LVal where
|
||||||
|
arbitrary = oneof
|
||||||
|
[ LId <$> arbitrary
|
||||||
|
, LIndex <$> arbitrary <*> arbitrary
|
||||||
|
, LDeref <$> arbitrary
|
||||||
|
, LMember <$> arbitrary <*> arbitrary
|
||||||
|
]
|
||||||
|
|
||||||
instance Arbitrary Expr where
|
instance Arbitrary Expr where
|
||||||
arbitrary = oneof
|
arbitrary = oneof
|
||||||
[ Id <$> arbitrary
|
[ Id <$> arbitrary
|
||||||
|
|||||||
@@ -48,6 +48,13 @@ data AssignOp
|
|||||||
| ShiftRAssign
|
| ShiftRAssign
|
||||||
deriving (Show, Eq)
|
deriving (Show, Eq)
|
||||||
|
|
||||||
|
data LVal
|
||||||
|
= LId Text
|
||||||
|
| LIndex Expr Expr
|
||||||
|
| LDeref Expr
|
||||||
|
| LMember Expr Text
|
||||||
|
deriving (Show, Eq)
|
||||||
|
|
||||||
data Expr
|
data Expr
|
||||||
= Id Text
|
= Id Text
|
||||||
| IntLit Int
|
| IntLit Int
|
||||||
@@ -71,7 +78,7 @@ data Stmt
|
|||||||
| Return Expr
|
| Return Expr
|
||||||
| If Expr [Stmt] (Maybe [Stmt])
|
| If Expr [Stmt] (Maybe [Stmt])
|
||||||
| While Expr [Stmt]
|
| While Expr [Stmt]
|
||||||
| Assign AssignOp Expr Expr
|
| Assign AssignOp LVal Expr
|
||||||
| Block [Stmt]
|
| Block [Stmt]
|
||||||
| Var Text (Maybe Type) (Maybe Expr)
|
| Var Text (Maybe Type) (Maybe Expr)
|
||||||
deriving (Show, Eq)
|
deriving (Show, Eq)
|
||||||
@@ -149,6 +156,12 @@ instance Pretty AssignOp where
|
|||||||
pretty ShiftLAssign = "<<="
|
pretty ShiftLAssign = "<<="
|
||||||
pretty ShiftRAssign = ">>="
|
pretty ShiftRAssign = ">>="
|
||||||
|
|
||||||
|
instance Pretty LVal where
|
||||||
|
pretty (LId x) = pretty (Id x)
|
||||||
|
pretty (LIndex arr idx) = pretty (Index arr idx)
|
||||||
|
pretty (LDeref e) = pretty (UnOp Deref e)
|
||||||
|
pretty (LMember e m) = pretty (Member e m)
|
||||||
|
|
||||||
instance Pretty Expr where
|
instance Pretty Expr where
|
||||||
pretty (Id x) = pretty x
|
pretty (Id x) = pretty x
|
||||||
pretty (IntLit x) = pretty x
|
pretty (IntLit x) = pretty x
|
||||||
|
|||||||
@@ -101,15 +101,15 @@ size VoidType = return 0
|
|||||||
|
|
||||||
|
|
||||||
-- CodeGen for LValues
|
-- CodeGen for LValues
|
||||||
codegenLVal :: Expr -> IRBuilder Operand
|
codegenLVal :: LVal -> IRBuilder Operand
|
||||||
codegenLVal (Id name) = do
|
codegenLVal (LId name) = do
|
||||||
ctx <- get
|
ctx <- get
|
||||||
case lookup name (operands ctx) of
|
case lookup name (operands ctx) of
|
||||||
Just (_type, op) -> return op
|
Just (_type, op) -> return op
|
||||||
Nothing -> error $ "Variable " ++ show name ++ " not found"
|
Nothing -> error $ "Variable " ++ show name ++ " not found"
|
||||||
|
|
||||||
-- TODO support members of members
|
-- TODO support members of members
|
||||||
codegenLVal (Member (Id sName) field) = do
|
codegenLVal (LMember (Id sName) field) = do
|
||||||
ctx <- get
|
ctx <- get
|
||||||
case lookup sName (operands ctx) of
|
case lookup sName (operands ctx) of
|
||||||
Just ((Just (StructType op_type)), struct) -> do
|
Just ((Just (StructType op_type)), struct) -> do
|
||||||
@@ -128,7 +128,7 @@ structFieldOffset (Struct name fields) field = do
|
|||||||
|
|
||||||
-- CodeGen for expressions
|
-- CodeGen for expressions
|
||||||
codegenExpr :: Expr -> IRBuilder Operand
|
codegenExpr :: Expr -> IRBuilder Operand
|
||||||
codegenExpr (Id name) = flip load 0 =<< codegenLVal (Id name)
|
codegenExpr (Id name) = flip load 0 =<< codegenLVal (LId name) -- TODO (?)
|
||||||
codegenExpr (IntLit i) = return $ ConstantOperand (C.Int 32 (fromIntegral i))
|
codegenExpr (IntLit i) = return $ ConstantOperand (C.Int 32 (fromIntegral i))
|
||||||
codegenExpr (UIntLit i) = return $ ConstantOperand (C.Int 32 (fromIntegral i))
|
codegenExpr (UIntLit i) = return $ ConstantOperand (C.Int 32 (fromIntegral i))
|
||||||
codegenExpr (FloatLit f) = undefined -- TODO floats
|
codegenExpr (FloatLit f) = undefined -- TODO floats
|
||||||
@@ -287,7 +287,7 @@ codegenStmt (Assign SubAssign l e) = do
|
|||||||
codegenStmt (Block stmts) = mapM_ codegenStmt stmts
|
codegenStmt (Block stmts) = mapM_ codegenStmt stmts
|
||||||
|
|
||||||
-- Since the vars are already allocated by genBody, we just need to assign the value
|
-- Since the vars are already allocated by genBody, we just need to assign the value
|
||||||
codegenStmt (Var name t (Just e)) = codegenStmt (Assign BaseAssign (Id name) e)
|
codegenStmt (Var name t (Just e)) = codegenStmt (Assign BaseAssign (LId name) e) -- TODO (?)
|
||||||
|
|
||||||
-- Do nothing with variable declaration if no expression is given
|
-- Do nothing with variable declaration if no expression is given
|
||||||
-- This is because allocation is done already
|
-- This is because allocation is done already
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import Control.Monad.Combinators.Expr
|
|||||||
import Text.Megaparsec
|
import Text.Megaparsec
|
||||||
import Windows12.Ast
|
import Windows12.Ast
|
||||||
import Windows12.Lexer
|
import Windows12.Lexer
|
||||||
|
import Data.Text.Prettyprint.Doc (pretty)
|
||||||
|
|
||||||
opTable :: [[Operator Parser Expr]]
|
opTable :: [[Operator Parser Expr]]
|
||||||
opTable =
|
opTable =
|
||||||
@@ -82,6 +83,20 @@ termP =
|
|||||||
exprP :: Parser Expr
|
exprP :: Parser Expr
|
||||||
exprP = makeExprParser termP opTable
|
exprP = makeExprParser termP opTable
|
||||||
|
|
||||||
|
exprToLVal :: Expr -> Maybe LVal
|
||||||
|
exprToLVal (Id x) = Just (LId x)
|
||||||
|
exprToLVal (Index arr idx) = Just (LIndex arr idx)
|
||||||
|
exprToLVal (UnOp Deref e) = Just (LDeref e)
|
||||||
|
exprToLVal (Member e m) = Just (LMember e m)
|
||||||
|
exprToLVal _ = Nothing
|
||||||
|
|
||||||
|
lvalP :: Parser LVal
|
||||||
|
lvalP = do
|
||||||
|
e <- exprP
|
||||||
|
case exprToLVal e of
|
||||||
|
Just lv -> pure lv
|
||||||
|
Nothing -> fail $ "Invalid l-value: " ++ show (pretty e) ++ " (" ++ show e ++ ")"
|
||||||
|
|
||||||
structP :: Parser TLStruct
|
structP :: Parser TLStruct
|
||||||
structP = do
|
structP = do
|
||||||
reserved "struct"
|
reserved "struct"
|
||||||
@@ -104,7 +119,7 @@ typeP = do
|
|||||||
|
|
||||||
assignP :: Parser Stmt
|
assignP :: Parser Stmt
|
||||||
assignP = do
|
assignP = do
|
||||||
lhs <- exprP
|
lhs <- lvalP
|
||||||
op <-
|
op <-
|
||||||
AddAssign <$ symbol "+="
|
AddAssign <$ symbol "+="
|
||||||
<|> SubAssign <$ symbol "-="
|
<|> SubAssign <$ symbol "-="
|
||||||
|
|||||||
Reference in New Issue
Block a user