# HG changeset patch # User David Anderson # Date 1356669890 28800 # Node ID 9371f058625acbfecc192b947cec37bd4cd690f1 # Parent 3c57bbf22aa2ad3fb1a08325a4504b47da37bf7e Support admin.inc again. diff -r 3c57bbf22aa2 -r 9371f058625a src/Interpreter.cpp --- a/src/Interpreter.cpp Wed Dec 26 17:20:55 2012 -0800 +++ b/src/Interpreter.cpp Thu Dec 27 20:44:50 2012 -0800 @@ -875,11 +875,9 @@ break; } -case OP_BITS_I2F: -case OP_BITS_F2I: +case OP_BITCAST: { - // Because the stack is a union, these are actually no-ops in the - // interpreter. + // Because the stack is a union, this is a no-ops. break; } diff -r 3c57bbf22aa2 -r 9371f058625a src/Messages.tbl --- a/src/Messages.tbl Wed Dec 26 17:20:55 2012 -0800 +++ b/src/Messages.tbl Thu Dec 27 20:44:50 2012 -0800 @@ -21,7 +21,6 @@ MSG(CalleeNotFunction, SyntaxError, "callee is not a function") MSG(ArgumentCountMismatch, SyntaxError, "argument counts do not match") MSG(CannotAssignArrayToScalar, SyntaxError, "cannot coerce an array to a scalar") -MSG(UnsupportedType, SyntaxError, "unsupported type") MSG(ArrayDimensionsMismatch, SyntaxError, "number of array dimensions does not match") MSG(ExpectedArray, SyntaxError, "expected array") MSG(ArrayDimensionSizeMismatch, SyntaxError, "array dimension sizes do not match (level %d)") @@ -39,7 +38,7 @@ MSG(ExpectedGlobal, SyntaxError, "expected global variable or function") MSG(ForwardNotImplemented, SyntaxError, "forward '%s' not implemented") MSG(ForwardDeclareMismatches, SyntaxError, "declaration does not match original forward signature") -MSG(ArrayCantBeReference, SyntaxError, "this type cannot be used with a reference") +MSG(ArrayCantBeReference, TypeError, "this type cannot be used with a reference") MSG(ArraySizeMustBeConstant, SyntaxError, "array size must be a constant integer") MSG(MultiArrayInNative, SyntaxError, "multidimensional arrays cannot be passed to natives") MSG(InvalidVarArgs, SyntaxError, "varargs cannot be const or ref") @@ -82,4 +81,6 @@ MSG(InvalidCoercion, TypeError, "cannot coerce type '%s' to type '%s'") MSG(CannotConstReference, TypeError, "constant outparams are not allowed") MSG(CannotModifyConst, TypeError, "cannot change constant value or structure") -MSG(InvalidConstOnFormal, TypeError, "const parameters must be arrays or structs") \ No newline at end of file +MSG(InvalidConstOnFormal, TypeError, "const parameters must be arrays or structs") +MSG(InvalidUncheckedCastFrom, TypeError, "cannot perform an unchecked cast on type '%s'") +MSG(InvalidUncheckedCastTo, TypeError, "cannot perform an unchecked cast to type '%s'") \ No newline at end of file diff -r 3c57bbf22aa2 -r 9371f058625a src/Opcodes.cpp --- a/src/Opcodes.cpp Wed Dec 26 17:20:55 2012 -0800 +++ b/src/Opcodes.cpp Thu Dec 27 20:44:50 2012 -0800 @@ -203,8 +203,7 @@ case OP_NEG: case OP_NEG_F: case OP_MOD: - case OP_BITS_I2F: - case OP_BITS_F2I: + case OP_BITCAST: case OP_TRUE: case OP_FALSE: case OP_SIZEOF: diff -r 3c57bbf22aa2 -r 9371f058625a src/Opcodes.tbl --- a/src/Opcodes.tbl Wed Dec 26 17:20:55 2012 -0800 +++ b/src/Opcodes.tbl Thu Dec 27 20:44:50 2012 -0800 @@ -216,9 +216,9 @@ OPDEF(OP_SETGLOBAL, "setglobal", 5, 1, 1) OPDEF(OP_GETGLOBAL, "getglobal", 5, 0, 1) -// Reinterprets a 32-bit integer as a float, or vice-versa. -OPDEF(OP_BITS_I2F, "bits.i2f", 1, 1, 1) -OPDEF(OP_BITS_F2I, "bits.f2i", 1, 1, 1) +// Reinterpret casts from one 32-bit POD type to another. The new type pointer +// is encoded into the object table, for the JITs' type flow. +OPDEF(OP_BITCAST, "BITCAST", 5, 1, 1) // Pushes a boolean value. OPDEF(OP_TRUE, "true", 1, 0, 1) diff -r 3c57bbf22aa2 -r 9371f058625a src/compiler/BytecodeEmitter.h --- a/src/compiler/BytecodeEmitter.h Wed Dec 26 17:20:55 2012 -0800 +++ b/src/compiler/BytecodeEmitter.h Thu Dec 27 20:44:50 2012 -0800 @@ -627,12 +627,6 @@ void neg_f() { singleByteOp(OP_NEG_F); } - void bits_i2f() { - singleByteOp(OP_BITS_I2F); - } - void bits_f2i() { - singleByteOp(OP_BITS_F2I); - } void true_() { singleByteOp(OP_TRUE); } @@ -657,6 +651,12 @@ singleByteOp(OP_PUBLIC); } + void bitcast(Type *type) { + ensure(OP_BITCAST_LENGTH); + writeOp(OP_BITCAST); + writeObject(type); + } + void tableswitch(int low, int high, Label *def, Label **labels) { unsigned tablesize = TableSwitchEntries(low, high); assert(tablesize <= MAX_TABLESWITCH_ENTRIES); diff -r 3c57bbf22aa2 -r 9371f058625a src/compiler/HIR.cpp --- a/src/compiler/HIR.cpp Wed Dec 26 17:20:55 2012 -0800 +++ b/src/compiler/HIR.cpp Thu Dec 27 20:44:50 2012 -0800 @@ -38,6 +38,7 @@ hir->accept(this); } + void visitBoolean(HBoolean *hir); void visitFloat(HFloat *hir); void visitInteger(HInteger *hir); void visitArray(HArray *hir); @@ -59,6 +60,15 @@ #define __ emitter_. void +HIRTranslator::visitBoolean(HBoolean *hir) +{ + if (hir->value()) + __ true_(); + else + __ false_(); +} + +void HIRTranslator::visitFloat(HFloat *hir) { __ float_(hir->value()); diff -r 3c57bbf22aa2 -r 9371f058625a src/compiler/HIR.h --- a/src/compiler/HIR.h Wed Dec 26 17:20:55 2012 -0800 +++ b/src/compiler/HIR.h Thu Dec 27 20:44:50 2012 -0800 @@ -27,6 +27,7 @@ #define HIR_OPS(_) \ _(Call) \ + _(Boolean) \ _(Integer) \ _(Float) \ _(String) \ @@ -127,6 +128,24 @@ visitor->visit##name(this); \ } +class HBoolean : public HIR +{ + public: + HBoolean(AstNode *node, Type *type, bool value) + : HIR(node, type), + value_(value) + { + } + + DEFINE_HIR(Boolean); + bool value() const { + return value_; + } + + private: + bool value_; +}; + class HInteger : public HIR { public: diff -r 3c57bbf22aa2 -r 9371f058625a src/compiler/SemanticAnalysis.cpp --- a/src/compiler/SemanticAnalysis.cpp Wed Dec 26 17:20:55 2012 -0800 +++ b/src/compiler/SemanticAnalysis.cpp Thu Dec 27 20:44:50 2012 -0800 @@ -623,6 +623,13 @@ } void +SemanticAnalysis::visitBooleanLiteral(BooleanLiteral *node) +{ + Local type(zone_, zone_->types()->getPrimitive(PrimitiveType_Bool)); + hir_ = new (pool_) HBoolean(node, type, node->token() == TOK_TRUE); +} + +void SemanticAnalysis::visitIntegerLiteral(IntegerLiteral *lit) { Local type(zone_, zone_->types()->getPrimitive(PrimitiveType_Int32)); @@ -1069,6 +1076,53 @@ } } +static inline bool +IsValidUncheckedType(Type *type) +{ + return type->isEnum() || + type->isFloat() || + type->isInt32() || + type->isChar() || + type->isUnchecked() || + type->isBool(); +} + +void +SemanticAnalysis::visitUnaryExpression(UnaryExpression *node) +{ + switch (node->token()) { + case TOK_LABEL: + { + assert(node->token() == TOK_LABEL); + HIR *hir = eval(node->expression()); + if (!hir) + return; + + TypeSymbol *sym = node->tag()->sym()->asType(); + if (!sym) { + cc_.reportError(node->pos(), Message_IdentifierIsNotAType, + sym->name()->chars()); + return; + } + + if (!IsValidUncheckedType(sym->type())) { + char name[255]; + cc_.reportError(node->pos(), Message_InvalidUncheckedCastTo, + GetTypeName(hir->type(), name, sizeof(name))); + return; + } + if (!IsValidUncheckedType(hir->type())) { + char name[255]; + cc_.reportError(node->pos(), Message_InvalidUncheckedCastFrom, + GetTypeName(hir->type(), name, sizeof(name))); + return; + } + + break; + } + } +} + static inline TokenKind ToCompare(Expression *expr) { diff -r 3c57bbf22aa2 -r 9371f058625a src/compiler/SemanticAnalysis.h --- a/src/compiler/SemanticAnalysis.h Wed Dec 26 17:20:55 2012 -0800 +++ b/src/compiler/SemanticAnalysis.h Thu Dec 27 20:44:50 2012 -0800 @@ -65,15 +65,15 @@ void visitIndexExpression(IndexExpression *node); void visitIncDecExpression(IncDecExpression *node); void visitStringLiteral(StringLiteral *node); + void visitUnaryExpression(UnaryExpression *node); + void visitBooleanLiteral(BooleanLiteral *node); #if 0 void visitFunctionTypeStatement(FunctionTypeStatement *node); void visitImportStatement(ImportStatement *node); void visitStructureStatement(StructureStatement *node); void visitSwitchStatement(SwitchStatement *node); - void visitUnaryExpression(UnaryExpression *node); void visitTernaryExpression(TernaryExpression *node); - void visitBooleanLiteral(BooleanLiteral *node); void visitFieldExpression(FieldExpression *node); void visitArrayLiteral(ArrayLiteral *node); #endif