11 import Control.Monad.IO.Class |
11 import Control.Monad.IO.Class |
12 import PascalPreprocessor |
12 import PascalPreprocessor |
13 import Control.Exception |
13 import Control.Exception |
14 import System.IO.Error |
14 import System.IO.Error |
15 import qualified Data.Map as Map |
15 import qualified Data.Map as Map |
|
16 import qualified Data.Set as Set |
16 import Data.List (find) |
17 import Data.List (find) |
17 import Numeric |
18 import Numeric |
18 |
19 |
19 import PascalParser |
20 import PascalParser |
20 import PascalUnitSyntaxTree |
21 import PascalUnitSyntaxTree |
21 |
22 |
22 |
23 |
23 data InsertOption = |
24 data InsertOption = |
24 IOInsert |
25 IOInsert |
25 | IOLookup |
26 | IOLookup |
|
27 | IOLookupLast |
|
28 | IOLookupFunction Int |
26 | IODeferred |
29 | IODeferred |
27 |
30 |
28 type Record = (String, (String, BaseType)) |
31 type Record = (String, BaseType) |
|
32 type Records = Map.Map String [Record] |
29 data RenderState = RenderState |
33 data RenderState = RenderState |
30 { |
34 { |
31 currentScope :: [Record], |
35 currentScope :: Records, |
32 lastIdentifier :: String, |
36 lastIdentifier :: String, |
33 lastType :: BaseType, |
37 lastType :: BaseType, |
34 stringConsts :: [(String, String)], |
38 stringConsts :: [(String, String)], |
35 uniqCounter :: Int, |
39 uniqCounter :: Int, |
36 namespaces :: Map.Map String [Record] |
40 toMangle :: Set.Set String, |
|
41 currentUnit :: String, |
|
42 namespaces :: Map.Map String Records |
37 } |
43 } |
38 |
44 |
39 emptyState = RenderState [] "" BTUnknown [] 0 |
45 emptyState = RenderState Map.empty "" BTUnknown [] 0 Set.empty "" |
40 |
46 |
41 getUniq :: State RenderState Int |
47 getUniq :: State RenderState Int |
42 getUniq = do |
48 getUniq = do |
43 i <- gets uniqCounter |
49 i <- gets uniqCounter |
44 modify(\s -> s{uniqCounter = uniqCounter s + 1}) |
50 modify(\s -> s{uniqCounter = uniqCounter s + 1}) |
140 |
150 |
141 withLastIdNamespace :: State RenderState Doc -> State RenderState Doc |
151 withLastIdNamespace :: State RenderState Doc -> State RenderState Doc |
142 withLastIdNamespace f = do |
152 withLastIdNamespace f = do |
143 li <- gets lastIdentifier |
153 li <- gets lastIdentifier |
144 nss <- gets namespaces |
154 nss <- gets namespaces |
145 withState' (\st -> st{currentScope = fromMaybe [] $ Map.lookup li (namespaces st)}) f |
155 withState' (\st -> st{currentScope = fromMaybe Map.empty $ Map.lookup li (namespaces st)}) f |
146 |
156 |
147 withRecordNamespace :: String -> [(String, BaseType)] -> State RenderState Doc -> State RenderState Doc |
157 withRecordNamespace :: String -> [(String, BaseType)] -> State RenderState Doc -> State RenderState Doc |
148 withRecordNamespace _ [] = error "withRecordNamespace: empty record" |
158 withRecordNamespace _ [] = error "withRecordNamespace: empty record" |
149 withRecordNamespace prefix recs = withState' f |
159 withRecordNamespace prefix recs = withState' f |
150 where |
160 where |
151 f st = st{currentScope = records ++ currentScope st} |
161 f st = st{currentScope = Map.unionWith un records (currentScope st), currentUnit = ""} |
152 records = map (\(a, b) -> (map toLower a, (prefix ++ a, b))) recs |
162 records = Map.fromList $ map (\(a, b) -> (map toLower a, [(prefix ++ a, b)])) recs |
153 |
163 un [a] b = a : b |
154 toCFiles :: Map.Map String [Record] -> (String, PascalUnit) -> IO () |
164 |
|
165 toCFiles :: Map.Map String Records -> (String, PascalUnit) -> IO () |
155 toCFiles _ (_, System _) = return () |
166 toCFiles _ (_, System _) = return () |
156 toCFiles ns p@(fn, pu) = do |
167 toCFiles ns p@(fn, pu) = do |
157 hPutStrLn stderr $ "Rendering '" ++ fn ++ "'..." |
168 hPutStrLn stderr $ "Rendering '" ++ fn ++ "'..." |
158 toCFiles' p |
169 toCFiles' p |
159 where |
170 where |
160 toCFiles' (fn, p@(Program {})) = writeFile (fn ++ ".c") $ (render2C initialState . pascal2C) p |
171 toCFiles' (fn, p@(Program {})) = writeFile (fn ++ ".c") $ (render2C initialState . pascal2C) p |
161 toCFiles' (fn, (Unit unitId interface implementation _ _)) = do |
172 toCFiles' (fn, (Unit unitId@(Identifier i _) interface implementation _ _)) = do |
162 let (a, s) = runState (id2C IOInsert (setBaseType BTUnit unitId) >> interface2C interface) initialState |
173 let (a, s) = runState (id2C IOInsert (setBaseType BTUnit unitId) >> interface2C interface) initialState{currentUnit = map toLower i ++ "_"} |
163 writeFile (fn ++ ".h") $ "#pragma once\n\n#include \"pas2c.h\"\n\n" ++ (render (a $+$ text "")) |
174 writeFile (fn ++ ".h") $ "#pragma once\n\n#include \"pas2c.h\"\n\n" ++ (render (a $+$ text "")) |
164 writeFile (fn ++ ".c") $ "#include \"" ++ fn ++ ".h\"\n" ++ (render2C s . implementation2C) implementation |
175 writeFile (fn ++ ".c") $ "#include \"" ++ fn ++ ".h\"\n" ++ (render2C s . implementation2C) implementation |
165 initialState = emptyState ns |
176 initialState = emptyState ns |
166 |
177 |
167 render2C :: RenderState -> State RenderState Doc -> String |
178 render2C :: RenderState -> State RenderState Doc -> String |
212 mapM_ (id2C IOInsert . setBaseType BTUnit) unitIds |
233 mapM_ (id2C IOInsert . setBaseType BTUnit) unitIds |
213 return $ vcat . map (\i -> text $ "#include \"" ++ i ++ ".h\"") $ uses2List uses |
234 return $ vcat . map (\i -> text $ "#include \"" ++ i ++ ".h\"") $ uses2List uses |
214 where |
235 where |
215 injectNamespace (Identifier i _) = do |
236 injectNamespace (Identifier i _) = do |
216 getNS <- gets (flip Map.lookup . namespaces) |
237 getNS <- gets (flip Map.lookup . namespaces) |
217 let f = flip (foldl (flip (:))) (fromMaybe [] (getNS i)) |
238 modify (\s -> s{currentScope = Map.unionWith (++) (fromMaybe Map.empty (getNS i)) $ currentScope s}) |
218 modify (\s -> s{currentScope = f $ currentScope s}) |
|
219 |
239 |
220 uses2List :: Uses -> [String] |
240 uses2List :: Uses -> [String] |
221 uses2List (Uses ids) = map (\(Identifier i _) -> i) ids |
241 uses2List (Uses ids) = map (\(Identifier i _) -> i) ids |
222 |
242 |
223 |
243 |
224 id2C :: InsertOption -> Identifier -> State RenderState Doc |
244 id2C :: InsertOption -> Identifier -> State RenderState Doc |
225 id2C IOInsert (Identifier i t) = do |
245 id2C IOInsert (Identifier i t) = do |
226 ns <- gets currentScope |
246 ns <- gets currentScope |
227 {-- case t of |
247 tom <- gets (Set.member n . toMangle) |
228 BTUnknown -> do |
248 cu <- gets currentUnit |
229 ns <- gets currentScope |
249 let i' = case (t, tom) of |
230 error $ "id2C IOInsert: type BTUnknown for " ++ show i ++ "\nnamespace: " ++ show (take 100 ns) |
250 (BTFunction p _, True) -> cu ++ i ++ ('_' : show p) |
231 _ -> do --} |
251 (BTFunction _ _, _) -> cu ++ i |
232 modify (\s -> s{currentScope = (n, (i, t)) : currentScope s, lastIdentifier = n}) |
252 _ -> i |
233 return $ text i |
253 modify (\s -> s{currentScope = Map.insertWith (++) n [(i', t)] (currentScope s), lastIdentifier = n}) |
|
254 return $ text i' |
234 where |
255 where |
235 n = map toLower i |
256 n = map toLower i |
236 id2C IOLookup (Identifier i t) = do |
257 id2C IOLookup i = id2CLookup head i |
|
258 id2C IOLookupLast i = id2CLookup last i |
|
259 id2C (IOLookupFunction params) (Identifier i t) = do |
237 let i' = map toLower i |
260 let i' = map toLower i |
238 v <- gets $ find (\(a, _) -> a == i') . currentScope |
261 v <- gets $ Map.lookup i' . currentScope |
239 ns <- gets currentScope |
|
240 lt <- gets lastType |
262 lt <- gets lastType |
241 if isNothing v then |
263 if isNothing v then |
242 error $ "Not defined: '" ++ i' ++ "'\n" ++ show lt ++ "\n" ++ show (take 100 ns) |
264 error $ "Not defined: '" ++ i' ++ "'\n" ++ show lt ++ "\nwith num of params = " ++ show params ++ "\n" ++ show v |
243 else |
265 else |
244 let vv = snd $ fromJust v in modify (\s -> s{lastType = snd vv, lastIdentifier = fst vv}) >> (return . text . fst $ vv) |
266 let vv = fromMaybe (head $ fromJust v) . find checkParam $ fromJust v in |
|
267 modify (\s -> s{lastType = snd vv, lastIdentifier = fst vv}) >> (return . text . fst $ vv) |
|
268 where |
|
269 checkParam (_, BTFunction p _) = p == params |
|
270 checkParam _ = False |
245 id2C IODeferred (Identifier i t) = do |
271 id2C IODeferred (Identifier i t) = do |
246 let i' = map toLower i |
272 let i' = map toLower i |
247 v <- gets $ find (\(a, _) -> a == i') . currentScope |
273 v <- gets $ Map.lookup i' . currentScope |
248 if (isNothing v) then |
274 if (isNothing v) then |
249 return $ text i |
275 modify (\s -> s{lastType = BTUnknown, lastIdentifier = i}) >> return (text i) |
250 else |
276 else |
251 return . text . fst . snd . fromJust $ v |
277 let vv = head $ fromJust v in modify (\s -> s{lastType = snd vv, lastIdentifier = fst vv}) >> (return . text . fst $ vv) |
252 |
278 |
|
279 id2CLookup :: ([Record] -> Record) -> Identifier -> State RenderState Doc |
|
280 id2CLookup f (Identifier i _) = do |
|
281 let i' = map toLower i |
|
282 v <- gets $ Map.lookup i' . currentScope |
|
283 lt <- gets lastType |
|
284 if isNothing v then |
|
285 error $ "Not defined: '" ++ i' ++ "'\n" ++ show lt |
|
286 else |
|
287 let vv = f $ fromJust v in modify (\s -> s{lastType = snd vv, lastIdentifier = fst vv}) >> (return . text . fst $ vv) |
|
288 |
|
289 |
253 id2CTyped :: TypeDecl -> Identifier -> State RenderState Doc |
290 id2CTyped :: TypeDecl -> Identifier -> State RenderState Doc |
254 id2CTyped t (Identifier i _) = do |
291 id2CTyped t (Identifier i _) = do |
255 tb <- resolveType t |
292 tb <- resolveType t |
256 ns <- gets currentScope |
293 case (t, tb) of |
257 case tb of |
294 (_, BTUnknown) -> do |
258 BTUnknown -> do |
295 error $ "id2CTyped: type BTUnknown for " ++ show i ++ "\ntype: " ++ show t |
259 ns <- gets currentScope |
296 (SimpleType {}, BTRecord _ r) -> do |
260 error $ "id2CTyped: type BTUnknown for " ++ show i ++ "\ntype: " ++ show t ++ "\nnamespace: " ++ show (take 100 ns) |
297 ts <- type2C t |
261 _ -> return () |
298 id2C IOInsert (Identifier i (BTRecord (render $ ts empty) r)) |
262 id2C IOInsert (Identifier i tb) |
299 (_, BTRecord _ r) -> do |
|
300 ts <- type2C t |
|
301 id2C IOInsert (Identifier i (BTRecord i r)) |
|
302 _ -> id2C IOInsert (Identifier i tb) |
|
303 |
263 |
304 |
264 |
305 |
265 resolveType :: TypeDecl -> State RenderState BaseType |
306 resolveType :: TypeDecl -> State RenderState BaseType |
266 resolveType st@(SimpleType (Identifier i _)) = do |
307 resolveType st@(SimpleType (Identifier i _)) = do |
267 let i' = map toLower i |
308 let i' = map toLower i |
268 v <- gets $ find (\(a, _) -> a == i') . currentScope |
309 v <- gets $ Map.lookup i' . currentScope |
269 if isJust v then return . snd . snd $ fromJust v else return $ f i' |
310 if isJust v then return . snd . head $ fromJust v else return $ f i' |
270 where |
311 where |
271 f "integer" = BTInt |
312 f "integer" = BTInt |
272 f "pointer" = BTPointerTo BTVoid |
313 f "pointer" = BTPointerTo BTVoid |
273 f "boolean" = BTBool |
314 f "boolean" = BTBool |
274 f "float" = BTFloat |
315 f "float" = BTFloat |
277 f _ = error $ "Unknown system type: " ++ show st |
318 f _ = error $ "Unknown system type: " ++ show st |
278 resolveType (PointerTo (SimpleType (Identifier i _))) = return . BTPointerTo $ BTUnresolved (map toLower i) |
319 resolveType (PointerTo (SimpleType (Identifier i _))) = return . BTPointerTo $ BTUnresolved (map toLower i) |
279 resolveType (PointerTo t) = liftM BTPointerTo $ resolveType t |
320 resolveType (PointerTo t) = liftM BTPointerTo $ resolveType t |
280 resolveType (RecordType tv mtvs) = do |
321 resolveType (RecordType tv mtvs) = do |
281 tvs <- mapM f (concat $ tv : fromMaybe [] mtvs) |
322 tvs <- mapM f (concat $ tv : fromMaybe [] mtvs) |
282 return . BTRecord . concat $ tvs |
323 return . BTRecord "" . concat $ tvs |
283 where |
324 where |
284 f :: TypeVarDeclaration -> State RenderState [(String, BaseType)] |
325 f :: TypeVarDeclaration -> State RenderState [(String, BaseType)] |
285 f (VarDeclaration _ (ids, td) _) = mapM (\(Identifier i _) -> liftM ((,) i) $ resolveType td) ids |
326 f (VarDeclaration _ (ids, td) _) = mapM (\(Identifier i _) -> liftM ((,) i) $ resolveType td) ids |
286 resolveType (ArrayDecl (Just i) t) = do |
327 resolveType (ArrayDecl (Just i) t) = do |
287 t' <- resolveType t |
328 t' <- resolveType t |
288 return $ BTArray i BTInt t' |
329 return $ BTArray i BTInt t' |
289 resolveType (ArrayDecl Nothing t) = liftM (BTArray RangeInfinite BTInt) $ resolveType t |
330 resolveType (ArrayDecl Nothing t) = liftM (BTArray RangeInfinite BTInt) $ resolveType t |
290 resolveType (FunctionType t _) = liftM BTFunction $ resolveType t |
331 resolveType (FunctionType t a) = liftM (BTFunction (length a)) $ resolveType t |
291 resolveType (DeriveType (InitHexNumber _)) = return BTInt |
332 resolveType (DeriveType (InitHexNumber _)) = return BTInt |
292 resolveType (DeriveType (InitNumber _)) = return BTInt |
333 resolveType (DeriveType (InitNumber _)) = return BTInt |
293 resolveType (DeriveType (InitFloat _)) = return BTFloat |
334 resolveType (DeriveType (InitFloat _)) = return BTFloat |
294 resolveType (DeriveType (InitString _)) = return BTString |
335 resolveType (DeriveType (InitString _)) = return BTString |
295 resolveType (DeriveType (InitBinOp {})) = return BTInt |
336 resolveType (DeriveType (InitBinOp {})) = return BTInt |
304 resolveType (Set t) = liftM BTSet $ resolveType t |
345 resolveType (Set t) = liftM BTSet $ resolveType t |
305 |
346 |
306 |
347 |
307 resolve :: String -> BaseType -> State RenderState BaseType |
348 resolve :: String -> BaseType -> State RenderState BaseType |
308 resolve s (BTUnresolved t) = do |
349 resolve s (BTUnresolved t) = do |
309 v <- gets $ find (\(a, _) -> a == t) . currentScope |
350 v <- gets $ Map.lookup t . currentScope |
310 if isJust v then |
351 if isJust v then |
311 resolve s . snd . snd . fromJust $ v |
352 resolve s . snd . head . fromJust $ v |
312 else |
353 else |
313 error $ "Unknown type " ++ show t ++ "\n" ++ s |
354 error $ "Unknown type " ++ show t ++ "\n" ++ s |
314 resolve _ t = return t |
355 resolve _ t = return t |
315 |
356 |
316 fromPointer :: String -> BaseType -> State RenderState BaseType |
357 fromPointer :: String -> BaseType -> State RenderState BaseType |
317 fromPointer s (BTPointerTo t) = resolve s t |
358 fromPointer s (BTPointerTo t) = resolve s t |
318 fromPointer s (BTFunctionReturn _ (BTPointerTo t)) = resolve s t |
|
319 fromPointer s t = do |
359 fromPointer s t = do |
320 ns <- gets currentScope |
360 error $ "Dereferencing from non-pointer type " ++ show t ++ "\n" ++ s |
321 error $ "Dereferencing from non-pointer type " ++ show t ++ "\n" ++ s ++ "\n\n" ++ show (take 100 ns) |
|
322 |
361 |
323 |
362 |
324 functionParams2C params = liftM (hcat . punctuate comma . concat) $ mapM (tvar2C False) params |
363 functionParams2C params = liftM (hcat . punctuate comma . concat) $ mapM (tvar2C False) params |
|
364 |
|
365 numberOfDeclarations :: [TypeVarDeclaration] -> Int |
|
366 numberOfDeclarations = sum . map cnt |
|
367 where |
|
368 cnt (VarDeclaration _ (ids, _) _) = length ids |
|
369 cnt _ = 1 |
325 |
370 |
326 fun2C :: Bool -> String -> TypeVarDeclaration -> State RenderState [Doc] |
371 fun2C :: Bool -> String -> TypeVarDeclaration -> State RenderState [Doc] |
327 fun2C _ _ (FunctionDeclaration name returnType params Nothing) = do |
372 fun2C _ _ (FunctionDeclaration name returnType params Nothing) = do |
328 t <- type2C returnType |
373 t <- type2C returnType |
329 t'<- gets lastType |
374 t'<- gets lastType |
330 p <- withState' id $ functionParams2C params |
375 p <- withState' id $ functionParams2C params |
331 n <- id2C IOInsert $ setBaseType (BTFunction t') name |
376 n <- id2C IOInsert $ setBaseType (BTFunction (numberOfDeclarations params) t') name |
332 return [t empty <+> n <> parens p] |
377 return [t empty <+> n <> parens p] |
333 |
378 |
334 fun2C True rv (FunctionDeclaration name returnType params (Just (tvars, phrase))) = do |
379 fun2C True rv (FunctionDeclaration name returnType params (Just (tvars, phrase))) = do |
335 let res = docToLower $ text rv <> text "_result" |
380 let res = docToLower $ text rv <> text "_result" |
336 t <- type2C returnType |
381 t <- type2C returnType |
337 t'<- gets lastType |
382 t'<- gets lastType |
338 n <- id2C IOInsert $ setBaseType (BTFunction t') name |
383 n <- id2C IOInsert $ setBaseType (BTFunction (numberOfDeclarations params) t') name |
339 (p, ph) <- withState' (\st -> st{currentScope = (map toLower rv, (render res, BTFunctionReturn (render n) t')) : currentScope st}) $ do |
384 (p, ph) <- withState' (\st -> st{currentScope = Map.insertWith un (map toLower rv) [(render res, t')] $ currentScope st}) $ do |
340 p <- functionParams2C params |
385 p <- functionParams2C params |
341 ph <- liftM2 ($+$) (typesAndVars2C False tvars) (phrase2C' phrase) |
386 ph <- liftM2 ($+$) (typesAndVars2C False tvars) (phrase2C' phrase) |
342 return (p, ph) |
387 return (p, ph) |
343 let phrasesBlock = case returnType of |
388 let phrasesBlock = case returnType of |
344 VoidType -> ph |
389 VoidType -> ph |
392 |
437 |
393 op2CTyped :: String -> [TypeDecl] -> State RenderState Identifier |
438 op2CTyped :: String -> [TypeDecl] -> State RenderState Identifier |
394 op2CTyped op t = do |
439 op2CTyped op t = do |
395 t' <- liftM (render . hcat . punctuate (char '_') . map (\t -> t empty)) $ mapM type2C t |
440 t' <- liftM (render . hcat . punctuate (char '_') . map (\t -> t empty)) $ mapM type2C t |
396 bt <- gets lastType |
441 bt <- gets lastType |
397 return $ case bt of |
442 return $ Identifier (t' ++ "_op_" ++ opStr) bt |
398 BTRecord {} -> Identifier (t' ++ "_op_" ++ opStr) bt |
|
399 _ -> Identifier t' bt |
|
400 where |
443 where |
401 opStr = case op of |
444 opStr = case op of |
402 "+" -> "add" |
445 "+" -> "add" |
403 "-" -> "sub" |
446 "-" -> "sub" |
404 "*" -> "mul" |
447 "*" -> "mul" |
405 "/" -> "div" |
448 "/" -> "div" |
406 "=" -> "eq" |
449 "=" -> "eq" |
407 "<" -> "lt" |
450 "<" -> "lt" |
408 ">" -> "gt" |
451 ">" -> "gt" |
|
452 "<>" -> "neq" |
409 _ -> error $ "op2CTyped: unknown op '" ++ op ++ "'" |
453 _ -> error $ "op2CTyped: unknown op '" ++ op ++ "'" |
410 |
454 |
411 extractTypes :: [TypeVarDeclaration] -> [TypeDecl] |
455 extractTypes :: [TypeVarDeclaration] -> [TypeDecl] |
412 extractTypes = concatMap f |
456 extractTypes = concatMap f |
413 where |
457 where |
414 f (VarDeclaration _ (ids, t) _) = replicate (length ids) t |
458 f (VarDeclaration _ (ids, t) _) = replicate (length ids) t |
415 f a = error $ "extractTypes: can't extract from " ++ show a |
459 f a = error $ "extractTypes: can't extract from " ++ show a |
416 |
460 |
417 initExpr2C :: InitExpression -> State RenderState Doc |
461 initExpr2C, initExpr2C' :: InitExpression -> State RenderState Doc |
418 initExpr2C InitNull = return $ text "NULL" |
462 initExpr2C (InitArray values) = liftM (braces . vcat . punctuate comma) $ mapM initExpr2C values |
419 initExpr2C (InitAddress expr) = liftM ((<>) (text "&")) (initExpr2C expr) |
463 initExpr2C a = initExpr2C' a |
420 initExpr2C (InitPrefixOp op expr) = liftM (text (op2C op) <>) (initExpr2C expr) |
464 initExpr2C' InitNull = return $ text "NULL" |
421 initExpr2C (InitBinOp op expr1 expr2) = do |
465 initExpr2C' (InitAddress expr) = liftM ((<>) (text "&")) (initExpr2C' expr) |
422 e1 <- initExpr2C expr1 |
466 initExpr2C' (InitPrefixOp op expr) = liftM (text (op2C op) <>) (initExpr2C' expr) |
423 e2 <- initExpr2C expr2 |
467 initExpr2C' (InitBinOp op expr1 expr2) = do |
|
468 e1 <- initExpr2C' expr1 |
|
469 e2 <- initExpr2C' expr2 |
424 return $ parens $ e1 <+> text (op2C op) <+> e2 |
470 return $ parens $ e1 <+> text (op2C op) <+> e2 |
425 initExpr2C (InitNumber s) = return $ text s |
471 initExpr2C' (InitNumber s) = return $ text s |
426 initExpr2C (InitFloat s) = return $ text s |
472 initExpr2C' (InitFloat s) = return $ text s |
427 initExpr2C (InitHexNumber s) = return $ text "0x" <> (text . map toLower $ s) |
473 initExpr2C' (InitHexNumber s) = return $ text "0x" <> (text . map toLower $ s) |
428 initExpr2C (InitString [a]) = return . quotes $ text [a] |
474 initExpr2C' (InitString [a]) = return . quotes $ text [a] |
429 initExpr2C (InitString s) = return $ strInit s |
475 initExpr2C' (InitString s) = return $ strInit s |
430 initExpr2C (InitChar a) = return $ quotes $ text "\\x" <> text (showHex (read a) "") |
476 initExpr2C' (InitChar a) = return $ quotes $ text "\\x" <> text (showHex (read a) "") |
431 initExpr2C (InitReference i) = id2C IOLookup i |
477 initExpr2C' (InitReference i) = id2C IOLookup i |
432 initExpr2C (InitRecord fields) = do |
478 initExpr2C' (InitRecord fields) = do |
433 (fs :: [Doc]) <- mapM (\(Identifier a _, b) -> liftM (text "." <> text a <+> equals <+>) $ initExpr2C b) fields |
479 (fs :: [Doc]) <- mapM (\(Identifier a _, b) -> liftM (text "." <> text a <+> equals <+>) $ initExpr2C b) fields |
434 return $ lbrace $+$ (nest 4 . vcat . punctuate comma $ fs) $+$ rbrace |
480 return $ lbrace $+$ (nest 4 . vcat . punctuate comma $ fs) $+$ rbrace |
435 initExpr2C (InitArray [value]) = initExpr2C value |
481 initExpr2C' (InitArray [value]) = initExpr2C value |
436 initExpr2C (InitArray values) = liftM (braces . vcat . punctuate comma) $ mapM initExpr2C values |
482 initExpr2C' r@(InitRange (Range i@(Identifier i' _))) = do |
437 initExpr2C r@(InitRange (Range i@(Identifier i' _))) = do |
|
438 id2C IOLookup i |
483 id2C IOLookup i |
439 t <- gets lastType |
484 t <- gets lastType |
440 case t of |
485 case t of |
441 BTEnum s -> return . int $ length s |
486 BTEnum s -> return . int $ length s |
442 BTInt -> case i' of |
487 BTInt -> case i' of |
443 "byte" -> return $ int 256 |
488 "byte" -> return $ int 256 |
444 _ -> error $ "InitRange identifier: " ++ i' |
489 _ -> error $ "InitRange identifier: " ++ i' |
445 _ -> error $ "InitRange: " ++ show r |
490 _ -> error $ "InitRange: " ++ show r |
446 initExpr2C (InitRange (RangeFromTo (InitNumber "0") r)) = initExpr2C $ BuiltInFunction "succ" [r] |
491 initExpr2C' (InitRange (RangeFromTo (InitNumber "0") r)) = initExpr2C $ BuiltInFunction "succ" [r] |
447 initExpr2C (InitRange (RangeFromTo (InitChar "0") (InitChar r))) = initExpr2C $ BuiltInFunction "succ" [InitNumber r] |
492 initExpr2C' (InitRange (RangeFromTo (InitChar "0") (InitChar r))) = initExpr2C $ BuiltInFunction "succ" [InitNumber r] |
448 initExpr2C (InitRange a) = error $ show a --return $ text "<<range>>" |
493 initExpr2C' (InitRange a) = error $ show a --return $ text "<<range>>" |
449 initExpr2C (InitSet []) = return $ text "0" |
494 initExpr2C' (InitSet []) = return $ text "0" |
450 initExpr2C (InitSet a) = return $ text "<<set>>" |
495 initExpr2C' (InitSet a) = return $ text "<<set>>" |
451 initExpr2C (BuiltInFunction "low" [InitReference e]) = return $ |
496 initExpr2C' (BuiltInFunction "low" [InitReference e]) = return $ |
452 case e of |
497 case e of |
453 (Identifier "LongInt" _) -> int (-2^31) |
498 (Identifier "LongInt" _) -> int (-2^31) |
454 (Identifier "SmallInt" _) -> int (-2^15) |
499 (Identifier "SmallInt" _) -> int (-2^15) |
455 _ -> error $ "BuiltInFunction 'low': " ++ show e |
500 _ -> error $ "BuiltInFunction 'low': " ++ show e |
456 initExpr2C (BuiltInFunction "high" [e]) = do |
501 initExpr2C' (BuiltInFunction "high" [e]) = do |
457 initExpr2C e |
502 initExpr2C e |
458 t <- gets lastType |
503 t <- gets lastType |
459 case t of |
504 case t of |
460 (BTArray i _ _) -> initExpr2C $ BuiltInFunction "pred" [InitRange i] |
505 (BTArray i _ _) -> initExpr2C' $ BuiltInFunction "pred" [InitRange i] |
461 a -> error $ "BuiltInFunction 'high': " ++ show a |
506 a -> error $ "BuiltInFunction 'high': " ++ show a |
462 initExpr2C (BuiltInFunction "succ" [BuiltInFunction "pred" [e]]) = initExpr2C e |
507 initExpr2C' (BuiltInFunction "succ" [BuiltInFunction "pred" [e]]) = initExpr2C' e |
463 initExpr2C (BuiltInFunction "pred" [BuiltInFunction "succ" [e]]) = initExpr2C e |
508 initExpr2C' (BuiltInFunction "pred" [BuiltInFunction "succ" [e]]) = initExpr2C' e |
464 initExpr2C (BuiltInFunction "succ" [e]) = liftM (<> text " + 1") $ initExpr2C e |
509 initExpr2C' (BuiltInFunction "succ" [e]) = liftM (<> text " + 1") $ initExpr2C' e |
465 initExpr2C (BuiltInFunction "pred" [e]) = liftM (<> text " - 1") $ initExpr2C e |
510 initExpr2C' (BuiltInFunction "pred" [e]) = liftM (<> text " - 1") $ initExpr2C' e |
466 initExpr2C b@(BuiltInFunction _ _) = error $ show b |
511 initExpr2C' b@(BuiltInFunction _ _) = error $ show b |
467 initExpr2C a = error $ "initExpr2C: don't know how to render " ++ show a |
512 initExpr2C' a = error $ "initExpr2C: don't know how to render " ++ show a |
468 |
513 |
469 |
514 |
470 range2C :: InitExpression -> State RenderState [Doc] |
515 range2C :: InitExpression -> State RenderState [Doc] |
471 range2C (InitString [a]) = return [quotes $ text [a]] |
516 range2C (InitString [a]) = return [quotes $ text [a]] |
472 range2C (InitRange (Range i)) = liftM (flip (:) []) $ id2C IOLookup i |
517 range2C (InitRange (Range i)) = liftM (flip (:) []) $ id2C IOLookup i |
487 modify (\st -> st{lastType = rt}) |
532 modify (\st -> st{lastType = rt}) |
488 return r |
533 return r |
489 where |
534 where |
490 type2C' VoidType = return (text "void" <+>) |
535 type2C' VoidType = return (text "void" <+>) |
491 type2C' (String l) = return (text "string255" <+>)--return (text ("string" ++ show l) <+>) |
536 type2C' (String l) = return (text "string255" <+>)--return (text ("string" ++ show l) <+>) |
492 type2C' (PointerTo (SimpleType i)) = liftM (\i a -> text "struct __" <> i <+> text "*" <+> a) $ id2C IODeferred i |
537 type2C' (PointerTo (SimpleType i)) = do |
|
538 i' <- id2C IODeferred i |
|
539 lt <- gets lastType |
|
540 case lt of |
|
541 BTRecord _ _ -> return $ \a -> text "struct __" <> i' <+> text "*" <+> a |
|
542 BTUnknown -> return $ \a -> text "struct __" <> i' <+> text "*" <+> a |
|
543 _ -> return $ \a -> i' <+> text "*" <+> a |
493 type2C' (PointerTo t) = liftM (\t a -> t (parens $ text "*" <> a)) $ type2C t |
544 type2C' (PointerTo t) = liftM (\t a -> t (parens $ text "*" <> a)) $ type2C t |
494 type2C' (RecordType tvs union) = do |
545 type2C' (RecordType tvs union) = do |
495 t <- withState' id $ mapM (tvar2C False) tvs |
546 t <- withState' f $ mapM (tvar2C False) tvs |
496 u <- unions |
547 u <- unions |
497 return $ \i -> text "struct __" <> i <+> lbrace $+$ nest 4 ((vcat . map (<> semi) . concat $ t) $$ u) $+$ rbrace <+> i |
548 return $ \i -> text "struct __" <> i <+> lbrace $+$ nest 4 ((vcat . map (<> semi) . concat $ t) $$ u) $+$ rbrace <+> i |
498 where |
549 where |
|
550 f s = s{currentUnit = ""} |
499 unions = case union of |
551 unions = case union of |
500 Nothing -> return empty |
552 Nothing -> return empty |
501 Just a -> do |
553 Just a -> do |
502 structs <- mapM struct2C a |
554 structs <- mapM struct2C a |
503 return $ text "union" $+$ braces (nest 4 $ vcat structs) <> semi |
555 return $ text "union" $+$ braces (nest 4 $ vcat structs) <> semi |
504 struct2C tvs = do |
556 struct2C tvs = do |
505 t <- withState' id $ mapM (tvar2C False) tvs |
557 t <- withState' f $ mapM (tvar2C False) tvs |
506 return $ text "struct" $+$ braces (nest 4 (vcat . map (<> semi) . concat $ t)) <> semi |
558 return $ text "struct" $+$ braces (nest 4 (vcat . map (<> semi) . concat $ t)) <> semi |
507 type2C' (RangeType r) = return (text "int" <+>) |
559 type2C' (RangeType r) = return (text "int" <+>) |
508 type2C' (Sequence ids) = do |
560 type2C' (Sequence ids) = do |
509 is <- mapM (id2C IOInsert . setBaseType bt) ids |
561 is <- mapM (id2C IOInsert . setBaseType bt) ids |
510 return (text "enum" <+> (braces . vcat . punctuate comma . map (\(a, b) -> a <+> equals <+> text "0x" <> text (showHex b "")) $ zip is [1..]) <+>) |
562 return (text "enum" <+> (braces . vcat . punctuate comma . map (\(a, b) -> a <+> equals <+> text "0x" <> text (showHex b "")) $ zip is [0..]) <+>) |
511 where |
563 where |
512 bt = BTEnum $ map (\(Identifier i _) -> map toLower i) ids |
564 bt = BTEnum $ map (\(Identifier i _) -> map toLower i) ids |
513 type2C' (ArrayDecl Nothing t) = type2C (PointerTo t) |
565 type2C' (ArrayDecl Nothing t) = type2C (PointerTo t) |
514 type2C' (ArrayDecl (Just r) t) = do |
566 type2C' (ArrayDecl (Just r) t) = do |
515 t' <- type2C t |
567 t' <- type2C t |
|
568 lt <- gets lastType |
|
569 ft <- case lt of |
|
570 BTFunction {} -> type2C (PointerTo t) |
|
571 _ -> return t' |
516 r' <- initExpr2C (InitRange r) |
572 r' <- initExpr2C (InitRange r) |
517 return $ \i -> t' i <> brackets r' |
573 return $ \i -> ft i <> brackets r' |
518 type2C' (Set t) = return (text "<<set>>" <+>) |
574 type2C' (Set t) = return (text "<<set>>" <+>) |
519 type2C' (FunctionType returnType params) = do |
575 type2C' (FunctionType returnType params) = do |
520 t <- type2C returnType |
576 t <- type2C returnType |
521 p <- withState' id $ functionParams2C params |
577 p <- withState' id $ functionParams2C params |
522 return (\i -> t empty <+> i <> parens p) |
578 return (\i -> t empty <+> i <> parens p) |
615 wrapPhrase p@(Phrases _) = p |
684 wrapPhrase p@(Phrases _) = p |
616 wrapPhrase p = Phrases [p] |
685 wrapPhrase p = Phrases [p] |
617 |
686 |
618 expr2C :: Expression -> State RenderState Doc |
687 expr2C :: Expression -> State RenderState Doc |
619 expr2C (Expression s) = return $ text s |
688 expr2C (Expression s) = return $ text s |
620 expr2C (BinOp op expr1 expr2) = do |
689 expr2C b@(BinOp op expr1 expr2) = do |
621 e1 <- expr2C expr1 |
690 e1 <- expr2C expr1 |
622 t1 <- gets lastType |
691 t1 <- gets lastType |
623 e2 <- expr2C expr2 |
692 e2 <- expr2C expr2 |
624 t2 <- gets lastType |
693 t2 <- gets lastType |
625 case (op2C op, t1, t2) of |
694 case (op2C op, t1, t2) of |
626 ("+", BTString, BTString) -> expr2C $ BuiltInFunCall [expr1, expr2] (SimpleReference $ Identifier "_strconcat" (BTFunction BTString)) |
695 ("+", BTString, BTString) -> expr2C $ BuiltInFunCall [expr1, expr2] (SimpleReference $ Identifier "_strconcat" (BTFunction 2 BTString)) |
627 ("+", BTString, BTChar) -> expr2C $ BuiltInFunCall [expr1, expr2] (SimpleReference $ Identifier "_strappend" (BTFunction BTString)) |
696 ("+", BTString, BTChar) -> expr2C $ BuiltInFunCall [expr1, expr2] (SimpleReference $ Identifier "_strappend" (BTFunction 2 BTString)) |
628 ("+", BTChar, BTString) -> expr2C $ BuiltInFunCall [expr1, expr2] (SimpleReference $ Identifier "_strprepend" (BTFunction BTString)) |
697 ("+", BTChar, BTString) -> expr2C $ BuiltInFunCall [expr1, expr2] (SimpleReference $ Identifier "_strprepend" (BTFunction 2 BTString)) |
629 ("==", BTString, _) -> expr2C $ BuiltInFunCall [expr1, expr2] (SimpleReference $ Identifier "_strcompare" (BTFunction BTBool)) |
698 ("==", BTString, BTChar) -> expr2C $ BuiltInFunCall [expr1, expr2] (SimpleReference $ Identifier "_strcomparec" (BTFunction 2 BTBool)) |
630 ("!=", BTString, _) -> expr2C $ BuiltInFunCall [expr1, expr2] (SimpleReference $ Identifier "_strncompare" (BTFunction BTBool)) |
699 ("==", BTString, BTString) -> expr2C $ BuiltInFunCall [expr1, expr2] (SimpleReference $ Identifier "_strcompare" (BTFunction 2 BTBool)) |
|
700 ("!=", BTString, _) -> expr2C $ BuiltInFunCall [expr1, expr2] (SimpleReference $ Identifier "_strncompare" (BTFunction 2 BTBool)) |
631 ("&", BTBool, _) -> return $ parens e1 <+> text "&&" <+> parens e2 |
701 ("&", BTBool, _) -> return $ parens e1 <+> text "&&" <+> parens e2 |
632 ("|", BTBool, _) -> return $ parens e1 <+> text "||" <+> parens e2 |
702 ("|", BTBool, _) -> return $ parens e1 <+> text "||" <+> parens e2 |
|
703 (_, BTRecord t1 _, BTRecord t2 _) -> do |
|
704 i <- op2CTyped op [SimpleType (Identifier t1 undefined), SimpleType (Identifier t2 undefined)] |
|
705 ref2C $ FunCall [expr1, expr2] (SimpleReference i) |
|
706 (_, BTRecord t1 _, BTInt) -> do |
|
707 -- aw, "LongInt" here is hwengine-specific hack |
|
708 i <- op2CTyped op [SimpleType (Identifier t1 undefined), SimpleType (Identifier "LongInt" undefined)] |
|
709 ref2C $ FunCall [expr1, expr2] (SimpleReference i) |
|
710 ("in", _, _) -> |
|
711 case expr2 of |
|
712 SetExpression set -> do |
|
713 ids <- mapM (id2C IOLookup) set |
|
714 return . parens . hcat . punctuate (text " || ") . map (\i -> parens $ e1 <+> text "==" <+> i) $ ids |
|
715 _ -> error "'in' against not set expression" |
633 (o, _, _) | o `elem` boolOps -> do |
716 (o, _, _) | o `elem` boolOps -> do |
634 modify(\s -> s{lastType = BTBool}) |
717 modify(\s -> s{lastType = BTBool}) |
635 return $ parens e1 <+> text o <+> parens e2 |
718 return $ parens e1 <+> text o <+> parens e2 |
636 | otherwise -> return $ parens e1 <+> text o <+> parens e2 |
719 | otherwise -> return $ parens e1 <+> text o <+> parens e2 |
637 where |
720 where |
638 boolOps = ["==", "!=", "<", ">", "<=", ">="] |
721 boolOps = ["==", "!=", "<", ">", "<=", ">="] |
639 expr2C (NumberLiteral s) = return $ text s |
722 expr2C (NumberLiteral s) = do |
|
723 modify(\s -> s{lastType = BTInt}) |
|
724 return $ text s |
640 expr2C (FloatLiteral s) = return $ text s |
725 expr2C (FloatLiteral s) = return $ text s |
641 expr2C (HexNumber s) = return $ text "0x" <> (text . map toLower $ s) |
726 expr2C (HexNumber s) = return $ text "0x" <> (text . map toLower $ s) |
642 expr2C (StringLiteral [a]) = do |
727 {-expr2C (StringLiteral [a]) = do |
643 modify(\s -> s{lastType = BTChar}) |
728 modify(\s -> s{lastType = BTChar}) |
644 return . quotes $ text [a] |
729 return . quotes . text $ escape a |
|
730 where |
|
731 escape '\'' = "\\\'" |
|
732 escape a = [a]-} |
645 expr2C (StringLiteral s) = addStringConst s |
733 expr2C (StringLiteral s) = addStringConst s |
|
734 expr2C (PCharLiteral s) = return . doubleQuotes $ text s |
646 expr2C (Reference ref) = ref2CF ref |
735 expr2C (Reference ref) = ref2CF ref |
647 expr2C (PrefixOp op expr) = liftM (text (op2C op) <>) (expr2C expr) |
736 expr2C (PrefixOp op expr) = do |
|
737 e <- expr2C expr |
|
738 lt <- gets lastType |
|
739 case lt of |
|
740 BTRecord t _ -> do |
|
741 i <- op2CTyped op [SimpleType (Identifier t undefined)] |
|
742 ref2C $ FunCall [expr] (SimpleReference i) |
|
743 _ -> return $ text (op2C op) <> e |
648 expr2C Null = return $ text "NULL" |
744 expr2C Null = return $ text "NULL" |
649 expr2C (CharCode a) = do |
745 expr2C (CharCode a) = do |
650 modify(\s -> s{lastType = BTChar}) |
746 modify(\s -> s{lastType = BTChar}) |
651 return $ quotes $ text "\\x" <> text (showHex (read a) "") |
747 return $ quotes $ text "\\x" <> text (showHex (read a) "") |
652 expr2C (HexCharCode a) = return $ quotes $ text "\\x" <> text (map toLower a) |
748 expr2C (HexCharCode a) = if length a <= 2 then return $ quotes $ text "\\x" <> text (map toLower a) else expr2C $ HexNumber a |
653 expr2C (SetExpression ids) = mapM (id2C IOLookup) ids >>= return . parens . hcat . punctuate (text " | ") |
749 expr2C (SetExpression ids) = mapM (id2C IOLookup) ids >>= return . parens . hcat . punctuate (text " | ") |
654 |
750 |
|
751 expr2C (BuiltInFunCall [e] (SimpleReference (Identifier "low" _))) = do |
|
752 e' <- liftM (map toLower . render) $ expr2C e |
|
753 lt <- gets lastType |
|
754 case lt of |
|
755 BTEnum a -> return $ int 0 |
|
756 BTInt -> case e' of |
|
757 "longint" -> return $ int (-2147483648) |
|
758 BTArray {} -> return $ int 0 |
|
759 _ -> error $ "BuiltInFunCall 'low' from " ++ show e ++ "\ntype: " ++ show lt |
|
760 expr2C (BuiltInFunCall [e] (SimpleReference (Identifier "high" _))) = do |
|
761 e' <- liftM (map toLower . render) $ expr2C e |
|
762 lt <- gets lastType |
|
763 case lt of |
|
764 BTEnum a -> return . int $ length a - 1 |
|
765 BTInt -> case e' of |
|
766 "longint" -> return $ int (2147483647) |
|
767 BTString -> return $ int 255 |
|
768 BTArray (RangeFromTo _ n) _ _ -> initExpr2C n |
|
769 _ -> error $ "BuiltInFunCall 'high' from " ++ show e ++ "\ntype: " ++ show lt |
655 expr2C (BuiltInFunCall [e] (SimpleReference (Identifier "ord" _))) = liftM parens $ expr2C e |
770 expr2C (BuiltInFunCall [e] (SimpleReference (Identifier "ord" _))) = liftM parens $ expr2C e |
656 expr2C (BuiltInFunCall [e] (SimpleReference (Identifier "succ" _))) = liftM (<> text " + 1") $ expr2C e |
771 expr2C (BuiltInFunCall [e] (SimpleReference (Identifier "succ" _))) = liftM (<> text " + 1") $ expr2C e |
657 expr2C (BuiltInFunCall [e] (SimpleReference (Identifier "pred" _))) = liftM (<> text " - 1") $ expr2C e |
772 expr2C (BuiltInFunCall [e] (SimpleReference (Identifier "pred" _))) = liftM (<> text " - 1") $ expr2C e |
|
773 expr2C (BuiltInFunCall [e] (SimpleReference (Identifier "length" _))) = do |
|
774 e' <- expr2C e |
|
775 lt <- gets lastType |
|
776 modify (\s -> s{lastType = BTInt}) |
|
777 case lt of |
|
778 BTString -> return $ text "Length" <> parens e' |
|
779 BTArray {} -> return $ text "length_ar" <> parens e' |
|
780 _ -> error $ "length() called on " ++ show lt |
658 expr2C (BuiltInFunCall params ref) = do |
781 expr2C (BuiltInFunCall params ref) = do |
659 r <- ref2C ref |
782 r <- ref2C ref |
660 t <- gets lastType |
783 t <- gets lastType |
661 ps <- mapM expr2C params |
784 ps <- mapM expr2C params |
662 case t of |
785 case t of |
663 BTFunction t' -> do |
786 BTFunction _ t' -> do |
664 modify (\s -> s{lastType = t'}) |
787 modify (\s -> s{lastType = t'}) |
665 _ -> error $ "BuiltInFunCall lastType: " ++ show t |
788 _ -> error $ "BuiltInFunCall lastType: " ++ show t |
666 return $ |
789 return $ |
667 r <> parens (hsep . punctuate (char ',') $ ps) |
790 r <> parens (hsep . punctuate (char ',') $ ps) |
668 expr2C a = error $ "Don't know how to render " ++ show a |
791 expr2C a = error $ "Don't know how to render " ++ show a |
686 -- conversion routines |
819 -- conversion routines |
687 ref2C ae@(ArrayElement [expr] ref) = do |
820 ref2C ae@(ArrayElement [expr] ref) = do |
688 e <- expr2C expr |
821 e <- expr2C expr |
689 r <- ref2C ref |
822 r <- ref2C ref |
690 t <- gets lastType |
823 t <- gets lastType |
691 ns <- gets currentScope |
|
692 case t of |
824 case t of |
693 (BTArray _ _ t') -> modify (\st -> st{lastType = t'}) |
825 (BTArray _ _ t') -> modify (\st -> st{lastType = t'}) |
694 (BTFunctionReturn _ (BTArray _ _ t')) -> modify (\st -> st{lastType = t'}) |
826 -- (BTFunctionReturn _ (BTArray _ _ t')) -> modify (\st -> st{lastType = t'}) |
695 (BTFunctionReturn _ (BTString)) -> modify (\st -> st{lastType = BTChar}) |
827 -- (BTFunctionReturn _ (BTString)) -> modify (\st -> st{lastType = BTChar}) |
696 (BTString) -> modify (\st -> st{lastType = BTChar}) |
828 (BTString) -> modify (\st -> st{lastType = BTChar}) |
697 (BTPointerTo t) -> do |
829 (BTPointerTo t) -> do |
698 t'' <- fromPointer (show t) =<< gets lastType |
830 t'' <- fromPointer (show t) =<< gets lastType |
699 case t'' of |
831 case t'' of |
700 BTChar -> modify (\st -> st{lastType = BTChar}) |
832 BTChar -> modify (\st -> st{lastType = BTChar}) |
701 a -> error $ "Getting element of " ++ show a ++ "\nReference: " ++ show ae ++ "\n" ++ show (take 100 ns) |
833 a -> error $ "Getting element of " ++ show a ++ "\nReference: " ++ show ae |
702 a -> error $ "Getting element of " ++ show a ++ "\nReference: " ++ show ae ++ "\n" ++ show (take 100 ns) |
834 a -> error $ "Getting element of " ++ show a ++ "\nReference: " ++ show ae |
703 case t of |
835 case t of |
704 BTString -> return $ r <> text ".s" <> brackets e |
836 BTString -> return $ r <> text ".s" <> brackets e |
705 _ -> return $ r <> brackets e |
837 _ -> return $ r <> brackets e |
706 ref2C (SimpleReference name) = id2C IOLookup name |
838 ref2C (SimpleReference name) = id2C IOLookup name |
707 ref2C rf@(RecordField (Dereference ref1) ref2) = do |
839 ref2C rf@(RecordField (Dereference ref1) ref2) = do |
708 r1 <- ref2C ref1 |
840 r1 <- ref2C ref1 |
709 t <- fromPointer (show ref1) =<< gets lastType |
841 t <- fromPointer (show ref1) =<< gets lastType |
710 ns <- gets currentScope |
|
711 r2 <- case t of |
842 r2 <- case t of |
712 BTRecord rs -> withRecordNamespace "" rs $ ref2C ref2 |
843 BTRecord _ rs -> withRecordNamespace "" rs $ ref2C ref2 |
713 BTUnit -> withLastIdNamespace $ ref2C ref2 |
844 BTUnit -> error "What??" |
714 a -> error $ "dereferencing from " ++ show a ++ "\n" ++ show rf ++ "\n" ++ show (take 100 ns) |
845 a -> error $ "dereferencing from " ++ show a ++ "\n" ++ show rf |
715 return $ |
846 return $ |
716 r1 <> text "->" <> r2 |
847 r1 <> text "->" <> r2 |
717 ref2C rf@(RecordField ref1 ref2) = do |
848 ref2C rf@(RecordField ref1 ref2) = do |
718 r1 <- ref2C ref1 |
849 r1 <- ref2C ref1 |
719 t <- gets lastType |
850 t <- gets lastType |
720 ns <- gets currentScope |
851 case t of |
721 r2 <- case t of |
852 BTRecord _ rs -> do |
722 BTFunctionReturn s (BTRecord rs) -> withRecordNamespace "" rs $ ref2C ref2 |
853 r2 <- withRecordNamespace "" rs $ ref2C ref2 |
723 BTRecord rs -> withRecordNamespace "" rs $ ref2C ref2 |
854 return $ r1 <> text "." <> r2 |
724 BTUnit -> withLastIdNamespace $ ref2C ref2 |
855 BTUnit -> withLastIdNamespace $ ref2C ref2 |
725 a -> error $ "dereferencing from " ++ show a ++ "\n" ++ show rf ++ "\n" ++ show (take 100 ns) |
856 a -> error $ "dereferencing from " ++ show a ++ "\n" ++ show rf |
726 return $ |
|
727 r1 <> text "." <> r2 |
|
728 ref2C d@(Dereference ref) = do |
857 ref2C d@(Dereference ref) = do |
729 r <- ref2C ref |
858 r <- ref2C ref |
730 t <- fromPointer (show d) =<< gets lastType |
859 t <- fromPointer (show d) =<< gets lastType |
731 modify (\st -> st{lastType = t}) |
860 modify (\st -> st{lastType = t}) |
732 return $ (parens $ text "*" <> r) |
861 return $ (parens $ text "*" <> r) |
733 ref2C f@(FunCall params ref) = do |
862 ref2C f@(FunCall params ref) = do |
734 r <- ref2C ref |
863 r <- fref2C ref |
735 t <- gets lastType |
864 t <- gets lastType |
736 case t of |
865 case t of |
737 BTFunction t' -> do |
866 BTFunction _ t' -> do |
738 ps <- liftM (parens . hsep . punctuate (char ',')) $ mapM expr2C params |
867 ps <- liftM (parens . hsep . punctuate (char ',')) $ mapM expr2C params |
739 modify (\s -> s{lastType = t'}) |
868 modify (\s -> s{lastType = t'}) |
740 return $ r <> ps |
869 return $ r <> ps |
741 BTFunctionReturn r t' -> do |
|
742 ps <- liftM (parens . hsep . punctuate (char ',')) $ mapM expr2C params |
|
743 modify (\s -> s{lastType = t'}) |
|
744 return $ text r <> ps |
|
745 _ -> case (ref, params) of |
870 _ -> case (ref, params) of |
746 (SimpleReference i, [p]) -> ref2C $ TypeCast i p |
871 (SimpleReference i, [p]) -> ref2C $ TypeCast i p |
747 _ -> error $ "ref2C FunCall erroneous type cast detected: " ++ show f ++ "\nType detected: " ++ show t |
872 _ -> error $ "ref2C FunCall erroneous type cast detected: " ++ show f ++ "\nType detected: " ++ show t |
|
873 where |
|
874 fref2C (SimpleReference name) = id2C (IOLookupFunction $ length params) name |
|
875 fref2C a = ref2C a |
748 |
876 |
749 ref2C (Address ref) = do |
877 ref2C (Address ref) = do |
750 r <- ref2C ref |
878 r <- ref2C ref |
751 return $ text "&" <> parens r |
879 return $ text "&" <> parens r |
752 ref2C (TypeCast t'@(Identifier i _) expr) = do |
880 ref2C (TypeCast t'@(Identifier i _) expr) = do |
753 case map toLower i of |
881 case map toLower i of |
754 "pchar" -> ref2C $ FunCall [expr] (SimpleReference (Identifier "_pchar" $ BTPointerTo BTChar)) |
882 "pchar" -> ref2C $ FunCall [expr] (SimpleReference (Identifier "_pchar" $ BTPointerTo BTChar)) |
755 a -> do |
883 a -> do |
756 e <- expr2C expr |
884 e <- expr2C expr |
757 t <- id2C IOLookup t' |
885 t <- id2C IOLookup t' |
758 return $ parens t <> e |
886 return . parens $ parens t <> e |
759 ref2C (RefExpression expr) = expr2C expr |
887 ref2C (RefExpression expr) = expr2C expr |
760 |
888 |
761 |
889 |
762 op2C :: String -> String |
890 op2C :: String -> String |
763 op2C "or" = "|" |
891 op2C "or" = "|" |