Mercurial > projects > dang
view sema/Operation.d @ 107:189c049cbfcc new_gen
Cleanup of codegen, better support for operators a few bugfixes
author | Anders Halager <halager@gmail.com> |
---|---|
date | Sun, 25 May 2008 14:40:14 +0200 |
parents | |
children | ed815b31479b |
line wrap: on
line source
module sema.Operation; /// Operators public enum Operator { Add, Sub, Mul, Div, Rem, Shl, LShr, AShr, And, Or, Xor, Eq, Ne, Lt, Le, Gt, Ge, } /** Enum for the basic builtin operations. S for signed, U for unsigned and F for floating point. **/ public enum BuiltinOperation { Add, Sub, Mul, SDiv, UDiv, FDiv, SRem, URem, FRem, Shl, LShr, AShr, And, Or, Xor, Eq, Ne, SLt, ULt, FLt, SLe, ULe, FLe, SGt, UGt, FGt, SGe, UGe, FGe, None } /** Returns true if the operation has an unsigned variant. Will only be true for the S version, so SDiv gives true, UDiv or FDiv dont. **/ private bool hasUnsignedVariant(BuiltinOperation op) { alias BuiltinOperation O; return op is O.SDiv || op is O.SRem || op is O.SLt || op is O.SLe || op is O.SGt || op is O.SGe; } /// Same as hasUnsignedVariant, but for float variants private bool hasFloatVariant(BuiltinOperation op) { alias BuiltinOperation O; return op is O.SDiv || op is O.SRem || op is O.SLt || op is O.SLe || op is O.SGt || op is O.SGe; } private BuiltinOperation OpToBI(Operator op) { // This is dependent on the definition of Operator // Maps from an Operator to the first appropiate BuiltinOperation static const BuiltinOperation[] map = [ BuiltinOperation.Add, BuiltinOperation.Sub, BuiltinOperation.Mul, BuiltinOperation.SDiv, BuiltinOperation.SRem, BuiltinOperation.Shl, BuiltinOperation.LShr, BuiltinOperation.AShr, BuiltinOperation.And, BuiltinOperation.Or, BuiltinOperation.Xor, BuiltinOperation.Eq, BuiltinOperation.Ne, BuiltinOperation.SLt, BuiltinOperation.SLe, BuiltinOperation.SGt, BuiltinOperation.SGe, ]; if (op >= Operator.Add && op <= Operator.Ge) return map[op]; return BuiltinOperation.None; } /** Represents an operation on to values of (potentionally) different types. Can be either some built-in thing (addition of floats, int etc) or a user defined operation (a method in a struct/class). **/ struct Operation { /// Returns true if the operation is legal bool isPossible() { return is_valid; } /// True for <, <=, ==, !=, >, >= bool isComparison() { return false; } /// Built in operations like adding ints or floats bool isBuiltin() { return is_bi; } /// Get the builtin operation - only valid if isBuiltin() returns true BuiltinOperation builtinOp() { return bi_op; }; /// Create builtin operation static Operation builtin(Operator op, bool unsigned, bool fp) { assert(!(unsigned && fp), "Can't be both unsigned and a float"); Operation res; res.is_valid = true; res.is_bi = true; res.bi_op = OpToBI(op); if (unsigned && hasUnsignedVariant(res.bi_op)) res.bi_op += 1; if (fp && hasFloatVariant(res.bi_op)) res.bi_op += 2; return res; } private: bool is_valid = false; bool is_bi; BuiltinOperation bi_op; }