[svn] r7733: nemerle/trunk: macros/Late.n ncc/generation/ILEmitter.n ncc/generation/Typer3.n ncc/generatio...

IT svnadmin at nemerle.org
Thu Jul 5 07:28:40 CEST 2007


Log:
Working on debugging.

Author: IT
Date: Thu Jul  5 07:28:34 2007
New Revision: 7733

Modified:
   nemerle/trunk/macros/Late.n
   nemerle/trunk/ncc/generation/ILEmitter.n
   nemerle/trunk/ncc/generation/Typer3.n
   nemerle/trunk/ncc/generation/Typer4.n
   nemerle/trunk/ncc/misc/ExprWalker.n
   nemerle/trunk/ncc/parsing/AST.n
   nemerle/trunk/ncc/parsing/MainParser.n
   nemerle/trunk/ncc/parsing/ParseTree.n
   nemerle/trunk/ncc/parsing/Utility.n
   nemerle/trunk/ncc/typing/TypedTree.n
   nemerle/trunk/ncc/typing/Typer.n

Modified: nemerle/trunk/macros/Late.n
==============================================================================
--- nemerle/trunk/macros/Late.n	(original)
+++ nemerle/trunk/macros/Late.n	Thu Jul  5 07:28:34 2007
@@ -277,14 +277,14 @@
         | 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) =>
+        | PExpr.Match(mexpr, cases, expr_loc) =>
           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.Match(loc, recurse(mexpr), cases.Map(recurse_case), expr_loc)
         | PExpr.Ref => expr
         | PExpr.Member(obj, mem) => 
           if (Macros.IsTypeName (obj))

Modified: nemerle/trunk/ncc/generation/ILEmitter.n
==============================================================================
--- nemerle/trunk/ncc/generation/ILEmitter.n	(original)
+++ nemerle/trunk/ncc/generation/ILEmitter.n	Thu Jul  5 07:28:34 2007
@@ -31,9 +31,11 @@
   using Nemerle.Collections;
   using Nemerle.Utility;
 
+  using System;
   using System.IO;
   using System.Reflection;
   using System.Reflection.Emit;
+  using System.Runtime.InteropServices;
   using System.Diagnostics.SymbolStore;
 
   using Nemerle.Compiler.Typedtree;
@@ -55,7 +57,7 @@
   class ILEmitter
   {
     private _module_builder : ModuleBuilder;
-    private _ilg : ILGenerator;   
+    private _ilg : NemerleGenerator;
     private _parent_type_builder : NC.TypeBuilder;
 
     private _this_is_value_type : bool;
@@ -87,7 +89,7 @@
       _method_builder = method_builder;
       def mbase = _method_builder.GetMethodBase ();
 
-      _ilg = Late.late_macro (mbase.GetILGenerator () :> ILGenerator);
+      _ilg = Late.late_macro (NemerleGenerator (mbase.GetILGenerator () :> ILGenerator));
       _module_builder = mbase.Module :> ModuleBuilder;
       _parent_type_builder = _method_builder.DeclaringType;
 
@@ -109,6 +111,7 @@
 
           when (IsDebugEnabled) {
             Mark (beginLocation (_method_builder.BodyLocation));
+            //IT.TEMP
             _ilg.Emit (OpCodes.Nop);
           }
 
@@ -1651,27 +1654,24 @@
       }
       else
       {
-        def emit_debug(line, col, eline, ecol, emit_nop)
+        def emit_debug(line, col, eline, ecol)
         {
           _ilg.MarkSequencePoint (_debug_doc, line, col, eline, ecol);
-
-          when (emit_nop)
-            _ilg.Emit (OpCodes.Nop);
         }
 
         def l = di.loc;
 
         match (di.pexpr)
         {
-          | Sequence => emit_debug(l.Line, l.Column, l.Line,    l.Column + 1, true);
-          | _        => emit_debug(l.Line, l.Column, l.EndLine, l.EndColumn,  false);
+          | Sequence => emit_debug(l.Line, l.Column, l.Line,    l.Column + 1);
+          | _        => emit_debug(l.Line, l.Column, l.EndLine, l.EndColumn);
         }
 
         emit(di.expr);
 
         match (di.pexpr)
         {
-          | Sequence => emit_debug(l.EndLine, l.EndColumn - 1, l.EndLine, l.EndColumn, false);
+          | Sequence => emit_debug(l.EndLine, l.EndColumn - 1, l.EndLine, l.EndColumn);
           | _ => ()
         }
       }
@@ -2273,6 +2273,86 @@
       _ilg.Emit (OpCodes.Ldc_I4_1);
       _ilg.MarkLabel (label_condition_not_met)
     }
+
+#pragma warning disable 10003
+
+    class NemerleGenerator
+    {
+      public this(ilg : ILGenerator)
+      {
+        _ilg = ilg;
+      }
+
+      private _ilg : ILGenerator;
+
+      public BeginCatchBlock (tp : Type) : void  { _ilg.BeginCatchBlock(tp)      }
+      public BeginExceptFilterBlock ()   : void  { _ilg.BeginExceptFilterBlock() }
+      public BeginExceptionBlock    ()   : Label { _ilg.BeginExceptionBlock()    }
+      public BeginFaultBlock        ()   : void  { _ilg.BeginFaultBlock()        }
+      public BeginFinallyBlock      ()   : void  { _ilg.BeginFinallyBlock()      }
+      public EndExceptionBlock      ()   : void  { _ilg.EndExceptionBlock()      }
+
+      public ThrowException (excType : Type) : void { _ilg.ThrowException(excType) }
+
+      public BeginScope () : void { _ilg.BeginScope() }
+      public EndScope   () : void { _ilg.EndScope  () }
+
+      public DeclareLocal (localType : Type)                : LocalBuilder { _ilg.DeclareLocal(localType)         }
+      public DeclareLocal (localType : Type, pinned : bool) : LocalBuilder { _ilg.DeclareLocal(localType, pinned) }
+
+      public DefineLabel ()             : Label { _ilg.DefineLabel()  }
+      public MarkLabel   (loc : Label ) : void  { _ilg.MarkLabel(loc) }
+
+      public Emit (opcode : OpCode)                              : void { Emited(); _ilg.Emit(opcode)            }
+      public Emit (opcode : OpCode, arg       : byte)            : void { Emited(); _ilg.Emit(opcode, arg)       }
+      public Emit (opcode : OpCode, con       : ConstructorInfo) : void { Emited(); _ilg.Emit(opcode, con)       }
+      public Emit (opcode : OpCode, arg       : double )         : void { Emited(); _ilg.Emit(opcode, arg)       }
+      public Emit (opcode : OpCode, field     : FieldInfo )      : void { Emited(); _ilg.Emit(opcode, field)     }
+      public Emit (opcode : OpCode, arg       : float)           : void { Emited(); _ilg.Emit(opcode, arg)       }
+      public Emit (opcode : OpCode, arg       : int)             : void { Emited(); _ilg.Emit(opcode, arg)       }
+      public Emit (opcode : OpCode, label     : Label)           : void { Emited(); _ilg.Emit(opcode, label)     }
+      public Emit (opcode : OpCode, labels    : array[Label])    : void { Emited(); _ilg.Emit(opcode, labels)    }
+      public Emit (opcode : OpCode, local     : LocalBuilder)    : void { Emited(); _ilg.Emit(opcode, local)     }
+      public Emit (opcode : OpCode, arg       : long)            : void { Emited(); _ilg.Emit(opcode, arg)       }
+      public Emit (opcode : OpCode, meth      : MethodInfo)      : void { Emited(); _ilg.Emit(opcode, meth)      }
+      public Emit (opcode : OpCode, arg       : sbyte)           : void { Emited(); _ilg.Emit(opcode, arg)       }
+      public Emit (opcode : OpCode, arg       : short)           : void { Emited(); _ilg.Emit(opcode, arg)       }
+      public Emit (opcode : OpCode, signature : SignatureHelper) : void { Emited(); _ilg.Emit(opcode, signature) }
+      public Emit (opcode : OpCode, str       : string)          : void { Emited(); _ilg.Emit(opcode, str)       }
+      public Emit (opcode : OpCode, cls       : Type)            : void { Emited(); _ilg.Emit(opcode, cls)       }
+
+      public EmitCall (opcode : OpCode, methodInfo : MethodInfo , optionalParameterTypes : array[Type]) : void
+        { _ilg.EmitCall(opcode, methodInfo, optionalParameterTypes) }
+      public EmitCalli (opcode : OpCode, unmanagedCallConv : CallingConvention, returnType : Type, parameterTypes : array[Type]) : void
+        { _ilg.EmitCalli(opcode, unmanagedCallConv, returnType, parameterTypes) }
+      public EmitCalli (opcode : OpCode, callingConvention : CallingConventions, returnType : Type, parameterTypes : array[Type], optionalParameterTypes : array[Type]) : void
+        { _ilg.EmitCalli(opcode, callingConvention, returnType, parameterTypes, optionalParameterTypes) }
+
+      public EmitWriteLine (fld          : FieldInfo)    : void { _ilg.EmitWriteLine(fld)          }
+      public EmitWriteLine (localBuilder : LocalBuilder) : void { _ilg.EmitWriteLine(localBuilder) }
+      public EmitWriteLine (value        : string)       : void { _ilg.EmitWriteLine(value)        }
+
+      private mutable _justMarked : bool;
+
+      public MarkSequencePoint (document : ISymbolDocumentWriter, startLine : int, startColumn : int, endLine : int, endColumn : int) : void
+      {
+        when (_justMarked)
+          Emit (OpCodes.Nop);
+
+        _ilg.MarkSequencePoint (document, startLine, startColumn, endLine, endColumn);
+        _justMarked = true;
+      }
+
+      public UsingNamespace (usingNamespace : string) : void { _ilg.UsingNamespace(usingNamespace) }
+
+      private Emited() : void
+      {
+        _justMarked = false;
+      }
+    }
+
+#pragma warning restore 10003
+
   } /* end of the class */
 
 } /* end of the namespace */

Modified: nemerle/trunk/ncc/generation/Typer3.n
==============================================================================

Modified: nemerle/trunk/ncc/generation/Typer4.n
==============================================================================
--- nemerle/trunk/ncc/generation/Typer4.n	(original)
+++ nemerle/trunk/ncc/generation/Typer4.n	Thu Jul  5 07:28:34 2007
@@ -302,6 +302,7 @@
             else
               Throws (e, allow_try, false)
 
+          | DebugInfo     (e, _)
           | MacroEnvelope (_, _, e)
           | Label (_, e) =>
             Throws (e, allow_try, is_top)
@@ -316,9 +317,6 @@
               | None => all // ???
             }
 
-          | DebugInfo (e, _) =>
-            Throws (e, allow_try, is_top)
-
           | Cache
           | CacheRef
           | LocalFunRef
@@ -521,6 +519,7 @@
               
             TExpr.FieldMember (obj, fld)
 
+          | Assign (DebugInfo (e1, _), e2)
           | Assign (e1, e2) =>
             e1.IsAssigned = true;
 

Modified: nemerle/trunk/ncc/misc/ExprWalker.n
==============================================================================
--- nemerle/trunk/ncc/misc/ExprWalker.n	(original)
+++ nemerle/trunk/ncc/misc/ExprWalker.n	Thu Jul  5 07:28:34 2007
@@ -380,7 +380,8 @@
       }
     }
 
-    private static Sort[T] (lst : list[T]) : list[T] where T : Located
+    private static 
+      Sort[T] (lst : list[T]) : list[T] where T : Located
     {
       lst.Sort((i1, i2) =>
       {
@@ -427,7 +428,7 @@
         | ParmOut         (e)                         // { parm : PExpr; }
         | Spliced         (e)                         // { body : PExpr; }
         | Ellipsis        (e)      => Go(e);          // { body : PExpr; }
-        | Match           (e, cs)  => Go(e); Go(cs);  // { expr : PExpr; cases : list [MatchCase]; }
+        | Match           (e, cs, _) => Go(e); Go(cs);  // { expr : PExpr; cases : list [MatchCase]; mutable expr_loc : Location; }
         | Call            (e, lst)                    // { func : PExpr; parms : list [PExpr]; }
         | GenericSpecifier(e, lst)                    // { func : PExpr; generic_parms : list [PExpr]; }
         | Indexer         (e, lst) =>                 // { obj : PExpr; args : list [PExpr]; }

Modified: nemerle/trunk/ncc/parsing/AST.n
==============================================================================
--- nemerle/trunk/ncc/parsing/AST.n	(original)
+++ nemerle/trunk/ncc/parsing/AST.n	Thu Jul  5 07:28:34 2007
@@ -118,6 +118,8 @@
     public IsGenerated : bool { get { _fileIndex %&& GeneratedMask } }
     public MarkAsGenerated() : void { _fileIndex |= GeneratedMask; }
     
+    public IsGeneratedOrEmpty : bool { get { IsGenerated || IsEmpty } }
+
     public IsSourceAvailable : bool { get { _line > 0 } }
 
     public static GetFileName(index : int) : string

Modified: nemerle/trunk/ncc/parsing/MainParser.n
==============================================================================
--- nemerle/trunk/ncc/parsing/MainParser.n	(original)
+++ nemerle/trunk/ncc/parsing/MainParser.n	Thu Jul  5 07:28:34 2007
@@ -2196,16 +2196,20 @@
             }
             
           | Token.Keyword ("match") =>
-            def expr = 
+            def (expr, expr_loc) = 
               match (get_token ()) {
                 | Token.RoundGroup (group) as whole when group != null =>
                   loc = loc + whole.Location;
+                  (
                   match (parse_expr_sequence (group, [])) {
                     | [x] => x
                     | [] => fatal_error (group.Location, "expecting expression inside `match (..)'");
                     | xs => PExpr.Tuple (loc, xs.Reverse ())
                   }
-                | x => fatal_error (x, "expecting non-empty `(..)' after `match'");
+                    ,
+                    whole.Location
+                  )
+                | x => (fatal_error (x, "expecting non-empty `(..)' after `match'"), Location.Default);
               }
             match (get_token ()) {
               | Token.BracesGroup (Token.LooseGroup (Token.Operator ("..")) as group) =>
@@ -2213,11 +2217,11 @@
                 match (maybe_parse_ellipsis ()) {
                   | Some (e) =>
                     pop_stream ("match body");
-                    PExpr.Match (loc, expr, [MatchCase ([], e)]);
+                    PExpr.Match (loc, expr, [MatchCase ([], e)], expr_loc);
                   | _        => Util.ice ()
                 }
               | Token.BracesGroup (group) as tok =>
-                PExpr.Match (loc.Combine(tok.Location), expr, process_groups (group, "match body", parse_match_case))
+                PExpr.Match (loc.Combine(tok.Location), expr, process_groups (group, "match body", parse_match_case), expr_loc)
                 
               | x => fatal_error (x, "expecting '{' after 'match (e)'");
             }

Modified: nemerle/trunk/ncc/parsing/ParseTree.n
==============================================================================
--- nemerle/trunk/ncc/parsing/ParseTree.n	(original)
+++ nemerle/trunk/ncc/parsing/ParseTree.n	Thu Jul  5 07:28:34 2007
@@ -400,7 +400,10 @@
     | As              { pat : PExpr; name : Splicable; }
     | Is              { pat : PExpr; ty : PExpr; }
     | Where           { name : PExpr; fields : PExpr; }
-    | Match           { expr : PExpr; cases : list [MatchCase]; }
+    | Match           { expr : PExpr; cases : list [MatchCase]; mutable expr_loc : Location;
+                        this(loc : Location, expr : PExpr, cases : list [MatchCase]) { this(loc, expr, cases, Location.Default); }
+                        this(expr : PExpr, cases : list [MatchCase]) { this(expr, cases, Location.Default); }
+                      }
 
     | Ref             { name : Name; }
     | Member          { obj : PExpr; member : Splicable; }

Modified: nemerle/trunk/ncc/parsing/Utility.n
==============================================================================
--- nemerle/trunk/ncc/parsing/Utility.n	(original)
+++ nemerle/trunk/ncc/parsing/Utility.n	Thu Jul  5 07:28:34 2007
@@ -329,7 +329,8 @@
         if (mng.IsIntelliSenseMode)
           s [s.Count - 1].AsGenerated ()
         else
-          s [s.Count - 1]//IT.TEMP.AsGenerated ()
+          s [s.Count - 1]//IT.TEMP
+        .AsGenerated ()
     }
   }
 }

Modified: nemerle/trunk/ncc/typing/TypedTree.n
==============================================================================
--- nemerle/trunk/ncc/typing/TypedTree.n	(original)
+++ nemerle/trunk/ncc/typing/TypedTree.n	Thu Jul  5 07:28:34 2007
@@ -586,9 +586,8 @@
         }
       }
 
-      def expr = unfold (t_expr);
-      ref_is =
-        match (expr) {
+      def get_ref (expr : TExpr)
+      {
           | LocalRef
           | This
           | StaticRef
@@ -609,8 +608,13 @@
               | _ => Util.ice ()
             }
 
+        | DebugInfo (e, pe) => TExpr.DebugInfo (expr.loc, null, get_ref (unfold (e)), pe)
+
           | _ => Util.ice ($ "invalid cached expr: $expr")
         }
+
+      def expr = unfold (t_expr);
+      ref_is     = get_ref (expr);
       ref_is.loc = t_expr.loc;
       ref_is.ty = t_expr.ty;
       body

Modified: nemerle/trunk/ncc/typing/Typer.n
==============================================================================
--- nemerle/trunk/ncc/typing/Typer.n	(original)
+++ nemerle/trunk/ncc/typing/Typer.n	Thu Jul  5 07:28:34 2007
@@ -644,6 +644,7 @@
             e.SkipWriteCheck && mem.Attributes %&& NemerleAttributes.CompilerMutable
 
         | TExpr.CacheRef (desc) => IsLValue (desc.TExpr, need_ref)
+        | TExpr.DebugInfo(expr, _) => IsLValue (expr,       need_ref)
           
         | TExpr.PropertyMember (_, p) when !need_ref => p.IsMutable
         | TExpr.Call (TExpr.PropertyMember (_, p), _, _) when !need_ref => p.IsMutable
@@ -1059,22 +1060,20 @@
     }
 
 
-    public TypeExpr (e : PT.PExpr, expected : TyVar, is_toplevel_in_seq : bool) : TExpr
+    public TypeExpr (expr : PT.PExpr, expected : TyVar, is_toplevel_in_seq : bool) : TExpr
     {
-      log (TYPING, e.loc, $ "(typing expression: $e, exp=$expected");
+      log (TYPING, expr.loc, $ "(typing expression: $expr, exp=$expected");
 
-      def texpr = Util.locate (e.loc, {
-        def e' = InterceptSpecialMacros (e, expected);
+      def texpr = Util.locate (expr.loc, {
+        def e' = InterceptSpecialMacros (expr, expected);
         def e' = 
           try {
             if (e' != null) {
-              log (TYPING, e.loc, $ "intercepted: $e'");
+              log (TYPING, expr.loc, $ "intercepted: $e'");
               e'
             } else {
-              def orig_loc = e.Location;
-
-              log (MACRO_EXPANSIONS, e.loc, $ "running expand with: $e");
-              match (MacroRegistry.expand_one_macro (this, e)) {
+              log (MACRO_EXPANSIONS, expr.loc, $ "running expand with: $expr");
+              match (MacroRegistry.expand_one_macro (this, expr)) {
                 | (e, None) => 
                   log (MACRO_EXPANSIONS, e.loc, $ "after expansion: $e");
 
@@ -1089,13 +1088,24 @@
                 | (e, Some ((orig, im))) =>
                   log (MACRO_EXPANSIONS, e.loc, $ "after expansion: $e");
 
+                  def debugLocation = 
+                    if (Manager.Options.EmitDebug && !expr.loc.IsGeneratedOrEmpty)
+                      GetDebugLocation(expr);
+                    else
+                      Location.Default;
+
                   def res = TypeExpr (e, expected, is_toplevel_in_seq);
 
                   // IT: In some cases, MacroEnvelope takes e.Location without keyword location.
                   // For example, for (mutable i;;) {} takes e.Location without 'for'.
                   // The following fixes that.
-                  def loc = if (orig_loc.IsGenerated) res.Location else orig_loc;
-                  TExpr.MacroEnvelope (loc, res.Type, im, orig, res)
+                  def loc = if (expr.loc.IsGeneratedOrEmpty) res.Location else expr.loc;
+                  def res = TExpr.MacroEnvelope (loc, res.Type, im, orig, res);
+
+                  if (debugLocation.IsEmpty)
+                    res
+                  else
+                    TExpr.DebugInfo (debugLocation, null, res, expr);
               }
             }
           } catch {
@@ -1112,8 +1122,8 @@
         e'
       });
 
-      when (e.typed_object == null)
-        e.typed_object = texpr;
+      when (expr.typed_object == null)
+        expr.typed_object = texpr;
       texpr;
     }
 
@@ -1162,10 +1172,6 @@
       DoExpect (expected, actual, place, true)
     }
 
-    static _debug(obj : object) : void
-    {
-      _ = obj.ToString();
-    }
 
     DoType (expression : PT.PExpr, expected : TyVar, is_toplevel_in_seq : bool) : TExpr
     {
@@ -1175,13 +1181,7 @@
         Manager.Complete (expression, expected, this, env);
       }
 
-      def addDebugInfo(res)
-      {
-          //if (expression.IsGenerated || expression.loc.IsEmpty || Manager.IsIntelliSenseMode)
-            res
-          //else
-          //  TExpr.DebugInfo(expression.Location, null, res, expression);
-      }
+      def debugLocation = GetDebugLocation(expression);
 
       def texpr = match (expression)
       {
@@ -1191,12 +1191,11 @@
                        "ref and out parameters are only allowed in function calls")
 
         | PT.PExpr.DefMutable (x, null) => 
-          DoType (PT.PExpr.DefMutable (x, <[ $(TExpr.DefaultValue (FreshTyVar ()) : typed) ]>), expected, is_toplevel_in_seq)
+          DoType (PT.PExpr.DefMutable (x, <[ $(TExpr.DefaultValue (FreshTyVar ()) : typed) ]>), expected, is_toplevel_in_seq);
                        
         | PT.PExpr.DefMutable (PT.PExpr.Ref as name, val)
         | PT.PExpr.Define (PT.PExpr.Ref as name, val) =>
           def is_mutable = expression is PT.PExpr.DefMutable;
-          def res =
             if (Expect (expected, InternalType.Void, "definition ``result''"))
               if (is_toplevel_in_seq)
                 TypeLocalDefinition (is_mutable, name.name, name.Location, val)
@@ -1209,7 +1208,6 @@
                 }
             else
               TExpr.Error ();
-          addDebugInfo(res);
 
         | PT.PExpr.DefMutable (Tuple (Ref (first_n) :: names), Tuple (first_v :: vals)) =>
           if (Expect (expected, InternalType.Void, "definition ``result''"))
@@ -1244,7 +1242,7 @@
                 PopLocals ()
             }
           else
-            TExpr.Error ()
+            TExpr.Error ();
 
         | PT.PExpr.DefMutable (TypeEnforcement (nm, ty) as te, val) =>
           def nte = PT.PExpr.TypeEnforcement (ty.Location.Combine(val.Location), val, ty);
@@ -1266,7 +1264,7 @@
                 PopLocals ()
               }
           else
-            TExpr.Error ()
+            TExpr.Error ();
           
 
         | PT.PExpr.DefFunctions (functions) =>
@@ -1527,7 +1525,7 @@
               PT.PExpr.Call (star_ref, [loop (ps), p])
             | [] => assert (false)
           }
-          TypeExpr (loop (List.Rev (parms)), expected)
+          TypeExpr (loop (List.Rev (parms)), expected);
           
         | <[ $("_N_ref_cache" : dyn) ($(name : name), $val) ]> =>
             if (Expect (expected, InternalType.Void, "definition ``result''")) {
@@ -1549,7 +1547,7 @@
                 }) || fnc is <[ _ . $_ ]>)
             TypeExpr (PartialApplication (expression), expected)
           else
-            TypeCall (fnc, parms, expected, is_property = false)
+            TypeCall (fnc, parms, expected, is_property = false);
 
 
         | PT.PExpr.Assign (PT.PExpr.Tuple (vars), e2) =>
@@ -1562,14 +1560,14 @@
             ]>;
             TypeExpr (expr, expected)
           } else 
-            TExpr.Error ()
+            TExpr.Error ();
 
 
         | PT.PExpr.Assign (PT.PExpr.Wildcard, e2) =>
           if (Expect (expected, InternalType.Void, "assignment ``result''"))
             TypeExpr (<[ def _ = $e2 ]>, expected)
           else
-            TExpr.Error ()
+            TExpr.Error ();
 
 
         | PT.PExpr.Assign (e1, e2) =>
@@ -1579,7 +1577,7 @@
             def e2 = TypeExpr (e2);
             TExpr.Assign (e1, AddCastTo (e2, e1.Type, "assigned value"))
           } else
-            TExpr.Error ()
+            TExpr.Error ();
             
 
         | PT.PExpr.GenericSpecifier (fnc, gen_params) =>
@@ -1648,7 +1646,7 @@
 
         | PT.PExpr.Sequence ([]) =>
           _ = Expect (expected, InternalType.Void, "empty sequence");
-          addDebugInfo (VoidLiteral ())
+          VoidLiteral ()
 
 
         | PT.PExpr.Sequence (l) =>
@@ -1670,7 +1668,7 @@
           def res = loop ([], l);
           //Message.Debug ("pop seq");
           PopLocals ();
-          addDebugInfo (res)
+          res
 
 
         | PT.PExpr.Tuple (l) =>
@@ -1770,13 +1768,116 @@
 
       when (expression.typed_object == null)
         expression.typed_object = texpr;
+
+      if (debugLocation.IsEmpty)
       texpr
+      else
+        TExpr.DebugInfo (debugLocation, null, texpr, expression)
     }
 
-    #endregion
+    private mutable debugInfos : list[Location * PT.PExpr] = [];
+
+    private GetDebugLocation(pexpr : PT.PExpr) : Location
+    {
+      def skip(l) 
+      {
+        debugInfos.Exists((loc, _) => loc.Contains(l));
+      }
 
+      //IT.TEMP
+      _ = 
+      if (!Manager.Options.EmitDebug || pexpr.loc.IsGeneratedOrEmpty || skip(pexpr.loc))
+        Location.Default
+      else
+      {
+        mutable loc = pexpr.Location;
+
+        def truncateLoc()
+        {
+          mutable isTruncated = false;
+
+          // Truncate DebugInfo location to inner exprs.
+          //
+          ExprWalker().Walk(pexpr, info =>
+          {
+            def truncate(line, col)
+            {
+              when (line < loc.EndLine || line == loc.EndLine && col < loc.EndColumn)
+              {
+                loc = Location(loc.FileIndex, loc.Line, loc.Column, line, col);
+                isTruncated = true;
+              }
+            }
+
+            match (info.Node)
+            {
+              | PT.PExpr.Sequence as s when !s.loc.IsGeneratedOrEmpty => truncate(s.loc.Line, s.loc.Column);
+              | PT.PExpr.Match(_, _, l) when !l.IsGeneratedOrEmpty => truncate(l.EndLine,  l.EndColumn);
+              | _ => ()
+            }
+          });
+
+          when (isTruncated)
+          {
+            // Here we store the location of the last element,
+            // which ends on the same line where the original pexpr starts.
+            // It's used to truncate DebugInfo location to a single line.
+            //
+            mutable lastLineLoc;
+
+            // Scan inner exprs.
+            //
+            ExprWalker().Walk(pexpr, info =>
+            {
+              when (info.Node is Located)
+              {
+                def l = (info.Node :> Located).loc;
+
+                when (
+                  l.EndLine == loc.Line &&
+                  l.EndColumn > lastLineLoc.EndColumn &&
+                  (loc.EndLine != loc.Line || l.EndColumn < loc.EndColumn))
+                {
+                  lastLineLoc = l;
+                }
+              }
+            });
+
+            unless (lastLineLoc.IsEmpty)
+              loc = Location(loc.FileIndex, loc.Line, loc.Column, lastLineLoc.EndLine, lastLineLoc.EndColumn);
+          }
+        }
+
+        match (pexpr)
+        {
+          | PT.PExpr.Sequence => ()
+          | PT.PExpr.MacroCall(nm, _, _) when
+            nm.loc.IsGenerated == false &&
+            nm.loc.Line   == loc.Line &&
+            nm.loc.Column == loc.Column =>
+
+            loc = nm.loc;
+
+          | _ =>
+            truncateLoc();
+            unless (loc.IsEmpty)
+            {
+              if (skip (loc))
+                loc = Location.Default;
+              else
+                debugInfos ::= (loc, pexpr);
+            }
+        }
+
+        loc;
+      }
+      Location.Default;
+    }
+
+    #endregion
        
     #region ,,def''
+    
     TypeLocalDefinition (is_mutable : bool, name : PT.Name, val : PT.PExpr) : TExpr.DefValIn
     {
       TypeLocalDefinition (is_mutable, name, Location.Default, val)



More information about the svn mailing list