Implement sizeof operator.
Implement sizeof operator.
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, "-") \