[svn] r6742: nemerle/trunk: macros/operators.n ncc/external/InternalTypes.n

iae svnadmin at nemerle.org
Mon Oct 2 14:00:11 CEST 2006


Log:
Added '??' operator.

Author: iae
Date: Mon Oct  2 14:00:07 2006
New Revision: 6742

Modified:
   nemerle/trunk/macros/operators.n
   nemerle/trunk/ncc/external/InternalTypes.n

Modified: nemerle/trunk/macros/operators.n
==============================================================================
--- nemerle/trunk/macros/operators.n	(original)
+++ nemerle/trunk/macros/operators.n	Mon Oct  2 14:00:07 2006
@@ -220,4 +220,47 @@
     }
     <[ fun (..$parms) $(convert_body (body, parms, loc)) ]>
   }
+
+  macro @?? (exprA, exprB) 
+  {
+    def tnullable = ManagerClass.Instance.InternalType.Generic_Nullable_tc;
+    def toption = ManagerClass.Instance.InternalType.Nemerle_option_tc;
+
+    def isNullable = tnullable.Equals(_);
+    def isOption (t)
+    {
+      toption.Equals (t) 
+      || (t.BaseType != null && toption.Equals (t.BaseType))
+    }
+
+    def typer = Macros.ImplicitCTX ();
+    def hA = typer.TypeExpr (exprA).Type.Hint;
+    def hB = typer.TypeExpr (exprB).Type.Hint;
+
+    def resolve (tiA, check)
+    {
+      match (hB) {
+        | Some (Class (tiB, _)) =>
+            def v = if (check(tiB)) <[ $exprA ]> else <[ $exprA.Value ]>;
+            <[ match ($exprA.HasValue) { | true => $v | _ => $exprB } ]>
+        | None => 
+            Message.FatalError (exprB.Location, $"Operator `??' cannot be"
+                                " applied to operands of type `$tiA' and "
+                                "`_UNKNOWN_TYPE_'");
+        | _ =>
+            <[ if ($exprA != null) $exprA else $exprB ]>;
+      }
+    }
+
+    match (hA) {
+      | None 
+      | Some (Class (tiA, _)) when tiA.IsValueType && !isNullable(tiA) =>
+          Message.FatalError (exprA.Location, 
+                              $"Left operand of the `??' operator should be "
+                              "reference or nullable type ");
+      | Some (Class (tiA, _)) when isNullable (tiA) => resolve (tiA, isNullable)
+      | Some (Class (tiA, _)) when isOption (tiA) => resolve (tiA, isOption)
+      | _ => <[ if ($exprA != null) $exprA else $exprB ]>;
+    }
+  }
 }

Modified: nemerle/trunk/ncc/external/InternalTypes.n
==============================================================================
--- nemerle/trunk/ncc/external/InternalTypes.n	(original)
+++ nemerle/trunk/ncc/external/InternalTypes.n	Mon Oct  2 14:00:07 2006
@@ -407,6 +407,7 @@
   public mutable AssemblyKeyFileAttribute_tc : TypeInfo;
   public mutable AssemblyCultureAttribute_tc : TypeInfo;  
   public mutable Nemerle_list_tc : TypeInfo;
+  public mutable Nemerle_option_tc : TypeInfo;
   public mutable IEnumerable_tc : TypeInfo;
   public mutable IEnumerator_tc : TypeInfo;
   public mutable Generic_IEnumerable_tc : TypeInfo;
@@ -649,6 +650,7 @@
       InternalType.ExtensionPatternEncodingAttribute_tc = lookup ("Nemerle.Internal.ExtensionPatternEncodingAttribute");
       
       InternalType.Nemerle_list_tc = lookup ("Nemerle.Core.list");
+      InternalType.Nemerle_option_tc = lookup ("Nemerle.Core.option");
     }
   }
 



More information about the svn mailing list