aboutsummaryrefslogtreecommitdiff
path: root/BuildIR.hs
diff options
context:
space:
mode:
Diffstat (limited to 'BuildIR.hs')
-rw-r--r--BuildIR.hs55
1 files changed, 46 insertions, 9 deletions
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