added boolean expression assembly
This commit is contained in:
parent
d54c7cd7e6
commit
09469e0e45
@ -5,7 +5,8 @@ module ByteCode.ClassFile(
|
|||||||
ClassFile(..),
|
ClassFile(..),
|
||||||
Operation(..),
|
Operation(..),
|
||||||
serialize,
|
serialize,
|
||||||
emptyClassFile
|
emptyClassFile,
|
||||||
|
opcodeEncodingLength
|
||||||
) where
|
) where
|
||||||
|
|
||||||
import Data.Word
|
import Data.Word
|
||||||
@ -41,6 +42,7 @@ data Operation = Opiadd
|
|||||||
| Opreturn
|
| Opreturn
|
||||||
| Opireturn
|
| Opireturn
|
||||||
| Opareturn
|
| Opareturn
|
||||||
|
| Opgoto Word16
|
||||||
| Opsipush Word16
|
| Opsipush Word16
|
||||||
| Opldc_w Word16
|
| Opldc_w Word16
|
||||||
| Opaload Word16
|
| Opaload Word16
|
||||||
@ -87,6 +89,35 @@ emptyClassFile = ClassFile {
|
|||||||
attributes = []
|
attributes = []
|
||||||
}
|
}
|
||||||
|
|
||||||
|
opcodeEncodingLength :: Operation -> Word16
|
||||||
|
opcodeEncodingLength Opiadd = 1
|
||||||
|
opcodeEncodingLength Opisub = 1
|
||||||
|
opcodeEncodingLength Opimul = 1
|
||||||
|
opcodeEncodingLength Opidiv = 1
|
||||||
|
opcodeEncodingLength Opiand = 1
|
||||||
|
opcodeEncodingLength Opior = 1
|
||||||
|
opcodeEncodingLength Opixor = 1
|
||||||
|
opcodeEncodingLength Opineg = 1
|
||||||
|
opcodeEncodingLength (Opif_icmplt _) = 3
|
||||||
|
opcodeEncodingLength (Opif_icmple _) = 3
|
||||||
|
opcodeEncodingLength (Opif_icmpgt _) = 3
|
||||||
|
opcodeEncodingLength (Opif_icmpge _) = 3
|
||||||
|
opcodeEncodingLength (Opif_icmpeq _) = 3
|
||||||
|
opcodeEncodingLength (Opif_icmpne _) = 3
|
||||||
|
opcodeEncodingLength Opaconst_null = 1
|
||||||
|
opcodeEncodingLength Opreturn = 1
|
||||||
|
opcodeEncodingLength Opireturn = 1
|
||||||
|
opcodeEncodingLength Opareturn = 1
|
||||||
|
opcodeEncodingLength (Opgoto _) = 3
|
||||||
|
opcodeEncodingLength (Opsipush _) = 3
|
||||||
|
opcodeEncodingLength (Opldc_w _) = 3
|
||||||
|
opcodeEncodingLength (Opaload _) = 3
|
||||||
|
opcodeEncodingLength (Opiload _) = 3
|
||||||
|
opcodeEncodingLength (Opastore _) = 3
|
||||||
|
opcodeEncodingLength (Opistore _) = 3
|
||||||
|
opcodeEncodingLength (Opputfield _) = 3
|
||||||
|
opcodeEncodingLength (OpgetField _) = 3
|
||||||
|
|
||||||
class Serializable a where
|
class Serializable a where
|
||||||
serialize :: a -> [Word8]
|
serialize :: a -> [Word8]
|
||||||
|
|
||||||
@ -126,6 +157,7 @@ instance Serializable Operation where
|
|||||||
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 (Opsipush index) = 0x11 : unpackWord16 index
|
serialize (Opsipush index) = 0x11 : unpackWord16 index
|
||||||
serialize (Opldc_w index) = 0x13 : unpackWord16 index
|
serialize (Opldc_w index) = 0x13 : unpackWord16 index
|
||||||
serialize (Opaload index) = [0xC4, 0x19] ++ unpackWord16 index
|
serialize (Opaload index) = [0xC4, 0x19] ++ unpackWord16 index
|
||||||
|
@ -10,10 +10,11 @@ module ByteCode.ClassFile.Generator(
|
|||||||
) where
|
) where
|
||||||
|
|
||||||
import ByteCode.Constants
|
import ByteCode.Constants
|
||||||
import ByteCode.ClassFile (ClassFile (..), ConstantInfo (..), MemberInfo(..), Operation(..), Attribute(..))
|
import ByteCode.ClassFile (ClassFile (..), ConstantInfo (..), MemberInfo(..), Operation(..), Attribute(..), opcodeEncodingLength)
|
||||||
import Ast
|
import Ast
|
||||||
import Data.Char
|
import Data.Char
|
||||||
import Data.List
|
import Data.List
|
||||||
|
import Data.Word
|
||||||
|
|
||||||
|
|
||||||
type ClassFileBuilder a = a -> ClassFile -> ClassFile
|
type ClassFileBuilder a = a -> ClassFile -> ClassFile
|
||||||
@ -176,13 +177,22 @@ returnOperation dtype
|
|||||||
| otherwise = Opareturn
|
| otherwise = Opareturn
|
||||||
|
|
||||||
binaryOperation :: BinaryOperator -> Operation
|
binaryOperation :: BinaryOperator -> Operation
|
||||||
binaryOperation Addition = Opiadd
|
binaryOperation Addition = Opiadd
|
||||||
binaryOperation Subtraction = Opisub
|
binaryOperation Subtraction = Opisub
|
||||||
binaryOperation Multiplication = Opimul
|
binaryOperation Multiplication = Opimul
|
||||||
binaryOperation Division = Opidiv
|
binaryOperation Division = Opidiv
|
||||||
binaryOperation BitwiseAnd = Opiand
|
binaryOperation BitwiseAnd = Opiand
|
||||||
binaryOperation BitwiseOr = Opior
|
binaryOperation BitwiseOr = Opior
|
||||||
binaryOperation BitwiseXor = Opixor
|
binaryOperation BitwiseXor = Opixor
|
||||||
|
|
||||||
|
comparisonOperation :: BinaryOperator -> Word16 -> Operation
|
||||||
|
comparisonOperation CompareEqual branchLocation = Opif_icmpeq branchLocation
|
||||||
|
comparisonOperation CompareNotEqual branchLocation = Opif_icmpne branchLocation
|
||||||
|
comparisonOperation CompareLessThan branchLocation = Opif_icmplt branchLocation
|
||||||
|
comparisonOperation CompareLessOrEqual branchLocation = Opif_icmple branchLocation
|
||||||
|
comparisonOperation CompareGreaterThan branchLocation = Opif_icmpgt branchLocation
|
||||||
|
comparisonOperation CompareGreaterOrEqual branchLocation = Opif_icmpge branchLocation
|
||||||
|
|
||||||
|
|
||||||
assembleMethod :: Assembler MethodDeclaration
|
assembleMethod :: Assembler MethodDeclaration
|
||||||
assembleMethod (MethodDeclaration _ _ _ (Block statements)) (constants, ops) =
|
assembleMethod (MethodDeclaration _ _ _ (Block statements)) (constants, ops) =
|
||||||
@ -203,6 +213,14 @@ assembleExpression (TypedExpression _ (BinaryOperation op a b)) (constants, ops)
|
|||||||
(bConstants, bOps) = assembleExpression b (aConstants, aOps)
|
(bConstants, bOps) = assembleExpression b (aConstants, aOps)
|
||||||
in
|
in
|
||||||
(bConstants, bOps ++ [binaryOperation op])
|
(bConstants, bOps ++ [binaryOperation op])
|
||||||
|
| elem op [CompareEqual, CompareNotEqual, CompareLessThan, CompareLessOrEqual, CompareGreaterThan, CompareGreaterOrEqual] = let
|
||||||
|
(aConstants, aOps) = assembleExpression a (constants, ops)
|
||||||
|
(bConstants, bOps) = assembleExpression b (aConstants, aOps)
|
||||||
|
current_offset = sum (map opcodeEncodingLength bOps)
|
||||||
|
cmp_op = comparisonOperation op (fromIntegral (current_offset + 10))
|
||||||
|
cmp_ops = [cmp_op, Opsipush 1, Opgoto (fromIntegral (current_offset + 13)), Opsipush 0]
|
||||||
|
in
|
||||||
|
(bConstants, bOps ++ cmp_ops)
|
||||||
assembleExpression (TypedExpression _ (CharacterLiteral literal)) (constants, ops) =
|
assembleExpression (TypedExpression _ (CharacterLiteral literal)) (constants, ops) =
|
||||||
(constants, ops ++ [Opsipush (fromIntegral (ord literal))])
|
(constants, ops ++ [Opsipush (fromIntegral (ord literal))])
|
||||||
assembleExpression (TypedExpression _ (BooleanLiteral literal)) (constants, ops) =
|
assembleExpression (TypedExpression _ (BooleanLiteral literal)) (constants, ops) =
|
||||||
|
@ -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 {int a; int b; void something(){} void something_else(){} Testklasse(){}}"
|
let untypedAST = parse $ alexScanTokens "class Testklasse {int a; int b; void something(){} void something_else(){}}"
|
||||||
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)
|
||||||
|
Loading…
Reference in New Issue
Block a user