Mercurial > projects > dang
view sema/Operation.d @ 158:57b0b4464a0b
Parsing "new", putting it in AST and performs some tests on it. Eg. if the contructor exists and the params matches.
author | Anders Johnsen <skabet@gmail.com> |
---|---|
date | Tue, 22 Jul 2008 00:33:58 +0200 |
parents | ed815b31479b |
children |
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, // FShr is a dummy element to avoid special case for signed >> unsigned Shl, LShr, AShr, FShr, 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; }