# HG changeset patch # User David Anderson # Date 1356671223 28800 # Node ID f9c4371d59d49001bc21193054abf5d9bbabb63e # Parent 9371f058625acbfecc192b947cec37bd4cd690f1 Add support for unary - and bitcast operator. diff -r 9371f058625a -r f9c4371d59d4 src/Messages.tbl --- a/src/Messages.tbl Thu Dec 27 20:44:50 2012 -0800 +++ b/src/Messages.tbl Thu Dec 27 21:07:03 2012 -0800 @@ -83,4 +83,5 @@ MSG(CannotModifyConst, TypeError, "cannot change constant value or structure") 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 +MSG(InvalidUncheckedCastTo, TypeError, "cannot perform an unchecked cast to type '%s'") +MSG(InvalidUnaryType, TypeError, "operator %s not defined for type '%s'") \ No newline at end of file diff -r 9371f058625a -r f9c4371d59d4 src/compiler/HIR.cpp --- a/src/compiler/HIR.cpp Thu Dec 27 20:44:50 2012 -0800 +++ b/src/compiler/HIR.cpp Thu Dec 27 21:07:03 2012 -0800 @@ -44,6 +44,7 @@ void visitArray(HArray *hir); void visitCall(HCall *call); void visitStore(HStore *store); + void visitUnary(HUnary *unary); void visitBinary(HBinary *binary); void visitLocal(HLocal *local); void visitGlobal(HGlobal *global); @@ -432,6 +433,26 @@ } void +HIRTranslator::visitUnary(HUnary *unary) +{ + unary->in()->accept(this); + + switch (unary->token()) { + case TOK_MINUS: + if (unary->type()->isFloat()) + __ neg_f(); + else + __ neg(); + break; + + default: + assert(unary->token() == TOK_LABEL); + __ bitcast(unary->type()); + break; + } +} + +void HIRTranslator::visitConvert(HConvert *convert) { convert->in()->accept(this); diff -r 9371f058625a -r f9c4371d59d4 src/compiler/HIR.h --- a/src/compiler/HIR.h Thu Dec 27 20:44:50 2012 -0800 +++ b/src/compiler/HIR.h Thu Dec 27 21:07:03 2012 -0800 @@ -39,6 +39,7 @@ _(Local) \ _(Global) \ /* End LValues */ \ + _(Unary) \ _(Binary) \ _(Convert) \ _(PostIncDec) @@ -382,6 +383,29 @@ float value_; }; +class HUnary : public HIR +{ + public: + HUnary(AstNode *node, Type *type, TokenKind tok, HIR *in) + : HIR(node, type), + in_(in), + token_(tok) + { + } + + DEFINE_HIR(Unary); + HIR *in() const { + return in_; + } + TokenKind token() const { + return token_; + } + + private: + HIR *in_; + TokenKind token_; +}; + class HStore : public HIR { public: diff -r 9371f058625a -r f9c4371d59d4 src/compiler/NameBinding.cpp --- a/src/compiler/NameBinding.cpp Thu Dec 27 20:44:50 2012 -0800 +++ b/src/compiler/NameBinding.cpp Thu Dec 27 21:07:03 2012 -0800 @@ -377,7 +377,7 @@ node->expression()->accept(this); } void visitUnaryExpression(UnaryExpression *node) { - assert(false); + node->expression()->accept(this); } void visitTernaryExpression(TernaryExpression *node) { assert(false); diff -r 9371f058625a -r f9c4371d59d4 src/compiler/SemanticAnalysis.cpp --- a/src/compiler/SemanticAnalysis.cpp Thu Dec 27 20:44:50 2012 -0800 +++ b/src/compiler/SemanticAnalysis.cpp Thu Dec 27 21:07:03 2012 -0800 @@ -744,6 +744,8 @@ } HIR *hir = eval(node->expression()); + if (!hir) + return; if ((hir = coerce(hir, lval->type(), Coerce_Assign)) == NULL) return; @@ -1090,35 +1092,56 @@ void SemanticAnalysis::visitUnaryExpression(UnaryExpression *node) { + HIR *hir = eval(node->expression()); + if (!hir) + return; + switch (node->token()) { - case TOK_LABEL: + case TOK_MINUS: { - 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()); + if (hir->type()->isInt32() || hir->type()->isEnum()) { + Local type(zone_, zone_->types()->getPrimitive(PrimitiveType_Int32)); + hir_ = new (pool_) HUnary(node, type, TOK_MINUS, hir); + return; + } + if (hir->type()->isFloat()) { + hir_ = new (pool_) HUnary(node, hir->type(), TOK_MINUS, hir); 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; - } + char name[255]; + cc_.reportError(node->pos(), Message_InvalidUnaryType, + "-", + GetTypeName(hir->type(), name, sizeof(name))); + break; + } + + default: + { + assert(node->token() == TOK_LABEL); - break; + 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; + } + + hir_ = new (pool_) HUnary(node, hir->type(), TOK_LABEL, hir); + break; } } }