Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

[dotnet] Add experimental support for :scope('outer') to PAST::Var (c…

…urious to see how pmichaud++ reacts), which does a lexical lookup but skipping the current scope. Currently, bind not supported, and of course :isdecl is invalid.
  • Loading branch information...
commit 0d7828213e3ba966575fba4177a65bcb80cd4666 1 parent 2ad10c2
@jnthn authored
View
22 dotnet/compiler/PAST2DNSTCompiler.pm
@@ -832,6 +832,14 @@ our multi sub dnst_for(PAST::Var $var) {
return emit_lexical_lookup($var.name);
}
}
+ elsif $scope eq 'outer' {
+ if $var.isdecl {
+ pir::die("Cannot use isdecl when scope is 'outer'.");
+ }
+ else {
+ return emit_outer_lexical_lookup($var.name);
+ }
+ }
elsif $scope eq 'contextual' {
if $var.isdecl {
return declare_lexical($var);
@@ -1025,6 +1033,20 @@ sub emit_lexical_lookup($name) {
$lookup
}
+# Emits a lookup of a lexical in a scope outside the present one.
+sub emit_outer_lexical_lookup($name) {
+ if $*BIND_CONTEXT {
+ pir::die("Cannot bind to something using scope 'outer'.");
+ }
+ my $lookup := DNST::MethodCall.new(
+ :on('Ops'), :name('get_lex_skip_current'),
+ :type('RakudoObject'),
+ 'TC',
+ DNST::Literal.new( :value($name), :escape(1) )
+ );
+ $lookup
+}
+
# Emits a lookup of a dynamic var.
sub emit_dynamic_lookup($name) {
my $lookup := DNST::MethodCall.new(
View
24 dotnet/runtime/Runtime/Ops.cs
@@ -299,7 +299,7 @@ public static RakudoObject coerce_str_to_num(ThreadContext TC, RakudoObject Str,
/// <summary>
/// Gets a lexical variable of the given name.
/// </summary>
- /// <param name="i"></param>
+ /// <param name="TC"></param>
/// <param name="name"></param>
/// <returns></returns>
public static RakudoObject get_lex(ThreadContext TC, string Name)
@@ -316,9 +316,29 @@ public static RakudoObject get_lex(ThreadContext TC, string Name)
}
/// <summary>
+ /// Gets a lexical variable of the given name, but skips the current
+ /// scope.
+ /// </summary>
+ /// <param name="TC"></param>
+ /// <param name="name"></param>
+ /// <returns></returns>
+ public static RakudoObject get_lex_skip_current(ThreadContext TC, string Name)
+ {
+ var CurContext = TC.CurrentContext.Outer;
+ while (CurContext != null)
+ {
+ int Index;
+ if (CurContext.LexPad.SlotMapping.TryGetValue(Name, out Index))
+ return CurContext.LexPad.Storage[Index];
+ CurContext = CurContext.Outer;
+ }
+ throw new InvalidOperationException("No variable " + Name + " found in the lexical scope");
+ }
+
+ /// <summary>
/// Binds the given value to a lexical variable of the given name.
/// </summary>
- /// <param name="i"></param>
+ /// <param name="TC"></param>
/// <param name="name"></param>
/// <returns></returns>
public static RakudoObject bind_lex(ThreadContext TC, string Name, RakudoObject Value)
Please sign in to comment.
Something went wrong with that request. Please try again.