Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Eliminate the lexical/let punning horror
  • Loading branch information
sorear committed Feb 19, 2011
1 parent 0668028 commit 8840f61
Show file tree
Hide file tree
Showing 7 changed files with 84 additions and 17 deletions.
7 changes: 3 additions & 4 deletions TODO
Expand Up @@ -29,10 +29,9 @@ EASY

Fudge and run your favorite spectest file.

Stuff spectests are blocking on: "is readonly",
"Block", "&hash",
"writable $_", "closure for", "ranges of chars", "gather for",
"unless", "my regex / <&foo>", "m//",
Stuff spectests are blocking on: "Block", "&hash", "writable $_",
"closure for", "ranges of chars", "gather for", "unless",
"my regex / <&foo>", "m//",

At least parsing Int et al on my-decls would help a lot

Expand Down
39 changes: 31 additions & 8 deletions lib/CLRBackend.cs
Expand Up @@ -2505,6 +2505,7 @@ class NamProcessor {
public readonly CpsBuilder cpb;
Dictionary<string, Type> let_types = new Dictionary<string, Type>();
List<List<ClrEhSpan>> eh_stack = new List<List<ClrEhSpan>>();
List<object[]> scope_stack = new List<object[]>();

public NamProcessor(CpsBuilder cpb, StaticSub sub) {
this.sub = sub;
Expand All @@ -2516,19 +2517,34 @@ class NamProcessor {
(zyg.Length > 2 ? Scan(zyg[2]) : null) );
}

CpsOp RawAccessLex(string type, string name, CpsOp set_to) {
bool core = (type == "corelex");
bool letonly = (type == "letvar");

CpsOp AccessLet(object[] zyg) {
string name = JScalar.S(zyg[1]);
CpsOp set_to = zyg.Length > 2 ? Scan(zyg[2]) : null;
Type t;
if (!core && let_types.TryGetValue(name, out t)) {

if (let_types.TryGetValue(name, out t)) {
return (set_to == null) ? CpsOp.PeekLet(name, t) :
CpsOp.PokeLet(name, new CpsOp[1] { set_to });
}
if (letonly)
throw new Exception("No such let " + name);
throw new Exception("No such let " + name);
}

CpsOp RawAccessLex(string type, string name, CpsOp set_to) {
bool core = type == "corelex";
int uplevel;

for (int i = (core ? -1 : scope_stack.Count - 1); i >= 0; i--) {
object[] rec = scope_stack[i];
for (int j = 2; j < rec.Length - 2; j += 2) {
if (JScalar.S(rec[j]) == name) {
string lname = JScalar.S(rec[j+1]);
return (set_to == null) ?
CpsOp.PeekLet(lname, let_types[lname]) :
CpsOp.PokeLet(lname, new CpsOp[1] { set_to });
}
}
}

Lexical lex = ResolveLex(name, out uplevel, core);

return CpsOp.LexAccess(lex, uplevel,
Expand Down Expand Up @@ -2779,8 +2795,15 @@ class NamProcessor {
throw new NotImplementedException();
return CpsOp.GetSField(m.metaObject);
};
handlers["letscope"] = delegate(NamProcessor th, object[] zyg) {
th.scope_stack.Add(zyg);
CpsOp co = th.Scan(zyg[zyg.Length - 1]);
th.scope_stack.RemoveAt(th.scope_stack.Count - 1);
return co;
};
handlers["letvar"] = delegate(NamProcessor th, object[] zyg) {
return th.AccessLet(zyg); };
handlers["scopedlex"] =
handlers["letvar"] =
handlers["corelex"] = delegate(NamProcessor th, object[] zyg) {
return th.AccessLex(zyg); };
handlers["methodcall"] = delegate (NamProcessor th, object[] zyg) {
Expand Down
1 change: 1 addition & 0 deletions src/Metamodel.pm6
Expand Up @@ -461,6 +461,7 @@ class StaticSub is RefTarget {
has $.outerx; # Xref
has $.run_once = False; # Bool
has $.spad_exists = False; # Bool
has $.transparent = False; # Bool; ignored by OUTER::
has $.lexicals = {};
has $.code; # Op, is rw
has $.signature; # Sig, is rw
Expand Down
2 changes: 2 additions & 0 deletions src/NAMOutput.pm6
Expand Up @@ -128,6 +128,7 @@ augment class Metamodel::StaticSub { #OK exist
$flags +|= 8 if $.strong_used;
$flags +|= 16 if $.returnable;
$flags +|= 32 if $.augmenting;
$flags +|= 64 if $.transparent;
[
'sub',
$.name,
Expand Down Expand Up @@ -164,6 +165,7 @@ sub sub_from_nam(@block) {
outerx => $outer,
run_once => ?($flags +& 1),
spad_exists => ?($flags +& 2),
transparent => ?($flags +& 64),
lexicals => {},
zyg => [],
class => $cls,
Expand Down
9 changes: 6 additions & 3 deletions src/NieczaPassBegin.pm6
Expand Up @@ -41,6 +41,7 @@ my %type2phaser = ( init => 0, end => 1, begin => 2 );
augment class Body { method begin(:$once = False, :$itop, :$body_of, :$cur_pkg, :$augmenting = False, :$prefix = '', :$gather_hack, :$augment_hack) {
my $top = @*opensubs ?? @*opensubs[*-1].xref !! $itop;
my $rtop = $top && $*unit.deref($top);
my $istop = !@*opensubs;

my $type = $.type // '';
my $metabody = ::Metamodel::StaticSub.new(
Expand All @@ -54,12 +55,13 @@ augment class Body { method begin(:$once = False, :$itop, :$body_of, :$cur_pkg,
augmenting => $augmenting,
name => $prefix ~ $.name,
returnable => $.returnable,
transparent=> $.transparent,
gather_hack=> $gather_hack,
augment_hack=> $augment_hack,
is_phaser => %type2phaser{$type},
class => $.class,
ltm => $.ltm,
run_once => $once && (!@*opensubs || $rtop.run_once));
run_once => $once && ($istop || $rtop.run_once));

$*unit.create_stash($metabody.cur_pkg);

Expand All @@ -73,8 +75,7 @@ augment class Body { method begin(:$once = False, :$itop, :$body_of, :$cur_pkg,
if $type eq 'regex' {
$metabody.add_my_name('$*/');
}
$metabody.add_my_name('$_') unless $.transparent ||
($metabody.lexicals<$_>:exists);
$metabody.add_my_name('$_') if $istop;

pop @*opensubs if $.transparent;

Expand Down Expand Up @@ -199,6 +200,7 @@ augment class Op::ConstantDecl { #OK exist

$.init.begin;
my $nb = ::Metamodel::StaticSub.new(
transparent=> True,
unit => $*unit,
outerx => @*opensubs[*-1].xref,
name => $.name,
Expand Down Expand Up @@ -237,6 +239,7 @@ augment class Op::Attribute { #OK exist
$ns = $*unit.deref($ns);
$ns.add_attribute($.name, +$.accessor, $ibvar, $ibref);
my $nb = ::Metamodel::StaticSub.new(
transparent=> True,
unit => $*unit,
outerx => @*opensubs[*-1].xref,
name => $.name,
Expand Down
9 changes: 7 additions & 2 deletions src/NieczaPassBeta.pm6
Expand Up @@ -85,23 +85,28 @@ sub beta_optimize($body, $op, $inv, $cbody) {
@$c = grep { $_ !=== $cbody }, @$c;
}

my @pos = (map { ::Op::Lexical.new(name => $_[1]) }, @args);
my @pos = (map { ::Op::LetVar.new(name => $_[1]) }, @args);

my $nop = ::Op::StatementList.new(children => [
::Op::SigBind.new(signature => $cbody.signature,
positionals => @pos),
$cbody.code]);

my @scope;
for sort keys $cbody.lexicals -> $dn {
my $d = $cbody.lexicals{$dn};
my $nm = ::GLOBAL::NieczaActions.gensym;
my $to = $d.noinit ?? CgOp.null('var') !!
$d.hash ?? CgOp.newblankhash !!
$d.list ?? CgOp.newblanklist !!
CgOp.newblankrwscalar;
$nop = ::Op::Let.new(var => $dn,
$nop = ::Op::Let.new(var => $nm,
to => ::Op::CgOp.new(op => $to), in => $nop);
push @scope, $dn, $nm;
}

$nop = ::Op::LetScope.new(names => @scope, inner => $nop,
transparent => $cbody.transparent);
for reverse @args -> $a {
$nop = ::Op::Let.new(var => $a.[1], to => $a.[0], in => $nop);
}
Expand Down
34 changes: 34 additions & 0 deletions src/niecza
Expand Up @@ -211,14 +211,48 @@ method quote_mod:h ($) { }
method quote_mod:f ($) { }
method quote_mod:c ($) { }
method quote_mod:b ($) { }
my %opshortcut = (
'@' => [ 'fetch' ],
'l' => [ 'letvar' ],
'ns' => [ 'newscalar' ],
'nsw' => [ 'newrwscalar' ],
's' => [ 'str' ],
'i' => [ 'int' ],
'b' => [ 'bool' ],
'd' => [ 'double' ],
'==' => [ 'compare', '==' ], '!=' => [ 'compare', '!=' ],
'>=' => [ 'compare', '>=' ], '<=' => [ 'compare', '<=' ],
'<' => [ 'compare', '<' ], '>' => [ 'compare', '>' ],
'+' => [ 'arith', '+' ], '-' => [ 'arith', '-' ],
'*' => [ 'arith', '*' ], '/' => [ 'arith', '/' ],
);

method cgexp:op ($/) {
my $l = ~$<cgopname>;
my @p = @( %opshortcut{$l} // [ $l ] );
make [@p, map *.ast, @( $<cgexp> )];
}
}

augment class CgOp {
method letscope(*@items) { self._cgop('letscope', @items) }
method xspan(*@items) { self._cgop('xspan', @items) }
method bif_mod($x,$y) { self._cgop('bif_mod', $x, $y) }
}

augment class Op {
class LetScope is Op {
has $.transparent;
has $.names;
has $.inner;

method zyg() { $.inner }

method code($body) {
CgOp.letscope(+$.transparent, @($.names), $.inner.cgop($body));
}
}

class Control is Op {
has $.payload = die "Control.payload required"; # Op
has $.name = "";
Expand Down

0 comments on commit 8840f61

Please sign in to comment.