constructor and method call using this

This commit is contained in:
mrab 2024-05-14 12:29:55 +02:00
parent 86e15b5856
commit d1d9a5d6e1
4 changed files with 72 additions and 61 deletions

View File

@ -42,6 +42,7 @@ data Operation = Opiadd
| Opreturn | Opreturn
| Opireturn | Opireturn
| Opareturn | Opareturn
| Opinvokespecial Word16
| Opgoto Word16 | Opgoto Word16
| Opsipush Word16 | Opsipush Word16
| Opldc_w Word16 | Opldc_w Word16
@ -90,33 +91,34 @@ emptyClassFile = ClassFile {
} }
opcodeEncodingLength :: Operation -> Word16 opcodeEncodingLength :: Operation -> Word16
opcodeEncodingLength Opiadd = 1 opcodeEncodingLength Opiadd = 1
opcodeEncodingLength Opisub = 1 opcodeEncodingLength Opisub = 1
opcodeEncodingLength Opimul = 1 opcodeEncodingLength Opimul = 1
opcodeEncodingLength Opidiv = 1 opcodeEncodingLength Opidiv = 1
opcodeEncodingLength Opiand = 1 opcodeEncodingLength Opiand = 1
opcodeEncodingLength Opior = 1 opcodeEncodingLength Opior = 1
opcodeEncodingLength Opixor = 1 opcodeEncodingLength Opixor = 1
opcodeEncodingLength Opineg = 1 opcodeEncodingLength Opineg = 1
opcodeEncodingLength (Opif_icmplt _) = 3 opcodeEncodingLength (Opif_icmplt _) = 3
opcodeEncodingLength (Opif_icmple _) = 3 opcodeEncodingLength (Opif_icmple _) = 3
opcodeEncodingLength (Opif_icmpgt _) = 3 opcodeEncodingLength (Opif_icmpgt _) = 3
opcodeEncodingLength (Opif_icmpge _) = 3 opcodeEncodingLength (Opif_icmpge _) = 3
opcodeEncodingLength (Opif_icmpeq _) = 3 opcodeEncodingLength (Opif_icmpeq _) = 3
opcodeEncodingLength (Opif_icmpne _) = 3 opcodeEncodingLength (Opif_icmpne _) = 3
opcodeEncodingLength Opaconst_null = 1 opcodeEncodingLength Opaconst_null = 1
opcodeEncodingLength Opreturn = 1 opcodeEncodingLength Opreturn = 1
opcodeEncodingLength Opireturn = 1 opcodeEncodingLength Opireturn = 1
opcodeEncodingLength Opareturn = 1 opcodeEncodingLength Opareturn = 1
opcodeEncodingLength (Opgoto _) = 3 opcodeEncodingLength (Opinvokespecial _) = 3
opcodeEncodingLength (Opsipush _) = 3 opcodeEncodingLength (Opgoto _) = 3
opcodeEncodingLength (Opldc_w _) = 3 opcodeEncodingLength (Opsipush _) = 3
opcodeEncodingLength (Opaload _) = 3 opcodeEncodingLength (Opldc_w _) = 3
opcodeEncodingLength (Opiload _) = 3 opcodeEncodingLength (Opaload _) = 3
opcodeEncodingLength (Opastore _) = 3 opcodeEncodingLength (Opiload _) = 3
opcodeEncodingLength (Opistore _) = 3 opcodeEncodingLength (Opastore _) = 3
opcodeEncodingLength (Opputfield _) = 3 opcodeEncodingLength (Opistore _) = 3
opcodeEncodingLength (OpgetField _) = 3 opcodeEncodingLength (Opputfield _) = 3
opcodeEncodingLength (OpgetField _) = 3
class Serializable a where class Serializable a where
serialize :: a -> [Word8] serialize :: a -> [Word8]
@ -139,33 +141,34 @@ instance Serializable MemberInfo where
++ concatMap serialize (memberAttributes member) ++ concatMap serialize (memberAttributes member)
instance Serializable Operation where instance Serializable Operation where
serialize Opiadd = [0x60] serialize Opiadd = [0x60]
serialize Opisub = [0x64] serialize Opisub = [0x64]
serialize Opimul = [0x68] serialize Opimul = [0x68]
serialize Opidiv = [0x6C] serialize Opidiv = [0x6C]
serialize Opiand = [0x7E] serialize Opiand = [0x7E]
serialize Opior = [0x80] serialize Opior = [0x80]
serialize Opixor = [0x82] serialize Opixor = [0x82]
serialize Opineg = [0x74] serialize Opineg = [0x74]
serialize (Opif_icmplt branch) = 0xA1 : unpackWord16 branch serialize (Opif_icmplt branch) = 0xA1 : unpackWord16 branch
serialize (Opif_icmple branch) = 0xA4 : unpackWord16 branch serialize (Opif_icmple branch) = 0xA4 : unpackWord16 branch
serialize (Opif_icmpgt branch) = 0xA3 : unpackWord16 branch serialize (Opif_icmpgt branch) = 0xA3 : unpackWord16 branch
serialize (Opif_icmpge branch) = 0xA2 : unpackWord16 branch serialize (Opif_icmpge branch) = 0xA2 : unpackWord16 branch
serialize (Opif_icmpeq branch) = 0x9F : unpackWord16 branch serialize (Opif_icmpeq branch) = 0x9F : unpackWord16 branch
serialize (Opif_icmpne branch) = 0xA0 : unpackWord16 branch serialize (Opif_icmpne branch) = 0xA0 : unpackWord16 branch
serialize Opaconst_null = [0x01] serialize Opaconst_null = [0x01]
serialize Opreturn = [0xB1] serialize Opreturn = [0xB1]
serialize Opireturn = [0xAC] serialize Opireturn = [0xAC]
serialize Opareturn = [0xB0] serialize Opareturn = [0xB0]
serialize (Opgoto index) = 0xA7 : unpackWord16 index serialize (Opinvokespecial index) = 0xB7 : unpackWord16 index
serialize (Opsipush index) = 0x11 : unpackWord16 index serialize (Opgoto index) = 0xA7 : unpackWord16 index
serialize (Opldc_w index) = 0x13 : unpackWord16 index serialize (Opsipush index) = 0x11 : unpackWord16 index
serialize (Opaload index) = [0xC4, 0x19] ++ unpackWord16 index serialize (Opldc_w index) = 0x13 : unpackWord16 index
serialize (Opiload index) = [0xC4, 0x15] ++ unpackWord16 index serialize (Opaload index) = [0xC4, 0x19] ++ unpackWord16 index
serialize (Opastore index) = [0xC4, 0x3A] ++ unpackWord16 index serialize (Opiload index) = [0xC4, 0x15] ++ unpackWord16 index
serialize (Opistore index) = [0xC4, 0x36] ++ unpackWord16 index serialize (Opastore index) = [0xC4, 0x3A] ++ unpackWord16 index
serialize (Opputfield index) = 0xB5 : unpackWord16 index serialize (Opistore index) = [0xC4, 0x36] ++ unpackWord16 index
serialize (OpgetField index) = 0xB4 : unpackWord16 index serialize (Opputfield index) = 0xB5 : unpackWord16 index
serialize (OpgetField index) = 0xB4 : unpackWord16 index
instance Serializable Attribute where instance Serializable Attribute where
serialize (CodeAttribute { attributeMaxStack = maxStack, serialize (CodeAttribute { attributeMaxStack = maxStack,

View File

@ -201,8 +201,17 @@ comparisonOperation CompareGreaterOrEqual branchLocation = Opif_icmpge branchLoc
assembleMethod :: Assembler MethodDeclaration assembleMethod :: Assembler MethodDeclaration
assembleMethod (MethodDeclaration _ _ _ (TypedStatement _ (Block statements))) (constants, ops) = assembleMethod (MethodDeclaration _ name _ (TypedStatement _ (Block statements))) (constants, ops)
foldr assembleStatement (constants, ops) statements | name == "<init>" = let
(constants_a, ops_a) = foldr assembleStatement (constants, ops) statements
init_ops = [Opaload 0, Opinvokespecial 2]
in
(constants_a, init_ops ++ ops_a)
| otherwise = let
(constants_a, ops_a) = foldr assembleStatement (constants, ops) statements
init_ops = [Opaload 0]
in
(constants_a, init_ops ++ ops_a)
assembleMethod (MethodDeclaration _ _ _ stmt) (_, _) = error ("Block expected for method body, got: " ++ show stmt) assembleMethod (MethodDeclaration _ _ _ stmt) (_, _) = error ("Block expected for method body, got: " ++ show stmt)
assembleStatement :: Assembler Statement assembleStatement :: Assembler Statement
@ -223,9 +232,8 @@ assembleExpression (TypedExpression _ (BinaryOperation op a b)) (constants, ops)
| elem op [CompareEqual, CompareNotEqual, CompareLessThan, CompareLessOrEqual, CompareGreaterThan, CompareGreaterOrEqual] = let | elem op [CompareEqual, CompareNotEqual, CompareLessThan, CompareLessOrEqual, CompareGreaterThan, CompareGreaterOrEqual] = let
(aConstants, aOps) = assembleExpression a (constants, ops) (aConstants, aOps) = assembleExpression a (constants, ops)
(bConstants, bOps) = assembleExpression b (aConstants, aOps) (bConstants, bOps) = assembleExpression b (aConstants, aOps)
current_offset = sum (map opcodeEncodingLength bOps) cmp_op = comparisonOperation op 9
cmp_op = comparisonOperation op (fromIntegral (current_offset + 10)) cmp_ops = [cmp_op, Opsipush 0, Opgoto 6, Opsipush 1]
cmp_ops = [cmp_op, Opsipush 1, Opgoto (fromIntegral (current_offset + 13)), Opsipush 0]
in in
(bConstants, bOps ++ cmp_ops) (bConstants, bOps ++ cmp_ops)
assembleExpression (TypedExpression _ (CharacterLiteral literal)) (constants, ops) = assembleExpression (TypedExpression _ (CharacterLiteral literal)) (constants, ops) =

View File

@ -9,7 +9,7 @@ import ByteCode.ClassFile
import Data.ByteString (pack, writeFile) import Data.ByteString (pack, writeFile)
main = do main = do
let untypedAST = parse $ alexScanTokens "class Testklasse {void something(){return;}}" let untypedAST = parse $ alexScanTokens "class Testklasse {Testklasse(){} boolean something(){return 5 + 8 - 12 * 22 > 9 - 2 + 3;}}"
let typedAST = head (typeCheckCompilationUnit untypedAST) let typedAST = head (typeCheckCompilationUnit untypedAST)
let abstractClassFile = classBuilder typedAST emptyClassFile let abstractClassFile = classBuilder typedAST emptyClassFile
let assembledClassFile = pack (serialize abstractClassFile) let assembledClassFile = pack (serialize abstractClassFile)

View File

@ -302,7 +302,7 @@ typeCheckStatement (Return expr) symtab classes =
Nothing -> Nothing Nothing -> Nothing
in case expr' of in case expr' of
Just e' -> TypedStatement (getTypeFromExpr e') (Return (Just e')) Just e' -> TypedStatement (getTypeFromExpr e') (Return (Just e'))
Nothing -> TypedStatement "Void" (Return Nothing) Nothing -> TypedStatement "void" (Return Nothing)
typeCheckStatement (StatementExpressionStatement stmtExpr) symtab classes = typeCheckStatement (StatementExpressionStatement stmtExpr) symtab classes =
let stmtExpr' = typeCheckStatementExpression stmtExpr symtab classes let stmtExpr' = typeCheckStatementExpression stmtExpr symtab classes