Add LVal to AST

This commit is contained in:
2025-09-02 20:00:33 -04:00
parent b9fc9c2845
commit 03161b228b
4 changed files with 43 additions and 7 deletions

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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 "-="