Implement re-tag unary expression.
authorDavid Anderson <dvander@alliedmods.net>
Mon Jul 30 12:13:22 2012 -0700 (2012-07-30)
changeset 142a000bafece09
parent 141 d2516d66101a
child 143 393f1b8ac8c3
Implement re-tag unary expression.
src/AST.h
src/BytecodeCompiler.cpp
src/BytecodeEmitter.h
src/Interpreter.cpp
src/Opcodes.cpp
src/Opcodes.tbl
src/Scanner.cpp
src/SemanticAnalysis.cpp
src/TypeManager.cpp
src/Types.cpp
     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;