[nem-en] Late Binding in Nemerle
Snaury
snaury at gmail.com
Fri Jul 21 20:25:48 CEST 2006
Or actually no, it's better to do it this way, because this seems the
really correct way to do this is to catch special expressions early:
Index: Late.n
===================================================================
--- Late.n (revision 6459)
+++ Late.n (working copy)
@@ -149,6 +149,22 @@
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
+ | _ => 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
@@ -168,30 +184,28 @@
/// scans single expression and returns (expr, list[LateCall])
/// returns (expr, []) if nothing in expression can be late bound
- public static scan(expr : PExpr) : PExpr * list[LateCall]
+ public scan(expr : PExpr) : PExpr * list[LateCall]
def loop(expr, r = [])
- def can_be_late(expr)
- | PExpr.This => false
- | PExpr.Base => false
- | _ when Macros.IsTypeName(expr) => false
- | _ => true
match(expr)
| null => (expr, r)
- | <[ $rest . $(id : name) [.. $args] = $value ]> when
can_be_late(rest) \
- | <[ $rest . $(id : name) = $value ]> when
can_be_late(rest) with (args = []) \
- | <[ $rest . [.. $args] = $value ]> when can_be_late(rest)
with(id = Name("")) \
- | <[ $rest [.. $args] = $value ]> when can_be_late(rest)
with(id = Name("")) =>
+ | _ 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 can_be_late(rest) \
- | <[ $rest . $(id : name) ]> when can_be_late(rest) with(args = []) \
- | <[ $rest . [.. $args] ]> when can_be_late(rest) with(id =
Name("")) \
- | <[ $rest [.. $args] ]> when can_be_late(rest) with(id =
Name("")) =>
+ | <[ $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 can_be_late(rest) =>
+ | <[ $rest . $(id : name) (.. $args) ]> when !special(rest) =>
loop(rest, LateCall.Method(expr.Location, CallInfo(id.Id,
args)) :: r)
| _ => (expr, r)
loop(expr)
@@ -245,6 +259,7 @@
mutable expr'
def result = match(expr)
| null => null
+ | _ when special(expr) => expr
| _ when latebound(expr, out expr', deep) => expr'
| PExpr.Wildcard \
| PExpr.Void => expr
@@ -265,18 +280,7 @@
expr
else
PExpr.Member(loc, recurse(obj), mem)
- | PExpr.Call(func, parms) =>
- def ismacro = match (Util.QidOfExpr (func))
- | Some ((id, name)) =>
- def ctx = name.GetEnv (env)
- match (ctx.LookupMacro (id))
- | Some (_) => true
- | None => false
- | None => false
- if (ismacro)
- PExpr.Call(loc, func, parms.Map(recurse))
- else
- PExpr.Call(loc, recurse(func), parms.Map(recurse))
+ | 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))
-------------- next part --------------
A non-text attachment was scrubbed...
Name: nemerle-fix-late-type-and-macro.patch
Type: application/octet-stream
Size: 4936 bytes
Desc: not available
Url : /mailman/pipermail/devel-en/attachments/20060721/073fc8ed/nemerle-fix-late-type-and-macro-0001.obj
More information about the devel-en
mailing list