Add support for unary - and bitcast operator.
Add support for unary - and bitcast operator.
1.1 --- a/src/Messages.tbl Thu Dec 27 20:44:50 2012 -0800
1.2 +++ b/src/Messages.tbl Thu Dec 27 21:07:03 2012 -0800
1.3 @@ -83,4 +83,5 @@
1.4 MSG(CannotModifyConst, TypeError, "cannot change constant value or structure")
1.5 MSG(InvalidConstOnFormal, TypeError, "const parameters must be arrays or structs")
1.6 MSG(InvalidUncheckedCastFrom, TypeError, "cannot perform an unchecked cast on type '%s'")
1.7 -MSG(InvalidUncheckedCastTo, TypeError, "cannot perform an unchecked cast to type '%s'")
1.8 \ No newline at end of file
1.9 +MSG(InvalidUncheckedCastTo, TypeError, "cannot perform an unchecked cast to type '%s'")
1.10 +MSG(InvalidUnaryType, TypeError, "operator %s not defined for type '%s'")
1.11 \ No newline at end of file
2.1 --- a/src/compiler/HIR.cpp Thu Dec 27 20:44:50 2012 -0800
2.2 +++ b/src/compiler/HIR.cpp Thu Dec 27 21:07:03 2012 -0800
2.3 @@ -44,6 +44,7 @@
2.4 void visitArray(HArray *hir);
2.5 void visitCall(HCall *call);
2.6 void visitStore(HStore *store);
2.7 + void visitUnary(HUnary *unary);
2.8 void visitBinary(HBinary *binary);
2.9 void visitLocal(HLocal *local);
2.10 void visitGlobal(HGlobal *global);
2.11 @@ -432,6 +433,26 @@
2.12 }
2.13
2.14 void
2.15 +HIRTranslator::visitUnary(HUnary *unary)
2.16 +{
2.17 + unary->in()->accept(this);
2.18 +
2.19 + switch (unary->token()) {
2.20 + case TOK_MINUS:
2.21 + if (unary->type()->isFloat())
2.22 + __ neg_f();
2.23 + else
2.24 + __ neg();
2.25 + break;
2.26 +
2.27 + default:
2.28 + assert(unary->token() == TOK_LABEL);
2.29 + __ bitcast(unary->type());
2.30 + break;
2.31 + }
2.32 +}
2.33 +
2.34 +void
2.35 HIRTranslator::visitConvert(HConvert *convert)
2.36 {
2.37 convert->in()->accept(this);
3.1 --- a/src/compiler/HIR.h Thu Dec 27 20:44:50 2012 -0800
3.2 +++ b/src/compiler/HIR.h Thu Dec 27 21:07:03 2012 -0800
3.3 @@ -39,6 +39,7 @@
3.4 _(Local) \
3.5 _(Global) \
3.6 /* End LValues */ \
3.7 + _(Unary) \
3.8 _(Binary) \
3.9 _(Convert) \
3.10 _(PostIncDec)
3.11 @@ -382,6 +383,29 @@
3.12 float value_;
3.13 };
3.14
3.15 +class HUnary : public HIR
3.16 +{
3.17 + public:
3.18 + HUnary(AstNode *node, Type *type, TokenKind tok, HIR *in)
3.19 + : HIR(node, type),
3.20 + in_(in),
3.21 + token_(tok)
3.22 + {
3.23 + }
3.24 +
3.25 + DEFINE_HIR(Unary);
3.26 + HIR *in() const {
3.27 + return in_;
3.28 + }
3.29 + TokenKind token() const {
3.30 + return token_;
3.31 + }
3.32 +
3.33 + private:
3.34 + HIR *in_;
3.35 + TokenKind token_;
3.36 +};
3.37 +
3.38 class HStore : public HIR
3.39 {
3.40 public:
4.1 --- a/src/compiler/NameBinding.cpp Thu Dec 27 20:44:50 2012 -0800
4.2 +++ b/src/compiler/NameBinding.cpp Thu Dec 27 21:07:03 2012 -0800
4.3 @@ -377,7 +377,7 @@
4.4 node->expression()->accept(this);
4.5 }
4.6 void visitUnaryExpression(UnaryExpression *node) {
4.7 - assert(false);
4.8 + node->expression()->accept(this);
4.9 }
4.10 void visitTernaryExpression(TernaryExpression *node) {
4.11 assert(false);
5.1 --- a/src/compiler/SemanticAnalysis.cpp Thu Dec 27 20:44:50 2012 -0800
5.2 +++ b/src/compiler/SemanticAnalysis.cpp Thu Dec 27 21:07:03 2012 -0800
5.3 @@ -744,6 +744,8 @@
5.4 }
5.5
5.6 HIR *hir = eval(node->expression());
5.7 + if (!hir)
5.8 + return;
5.9 if ((hir = coerce(hir, lval->type(), Coerce_Assign)) == NULL)
5.10 return;
5.11
5.12 @@ -1090,35 +1092,56 @@
5.13 void
5.14 SemanticAnalysis::visitUnaryExpression(UnaryExpression *node)
5.15 {
5.16 + HIR *hir = eval(node->expression());
5.17 + if (!hir)
5.18 + return;
5.19 +
5.20 switch (node->token()) {
5.21 - case TOK_LABEL:
5.22 + case TOK_MINUS:
5.23 {
5.24 - assert(node->token() == TOK_LABEL);
5.25 - HIR *hir = eval(node->expression());
5.26 - if (!hir)
5.27 - return;
5.28 -
5.29 - TypeSymbol *sym = node->tag()->sym()->asType();
5.30 - if (!sym) {
5.31 - cc_.reportError(node->pos(), Message_IdentifierIsNotAType,
5.32 - sym->name()->chars());
5.33 + if (hir->type()->isInt32() || hir->type()->isEnum()) {
5.34 + Local<Type> type(zone_, zone_->types()->getPrimitive(PrimitiveType_Int32));
5.35 + hir_ = new (pool_) HUnary(node, type, TOK_MINUS, hir);
5.36 + return;
5.37 + }
5.38 + if (hir->type()->isFloat()) {
5.39 + hir_ = new (pool_) HUnary(node, hir->type(), TOK_MINUS, hir);
5.40 return;
5.41 }
5.42
5.43 - if (!IsValidUncheckedType(sym->type())) {
5.44 - char name[255];
5.45 - cc_.reportError(node->pos(), Message_InvalidUncheckedCastTo,
5.46 - GetTypeName(hir->type(), name, sizeof(name)));
5.47 - return;
5.48 - }
5.49 - if (!IsValidUncheckedType(hir->type())) {
5.50 - char name[255];
5.51 - cc_.reportError(node->pos(), Message_InvalidUncheckedCastFrom,
5.52 - GetTypeName(hir->type(), name, sizeof(name)));
5.53 - return;
5.54 - }
5.55 + char name[255];
5.56 + cc_.reportError(node->pos(), Message_InvalidUnaryType,
5.57 + "-",
5.58 + GetTypeName(hir->type(), name, sizeof(name)));
5.59 + break;
5.60 + }
5.61 +
5.62 + default:
5.63 + {
5.64 + assert(node->token() == TOK_LABEL);
5.65
5.66 - break;
5.67 + TypeSymbol *sym = node->tag()->sym()->asType();
5.68 + if (!sym) {
5.69 + cc_.reportError(node->pos(), Message_IdentifierIsNotAType,
5.70 + sym->name()->chars());
5.71 + return;
5.72 + }
5.73 +
5.74 + if (!IsValidUncheckedType(sym->type())) {
5.75 + char name[255];
5.76 + cc_.reportError(node->pos(), Message_InvalidUncheckedCastTo,
5.77 + GetTypeName(hir->type(), name, sizeof(name)));
5.78 + return;
5.79 + }
5.80 + if (!IsValidUncheckedType(hir->type())) {
5.81 + char name[255];
5.82 + cc_.reportError(node->pos(), Message_InvalidUncheckedCastFrom,
5.83 + GetTypeName(hir->type(), name, sizeof(name)));
5.84 + return;
5.85 + }
5.86 +
5.87 + hir_ = new (pool_) HUnary(node, hir->type(), TOK_LABEL, hir);
5.88 + break;
5.89 }
5.90 }
5.91 }