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 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210
|
#pragma once
#include "Compiler/ExprResult.h"
#include "Core/SrcPos.h"
#include "Compiler/NamedThread.h"
#include "Compiler/CodeGen.h"
#include "Compiler/Syntax/SStr.h"
#include "Core/EnginePtr.h"
namespace storm {
namespace bs {
STORM_PKG(lang.bs);
/**
* Base class for expressions (no difference between statements and expressions in this language!).
*/
class Expr : public ObjectOn<Compiler> {
STORM_CLASS;
public:
STORM_CTOR Expr(SrcPos pos);
// Where is this expression located in the source code?
SrcPos pos;
// Result of an expression. Default is void.
virtual ExprResult STORM_FN result();
// Generate code.
// If "result" indicates that the expression returns a reference, you can ask for either
// a reference or a value. If "result" returns a value, you can only ask for a value.
// Some expressions support the other way around as well, but this can not be relied on.
virtual void STORM_FN code(CodeGen *state, CodeResult *r);
// Is it possible to cast this one expression to 'to'? < 0, no cast possible.
virtual Int STORM_FN castPenalty(Value to);
// Is it possible (and desirable) to isolate this expression in its own block? The
// default implementation returns 'true' as we wish to isolate most expressions when we
// put them inside an ExprBlock.
virtual Bool STORM_FN isolate();
// Get a position suitable as a source location. It sometimes differs from "pos" since
// we in error messages typically want to point at details (e.g. a particular operator),
// while in debugging information we want to include the entire range.
virtual SrcPos STORM_FN largePos();
// Is this an expression that is a "this"-variable? It may or may not be named "this",
// but it is known to be referring to the same object as the current one, so we know
// that we don't have to switch threads when calling member functions on the object this
// variable is referring to.
virtual Bool STORM_FN thisVariable() const;
};
/**
* Numeric literal.
*/
class NumLiteral : public Expr {
STORM_CLASS;
public:
// Create, describes an integer.
STORM_CTOR NumLiteral(SrcPos pos, Int i);
STORM_CTOR NumLiteral(SrcPos pos, Long i);
// Create, describes an unsigned number (will not allow signed output).
STORM_CTOR NumLiteral(SrcPos pos, Word i);
// Create, describes a floating-point number.
STORM_CTOR NumLiteral(SrcPos pos, Double f);
// Specify type using a suffix. 'suffix' is one of the characters 'binlwfd', which each
// corresponds to the first letter in one of the primitive types.
void STORM_FN setType(Str *suffix);
// Return value.
virtual ExprResult STORM_FN result();
// Generate code.
virtual void STORM_FN code(CodeGen *state, CodeResult *r);
// Castable to?
virtual Int STORM_FN castPenalty(Value to);
// To string.
virtual void STORM_FN toS(StrBuf *to) const;
private:
// Value (if integer).
Long intValue;
// Value (if float).
Double floatValue;
// Integer value?
Bool isInt;
// Unsigned number?
Bool isSigned;
// Specified type (if any).
MAYBE(Type *) type;
// Code for an int label.
void intCode(CodeGen *state, CodeResult *r);
// Code for a float label.
void floatCode(CodeGen *state, CodeResult *r);
};
NumLiteral *STORM_FN intConstant(SrcPos pos, Str *str);
NumLiteral *STORM_FN floatConstant(SrcPos pos, Str *str);
NumLiteral *STORM_FN hexConstant(SrcPos pos, Str *str);
/**
* String literal.
*/
class StrLiteral : public Expr {
STORM_CLASS;
public:
// Create.
STORM_CTOR StrLiteral(SrcPos pos, Str *str);
// Return value.
virtual ExprResult STORM_FN result();
// Generate code.
virtual void STORM_FN code(CodeGen *state, CodeResult *r);
// To string.
virtual void STORM_FN toS(StrBuf *to) const;
// Get the value.
Str *STORM_FN v() const { return value; }
private:
// Value.
Str *value;
};
StrLiteral *STORM_FN strConstant(syntax::SStr *str);
StrLiteral *STORM_FN strConstant(SrcPos pos, Str *str);
StrLiteral *STORM_FN rawStrConstant(SrcPos pos, Str *str);
/**
* Boolean literal.
*/
class BoolLiteral : public Expr {
STORM_CLASS;
public:
// Create.
STORM_CTOR BoolLiteral(SrcPos pos, Bool value);
// Return value.
virtual ExprResult STORM_FN result();
// Generate code.
virtual void STORM_FN code(CodeGen *state, CodeResult *r);
// To string.
virtual void STORM_FN toS(StrBuf *to) const;
private:
// Value.
Bool value;
};
/**
* Character literal.
*/
class CharLiteral : public Expr {
STORM_CLASS;
public:
// Create.
STORM_CTOR CharLiteral(SrcPos pos, Char value);
// Return value.
virtual ExprResult STORM_FN result();
// Generate code.
virtual void STORM_FN code(CodeGen *state, CodeResult *r);
// To string.
virtual void STORM_FN toS(StrBuf *to) const;
private:
// Value.
Char value;
};
// Create a literal from a string.
CharLiteral *STORM_FN charConstant(SrcPos pos, Str *value);
/**
* Dummy expression, tells that we're returning a value of a specific type, but will not
* generate any code.
*/
class DummyExpr : public Expr {
STORM_CLASS;
public:
STORM_CTOR DummyExpr(SrcPos pos, Value type);
virtual ExprResult STORM_FN result();
virtual void STORM_FN code(CodeGen *state, CodeResult *r);
private:
Value type;
};
}
}
|