Implement re-tag unary expression.
Implement re-tag unary expression.
1.1 --- a/src/AST.h Mon Jul 30 12:13:08 2012 -0700
1.2 +++ b/src/AST.h Mon Jul 30 12:13:22 2012 -0700
1.3 @@ -343,6 +343,7 @@
1.4 {
1.5 Expression *expression_;
1.6 TokenKind token_;
1.7 + ScopedRoot<String> tag_;
1.8
1.9 public:
1.10 UnaryExpression(const SourcePosition &pos, TokenKind token, Expression *expr)
1.11 @@ -352,6 +353,15 @@
1.12 {
1.13 }
1.14
1.15 + UnaryExpression(const SourcePosition &pos, TokenKind token, Expression *expr,
1.16 + Handle<String> tag)
1.17 + : Expression(pos),
1.18 + expression_(expr),
1.19 + token_(token),
1.20 + tag_(tag)
1.21 + {
1.22 + }
1.23 +
1.24 Kind kind() const {
1.25 return kUnaryExpression;
1.26 }
1.27 @@ -361,6 +371,9 @@
1.28 TokenKind token() const {
1.29 return token_;
1.30 }
1.31 + String *tag() const {
1.32 + return tag_;
1.33 + }
1.34 void accept(AstVisitor *visitor) {
1.35 visitor->visit(this);
1.36 }
2.1 --- a/src/BytecodeCompiler.cpp Mon Jul 30 12:13:08 2012 -0700
2.2 +++ b/src/BytecodeCompiler.cpp Mon Jul 30 12:13:22 2012 -0700
2.3 @@ -438,6 +438,19 @@
2.4 break;
2.5 }
2.6
2.7 + case TOK_LABEL:
2.8 + {
2.9 + Local<Type> from(zone_, node->expression()->type());
2.10 + Local<Type> to(zone_, node->type());
2.11 +
2.12 + node->expression()->accept(this);
2.13 + if (!from->isFloat() && to->isFloat())
2.14 + __ bits_f2i();
2.15 + else if (from->isFloat() && !to->isFloat())
2.16 + __ bits_i2f();
2.17 + break;
2.18 + }
2.19 +
2.20 default:
2.21 assert(node->token() == TOK_TILDE);
2.22 node->expression()->accept(this);
3.1 --- a/src/BytecodeEmitter.h Mon Jul 30 12:13:08 2012 -0700
3.2 +++ b/src/BytecodeEmitter.h Mon Jul 30 12:13:22 2012 -0700
3.3 @@ -600,6 +600,12 @@
3.4 void neg_f() {
3.5 singleByteOp(OP_NEG_F);
3.6 }
3.7 + void bits_i2f() {
3.8 + singleByteOp(OP_BITS_I2F);
3.9 + }
3.10 + void bits_f2i() {
3.11 + singleByteOp(OP_BITS_F2I);
3.12 + }
3.13
3.14 // Helpers.
3.15 void get(Variable *var) {
4.1 --- a/src/Interpreter.cpp Mon Jul 30 12:13:08 2012 -0700
4.2 +++ b/src/Interpreter.cpp Mon Jul 30 12:13:22 2012 -0700
4.3 @@ -918,6 +918,14 @@
4.4 break;
4.5 }
4.6
4.7 +case OP_BITS_I2F:
4.8 +case OP_BITS_F2I:
4.9 +{
4.10 + // Because the stack is a union, these are actually no-ops in the
4.11 + // interpreter.
4.12 + break;
4.13 +}
4.14 +
4.15 default:
4.16 assert(false);
4.17 return false;
5.1 --- a/src/Opcodes.cpp Mon Jul 30 12:13:08 2012 -0700
5.2 +++ b/src/Opcodes.cpp Mon Jul 30 12:13:22 2012 -0700
5.3 @@ -206,6 +206,8 @@
5.4 case OP_NEG:
5.5 case OP_NEG_F:
5.6 case OP_MOD:
5.7 + case OP_BITS_I2F:
5.8 + case OP_BITS_F2I:
5.9 break;
5.10
5.11 case OP_STOP:
6.1 --- a/src/Opcodes.tbl Mon Jul 30 12:13:08 2012 -0700
6.2 +++ b/src/Opcodes.tbl Mon Jul 30 12:13:22 2012 -0700
6.3 @@ -243,4 +243,9 @@
6.4 OPDEF(OP_SETGLOBAL_O, 95, "setglobal.o", 5, 1, 1)
6.5 OPDEF(OP_GETGLOBAL_I, 96, "getglobal.i", 5, 0, 1)
6.6 OPDEF(OP_GETGLOBAL_F, 97, "getglobal.f", 5, 0, 1)
6.7 -OPDEF(OP_GETGLOBAL_O, 98, "getglobal.o", 5, 0, 1)
6.8 \ No newline at end of file
6.9 +OPDEF(OP_GETGLOBAL_O, 98, "getglobal.o", 5, 0, 1)
6.10 +
6.11 +// Reinterprets a 32-bit integer as a float, or vice-versa.
6.12 +OPDEF(OP_BITS_I2F, 99, "bits.i2f", 1, 1, 1)
6.13 +OPDEF(OP_BITS_F2I, 100, "bits.f2i", 1, 1, 1)
6.14 +
7.1 --- a/src/Scanner.cpp Mon Jul 30 12:13:08 2012 -0700
7.2 +++ b/src/Scanner.cpp Mon Jul 30 12:13:22 2012 -0700
7.3 @@ -373,7 +373,7 @@
7.4 if (!literal_.append('\0'))
7.5 return TOK_ERROR;
7.6
7.7 - if (!strcmp(literal(), "_"))
7.8 + if (c != ':' && !strcmp(literal(), "_"))
7.9 return TOK_UNDERSCORE;
7.10 if (!strcmp(literal(), "new"))
7.11 return TOK_NEW;
8.1 --- a/src/SemanticAnalysis.cpp Mon Jul 30 12:13:08 2012 -0700
8.2 +++ b/src/SemanticAnalysis.cpp Mon Jul 30 12:13:22 2012 -0700
8.3 @@ -441,6 +441,24 @@
8.4 node->setType(type);
8.5 break;
8.6
8.7 + case TOK_LABEL:
8.8 + {
8.9 + Local<String> tag(zone_, node->tag());
8.10 + Local<Type> to(zone_, zone_->types()->getPrimitiveForTag(tag));
8.11 + if (!to)
8.12 + return;
8.13 +
8.14 + if ((!type->isFloat() && !type->isInt32()) ||
8.15 + (!to->isFloat() && !to->isInt32()))
8.16 + {
8.17 + unaryTypeError(node, node->token(), type);
8.18 + return;
8.19 + }
8.20 +
8.21 + node->setType(to);
8.22 + break;
8.23 + }
8.24 +
8.25 default:
8.26 assert(node->token() == TOK_TILDE);
8.27 if (!type->isInt32() || type->tag()) {
9.1 --- a/src/TypeManager.cpp Mon Jul 30 12:13:08 2012 -0700
9.2 +++ b/src/TypeManager.cpp Mon Jul 30 12:13:22 2012 -0700
9.3 @@ -71,7 +71,7 @@
9.4 Type *
9.5 TypeManager::getPrimitiveForTag(Handle<String> tag)
9.6 {
9.7 - if (!tag)
9.8 + if (!tag || strcmp(tag->chars(), "_") == 0)
9.9 return getPrimitive(PrimitiveType_Int32);
9.10 if (strcmp(tag->chars(), "Float") == 0)
9.11 return getPrimitive(PrimitiveType_Float);
10.1 --- a/src/Types.cpp Mon Jul 30 12:13:08 2012 -0700
10.2 +++ b/src/Types.cpp Mon Jul 30 12:13:22 2012 -0700
10.3 @@ -45,6 +45,8 @@
10.4 if (!type)
10.5 return NULL;
10.6
10.7 + assert(!tag || strcmp(tag->chars(), "_"));
10.8 +
10.9 type->kind_ = PRIMITIVE;
10.10 type->tag_ = tag;
10.11 type->contained_ = NULL;