Index: H:/Alex/mine/svn/Nemerle-0.9.3-local/macros/text.n
===================================================================
--- H:/Alex/mine/svn/Nemerle-0.9.3-local/macros/text.n	(revision 1)
+++ H:/Alex/mine/svn/Nemerle-0.9.3-local/macros/text.n	(revision 7)
@@ -106,30 +106,46 @@
                   // check if this group is optional (it's context information)
                   // so we must count [(] and [)]
                   def stack = Stack();
+                  mutable slashes_in_row = 0;
+                  mutable found_group = false;
                   for (mutable i = 0; !end && i < str.Length; ++i)
                   {
                     match (str[i]) {
-                      | '(' => stack.Push(i <= m.Index)
-                      | ')' =>
-                        when(stack.Pop() && i > m.Index && i + 1 < str.Length && str[i + 1] == '?') {
+                      | '\\' => slashes_in_row++
+                      | '(' when (slashes_in_row % 2 == 0) =>
+                        slashes_in_row = 0;
+                        if(i > m.Index && !found_group)
                           end = true;
+                        else {
+                          when(i == m.Index)
+                            found_group = true;
+                          stack.Push(i <= m.Index);
+                        }
+                      | ')' when (slashes_in_row % 2 == 0) =>
+                        slashes_in_row = 0;
+                        when(stack.Pop() && i > m.Index && i + 1 < str.Length && (str[i + 1] == '?' || str[i + 1] == '*')) {
+                          end = true;
                           optional = true;
                         }
-                      | _ => ()
+                      | _ => slashes_in_row = 0
                     }
                   }
 
-                  // store this existing named group with its name, information 
-                  // if it's optional and name of its enforced type  
-                  // - [(?<name : type>..)?]
-                  match ((m.Groups[1].Success, m.Groups[3].Success)) {
-                    | (true, false) =>
-                      patnames = (m.Groups[1].ToString (), optional, 
-                                  None ()) :: patnames
-                    | (true, true) =>
-                      patnames = (m.Groups[1].ToString (), optional,
-                                  Some (m.Groups[3].ToString ())) :: patnames;
-                    | _ => ()
+                  // the group can actually be escaped as in @"(\(?<something>.*)"
+                  // we can't properly check such escapes with regex thus check here
+                  when(found_group) {
+                    // store this existing named group with its name, information 
+                    // if it's optional and name of its enforced type  
+                    // - [(?<name : type>..)?]
+                    match ((m.Groups[1].Success, m.Groups[3].Success)) {
+                      | (true, false) =>
+                        patnames = (m.Groups[1].ToString (), optional, 
+                                    None ()) :: patnames
+                      | (true, true) =>
+                        patnames = (m.Groups[1].ToString (), optional,
+                                    Some (m.Groups[3].ToString ())) :: patnames;
+                      | _ => ()
+                    }
                   }
 
                   m = m.NextMatch ()
@@ -223,6 +239,8 @@
 
           match (cass) {
             // creates entire expression checking if one case have succeeded
+            | [(_, patnames, expr)] =>
+              <[ { .. $(List.Append (build_bindings (patnames, []), [expr])) } ]>
             | (grds, patnames, expr) :: xs =>
               <[ 
                 match ($(build_alts (grds))) { 
@@ -233,7 +251,7 @@
                 }
               ]>
 
-            | [] => <[ throw MatchFailureException () ]>
+            | [] => Message.FatalError("empty list of guards?")
           }
         }
 
@@ -242,7 +260,7 @@
           match (default) {
             | None =>
               Message.Warning ("this pattern might be not exhaustive");
-              <[ () ]>
+              <[ throw MatchFailureException() ]>
 
             | Some (defexpr) => defexpr
           }
Index: H:/Alex/mine/svn/Nemerle-0.9.3-local/macros/Late.n
===================================================================
--- H:/Alex/mine/svn/Nemerle-0.9.3-local/macros/Late.n	(revision 0)
+++ H:/Alex/mine/svn/Nemerle-0.9.3-local/macros/Late.n	(revision 7)
@@ -0,0 +1,374 @@
+//
+// Late Binding Macro for Nemerle
+// Copyright (c) 2006, Snaury (snaury@gmail.com)
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+//     * Redistributions of source code must retain the above copyright notice,
+//       this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above copyright notice,
+//       this list of conditions and the following disclaimer in the documentation
+//       and/or other materials provided with the distribution.
+//     * Neither the name of the author nor the names of its contributors may be
+//       used to endorse or promote products derived from this software without
+//       specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+#pragma indent
+
+namespace Nemerle.Late
+
+  using Nemerle.IO
+  using Nemerle.Compiler
+  using Nemerle.Compiler.Parsetree
+  using BF = System.Reflection.BindingFlags
+  using PM = System.Reflection.ParameterModifier
+
+  [Record] \
+  public class LateMacro
+    env : GlobalEnv
+  
+    /// This class holds info used when passing it to Type.InvokeMember
+    public class CallInfo
+      public mutable name : string
+      public mutable args : list[PExpr]
+      public mutable byref : list[bool]
+      public mutable isout : list[bool]
+      public mutable names : list[PExpr]
+
+      public this(name : string, args : list[PExpr], tail : list[PExpr] = null)
+        this.name = name
+        this.args = args
+        transform()
+        unless(tail == null)
+          this.args = this.args + tail
+
+      transform() : void
+        def transform_named()
+          def loop(args, named_args = [], named_names = [], unnamed_args = [])
+            match(args)
+              | [] => (named_args.Rev() + unnamed_args.Rev(), named_names.Rev())
+              | arg :: args => match(arg)
+                | <[ $(id : name) = $val ]> => loop(args, val :: named_args, <[ $(id.Id : string) ]> :: named_names, unnamed_args)
+                | _ => loop(args, named_args, named_names, arg :: unnamed_args)
+          (args, names) = loop(args)
+        def transform_byref()
+          def loop(args, _args = [], _byref = [], _isout = [])
+            match(args)
+              | [] => (_args.Rev(), _byref.Rev(), _isout.Rev())
+              | arg :: args => match(arg)
+                | <[ out $arg ]> => loop(args, arg :: _args, true :: _byref, true :: _isout)
+                | <[ ref $arg ]> => loop(args, arg :: _args, true :: _byref, false :: _isout)
+                | _ => loop(args, arg :: _args, false :: _byref, false :: _isout)
+          (args, byref, isout) = loop(args)
+        transform_named()
+        transform_byref()
+
+    public variant LateCall
+      | SetProperty { loc: Location; callinfo: CallInfo }
+      | GetProperty { loc: Location; callinfo: CallInfo }
+      | Method { loc: Location; callinfo: CallInfo }
+
+    /// returns expression that does a single late invoke
+    /// expr_name is used to hold expr
+    public static invoke(expr_name : Name, expr : PExpr, loc : Location, info : CallInfo, flags : BF, ignore_result = false) : PExpr
+      def array_literal(ty, args, exclude = [])
+        def transform(args, exclude, r = [])
+          match(args)
+            | [] => r.Rev()
+            | arg :: args => match(exclude)
+              | x :: exclude when x => transform(args, exclude, <[ null : object ]> :: r)
+              | _ :: exclude \
+              | exclude => transform(args, exclude, PExpr.TypeEnforcement(arg.Location, arg, ty) :: r)
+        if(args.Length != 0)
+          PExpr.Array(loc, <[ $(1 : int) ]>, PExpr.ListLiteral(loc, transform(args, exclude)))
+        else
+          <[ null ]>
+
+      def pms_literal(numargs, byrefs)
+        def pms_needed = need:
+          foreach(x in byrefs) when(x)
+            need(true)
+          false
+        if(pms_needed)
+          def pms = Macros.NewSymbol()
+          def init(byrefs, i = 0, r = [])
+            match(byrefs)
+              | x :: byrefs when (x && i < numargs) => init(byrefs, i + 1, PExpr.Assign(loc, PExpr.Indexer(loc, <[ $(pms : name) ]>, [<[ $(i : int)]>]), <[ true ]>) :: r)
+              | _ => r.Rev()
+          PExpr.Array(loc, <[ $(1 : int) ]>, PExpr.ListLiteral(loc, [PExpr.Sequence(loc, [<[ def $(pms : name) = PM($(numargs : int)) ]>, PExpr.Sequence(loc, init(byrefs)), <[ $(pms : name) ]>])]))
+        else
+          <[ null ]>
+
+      def name_expr = <[ $(info.name : string) ]>
+      def flags_expr = PExpr.Literal(Literal.FromObject(flags))
+      def args_expr = array_literal(<[ object ]>, info.args, info.isout) // FIXME: do we really need to pass info.isout here?
+      def pms_expr = pms_literal(info.args.Length, info.byref)
+      def names_expr = array_literal(<[ string ]>, info.names)
+      def call_expr(args_expr)
+        PExpr.Sequence(loc, [PExpr.Assign(loc, <[ $(expr_name : name) ]>, expr),
+                             <[ $(expr_name : name).GetType().InvokeMember($name_expr, $flags_expr, null, $(expr_name : name), $args_expr, $pms_expr, null, $names_expr) ]>])
+      def need_copyback = need:
+        foreach(x in info.byref) when(x)
+          need(true)
+        false
+      if(need_copyback)
+        def args_name = Macros.NewSymbol()
+        def init = PExpr.Define(loc, <[ $(args_name : name) ]>, args_expr)
+        def call = call_expr(<[ $(args_name : name) ]>)
+        def copyback(args, byref, i = 0, r = [])
+          match(args)
+            | arg :: args => match(byref)
+              | x :: byref when x => copyback(args, byref, i + 1, PExpr.Assign(arg.Location, arg, PExpr.Indexer(loc, <[ $(args_name : name) ]>, [<[ $(i : int) ]>])) :: r)
+              | _ :: byref => copyback(args, byref, i + 1, r)
+              | _ => r.Rev()
+            | _ => r.Rev()
+        def copyback = PExpr.Sequence(loc, copyback(info.args, info.byref))
+        if(ignore_result)
+          PExpr.Sequence(loc, [init, PExpr.Assign(loc, PExpr.Wildcard(), call), copyback])
+        else
+          def result_name = Macros.NewSymbol()
+          PExpr.Sequence(loc, [init, PExpr.Define(loc, <[ $(result_name : name) ]>, call), copyback, <[ $(result_name : name) ]>])
+      else
+        def call = call_expr(args_expr)
+        if(ignore_result)
+          PExpr.Sequence(loc, [PExpr.Assign(loc, PExpr.Wildcard(), call)])
+        else
+          call
+
+    /// returns true is expr is of some special kind
+    /// and shouldn't be transformed by late rules
+    public special(expr : PExpr) : bool
+      | PExpr.This => true
+      | PExpr.Base => true
+      | PExpr.Indexer(func, _) => match(Util.QidOfExpr(func))
+        | Some((id, name)) =>
+          def ctx = name.GetEnv(env)
+          if(ctx.LookupType(id) is Some(_))
+            true
+          else
+            false
+        | _ => false
+      | PExpr.GenericSpecifier(func, _) => match(Util.QidOfExpr(func))
+        | Some((id, name)) =>
+          def ctx = name.GetEnv(env)
+          if(ctx.LookupType(id) is Some(_))
+            true
+          else
+            false
+        | _ => false
+      | _ => match(Util.QidOfExpr(expr))
+        | Some((id, name)) =>
+          def ctx = name.GetEnv(env)
+          if(ctx.LookupType(id) is Some(_))
+            true
+          else if(ctx.LookupMacro(id) is Some(_))
+            true
+          else
+            false
+        | _ => false
+
+    /// returns expression that does all late invokes in chain
+    /// expr_name is used to hold expr with each invoke
+    public static build(expr_name : Name, expr : PExpr, chain : list[LateCall]) : PExpr
+      def loop(expr, chain)
+        match(chain)
+          | null => expr
+          | [] => expr
+          | x :: xs => match(x)
+            | null => loop(expr, xs)
+            | LateCall.SetProperty(loc, info) =>
+              loop(invoke(expr_name, expr, loc, info, if(info.args.Length > 1) BF.SetProperty else BF.SetField %| BF.SetProperty, true), xs)
+            | LateCall.GetProperty(loc, info) =>
+              loop(invoke(expr_name, expr, loc, info, if(info.args.Length > 0) BF.GetProperty else BF.GetField %| BF.GetProperty), xs)
+            | LateCall.Method(loc, info) =>
+              loop(invoke(expr_name, expr, loc, info, BF.InvokeMethod), xs)
+      loop(expr, chain)
+
+    /// scans single expression and returns (expr, list[LateCall])
+    /// returns (expr, []) if nothing in expression can be late bound
+    public scan(expr : PExpr) : PExpr * list[LateCall]
+      def loop(expr, r = [])
+        match(expr)
+          | null => (expr, r)
+          | _ when special(expr) => (expr, r)
+          | <[ $rest (.. $_) ]> when special(rest) \
+          | <[ $rest [.. $_] ]> when special(rest) => (expr, r)
+          | <[ $rest . $(id : name) [.. $args] = $value ]> when !special(rest) \
+          | <[ $rest . $(id : name) = $value ]> when !special(rest) with (args = []) \
+          | <[ $rest . [.. $args] = $value ]> when !special(rest) with(id = Name("")) \
+          | <[ $rest [.. $args] = $value ]> when !special(rest) with(id = Name("")) =>
+            when(id.Id == "" && args.Length == 0)
+              Message.FatalError(expr.Location, "default indexer must have parameters")
+            loop(rest, LateCall.SetProperty(expr.Location, CallInfo(id.Id, args, [value])) :: r)
+          | <[ $rest . $(id : name) [.. $args] ]> when !special(rest) \
+          | <[ $rest . $(id : name) ]> when !special(rest) with(args = []) \
+          | <[ $rest . [.. $args] ]> when !special(rest) with(id = Name("")) \
+          | <[ $rest [.. $args] ]> when !special(rest) with(id = Name("")) =>
+            when(id.Id == "" && args.Length == 0)
+              Message.FatalError(expr.Location, "default indexer must have parameters")
+            loop(rest, LateCall.GetProperty(expr.Location, CallInfo(id.Id, args)) :: r)
+          | <[ $rest . $(id : name) (.. $args) ]> when !special(rest) =>
+            loop(rest, LateCall.Method(expr.Location, CallInfo(id.Id, args)) :: r)
+          | _ => (expr, r)
+      loop(expr)
+
+    /// transform any first class lateexpr by transformation rules
+    /// sets expr' and returns true if expr is first class lateexpr
+    /// returns false otherwise
+    /// note: if deep is true then any subexpr in expr' is sent to transform(expr, true)
+    public latebound(expr : PExpr, expr' : out PExpr, deep = true) : bool
+      def (expr, chain) = scan(expr)
+      if(chain is [])
+        false
+      else
+        def expr = if(deep)
+          def deeptransform(expr)
+            transform(expr, true)
+          def expr = deeptransform(expr)
+          def loop(chain)
+            | x :: chain =>
+              match(x)
+                | LateCall.SetProperty(_, info) \
+                | LateCall.GetProperty(_, info) \
+                | LateCall.Method(_, info) =>
+                  info.args = info.args.Map(deeptransform)
+              loop(chain)
+            | _ => ()
+          loop(chain)
+          expr
+        else
+          expr
+        def expr_name = Macros.NewSymbol()
+        expr' = PExpr.Sequence(expr.Location, [PExpr.DefMutable(expr.Location, <[ $(expr_name : name) ]>, null), build(expr_name, expr, chain)])
+        true
+
+    /// transforms any lateexpr in expr by lateexpr transformation rules
+    /// if deep is true, then also transforms any subexpr in any lateexpr
+    /// note: mostly based on traverse in typing/Macros.n
+    /// too bad that traverse can't be used here directly
+    public transform(expr : PExpr, deep = true) : PExpr
+      def loc = expr.Location
+      def recurse(expr)
+        transform(expr, deep)
+      def recurse_fun(f)
+        def recurse_funparm(p)
+          def recurse_attr(attr)
+            | <[ System.ComponentModel.DefaultValueAttribute($e) ]> =>
+              <[ System.ComponentModel.DefaultValueAttribute($(recurse(e))) ]>
+            | _ => attr
+          Fun_parm(p.Location, p.name, p.ty, Modifiers(p.modifiers.mods, p.modifiers.custom_attrs.Map(recurse_attr)))
+        Function_decl(Fun_header(f.header.Location, f.header.typarms, f.header.name, f.header.ret_type, f.header.parms.Map(recurse_funparm)), recurse(f.body))
+      mutable expr'
+      def result = match(expr)
+        | null => null
+        | _ when special(expr) => expr
+        | _ when latebound(expr, out expr', deep) => expr'
+        | PExpr.Wildcard \
+        | PExpr.Void => expr
+        | PExpr.As(pat, name) => PExpr.As(loc, recurse(pat), name)
+        | PExpr.Is(pat, ty) => PExpr.Is(loc, recurse(pat), ty)
+        | PExpr.Where(name, fields) => PExpr.Where(loc, recurse(name), recurse(fields))
+        | PExpr.Match(mexpr, cases) =>
+          def recurse_case(c)
+            def recurse_guard(g)
+              | PExpr.Call(<[ $("when" : dyn) ]> as w, [pat, expr]) =>
+                PExpr.Call(g.Location, w, [pat, recurse(expr)])
+              | _ => g
+            MatchCase(c.patterns.Map(recurse_guard), recurse(c.body), c.disable_warnings)
+          PExpr.Match(loc, recurse(mexpr), cases.Map(recurse_case))
+        | PExpr.Ref => expr
+        | PExpr.Member(obj, mem) => 
+          if (Macros.IsTypeName (obj))
+            expr
+          else
+            PExpr.Member(loc, recurse(obj), mem)
+        | PExpr.Call(func, parms) => PExpr.Call(loc, recurse(func), parms.Map(recurse))
+        | PExpr.GenericSpecifier(func, parms) => PExpr.GenericSpecifier(loc, recurse(func), parms.Map(recurse))
+        | PExpr.ListLiteral(elems) => PExpr.ListLiteral(loc, elems.Map(recurse))
+        | PExpr.Assign(target, source) => PExpr.Assign(loc, recurse(target), recurse(source))
+        | PExpr.DefMutable(name, val) => PExpr.DefMutable(loc, name, recurse(val))
+        | PExpr.Define(name, val) => PExpr.Define(loc, name, recurse(val))
+        | PExpr.DefFunctions(funs) => PExpr.DefFunctions(loc, funs.Map(recurse_fun))
+        | PExpr.Lambda(decl) => PExpr.Lambda(loc, recurse_fun(decl))
+        | PExpr.Throw(expr) =>
+          PExpr.Throw(loc, recurse(expr))
+        | PExpr.TryWith(body, ex, ty, handler) =>
+          PExpr.TryWith(loc, recurse(body), ex, ty, recurse(handler))
+        | PExpr.TryFinally(body, handler) =>
+          PExpr.TryFinally(loc, recurse(body), recurse(handler))
+        | PExpr.Literal \
+        | PExpr.This \
+        | PExpr.Base \
+        | PExpr.Typeof => expr
+        | PExpr.TypeConversion(expr, ty) => PExpr.TypeConversion(loc, recurse(expr), ty)
+        | PExpr.TypeEnforcement(expr, ty) => PExpr.TypeEnforcement(loc, recurse(expr), ty)
+        | PExpr.Sequence(seq) => PExpr.Sequence(loc, seq.Map(recurse))
+        | PExpr.Tuple(args) => PExpr.Tuple(loc, args.Map(recurse))
+        | PExpr.Array(rank, args) => PExpr.Array(loc, recurse(rank), recurse(args))
+        | PExpr.EmptyArray(sizes) => PExpr.EmptyArray(loc, sizes.Map(recurse))
+        | PExpr.Indexer(obj, args) => PExpr.Indexer(loc, recurse(obj), args.Map(recurse))
+        | PExpr.ParmByRef \
+        | PExpr.ParmOut \
+        | PExpr.Error => expr
+        | PExpr.MacroCall(name, ns, parms) =>
+          match(ns.Value)
+            | NamespaceTree.TypeInfoCache.MacroCall(m) when (false
+                                                             || m is late_macroMacro
+                                                             || m is late_parens_macroMacro
+                                                             || m is nolate_macroMacro
+                                                             || m is nolate_parens_macroMacro
+                                                            ) =>
+              expr
+            | _ =>
+              def recurse_parm(parm)
+                | SyntaxElement.Expression(expr) =>
+                  SyntaxElement.Expression(recurse(expr))
+                | _ => parm
+              PExpr.MacroCall(loc, name, ns, parms.Map(recurse_parm))
+        | PExpr.Quoted(quot) =>
+          def inner = match(quot)
+            | SyntaxElement.Expression(expr) => SyntaxElement.Expression(recurse(expr))
+            | _ => quot // perhaps I shouldn't be lazy here, what if something new is added to the compiler?
+          PExpr.Quoted(loc, inner)
+        | PExpr.Spliced(expr) => PExpr.Spliced(loc, recurse(expr))
+        | PExpr.ToComplete => expr
+        | PExpr.Ellipsis(expr) => PExpr.Ellipsis(loc, recurse(expr))
+        | PExpr.Typed \
+        | PExpr.TypedPattern \
+        | PExpr.TypedType => expr
+      result.loc = loc // TODO: rewrite everything up there passing loc to constructors
+      result
+
+  macro late_parens_macro(expr) \
+  syntax("late", "(", expr, ")")
+    def result = LateMacro (Macros.ImplicitCTX().Env).transform(expr)
+    // [DEBUG] printf("result: %s\n", result.ToString())
+    result
+
+  macro late_macro(expr) \
+  syntax("late", expr)
+    def result = LateMacro (Macros.ImplicitCTX().Env).transform(expr)
+    // [DEBUG] printf("result: %s\n", result.ToString())
+    result
+
+  macro nolate_parens_macro(expr) \
+  syntax("nolate", "(", expr, ")")
+    expr
+
+  macro nolate_macro(expr) \
+  syntax("nolate", expr)
+    expr
Index: H:/Alex/mine/svn/Nemerle-0.9.3-local/tools/cs2n/Makefile
===================================================================
--- H:/Alex/mine/svn/Nemerle-0.9.3-local/tools/cs2n/Makefile	(revision 1)
+++ H:/Alex/mine/svn/Nemerle-0.9.3-local/tools/cs2n/Makefile	(revision 7)
@@ -39,7 +39,7 @@
 NCC_DIR = $(TOP_LEVEL)/ncc/out.stage3
 NCC = $(EXECUTE) $(NCC_DIR)/ncc.exe
 MCS = $(CSC)
-SNK_COMPILER = /keyfile:$(TOP_LEVEL)/misc/keys/Nemerle.Compiler.snk
+SNK_COMPILER = -keyfile:$(TOP_LEVEL)/misc/keys/Nemerle.Compiler.snk
 
 NEMERLE_DLLS = Nemerle.dll
 ANTLR_DLL = antlr.runtime.dll
@@ -72,7 +72,7 @@
 	$(NCC) -greedy- -texe -r:./antlr.runtime.dll -r:Nemerle.CSharp.CS.dll -r:Nemerle.CSharp.dll -o:$@ $(CS2N_EXE_SOURCES)
 
 Nemerle.CSharp.CS.dll : Nemerle.CSharp.dll $(GENERATED_SOURCES_PARSER) $(ANTLR_DLL)
-	$(MCS) /t:library /r:./antlr.runtime.dll /r:Nemerle.CSharp.dll /r:Nemerle.dll -out:$@ $(SNK_COMPILER) $(GENERATED_SOURCES) AssemblyInfo.cs
+	$(MCS) -t:library -r:./antlr.runtime.dll -r:Nemerle.CSharp.dll -r:Nemerle.dll -out:$@ $(SNK_COMPILER) $(GENERATED_SOURCES) AssemblyInfo.cs
 
 Nemerle.CSharp.dll : $(NEMERLE_CSHARP_DLL_SOURCES) $(ANTLR_DLL)
 	$(NCC) -tdll -r:./antlr.runtime.dll -r:Nemerle.Compiler.dll -o:$@ $(SNK_COMPILER) $(NEMERLE_CSHARP_DLL_SOURCES) 
Index: H:/Alex/mine/svn/Nemerle-0.9.3-local/ncc/testsuite/positive/late.n
===================================================================
--- H:/Alex/mine/svn/Nemerle-0.9.3-local/ncc/testsuite/positive/late.n	(revision 0)
+++ H:/Alex/mine/svn/Nemerle-0.9.3-local/ncc/testsuite/positive/late.n	(revision 7)
@@ -0,0 +1,38 @@
+#pragma indent
+
+using Nemerle.Late
+
+public class Foo 
+  public Run () : void
+    System.Console.WriteLine ("Foo running")
+
+public class Bar
+  public Run () : void
+    System.Console.WriteLine ("Bar running")
+
+public class Gen[T]
+  public static Run () : void
+    System.Console.WriteLine ("Gen running with T = {0}", typeof(T).FullName)
+    
+def justRun (x : object) 
+  late x.Run ()
+  
+_ = justRun (Foo ())
+_ = justRun (Bar ())
+late
+  Nemerle.IO.print ("Macros work\n")
+  _ = System.String ('A', 5)
+  Gen[System.Int32].Run ()
+  Gen.[System.Int64].Run ()
+
+/*
+OPTIONS: -i
+
+BEGIN-OUTPUT
+Foo running
+Bar running
+Macros work
+Gen running with T = System.Int32
+Gen running with T = System.Int64
+END-OUTPUT
+*/
\ No newline at end of file
Index: H:/Alex/mine/svn/Nemerle-0.9.3-local/ncc/generation/HierarchyEmitter.n
===================================================================
--- H:/Alex/mine/svn/Nemerle-0.9.3-local/ncc/generation/HierarchyEmitter.n	(revision 1)
+++ H:/Alex/mine/svn/Nemerle-0.9.3-local/ncc/generation/HierarchyEmitter.n	(revision 7)
@@ -444,7 +444,7 @@
             | TypeDeclaration.Enum           => TypeAttributes.Sealed %| TypeAttributes.Class
           };
 
-        def attrs = make_type_attributes (Attributes, is_nested) %| type_kind_attrs;
+        mutable attrs = make_type_attributes (Attributes, is_nested, IsStruct) %| type_kind_attrs;
         mutable typarms_len = TyparmsCount;
 
         when (is_nested)
@@ -456,13 +456,30 @@
             | l => "`" + l.ToString ()
           }
 
+        def empty_struct = IsStruct && GetFields(BindingFlags.Instance %|
+                                                 BindingFlags.Public %|
+                                                 BindingFlags.NonPublic).IsEmpty;
+
+        def no_static_ctor = GetConstructors (BindingFlags.Static %|
+                                              BindingFlags.Public %|
+                                              BindingFlags.NonPublic).IsEmpty;
+
+        when (no_static_ctor)
+          attrs = attrs %| TypeAttributes.BeforeFieldInit; /* [DF] mimick mcs behavior */
+
         /* create the type builder for a top-level or nested class declaration */
         type_builder =
           if (!is_nested)
-            Manager._module_builder.DefineType (FullName + generic_mark_suffix, attrs)
+            if (empty_struct)
+              Manager._module_builder.DefineType (FullName + generic_mark_suffix, attrs, null, 1)
+            else
+              Manager._module_builder.DefineType (FullName + generic_mark_suffix, attrs)
           else {
             def containing_builder = (DeclaringType :> TypeBuilder).GetTypeBuilder ();
-            containing_builder.DefineNestedType (Name + generic_mark_suffix, attrs)
+            if (empty_struct)
+              containing_builder.DefineNestedType (Name + generic_mark_suffix, attrs, null, 1)
+            else
+              containing_builder.DefineNestedType (Name + generic_mark_suffix, attrs)
           };
 
         // creates and store generic parameters in our StaticTyVars
@@ -483,17 +500,6 @@
         when (extension_patterns.Count > 0)
           Manager.contains_nemerle_specifics = true;
 
-        // Structs with no fields need to have at least one byte.
-        // The right thing would be to set the PackingSize in a DefineType
-        // but there are no functions that allow interfaces *and* the size to
-        // be specified.
-        // maybe in 2.0 there is a better API
-        when (IsStruct && GetFields (BindingFlags.Instance %|
-                                     BindingFlags.Public %| 
-                                     BindingFlags.NonPublic).IsEmpty)
-          _ = type_builder.DefineField ("$PLACE_HOLDER$", SystemType.Byte,
-                                        FieldAttributes.Private %| FieldAttributes.SpecialName);
-        
         system_type = type_builder;
       }
     }
@@ -532,9 +538,13 @@
     /**
      * Converts Nemerle modifiers to the Framework type attributes.
      */
-    private static make_type_attributes (attrs : NemerleAttributes, is_nested : bool) : TypeAttributes
+    private static make_type_attributes (attrs : NemerleAttributes, is_nested : bool, is_struct : bool = false) : TypeAttributes
     {
-      mutable result = TypeAttributes.AutoLayout;
+      mutable result =
+        if (is_struct)
+          TypeAttributes.SequentialLayout /* [DF] default struct layout is sequential */
+        else
+          TypeAttributes.AutoLayout;
       when (attrs %&& NemerleAttributes.Public)
         if (is_nested) result |= TypeAttributes.NestedPublic
         else result |= TypeAttributes.Public;
@@ -1088,7 +1098,7 @@
         field_builder.SetCustomAttribute (volatile_attr)
       }
 
-      unless (IsMutable) {
+      unless (IsLiteral || IsMutable) {
         def imm_attr = AttributeCompiler.MakeEmittedAttribute (SystemType.ImmutableAttribute);
         field_builder.SetCustomAttribute (imm_attr)
       }
Index: H:/Alex/mine/svn/Nemerle-0.9.3-local/ncc/generation/ILEmitter.n
===================================================================
--- H:/Alex/mine/svn/Nemerle-0.9.3-local/ncc/generation/ILEmitter.n	(revision 1)
+++ H:/Alex/mine/svn/Nemerle-0.9.3-local/ncc/generation/ILEmitter.n	(revision 7)
@@ -712,7 +712,7 @@
           }
         
         /* to nonvalue type */
-        | TypeConversion (expr, cast_to_type, _) when !cast_to_type.Fix ().IsValueType =>
+        | TypeConversion (expr, cast_to_type, kind) when !cast_to_type.Fix ().IsValueType =>
           emit (expr);
           if (is_void (expr.Type))
             /* special case casts from void */
@@ -741,7 +741,8 @@
               Message.Error (expr.loc, $ "attempting to cast a value type array "
                                          "$(expr.SystemType) to non-value type array "
                                          "$(cast_to_type) which cannot succeed");
-            _ilg.Emit (OpCodes.Castclass, cast_to_type);
+            unless (kind is ConversionKind.UpCast)
+              _ilg.Emit (OpCodes.Castclass, cast_to_type);
           }
 
         /* unbox value types or perform value type conversion */
Index: H:/Alex/mine/svn/Nemerle-0.9.3-local/ncc/Makefile
===================================================================
--- H:/Alex/mine/svn/Nemerle-0.9.3-local/ncc/Makefile	(revision 1)
+++ H:/Alex/mine/svn/Nemerle-0.9.3-local/ncc/Makefile	(revision 7)
@@ -165,6 +165,7 @@
 	../macros/Data.n \
 	../macros/DesignPatterns.n \
 	../macros/AssemblyInfo.n \
+	../macros/Late.n \
 
 ############################################################
 # OUTPUT

