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 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133
|
#pragma once
#include "Expr.h"
#include "Var.h"
#include "Core/SrcPos.h"
#include "Compiler/Scope.h"
#include "Core/Map.h"
namespace storm {
namespace bs {
STORM_PKG(lang.bs);
class BlockLookup;
/**
* A fundamental block. This block only acts as a new scope for variables. It
* is abstract to let other types of expressions act as some kind of block
* for variables.
*/
class Block : public Expr {
STORM_CLASS;
public:
STORM_CTOR Block(SrcPos pos, Scope scope);
STORM_CTOR Block(SrcPos pos, Block *parent);
// Lookup node.
BlockLookup *lookup;
// Scope.
Scope scope;
// Generate code. Override 'blockCode' to generate only block contents.
virtual void STORM_FN code(CodeGen *state, CodeResult *to);
// Override to initialize the block yourself.
virtual void STORM_FN blockCode(CodeGen *state, CodeResult *to, code::Block newBlock);
// Override to generate contents of the block.
virtual void STORM_FN blockCode(CodeGen *state, CodeResult *to);
// Find a variable. Same semantics as 'find'.
virtual MAYBE(LocalVar *) STORM_FN variable(SimplePart *name);
// Find a variable in this particular block. Does not recurse as "variable" does.
virtual MAYBE(LocalVar *) STORM_FN variableHere(SimplePart *name);
// Add a variable
virtual void STORM_FN add(LocalVar *v);
// Lift all variables present inside 'o' into this block. Can only be used one step at a
// time to not cause strange scoping issues.
virtual void STORM_FN liftVars(Block *from);
// Get our parent block, if any.
MAYBE(Block *) STORM_FN parent();
// Don't need to isolate blocks, we do that ourselves.
virtual Bool STORM_FN isolate();
protected:
// Initialize variables in a scope, if you're overriding "code" directly.
void STORM_FN initVariables(CodeGen *child);
private:
// Variables in this block.
typedef Map<Str *, LocalVar *> VarMap;
Map<Str *, LocalVar *> *variables;
// Check if 'x' is a child to us.
bool isParentTo(Block *x);
};
/**
* A block that contains statements.
*/
class ExprBlock : public Block {
STORM_CLASS;
public:
STORM_CTOR ExprBlock(SrcPos pos, Scope scope);
STORM_CTOR ExprBlock(SrcPos pos, Block *parent);
// Add an expression.
void STORM_FN add(Expr *s);
using Block::add;
// Add an expression to a specific location.
void STORM_FN insert(Nat pos, Expr *s);
// Result.
virtual ExprResult STORM_FN result();
// Optimization.
virtual void STORM_FN code(CodeGen *state, CodeResult *to);
// Code generation.
virtual void STORM_FN blockCode(CodeGen *state, CodeResult *to);
// Auto-casting should work across the boundaries of an expression.
virtual Int STORM_FN castPenalty(Value to);
// Get expression at location i.
Expr *STORM_FN operator [](Nat i) const;
// Get number of expressions.
Nat STORM_FN count() const;
// To string.
virtual void STORM_FN toS(StrBuf *to) const;
protected:
// Expressions here.
Array<Expr *> *exprs;
};
/**
* Node in the name lookup tree for our blocks.
*/
class BlockLookup : public NameLookup {
STORM_CLASS;
public:
// Create.
STORM_CTOR BlockLookup(Block *block, NameLookup *prev);
// Associated block.
Block *block;
// Find a variable here.
virtual MAYBE(Named *) STORM_FN find(SimplePart *part, Scope source);
};
}
}
|