22
33module HLasm.Instructions
44( Offset (.. ), Target (.. ), InstructionSet (.. )
5- , Instructions (.. )
5+ , Instructions (.. ), Variable (.. )
6+ , Section (.. ), ObjProgram (.. )
67, BackEnd (.. )
78, runBackend
8- , instructions
9+ , program
910) where
1011
1112import Control.Monad.Extra (concatMapM )
@@ -40,16 +41,24 @@ data Instructions =
4041
4142type InstructionSet = [Instructions ]
4243
43- newtype BackEnd = BackEnd (InstructionSet -> Result String )
44+ data Variable = Variable VariableName Type HLValue
45+
46+ data Section =
47+ Text InstructionSet
48+ | Data [Variable ]
49+ | Constants [Variable ]
50+
51+ newtype ObjProgram = ObjProgram [Section ]
52+
53+ newtype BackEnd = BackEnd (ObjProgram -> Result String )
4454runBackend (BackEnd f) x = f x
4555
4656
4757target :: StackFrame -> VariableData -> Target
48- target _ (VariableData (_, VariableDeclaration ( HLasm.Ast. Register (_, reg) ))) = HLasm.Instructions. Register reg
58+ target _ (VariableData (_, ( RegisterDeclaration _ reg))) = HLasm.Instructions. Register reg
4959target frame (VariableData (name, e)) = case findOffset frame name of
50- Just x -> FrameVar (x, size e, name)
60+ Just x -> FrameVar (x, stackVarSize e, name)
5161 Nothing -> NamedTarget name
52- where size (VariableDeclaration v) = valueSize v
5362
5463findTarget :: StackFrame -> [VariableData ] -> VariableName -> Target -- was a lot of checks, target garanteed be here.
5564findTarget frame xs name = target frame . fromJust . find (\ (VariableData (n, _)) -> n == name) $ xs
@@ -61,31 +70,61 @@ valuableTarget (sf, vd) (NameValue name) = findTarget sf vd name
6170loop :: Label -> Result (InstructionSet ) -> Result (InstructionSet )
6271loop lbl i = let begin = lbl ++ " begin" in fmap (\ x -> [Label begin] ++ x ++ [Jump begin Nothing , Label (lbl ++ " end" )]) $ i
6372
73+ isEmptyInstruction :: HLElement -> Bool
74+ isEmptyInstruction (FakeVariable _) = True
75+ isEmptyInstruction (FakeFrame _) = True
76+ isEmptyInstruction (VariableDeclaration _ _) = True
77+ isEmptyInstruction (RegisterDeclaration _ _) = True
78+ isEmptyInstruction _ = False
79+
80+
6481instructions :: Tree (HLElement , [VariableData ], [LabelData ], StackFrame ) -> Result (InstructionSet )
82+ instructions (Node (el, _, _, _) _) | isEmptyInstruction el = Right []
6583instructions (Node ((InstructionSet ), _, _, _) xs) = concatMapM instructions xs
66- instructions (Node ((VariableDeclaration val), _, _, _) _ ) = Right []
6784instructions (Node ((While lbl ), _, _, _) xs) = loop lbl (concatMapM instructions xs)
6885instructions (Node ((DoWhile lbl ), _, _, _) xs) = loop lbl (concatMapM instructions xs)
6986instructions (Node ((Break lbl ), _, _, _) _ ) = Right [Jump (lbl ++ " end" ) Nothing ]
7087instructions (Node ((AssemblyCall str ), _, _, _) _ ) = Right [PureAsm str]
7188instructions (Node ((Frame lbl ), _, _, f) xs) =
7289 (\ body -> [BeginFrame f lbl] ++ body ++ [EndFrame f lbl]) <$> concatMapM instructions xs
7390
91+ instructions (Node ((GlobalVarDeclaration n _ _), _, _, _) _ ) = Left (GlobalVariableInFrame n)
92+ instructions (Node ((ConstVarDeclaration n _ _), _, _, _) _ ) = Left (GlobalVariableInFrame n)
93+
7494instructions (Node ((Assignment name (NameValue val)), d, _, f) _) = Right [Move (findTarget f d name) (findTarget f d val)]
7595instructions (Node ((Assignment name (IntegerValue val)), d, _, f) _) = Right [Move (findTarget f d name) (ConstantTarget val)]
7696
7797instructions (Node ((HLasm.Ast. Call lbl ns ), d, _, f) _ ) =
7898 Right [HLasm.Instructions. Call lbl (fmap (findTarget f d) ns) size]
79- where size = foldl (+) 0 . fmap (\ (VariableData (_, ( VariableDeclaration d))) -> valueSize d) $ d
99+ where size = foldl (+) 0 . fmap (\ (VariableData (_, d)) -> stackVarSize d) $ d
80100
81101instructions (Node ((If lbl), _, _, _) [] ) = Right []
82102instructions (Node ((If lbl), _, _, _) xs) =
83103 do (conds, bodies') <- Right $ traverse (uncurry branch) (zip [1 .. ] xs)
84104 bodies <- fmap (concat ) . sequence $ bodies'
85105 Right $ conds ++ [Jump (lbl ++ " end" ) Nothing ] ++ bodies ++ [Label (lbl ++ " end" )]
86-
87106 where condition lbl pt (Condition (left, cmp, right)) =
88107 let find = valuableTarget pt in [Compare (find left) (find right), Jump lbl (Just cmp)]
89108 wrapif i = fmap (\ b -> [Label (lbl ++ show i)] ++ b ++ [Jump (lbl ++ " end" ) Nothing ]) . concatMapM instructions
90109 branch i (Node ((IfBranch (Just cond)), d, _, f) xs) = (condition (lbl ++ show i) (f, d) cond, wrapif i xs)
91110 branch i (Node ((IfBranch Nothing ), _, _, _) xs) = ([Jump (lbl ++ show i) Nothing ], wrapif i xs)
111+
112+
113+ dataFilter (Node ((GlobalVarDeclaration n t v), _, _, _) _) = Just $ Variable n t v
114+ dataFilter _ = Nothing
115+ constFilter (Node ((ConstVarDeclaration n t v), _, _, _) _) = Just $ Variable n t v
116+ constFilter _ = Nothing
117+
118+ varSection ctor f xs = Right . ctor . fmap fromJust . filter isJust . fmap f $ xs
119+
120+ filterF :: [(a -> Maybe b )] -> (a -> Bool )
121+ filterF fs = foldl or (const True ) . fmap ((.) (not . isJust)) $ fs
122+ where or f g x = f x && g x
123+
124+ program :: Tree (HLElement , [VariableData ], [LabelData ], StackFrame ) -> Result ObjProgram
125+ program (Node ((Program ), _, _, _) xs) =
126+ do text <- concatMapM instructions . filter (filterF [dataFilter, constFilter]) $ xs
127+ dat <- varSection Data dataFilter xs
128+ const <- varSection Constants constFilter xs
129+ Right $ ObjProgram [(Text text), dat, const ]
130+ program _ = undefined
0 commit comments