changeset 120:7d0898f77685

Implement the cast expression - works for integers and real/float/double
author Anders Halager <halager@gmail.com>
date Sun, 25 May 2008 20:18:55 +0200
parents c0b531362ca6
children 95dfe2f48dcf
files gen/CodeGen.d sema/DType.d
diffstat 2 files changed, 58 insertions(+), 42 deletions(-) [+]
line wrap: on
line diff
--- a/gen/CodeGen.d	Sun May 25 19:13:07 2008 +0200
+++ b/gen/CodeGen.d	Sun May 25 20:18:55 2008 +0200
@@ -357,14 +357,13 @@
                 return RValue(r);
             case ExpType.CastExp:
                 auto castExp = cast(CastExp)exp;
-                auto value = genExpression(castExp.exp).value;
+                exp = castExp.exp;
+                auto value = genExpression(exp);
 
-                if (!castExp.exp.type.hasImplicitConversionTo(castExp.type))
+                if (!exp.type.hasImplicitConversionTo(castExp.type))
                     assert(0, "Invalid cast");
 
-                Value v = buildCastLoad(castExp.exp.type, castExp.type, value);
-
-                return RValue(v);
+                return genTypeCast(value, exp.type, castExp.type);
 
             case ExpType.Identifier:
                 auto identifier = cast(Identifier)exp;
@@ -400,7 +399,7 @@
         {
             Operation op = t_a.getOperationWith(op2op(e.op), t_b);
             assert(op.isBuiltin(),
-                    "integers should only use builtin ops");
+                    "numbers should only use builtin ops");
             alias BuiltinOperation BO;
             BO val = op.builtinOp();
             // map val to buildAdd or similar
@@ -610,19 +609,6 @@
         }
     }
 
-    /**
-      Given the address of something, load it into an alloc.
-     **/
-    RValue loadLValue(LValue addr, char[] name = null)
-    {
-        Value val = addr.getAddress();
-        if (name is null)
-            name = val.name.length > 0? val.name : "load";
-
-        auto res = b.buildLoad(val, name);
-        return RValue(res);
-    }
-
     /*
        Get the address of an expression - allowing us to modify something in
        memory or on the stack.
@@ -735,6 +721,57 @@
     }
 
     /**
+      Generate the statements necessary to convert V, from type 'from' to type
+      'to'.
+     **/
+    RValue genTypeCast(RValue V, DType from, DType to)
+    {
+        Value delegate(Value, Type, char[]) extend, trunc;
+        if(auto ito = to.asInteger())
+        {
+            extend = ito.unsigned? &b.buildZExt : &b.buildSExt;
+            trunc = &b.buildTrunc;
+            if(auto rfrom = from.isReal())
+            {
+                extend = ito.unsigned? &b.buildFPToUI : &b.buildFPToSI;
+                trunc = extend;
+            }
+        }
+        else if (auto rto = to.asReal())
+        {
+            extend = &b.buildFPExt;
+            trunc = &b.buildFPTrunc;
+            if(auto ifrom = from.isInteger())
+            {
+                extend = rto.unsigned? &b.buildUIToFP : &b.buildSIToFP;
+                trunc = extend;
+            }
+        }
+        else
+            assert(0, "implicit cast need implimentation");
+
+        Value res;
+        if (from.byteSize() < to.byteSize())
+            res = extend(V.value, llvm(to), "ext");
+        else
+            res = trunc(V.value, llvm(to), "trunc");
+        return RValue(res);
+    }
+
+    /**
+      Given the address of something, load it into an alloc.
+     **/
+    RValue loadLValue(LValue addr, char[] name = null)
+    {
+        Value val = addr.getAddress();
+        if (name is null)
+            name = val.name.length > 0? val.name : "load";
+
+        auto res = b.buildLoad(val, name);
+        return RValue(res);
+    }
+
+    /**
       Get the LLVM Type corresponding to a DType.
 
       Currently using the built-in associative array - not sure if it works
@@ -830,25 +867,6 @@
         assert(0, "Only integers, structs and functions are supported");
     }
 
-    Value buildCastLoad(DType from, DType to, Value value)
-    {
-        if(typeof(from) == DInteger)
-        {
-            if(to == Type.Double)
-                return b.buildFPTrunc(value, llvm(_to), "fptrunc");
-            if(to == Type.Float)
-                return b.buildFPTrunc(value, llvm(_to), "fptrunc");
-        }
-        /*
-        if(from == Type.Int64)
-                if(castExp.exp.type.byteSize <= castExp.type.byteSize)
-                    v = b.buildZExt(value, llvm(castExp.type), "zext");
-                else
-                    v = b.buildTrunc(value, llvm(castExp.type), "trunc");
-        }
-*/
-        assert(0, "implicit cast need implimentation");
-    }
     // Might as well insert all the basic types from the start
     void createBasicTypes()
     {
--- a/sema/DType.d	Sun May 25 19:13:07 2008 +0200
+++ b/sema/DType.d	Sun May 25 20:18:55 2008 +0200
@@ -252,7 +252,7 @@
 
     override bool hasImplicitConversionTo(DType that)
     {
-        if (auto o = cast(DInteger)that)
+        if (that.isInteger() || that.isReal())
             return true;
         return false;
     }
@@ -270,9 +270,7 @@
 
     override bool hasImplicitConversionTo(DType that)
     {
-        if (auto o = cast(DInteger)that)
-            return true;
-        if (auto o = cast(DReal)that)
+        if (that.isInteger() || that.isReal())
             return true;
         return false;
     }