[svn] r6520: nemerle/trunk/macros/Late.n

dragonfox svnadmin at nemerle.org
Mon Aug 14 21:46:13 CEST 2006


Log:
Change late macro to use Util.locate in some places

Author: dragonfox
Date: Mon Aug 14 21:46:11 2006
New Revision: 6520

Modified:
   nemerle/trunk/macros/Late.n

Modified: nemerle/trunk/macros/Late.n
==============================================================================
--- nemerle/trunk/macros/Late.n	(original)
+++ nemerle/trunk/macros/Late.n	Mon Aug 14 21:46:11 2006
@@ -1,6 +1,6 @@
 //
 // Late Binding Macro for Nemerle
-// Copyright (c) 2006, Snaury (snaury at gmail.com)
+// Copyright (c) 2006, Alexey Borzenkov (snaury at gmail.com)
 // All rights reserved.
 //
 // Redistribution and use in source and binary forms, with or without modification,
@@ -85,92 +85,78 @@
     /// 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
+      Util.locate(loc, invoke_located(expr_name, expr, info, flags, ignore_result))
+
+    /// returns expression that does a single late invoke
+    /// expr_name is used to hold expr
+    /// note: locations for most expressions are taken off location stack
+    private static invoke_located(expr_name : Name, expr : PExpr, info : CallInfo, flags : BF, ignore_result : bool) : 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)
+              | true :: exclude => def e = Util.locate(arg.Location, <[ null : object ]>); transform(args, exclude, e :: r)
               | _ :: exclude \
-              | exclude => transform(args, exclude, PExpr.TypeEnforcement(arg.Location, arg, ty) :: r)
+              | exclude => def e = Util.locate(arg.Location, <[ $arg : $ty ]>); transform(args, exclude, e :: r)
         if(args.Length != 0)
-          PExpr.Array(loc, <[ $(1 : int) ]>, PExpr.ListLiteral(loc, transform(args, exclude)))
+          <[ array[..$(transform(args, exclude))] ]>
         else
           <[ null ]>
 
       def pms_literal(numargs, byrefs)
         def pms_needed = need:
-          foreach(x in byrefs) when(x)
+          foreach(byref in byrefs) when(byref)
             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) ]>])]))
+              | true :: byrefs when (i < numargs) => init(byrefs, i + 1, <[ $(pms : name)[$(i : int)] = true ]> :: r)
+              | _ => <[ { ..$(r.Rev()) } ]>
+          <[ array[{ def $(pms : name) = PM($(numargs : int)); $(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 flags_expr = <[ $(flags : enum) ]>
+      def args_expr = array_literal(<[ object ]>, info.args, info.isout)
       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) ]>])
+        <[ { $(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)
+        foreach(byref in info.byref) when(byref)
           need(true)
         false
       if(need_copyback)
         def args_name = Macros.NewSymbol()
-        def init = PExpr.Define(loc, <[ $(args_name : name) ]>, args_expr)
+        def init = <[ def $(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)
+              | true :: byref => copyback(args, byref, i + 1, <[ $arg = $(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))
+              | _ => <[ {..$(r.Rev())} ]>
+            | _ => <[ {..$(r.Rev())} ]>
+        def copyback = copyback(info.args, info.byref)
         if(ignore_result)
-          PExpr.Sequence(loc, [init, PExpr.Assign(loc, PExpr.Wildcard(), call), copyback])
+          <[ $init; _ = $call; $copyback; ]>
         else
           def result_name = Macros.NewSymbol()
-          PExpr.Sequence(loc, [init, PExpr.Define(loc, <[ $(result_name : name) ]>, call), copyback, <[ $(result_name : name) ]>])
+          <[ $init; def $(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)])
+          <[ _ = $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))
+    /// returns true if expr is class or macro name
+    public is_class_or_macro_name(expr : PExpr) : bool
+      match(Util.QidOfExpr(expr))
         | Some((id, name)) =>
           def ctx = name.GetEnv(env)
           if(ctx.LookupType(id) is Some(_))
@@ -181,6 +167,15 @@
             false
         | _ => false
 
+    /// 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, _) => is_class_or_macro_name(func)
+      | PExpr.GenericSpecifier(func, _) => is_class_or_macro_name(func)
+      | _ => is_class_or_macro_name(expr)
+
     /// 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
@@ -333,12 +328,10 @@
         | 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
-                                                            ) =>
+            | NamespaceTree.TypeInfoCache.MacroCall(m) when (m is late_macroMacro ||
+                                                             m is late_parens_macroMacro ||
+                                                             m is nolate_macroMacro ||
+                                                             m is nolate_parens_macroMacro) =>
               expr
             | _ =>
               def recurse_parm(parm)
@@ -357,19 +350,16 @@
         | 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) \



More information about the svn mailing list