added boolean expression assembly
This commit is contained in:
parent
d54c7cd7e6
commit
09469e0e45
@ -5,7 +5,8 @@ module ByteCode.ClassFile(
|
||||
ClassFile(..),
|
||||
Operation(..),
|
||||
serialize,
|
||||
emptyClassFile
|
||||
emptyClassFile,
|
||||
opcodeEncodingLength
|
||||
) where
|
||||
|
||||
import Data.Word
|
||||
@ -41,6 +42,7 @@ data Operation = Opiadd
|
||||
| Opreturn
|
||||
| Opireturn
|
||||
| Opareturn
|
||||
| Opgoto Word16
|
||||
| Opsipush Word16
|
||||
| Opldc_w Word16
|
||||
| Opaload Word16
|
||||
@ -87,6 +89,35 @@ emptyClassFile = ClassFile {
|
||||
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
|
||||
serialize :: a -> [Word8]
|
||||
|
||||
@ -126,6 +157,7 @@ instance Serializable Operation where
|
||||
serialize Opreturn = [0xB1]
|
||||
serialize Opireturn = [0xAC]
|
||||
serialize Opareturn = [0xB0]
|
||||
serialize (Opgoto index) = 0xA7 : unpackWord16 index
|
||||
serialize (Opsipush index) = 0x11 : unpackWord16 index
|
||||
serialize (Opldc_w index) = 0x13 : unpackWord16 index
|
||||
serialize (Opaload index) = [0xC4, 0x19] ++ unpackWord16 index
|
||||
|
@ -10,10 +10,11 @@ module ByteCode.ClassFile.Generator(
|
||||
) where
|
||||
|
||||
import ByteCode.Constants
|
||||
import ByteCode.ClassFile (ClassFile (..), ConstantInfo (..), MemberInfo(..), Operation(..), Attribute(..))
|
||||
import ByteCode.ClassFile (ClassFile (..), ConstantInfo (..), MemberInfo(..), Operation(..), Attribute(..), opcodeEncodingLength)
|
||||
import Ast
|
||||
import Data.Char
|
||||
import Data.List
|
||||
import Data.Word
|
||||
|
||||
|
||||
type ClassFileBuilder a = a -> ClassFile -> ClassFile
|
||||
@ -184,6 +185,15 @@ binaryOperation BitwiseAnd = Opiand
|
||||
binaryOperation BitwiseOr = Opior
|
||||
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 (MethodDeclaration _ _ _ (Block statements)) (constants, ops) =
|
||||
foldr assembleStatement (constants, ops) statements
|
||||
@ -203,6 +213,14 @@ assembleExpression (TypedExpression _ (BinaryOperation op a b)) (constants, ops)
|
||||
(bConstants, bOps) = assembleExpression b (aConstants, aOps)
|
||||
in
|
||||
(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) =
|
||||
(constants, ops ++ [Opsipush (fromIntegral (ord literal))])
|
||||
assembleExpression (TypedExpression _ (BooleanLiteral literal)) (constants, ops) =
|
||||
|
@ -9,7 +9,7 @@ import ByteCode.ClassFile
|
||||
import Data.ByteString (pack, writeFile)
|
||||
|
||||
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 abstractClassFile = classBuilder typedAST emptyClassFile
|
||||
let assembledClassFile = pack (serialize abstractClassFile)
|
||||
|
Loading…
Reference in New Issue
Block a user