Add support for unary - and bitcast operator.
authorDavid Anderson <dvander@alliedmods.net>
Thu Dec 27 21:07:03 2012 -0800 (2012-12-27)
changeset 246f9c4371d59d4
parent 245 9371f058625a
child 247 7721042bdb67
Add support for unary - and bitcast operator.
src/Messages.tbl
src/compiler/HIR.cpp
src/compiler/HIR.h
src/compiler/NameBinding.cpp
src/compiler/SemanticAnalysis.cpp
     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  }