From 35b17357b5b55e73c6bbc59e7dae094412b7b02a Mon Sep 17 00:00:00 2001 From: tomsmeding Date: Sat, 2 Sep 2017 10:18:40 +0200 Subject: Fully support structs --- BuildIR.hs | 55 ++++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 46 insertions(+), 9 deletions(-) (limited to 'BuildIR.hs') diff --git a/BuildIR.hs b/BuildIR.hs index 028c649..f40e141 100644 --- a/BuildIR.hs +++ b/BuildIR.hs @@ -417,15 +417,45 @@ convertExpression (ENew t sze) nextnext = do return ref convertAsExpression :: AsExpression -> Ref -> Id -> BuildM () -convertAsExpression (AEVar n _) valueref nextnext = do - mres <- findVar n - vref <- case mres of - Just (_, (r, _)) -> return r - Nothing -> throwError $ "Undefined variable '" ++ n ++ "'" ++ - " used in assignment expression" +convertAsExpression aevar@(AEVar _ _) valueref nextnext = do + vref <- getAEVarRef aevar addIns $ IMov vref valueref setTerm $ IJmp nextnext -convertAsExpression (AESubscript ae2 expr mrt) valueref nextnext = do +convertAsExpression aesubscript@(AESubscript _ _ _) valueref nextnext = do + elemptr <- getAESubscriptStoreRef aesubscript + addIns $ IStore elemptr valueref + setTerm $ IJmp nextnext +convertAsExpression topae@(AEGet _ _ _) valueref nextnext = do + let (core, _, offset) = collectAESets topae + case core of + aevar@(AEVar _ _) -> do + vref <- getAEVarRef aevar + addIns $ ISet vref offset valueref + aesubscript@(AESubscript _ _ _) -> do + elemptr <- getAESubscriptStoreRef aesubscript + fieldptr <- genTemp (refSize elemptr) + addIns $ IAri AAdd fieldptr elemptr (Constant (refSize elemptr) (fromIntegral offset)) + addIns $ IStore fieldptr valueref + AEGet _ _ _ -> undefined + setTerm $ IJmp nextnext + +collectAESets :: AsExpression -> (AsExpression, [AsExpression], Offset) +collectAESets ae@(AEGet ae2 n _) = + let (core, sets, offset) = collectAESets ae2 + in (core, ae : sets, offset + offsetInStruct (fromJust $ typeof ae2) n) +collectAESets ae = (ae, [], 0) + +getAEVarRef :: AsExpression -> BuildM Ref +getAEVarRef (AEVar n _) = do + mres <- findVar n + case mres of + Just (_, (r, _)) -> return r + Nothing -> throwError $ "Undefined variable '" ++ n ++ "'" ++ + " used in assignment expression" +getAEVarRef _ = undefined + +getAESubscriptStoreRef :: AsExpression -> BuildM Ref +getAESubscriptStoreRef (AESubscript ae2 expr mrt) = do let elemsz = sizeof $ fromJust mrt ae2ref <- goLoad ae2 bl2 <- newBlockNoSwitch @@ -446,9 +476,9 @@ convertAsExpression (AESubscript ae2 expr mrt) valueref nextnext = do switchBlock bl3 addIns $ IAri AMul offref subref (Constant (refSize subref) (fromIntegral elemsz)) addIns $ IAri AAdd elemptr ae2ref offref - addIns $ IStore elemptr valueref - setTerm $ IJmp nextnext + return elemptr where + -- evaluate as if it were an Expression goLoad :: AsExpression -> BuildM Ref goLoad (AEVar n _) = do mres <- findVar n @@ -483,3 +513,10 @@ convertAsExpression (AESubscript ae2 expr mrt) valueref nextnext = do dstref <- genTemp elemsz addIns $ ILoad dstref elemptr return dstref + goLoad topae@(AEGet topup _ _) = do + let (core, _, offset) = collectAESets topae + coreref <- goLoad core + ref <- genTemp (sizeof $ fromJust $ typeof topup) + addIns $ IGet ref coreref offset + return ref +getAESubscriptStoreRef _ = undefined -- cgit v1.2.3-54-g00ecf