[svn] r6218: nemerle/trunk/ncc: external/InternalTypes.n
generation/ILEmitter.n hierarchy/NamespaceTree.n ...
nazgul
svnadmin at nemerle.org
Wed May 3 16:24:03 CEST 2006
Log:
Add basic support for nullable types
Author: nazgul
Date: Wed May 3 16:23:42 2006
New Revision: 6218
Added:
nemerle/trunk/ncc/testsuite/positive/nullable.n
Modified:
nemerle/trunk/ncc/external/InternalTypes.n
nemerle/trunk/ncc/generation/ILEmitter.n
nemerle/trunk/ncc/hierarchy/NamespaceTree.n
nemerle/trunk/ncc/typing/MType.n
nemerle/trunk/ncc/typing/Typer2.n
Modified: nemerle/trunk/ncc/external/InternalTypes.n
==============================================================================
--- nemerle/trunk/ncc/external/InternalTypes.n (original)
+++ nemerle/trunk/ncc/external/InternalTypes.n Wed May 3 16:23:42 2006
@@ -397,6 +397,7 @@
public mutable Generic_IEnumerator_tc : TypeInfo;
public mutable Generic_IList_tc : TypeInfo;
public mutable Generic_ICollection_tc : TypeInfo;
+ public mutable Generic_Nullable_tc : TypeInfo;
public mutable DllImport_tc : TypeInfo;
public mutable Serializable_tc : TypeInfo;
@@ -513,6 +514,13 @@
}
}
+ lookup (type_name : string, args_count : int) : TypeInfo
+ {
+ match (NamespaceTree.LookupExactType (type_name, args_count)) {
+ | Some (t) => t
+ | None => Util.ice ("internal type " + type_name + " not found")
+ }
+ }
internal InitSystemTypes () : void
{
@@ -553,6 +561,7 @@
Generic_IEnumerator_tc = lookup ("System.Collections.Generic.IEnumerator");
Generic_IList_tc = lookup ("System.Collections.Generic.IList");
Generic_ICollection_tc = lookup ("System.Collections.Generic.ICollection");
+ Generic_Nullable_tc = lookup ("System.Nullable", 1);
DllImport_tc = lookup ("System.Runtime.InteropServices.DllImportAttribute");
Serializable_tc = lookup ("System.SerializableAttribute");
IObjectReference = MType.Class (lookup ("System.Runtime.Serialization.IObjectReference"), []);
Modified: nemerle/trunk/ncc/generation/ILEmitter.n
==============================================================================
--- nemerle/trunk/ncc/generation/ILEmitter.n (original)
+++ nemerle/trunk/ncc/generation/ILEmitter.n Wed May 3 16:23:42 2006
@@ -1268,12 +1268,16 @@
/* loads a literal on the evaluation stack */
| Literal (l) =>
Util.cassert (l != null);
- if (expr.MType is MType.TyVarRef && l is Literal.Null)
+ if (l is Literal.Null)
+ match (expr.MType) {
+ | TyVarRef
+ | Class (tc,[_]) when tc.Equals (InternalType.Generic_Nullable_tc) =>
emit (TExpr.DefaultValue (expr.loc, expr.Type))
+ | _ => emit_literal (l);
+ }
else
emit_literal (l);
-
/* loads address of given method */
| MethodAddress (from, meth, is_virt, typarms) =>
Mark (expr.loc);
Modified: nemerle/trunk/ncc/hierarchy/NamespaceTree.n
==============================================================================
--- nemerle/trunk/ncc/hierarchy/NamespaceTree.n (original)
+++ nemerle/trunk/ncc/hierarchy/NamespaceTree.n Wed May 3 16:23:42 2006
@@ -482,7 +482,11 @@
}
public LookupExactType (name : string) : option [TypeInfo] {
- namespace_tree.LookupType (NString.Split (name, '.'), -1)
+ LookupExactType (name, -1)
+ }
+
+ public LookupExactType (name : string, args_count : int) : option [TypeInfo] {
+ namespace_tree.LookupType (NString.Split (name, '.'), args_count)
}
public LookupExactType (name : list [string]) : option [TypeInfo] {
Added: nemerle/trunk/ncc/testsuite/positive/nullable.n
==============================================================================
--- (empty file)
+++ nemerle/trunk/ncc/testsuite/positive/nullable.n Wed May 3 16:23:42 2006
@@ -0,0 +1,35 @@
+
+module TestsNullable
+{
+ print (x : int?) : void {
+ def isnull = x == null;
+ def isnotnull = x != null;
+ assert (isnull == (null == x));
+ assert (isnotnull == (null != x));
+ assert (isnull != isnotnull);
+ Nemerle.IO.print ("isnull=$isnull value=$x\n");
+ }
+
+ basic () : void {
+ print (1);
+ print (null);
+ }
+
+ equals () : void {
+ mutable x = null;
+ assert (x.Equals (null));
+ _ = x : int?;
+ }
+
+ Main () : void {
+ basic();
+ equals ();
+ }
+}
+
+/*
+BEGIN-OUTPUT
+isnull=False value=1
+isnull=True value=
+END-OUTPUT
+*/
\ No newline at end of file
Modified: nemerle/trunk/ncc/typing/MType.n
==============================================================================
--- nemerle/trunk/ncc/typing/MType.n (original)
+++ nemerle/trunk/ncc/typing/MType.n Wed May 3 16:23:42 2006
@@ -444,7 +444,7 @@
{
get {
match (this) {
- | Class (ti, _) => !ti.IsValueType
+ | Class (ti, _) => !ti.IsValueType || ti.Equals (InternalType.Generic_Nullable_tc)
| Ref
| Out
Modified: nemerle/trunk/ncc/typing/Typer2.n
==============================================================================
--- nemerle/trunk/ncc/typing/Typer2.n (original)
+++ nemerle/trunk/ncc/typing/Typer2.n Wed May 3 16:23:42 2006
@@ -1002,8 +1002,8 @@
ValKind = LocalValue.Kind.BlockReturn) as decl) =>
BuildBlockReturn (ctx, expr.Type, decl, parms)
- | TExpr.OpCode ("==.ref")
- | TExpr.OpCode ("!=.ref") =>
+ | TExpr.OpCode ("==.ref") with eq = true
+ | TExpr.OpCode ("!=.ref") with eq = false =>
match (parms) {
| [p1, p2] =>
def e1 = StripImplicitConversion (p1.expr);
@@ -1011,6 +1011,31 @@
def t1 = e1.Type.Fix ();
def t2 = e2.Type.Fix ();
+
+ //Message.Debug ($"$t1 $t2 with $eq");
+
+ match ((t1, t2)) {
+ // nullable types need special handling in comparisons
+ | (MType.Class (tc, _), _) when tc.Equals (InternalType.Generic_Nullable_tc)
+ | (_, MType.Class (tc, _)) when tc.Equals (InternalType.Generic_Nullable_tc) =>
+ match ((e1, e2)) {
+ | (TExpr.Literal (Literal.Null), e)
+ | (e, TExpr.Literal (Literal.Null)) =>
+ def hasval = TExpr.Call (expr.Type, TExpr.MethodRef (e,
+ InternalType.Generic_Nullable_tc.LookupMember ("get_HasValue").Head :> IMethod, [], false), [], false);
+ if (eq)
+ TExpr.Call (expr.Type, TExpr.OpCode ("bool.!"), [Parm (hasval)], false)
+ else
+ hasval
+
+ | _ =>
+ ReportError (messenger,
+ $ "Comparison of two nullable instances is not yet supported.");
+ Message.HintOnce ("You can compare only with null or use Equals method.");
+ TExpr.Call (Unfold (func), parms, false)
+ }
+
+ | _ =>
def prob =
if (t1.IsSystemObject && !t2.CanBeNull) t2
else if (t2.IsSystemObject && !t1.CanBeNull) t1
@@ -1030,6 +1055,8 @@
} else {}
TExpr.Call (Unfold (func), parms, false)
+ }
+
| _ => assert (false)
}
More information about the svn
mailing list