Skip to content

Commit 24e02a8

Browse files
committed
Made a skeleton for the project and the parser works!
0 parents  commit 24e02a8

File tree

13 files changed

+1013
-0
lines changed

13 files changed

+1013
-0
lines changed

ByteCode.hs

Lines changed: 202 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,202 @@
1+
module ByteCode
2+
( Instruction(..)
3+
, ByteCode(..)
4+
, ByteCodes
5+
, Compare(..)
6+
, Location
7+
, sizeOf
8+
, sizeOfBC
9+
, parse ) where
10+
11+
import Data.Binary
12+
import Data.List
13+
import Data.Char
14+
import Data.Bits
15+
import Numeric
16+
17+
import Data.IntMap (IntMap)
18+
import qualified Data.IntMap as IM
19+
20+
data Instruction
21+
= AALoad
22+
| ALoad Word8
23+
| ALoadC Int
24+
| InvokeSpecial Word16
25+
| InvokeVirtual Word16
26+
| InvokeStatic Word16
27+
| ILoad Word8 | ILoadC Int
28+
| LLoad Word8 | LLoadC Int
29+
30+
| IConstC Int
31+
| LConstC Int
32+
33+
| IStoreC Int
34+
| LStoreC Int
35+
| AStoreC Int
36+
37+
| IStore Word8
38+
| LStore Word8
39+
| AStore Word8
40+
41+
| PutField Word16
42+
| GetStatic Word16
43+
| Return | IReturn | AReturn
44+
| LDC Word8
45+
| If_ACmp Compare Word16
46+
| Goto Word16
47+
| New Word16
48+
| Dup
49+
| LCmp
50+
| If Compare Word16
51+
| If_ICmp Compare Word16
52+
| AThrow
53+
| IAdd | LAdd | FAdd | DAdd
54+
| BiPush Word8
55+
| IInc Word8 Word8
56+
deriving (Eq,Show)
57+
58+
data Compare = Eq | Ne | Lt | Ge | Gt | Le
59+
deriving (Eq,Show)
60+
61+
type Location = Int
62+
63+
data ByteCode = BC Location Instruction Int
64+
type ByteCodes = IntMap ByteCode
65+
66+
instance Show ByteCode where
67+
show (BC l i _) = "(0x" ++ (showHex l "") ++ "): " ++ show i
68+
69+
data ByteTable
70+
= BTUnary Instruction
71+
| BTBinary (Word8 -> Instruction)
72+
| BTTrinary (Word8 -> Word8 -> Instruction)
73+
74+
(~>) :: Word8 -> Instruction -> (Word8, ByteTable)
75+
(~>) x y = (x, BTUnary y)
76+
(~~>) :: Word8 -> (Word8 -> Instruction) -> (Word8, ByteTable)
77+
(~~>) x y = (x, BTBinary y)
78+
(~~~>) :: Word8 -> (Word8 -> Word8 -> Instruction) -> (Word8, ByteTable)
79+
(~~~>) x y = (x, BTTrinary y)
80+
(~~>>) :: Word8 -> (Word16 -> Instruction) -> (Word8, ByteTable)
81+
(~~>>) x y = x ~~~> n'
82+
where n' = (y .) . (\i1 i2 -> ((fromIntegral i1) `shift` 8 .|. (fromIntegral i2)))
83+
{- n i1 i2 = y $ case i1 `testBit` 7 of
84+
True -> -(0xffff - n' i1 i2) -- - (n' (i1 `clearBit` 7) i2)
85+
False -> n' i1 i2 -}
86+
87+
parseBC :: [Word8] -> (Instruction, [Word8])
88+
parseBC (x:xs) = case lookup x bt of
89+
Nothing -> error $ "no opcode for: " ++ show x
90+
Just (BTUnary ins) -> (ins, xs)
91+
Just (BTBinary f) -> (f $ head xs, drop 1 xs)
92+
Just (BTTrinary f) -> (f (head xs) (head . tail $ xs), drop 2 xs)
93+
bt =
94+
[
95+
0x02 ~> IConstC (-1)
96+
, 0x03 ~> IConstC 0
97+
, 0x04 ~> IConstC 1
98+
, 0x05 ~> IConstC 2
99+
, 0x06 ~> IConstC 3
100+
, 0x07 ~> IConstC 4
101+
, 0x08 ~> IConstC 5
102+
, 0x09 ~> LConstC 0
103+
, 0x0a ~> LConstC 1
104+
, 0x10 ~~> BiPush
105+
, 0x12 ~~> LDC
106+
, 0x15 ~~> ILoad
107+
, 0x1a ~> ILoadC 0
108+
, 0x1b ~> ILoadC 1
109+
, 0x1c ~> ILoadC 2
110+
, 0x1d ~> ILoadC 3
111+
, 0x1e ~~> LLoad
112+
, 0x1f ~> LLoadC 0
113+
, 0x20 ~> LLoadC 1
114+
, 0x21 ~> LLoadC 2
115+
, 0x22 ~> LLoadC 3
116+
, 0x2a ~> ALoadC 0
117+
, 0x2b ~> ALoadC 1
118+
, 0x2c ~> ALoadC 2
119+
, 0x2d ~> ALoadC 3
120+
, 0x32 ~> AALoad
121+
, 0x36 ~~> IStore
122+
, 0x37 ~~> LStore
123+
, 0x3a ~~> AStore
124+
, 0x3b ~> IStoreC 0
125+
, 0x3c ~> IStoreC 1
126+
, 0x3d ~> IStoreC 2
127+
, 0x3e ~> IStoreC 3
128+
, 0x3f ~> LStoreC 0
129+
, 0x40 ~> LStoreC 1
130+
, 0x41 ~> LStoreC 2
131+
, 0x42 ~> LStoreC 3
132+
133+
, 0x4b ~> AStoreC 0
134+
, 0x4c ~> AStoreC 1
135+
, 0x4d ~> AStoreC 2
136+
, 0x4e ~> AStoreC 3
137+
, 0x59 ~> Dup
138+
, 0x60 ~> IAdd
139+
, 0x61 ~> LAdd
140+
, 0x62 ~> FAdd
141+
, 0x63 ~> DAdd
142+
143+
, 0x84 ~~~> IInc
144+
, 0x94 ~> LCmp
145+
146+
, 0x99 ~~>> If Eq
147+
, 0x9a ~~>> If Ne
148+
, 0x9b ~~>> If Lt
149+
, 0x9c ~~>> If Ge
150+
, 0x9d ~~>> If Gt
151+
, 0x9e ~~>> If Le
152+
, 0x9f ~~>> If_ICmp Eq
153+
, 0xa0 ~~>> If_ICmp Ne
154+
, 0xa1 ~~>> If_ICmp Lt
155+
, 0xa2 ~~>> If_ICmp Ge
156+
, 0xa3 ~~>> If_ICmp Gt
157+
, 0xa4 ~~>> If_ICmp Le
158+
159+
, 0x19 ~~> ALoad
160+
, 0xa5 ~~>> If_ACmp Eq
161+
, 0xa6 ~~>> If_ACmp Ne
162+
, 0xa7 ~~>> Goto
163+
, 0xac ~> IReturn
164+
, 0xb0 ~> AReturn
165+
, 0xb1 ~> Return
166+
, 0xb2 ~~>> GetStatic
167+
, 0xb5 ~~>> PutField
168+
, 0xb6 ~~>> InvokeVirtual
169+
, 0xb7 ~~>> InvokeSpecial
170+
, 0xb8 ~~>> InvokeStatic
171+
, 0xbb ~~>> New
172+
, 0xbf ~> AThrow
173+
]
174+
175+
example :: [Word8]
176+
example = [42,183,0,1,42,27,181,0,2,42,28,181,0,3,177]
177+
178+
179+
parse :: [Word8] -> Location -> ByteCodes
180+
parse a b = IM.fromList $ map (\x@(BC l _ _) -> (l,x)) (parse' a b)
181+
182+
parse' :: [Word8] -> Int -> [ByteCode]
183+
parse' [] _ = []
184+
parse' xs offset =
185+
let (inst, rest) = parseBC xs
186+
size :: Int
187+
size = fromIntegral $ sizeOf (head xs)
188+
in BC (fromIntegral offset) inst size : parse' rest (size + offset)
189+
190+
sizeOf :: Word8 -> Word8
191+
sizeOf a = case lookup a bt of
192+
Nothing -> error $ "no opcode for: " ++ show a
193+
Just (BTUnary _) -> w8
194+
Just (BTBinary _) -> w16
195+
Just (BTTrinary _) -> w24
196+
where
197+
(w8,w16,w24,w32) = (1,2,3,4)
198+
199+
sizeOfBC :: ByteCode -> Int
200+
sizeOfBC (BC _ _ s) = s
201+
202+
--fancy x = putStrLn . unlines . map show . parse x

ClassData.hs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
module ClassData where
2+
3+
data ClassData = ClassData

0 commit comments

Comments
 (0)