Commit 1df9e42c authored by Edward Z. Yang's avatar Edward Z. Yang
Browse files

Raw versions of if and switch.



This makes the following statements valid C--, which uses the
block ID directly rather than generating an anonymous block:

    if (expr) goto foo;
    switch expr {
        case 0: goto foo;
        case 1: goto bar;
    }
Signed-off-by: Edward Z. Yang's avatarEdward Z. Yang <ezyang@mit.edu>
parent 93b6e532
...@@ -396,13 +396,15 @@ stmt :: { ExtCode } ...@@ -396,13 +396,15 @@ stmt :: { ExtCode }
| NAME '(' exprs0 ')' ';' | NAME '(' exprs0 ')' ';'
{% stmtMacro $1 $3 } {% stmtMacro $1 $3 }
| 'switch' maybe_range expr '{' arms default '}' | 'switch' maybe_range expr '{' arms default '}'
{ doSwitch $2 $3 $5 $6 } { do as <- sequence $5; doSwitch $2 $3 as $6 }
| 'goto' NAME ';' | 'goto' NAME ';'
{ do l <- lookupLabel $2; stmtEC (CmmBranch l) } { do l <- lookupLabel $2; stmtEC (CmmBranch l) }
| 'jump' expr maybe_actuals ';' | 'jump' expr maybe_actuals ';'
{ do e1 <- $2; e2 <- sequence $3; stmtEC (CmmJump e1 e2) } { do e1 <- $2; e2 <- sequence $3; stmtEC (CmmJump e1 e2) }
| 'return' maybe_actuals ';' | 'return' maybe_actuals ';'
{ do e <- sequence $2; stmtEC (CmmReturn e) } { do e <- sequence $2; stmtEC (CmmReturn e) }
| 'if' bool_expr 'goto' NAME
{ do l <- lookupLabel $4; cmmRawIf $2 l }
| 'if' bool_expr '{' body '}' else | 'if' bool_expr '{' body '}' else
{ cmmIfThenElse $2 $4 $6 } { cmmIfThenElse $2 $4 $6 }
...@@ -441,12 +443,16 @@ maybe_range :: { Maybe (Int,Int) } ...@@ -441,12 +443,16 @@ maybe_range :: { Maybe (Int,Int) }
: '[' INT '..' INT ']' { Just (fromIntegral $2, fromIntegral $4) } : '[' INT '..' INT ']' { Just (fromIntegral $2, fromIntegral $4) }
| {- empty -} { Nothing } | {- empty -} { Nothing }
arms :: { [([Int],ExtCode)] } arms :: { [ExtFCode ([Int],Either BlockId ExtCode)] }
: {- empty -} { [] } : {- empty -} { [] }
| arm arms { $1 : $2 } | arm arms { $1 : $2 }
arm :: { ([Int],ExtCode) } arm :: { ExtFCode ([Int],Either BlockId ExtCode) }
: 'case' ints ':' '{' body '}' { ($2, $5) } : 'case' ints ':' arm_body { do b <- $4; return ($2, b) }
arm_body :: { ExtFCode (Either BlockId ExtCode) }
: '{' body '}' { return (Right $2) }
| 'goto' NAME ';' { do l <- lookupLabel $2; return (Left l) }
ints :: { [Int] } ints :: { [Int] }
: INT { [ fromIntegral $1 ] } : INT { [ fromIntegral $1 ] }
...@@ -458,6 +464,8 @@ default :: { Maybe ExtCode } ...@@ -458,6 +464,8 @@ default :: { Maybe ExtCode }
-- 'default' branches -- 'default' branches
| {- empty -} { Nothing } | {- empty -} { Nothing }
-- Note: OldCmm doesn't support a first class 'else' statement, though
-- CmmNode does.
else :: { ExtCode } else :: { ExtCode }
: {- empty -} { nopEC } : {- empty -} { nopEC }
| 'else' '{' body '}' { $3 } | 'else' '{' body '}' { $3 }
...@@ -952,6 +960,10 @@ cmmIfThenElse cond then_part else_part = do ...@@ -952,6 +960,10 @@ cmmIfThenElse cond then_part else_part = do
-- fall through to join -- fall through to join
code (labelC join_id) code (labelC join_id)
cmmRawIf cond then_id = do
c <- cond
emitCond c then_id
-- 'emitCond cond true_id' emits code to test whether the cond is true, -- 'emitCond cond true_id' emits code to test whether the cond is true,
-- branching to true_id if so, and falling through otherwise. -- branching to true_id if so, and falling through otherwise.
emitCond (BoolTest e) then_id = do emitCond (BoolTest e) then_id = do
...@@ -991,7 +1003,7 @@ emitCond (e1 `BoolAnd` e2) then_id = do ...@@ -991,7 +1003,7 @@ emitCond (e1 `BoolAnd` e2) then_id = do
-- optional range on the switch (eg. switch [0..7] {...}), or by -- optional range on the switch (eg. switch [0..7] {...}), or by
-- the minimum/maximum values from the branches. -- the minimum/maximum values from the branches.
doSwitch :: Maybe (Int,Int) -> ExtFCode CmmExpr -> [([Int],ExtCode)] doSwitch :: Maybe (Int,Int) -> ExtFCode CmmExpr -> [([Int],Either BlockId ExtCode)]
-> Maybe ExtCode -> ExtCode -> Maybe ExtCode -> ExtCode
doSwitch mb_range scrut arms deflt doSwitch mb_range scrut arms deflt
= do = do
...@@ -1018,12 +1030,12 @@ doSwitch mb_range scrut arms deflt ...@@ -1018,12 +1030,12 @@ doSwitch mb_range scrut arms deflt
-- ToDo: check for out of range and jump to default if necessary -- ToDo: check for out of range and jump to default if necessary
stmtEC (CmmSwitch expr entries) stmtEC (CmmSwitch expr entries)
where where
emitArm :: ([Int],ExtCode) -> ExtFCode [(Int,BlockId)] emitArm :: ([Int],Either BlockId ExtCode) -> ExtFCode [(Int,BlockId)]
emitArm (ints,code) = do emitArm (ints,Left blockid) = return [ (i,blockid) | i <- ints ]
emitArm (ints,Right code) = do
blockid <- forkLabelledCodeEC code blockid <- forkLabelledCodeEC code
return [ (i,blockid) | i <- ints ] return [ (i,blockid) | i <- ints ]
-- ----------------------------------------------------------------------------- -- -----------------------------------------------------------------------------
-- Putting it all together -- Putting it all together
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment