Implement sizeof operator.
authorDavid Anderson <dvander@alliedmods.net>
Mon Sep 17 00:10:01 2012 -0700 (2012-09-17)
changeset 194b029d63565a2
parent 193 970abfc9f077
child 195 c1ba166f3fc4
Implement sizeof operator.
src/BytecodeCompiler.cpp
src/BytecodeEmitter.h
src/Interpreter.cpp
src/Messages.tbl
src/Opcodes.cpp
src/Opcodes.tbl
src/Parser.cpp
src/Scanner.cpp
src/SemanticAnalysis.cpp
src/Token.h
     1.1 --- a/src/BytecodeCompiler.cpp	Sun Sep 16 23:33:48 2012 -0700
     1.2 +++ b/src/BytecodeCompiler.cpp	Mon Sep 17 00:10:01 2012 -0700
     1.3 @@ -530,6 +530,18 @@
     1.4          break;
     1.5        }
     1.6  
     1.7 +      case TOK_SIZEOF:
     1.8 +      {
     1.9 +        Local<Type> type(zone_, node->expression()->type());
    1.10 +        if (type->isFixedLength()) {
    1.11 +            __ int_(type->fixedLength());
    1.12 +        } else {
    1.13 +            node->expression()->accept(this);
    1.14 +            __ sizeof_();
    1.15 +        }
    1.16 +        break;
    1.17 +      }
    1.18 +
    1.19        default:
    1.20          assert(node->token() == TOK_TILDE);
    1.21          node->expression()->accept(this);
     2.1 --- a/src/BytecodeEmitter.h	Sun Sep 16 23:33:48 2012 -0700
     2.2 +++ b/src/BytecodeEmitter.h	Mon Sep 17 00:10:01 2012 -0700
     2.3 @@ -528,6 +528,9 @@
     2.4          singleByteOp(OP_COPYSTRUCT);
     2.5          markOop(1);
     2.6      }
     2.7 +    void sizeof_() {
     2.8 +        singleByteOp(OP_SIZEOF);
     2.9 +    }
    2.10  
    2.11      void dup() {
    2.12          bool oop = getOop(1);
     3.1 --- a/src/Interpreter.cpp	Sun Sep 16 23:33:48 2012 -0700
     3.2 +++ b/src/Interpreter.cpp	Mon Sep 17 00:10:01 2012 -0700
     3.3 @@ -1158,6 +1158,13 @@
     3.4      break;
     3.5  }
     3.6  
     3.7 +case OP_SIZEOF:
     3.8 +{
     3.9 +    Array *array = Array::cast(top.sp[-1].obj);
    3.10 +    top.sp[-1].i32 = array->length();
    3.11 +    break;
    3.12 +}
    3.13 +
    3.14  default:
    3.15      assert(false);
    3.16      return false;
     4.1 --- a/src/Messages.tbl	Sun Sep 16 23:33:48 2012 -0700
     4.2 +++ b/src/Messages.tbl	Mon Sep 17 00:10:01 2012 -0700
     4.3 @@ -79,4 +79,5 @@
     4.4  MSG(InvalidDimensionSize,           TypeError,              "invalid size %d for dimension %d")
     4.5  MSG(CannotComputeIndexRef,          SyntaxError,            "cannot use an array index as a reference")
     4.6  MSG(BadDynamicInitializer,          SyntaxError,            "dynamic length specified, but preceding array is empty")
     4.7 +MSG(SizeofNeedsArray,               TypeError,              "sizeof requires an array")
     4.8  
     5.1 --- a/src/Opcodes.cpp	Sun Sep 16 23:33:48 2012 -0700
     5.2 +++ b/src/Opcodes.cpp	Mon Sep 17 00:10:01 2012 -0700
     5.3 @@ -210,6 +210,7 @@
     5.4            case OP_BITS_F2I:
     5.5            case OP_TRUE:
     5.6            case OP_FALSE:
     5.7 +          case OP_SIZEOF:
     5.8              break;
     5.9  
    5.10            case OP_STOP:
     6.1 --- a/src/Opcodes.tbl	Sun Sep 16 23:33:48 2012 -0700
     6.2 +++ b/src/Opcodes.tbl	Mon Sep 17 00:10:01 2012 -0700
     6.3 @@ -271,3 +271,5 @@
     6.4  // [u8 op] [i32 low] [i32 high] [u32 jump] [u32 jumps...]
     6.5  OPDEF(OP_TABLESWITCH,   102,        "tableswitch",  9,      1, 0)
     6.6  
     6.7 +OPDEF(OP_SIZEOF,        103,        "sizeof",       1,      1, 1)
     6.8 +
     7.1 --- a/src/Parser.cpp	Sun Sep 16 23:33:48 2012 -0700
     7.2 +++ b/src/Parser.cpp	Mon Sep 17 00:10:01 2012 -0700
     7.3 @@ -357,6 +357,19 @@
     7.4          return new (pool_) UnaryExpression(pos, token, expr);
     7.5        }
     7.6  
     7.7 +      case TOK_SIZEOF:
     7.8 +      {
     7.9 +        scanner_.scan();
    7.10 +        if (!expect(TOK_LPAREN))
    7.11 +            return NULL;
    7.12 +        Expression *expr = unary();
    7.13 +        if (!expr)
    7.14 +            return NULL;
    7.15 +        if (!expect(TOK_RPAREN))
    7.16 +            return NULL;
    7.17 +        return new (pool_) UnaryExpression(pos, token, expr);
    7.18 +      }
    7.19 +
    7.20        case TOK_LABEL:
    7.21        {
    7.22          scanner_.scan();
     8.1 --- a/src/Scanner.cpp	Sun Sep 16 23:33:48 2012 -0700
     8.2 +++ b/src/Scanner.cpp	Mon Sep 17 00:10:01 2012 -0700
     8.3 @@ -432,6 +432,8 @@
     8.4          return TOK_VOID;
     8.5      if (!strcmp(str,  "int"))
     8.6          return TOK_INT;
     8.7 +    if (!strcmp(str,  "sizeof"))
     8.8 +        return TOK_SIZEOF;
     8.9      return TOK_NONE;
    8.10  }
    8.11  
     9.1 --- a/src/SemanticAnalysis.cpp	Sun Sep 16 23:33:48 2012 -0700
     9.2 +++ b/src/SemanticAnalysis.cpp	Mon Sep 17 00:10:01 2012 -0700
     9.3 @@ -547,6 +547,16 @@
     9.4          break;
     9.5        }
     9.6  
     9.7 +      case TOK_SIZEOF:
     9.8 +      {
     9.9 +        if (!type->isArray()) {
    9.10 +            cc_.reportError(node->pos(), Message_SizeofNeedsArray);
    9.11 +            return;
    9.12 +        }
    9.13 +        node->setType(zone_->types()->getPrimitive(PrimitiveType_Int32));
    9.14 +        break;
    9.15 +      }
    9.16 +
    9.17        default:
    9.18          assert(node->token() == TOK_TILDE);
    9.19          if (!type->isInt32()) {
    10.1 --- a/src/Token.h	Sun Sep 16 23:33:48 2012 -0700
    10.2 +++ b/src/Token.h	Mon Sep 17 00:10:01 2012 -0700
    10.3 @@ -77,6 +77,7 @@
    10.4      _(TYPEDEF,            "<typedef>")                  \
    10.5      _(VOID,               "<void>")                     \
    10.6      _(INT,                "<int>")                      \
    10.7 +    _(SIZEOF,             "<sizeof>")                   \
    10.8      _(ELLIPSES,           "...")                        \
    10.9      _(PLUS,               "+")                          \
   10.10      _(MINUS,              "-")                          \