1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90
|
#pragma once
#include "Block.h"
namespace storm {
namespace bs {
STORM_PKG(lang.bs);
class CatchBlock;
/**
* A try-catch block.
*
* The TryBlock instance itself contains the expressions protected by the block, and
* additional catch blocks are added as separate catch blocks.
*
* Note that the catch blocks are to reside outside the try-block, and not inside. I.e. when
* creating expressions or ExprBlock instances to put inside the try block, don't pass the
* TryBlock as the parent, but rather the TryBlock's parent. Otherwise, scoping will be wrong.
*/
class TryBlock : public ExprBlock {
STORM_CLASS;
public:
// Create.
STORM_CTOR TryBlock(SrcPos pos, Block *parent);
// Add a catch block. Catch blocks are searched in the order they were added for potential matches.
void STORM_FN addCatch(CatchBlock *block);
// Generate code.
virtual void STORM_FN code(CodeGen *state, CodeResult *to);
// Create the block.
virtual void STORM_FN blockCode(CodeGen *state, CodeResult *to, code::Block block);
// Make sure the return type is correct.
virtual void STORM_FN blockCode(CodeGen *state, CodeResult *to);
// Compute the result.
virtual ExprResult STORM_FN result();
// Output.
virtual void STORM_FN toS(StrBuf *to) const;
private:
// All catch blocks.
Array<CatchBlock *> *toCatch;
};
/**
* A catch-block.
*
* As mentioned for the TryBlock class, this block is considered to reside outside the try
* block. Thus, don't pass the TryBlock as parameter to the constructor, but rather the
* TryBlock's parent.
*/
class CatchBlock : public Block {
STORM_CLASS;
public:
// Create. Specify the type and optionally the name of the exception to catch.
STORM_CTOR CatchBlock(SrcPos pos, Block *parent, SrcName *type, MAYBE(syntax::SStr *) name);
STORM_CTOR CatchBlock(SrcPos pos, Block *parent, Type *type, MAYBE(syntax::SStr *) name);
// Type we're catching.
Type *type;
// Set contained expression (only one).
void STORM_ASSIGN expr(Expr *expr);
// Generate block contents.
void STORM_FN blockCode(CodeGen *state, CodeResult *to);
// Result.
ExprResult STORM_FN result();
// Tell the catch block where the exception is stored.
code::Var exceptionVar;
// Output.
virtual void STORM_FN toS(StrBuf *to) const;
private:
// Contained expression.
MAYBE(Expr *) run;
// Variable to initialize, if any. Initialized by 'TryBlock'.
MAYBE(LocalVar *) var;
};
}
}
|