[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