Skip to content

Commit

Permalink
Refactor QAST node structure.
Browse files Browse the repository at this point in the history
Now only nodes capable of holding children get a slot for them and an
array allocated, reducing memory. Also take the time to optimize the
new methods so we get away with a lot of the late-bound method calls.
  • Loading branch information
jnthn committed Aug 7, 2014
1 parent 26f36ac commit bd41f62
Show file tree
Hide file tree
Showing 22 changed files with 192 additions and 51 deletions.
9 changes: 9 additions & 0 deletions src/QAST/BVal.nqp
@@ -1,9 +1,18 @@
class QAST::BVal is QAST::Node {
has $!value;

method new(:$value, *%options) {
my $node := nqp::create(self);
nqp::bindattr($node, QAST::BVal, '$!value', $value);
$node.set(%options) if %options;
$node
}

method value($value = NO_VALUE) { $!value := $value unless $value =:= NO_VALUE; $!value }

method evaluate_unquotes(@unquotes) {
self
}

method dump_extra_node_info() { ~$!value.cuid }
}
11 changes: 10 additions & 1 deletion src/QAST/Block.nqp
@@ -1,4 +1,4 @@
class QAST::Block is QAST::Node {
class QAST::Block is QAST::Node does QAST::Children {
has str $!name;
has str $!blocktype;
has int $!custom_args;
Expand All @@ -7,6 +7,15 @@ class QAST::Block is QAST::Node {
has str $!cuid;
has int $!arity;
has %!symbol;

method new(str :$name, str :$blocktype, *@children, *%options) {
my $node := nqp::create(self);
nqp::bindattr($node, QAST::Block, '@!children', @children);
nqp::bindattr_s($node, QAST::Block, '$!name', $name);
nqp::bindattr_s($node, QAST::Block, '$!blocktype', $blocktype);
$node.set(%options) if %options;
$node
}

method name($value = NO_VALUE) {
$!name := $value unless $value =:= NO_VALUE;
Expand Down
33 changes: 33 additions & 0 deletions src/QAST/Children.nqp
@@ -0,0 +1,33 @@
role QAST::Children {
has @!children is positional_delegate;

method list() { @!children }
method pop() { nqp::pop(@!children) }
method push($value) { nqp::push(@!children, $value) }
method shift() { nqp::shift(@!children) }
method unshift($value) { nqp::unshift(@!children, $value) }

method shallow_clone() {
my $clone := nqp::clone(self);
$clone.set_children(nqp::clone(@!children));
$clone
}

method set_children(@children) {
@!children := @children;
}

method dump_children(int $indent, @onto) {
for @!children {
if nqp::istype($_, QAST::Node) {
nqp::push(@onto, $_.dump($indent));
}
else {
nqp::push(@onto, nqp::x(' ', $indent));
nqp::push(@onto, '- ');
nqp::push(@onto, nqp::istype($_, NQPMu) ?? '(NQPMu)' !! ~$_);
nqp::push(@onto, "\n");
}
}
}
}
9 changes: 8 additions & 1 deletion src/QAST/CompUnit.nqp
@@ -1,4 +1,4 @@
class QAST::CompUnit is QAST::Node {
class QAST::CompUnit is QAST::Node does QAST::Children {
# The serialization context for the compilation unit.
has $!sc;

Expand Down Expand Up @@ -28,6 +28,13 @@ class QAST::CompUnit is QAST::Node {

# What to run if this is the main entry point.
has $!main;

method new(*@children, *%options) {
my $node := nqp::create(self);
nqp::bindattr($node, QAST::CompUnit, '@!children', @children);
$node.set(%options) if %options;
$node
}

method sc($value = NO_VALUE) { $!sc := $value unless $value =:= NO_VALUE; $!sc }
method hll($value = NO_VALUE) { $!hll := $value unless $value =:= NO_VALUE; $!hll }
Expand Down
8 changes: 6 additions & 2 deletions src/QAST/IVal.nqp
@@ -1,8 +1,12 @@
class QAST::IVal is QAST::Node {
has int $!value;

method BUILD() {
nqp::bindattr(self, QAST::Node, '$!returns', int);
method new(:$value, *%options) {
my $node := nqp::create(self);
nqp::bindattr_i($node, QAST::IVal, '$!value', $value);
nqp::bindattr($node, QAST::Node, '$!returns', int);
$node.set(%options) if %options;
$node
}

method value($value = NO_VALUE) { $!value := $value unless $value =:= NO_VALUE; $!value }
Expand Down
9 changes: 8 additions & 1 deletion src/QAST/InlinePlaceholder.nqp
Expand Up @@ -2,7 +2,14 @@
# inlining where one of the arguments to the inlined routine was used.
class QAST::InlinePlaceholder is QAST::Node {
has int $!position;


method new(:$position, *%options) {
my $node := nqp::create(self);
nqp::bindattr_i($node, QAST::InlinePlaceholder, '$!position', $position);
$node.set(%options) if %options;
$node
}

method position(*@value) {
@value ?? ($!position := @value[0]) !! $!position
}
Expand Down
9 changes: 7 additions & 2 deletions src/QAST/NVal.nqp
@@ -1,8 +1,12 @@
class QAST::NVal is QAST::Node {
has num $!value;

method BUILD() {
nqp::bindattr(self, QAST::Node, '$!returns', num);
method new(:$value, *%options) {
my $node := nqp::create(self);
nqp::bindattr_n($node, QAST::NVal, '$!value', $value);
nqp::bindattr($node, QAST::Node, '$!returns', num);
$node.set(%options) if %options;
$node
}

method value($value = NO_VALUE) { $!value := $value unless $value =:= NO_VALUE; $!value }
Expand All @@ -16,5 +20,6 @@ class QAST::NVal is QAST::Node {
method evaluate_unquotes(@unquotes) {
self
}

method dump_extra_node_info() { ~$!value }
}
46 changes: 13 additions & 33 deletions src/QAST/Node.nqp
@@ -1,30 +1,29 @@
class QAST::Node {
# For children.
has @!array is positional_delegate;

# For annotations.
has %!annotations;

has $!node;
has $!returns;

method new(*@children, *%options) {
my $new := nqp::create(self);
nqp::bindattr($new, QAST::Node, '@!array', @children);
nqp::die('Can not instantiate QAST::Node; please use a subclass');
}

method set(%options) {
my $it := nqp::iterator(%options);
my $cur;
while $it {
$cur := nqp::shift($it);
nqp::findmethod($new, nqp::iterkey_s($cur))($new, nqp::iterval($cur))
my $cur := nqp::shift($it);
nqp::findmethod(self, nqp::iterkey_s($cur))(self, nqp::iterval($cur))
}
$new;
self
}

method list() { [] }

method node($value = NO_VALUE) {
$!node := $value unless $value =:= NO_VALUE;
$!node := NQPMu if nqp::isnull($value);
$!node
}

method returns($value = NO_VALUE) {
$!returns := $value unless $value =:= NO_VALUE;
$!returns
Expand All @@ -39,6 +38,7 @@ class QAST::Node {
self.named($value);
}
}

method flat($value = NO_VALUE) {
if $value =:= NO_VALUE {
0
Expand All @@ -58,12 +58,6 @@ class QAST::Node {
self.set_compile_time_value($value);
}

method list() { @!array }
method pop() { nqp::pop(@!array) }
method push($value) { nqp::push(@!array, $value) }
method shift() { nqp::shift(@!array) }
method unshift($value) { nqp::unshift(@!array, $value) }

method annotate(str $key, $value) {
%!annotations := nqp::hash() unless nqp::ishash(%!annotations);
%!annotations{$key} := $value;
Expand All @@ -88,9 +82,7 @@ class QAST::Node {
}

method shallow_clone() {
my $clone := nqp::clone(self);
nqp::bindattr($clone, QAST::Node, '@!array', nqp::clone(@!array));
$clone
nqp::clone(self)
}

method count_inline_placeholder_usages(@usages) {
Expand Down Expand Up @@ -129,19 +121,7 @@ class QAST::Node {
return join('', @chunks);
}

method dump_children(int $indent, @onto) {
for @!array {
if nqp::istype($_, QAST::Node) {
nqp::push(@onto, $_.dump($indent));
}
else {
nqp::push(@onto, nqp::x(' ', $indent));
nqp::push(@onto, '- ');
nqp::push(@onto, nqp::istype($_, NQPMu) ?? '(NQPMu)' !! ~$_);
nqp::push(@onto, "\n");
}
}
}
method dump_children(int $indent, @onto) { }

method dump_extra_node_info() { '' }
}
8 changes: 7 additions & 1 deletion src/QAST/NodeList.nqp
@@ -1,2 +1,8 @@
class QAST::NodeList is QAST::Node {
class QAST::NodeList is QAST::Node does QAST::Children {
method new(*@children, *%options) {
my $node := nqp::create(self);
nqp::bindattr($node, QAST::NodeList, '@!children', @children);
$node.set(%options) if %options;
$node
}
}
13 changes: 11 additions & 2 deletions src/QAST/Op.nqp
@@ -1,9 +1,18 @@
class QAST::Op is QAST::Node {
class QAST::Op is QAST::Node does QAST::Children {
has str $!name;
has str $!op;
has str $!childorder;
has int $!arity;


method new(str :$name, str :$op, *@children, *%options) {
my $node := nqp::create(self);
nqp::bindattr($node, QAST::Op, '@!children', @children);
nqp::bindattr_s($node, QAST::Op, '$!name', $name);
nqp::bindattr_s($node, QAST::Op, '$!op', $op);
$node.set(%options) if %options;
$node
}

method name($value = NO_VALUE) {
$!name := $value unless $value =:= NO_VALUE;
nqp::isnull_s($!name) ?? "" !! $!name
Expand Down
8 changes: 7 additions & 1 deletion src/QAST/ParamTypeCheck.nqp
@@ -1,2 +1,8 @@
class QAST::ParamTypeCheck is QAST::Node {
class QAST::ParamTypeCheck is QAST::Node does QAST::Children {
method new(*@children, *%options) {
my $node := nqp::create(self);
nqp::bindattr($node, QAST::ParamTypeCheck, '@!children', @children);
$node.set(%options) if %options;
$node
}
}
11 changes: 10 additions & 1 deletion src/QAST/Regex.nqp
Expand Up @@ -7,14 +7,23 @@ role QAST::RegexCursorType {
}
}

class QAST::Regex is QAST::Node {
class QAST::Regex is QAST::Node does QAST::Children {
has $!name;
has str $!rxtype;
has str $!subtype;
has str $!backtrack;
has int $!negate;
has int $!min;
has int $!max;

method new(str :$rxtype, str :$subtype, *@children, *%options) {
my $node := nqp::create(self);
nqp::bindattr($node, QAST::Regex, '@!children', @children);
nqp::bindattr_s($node, QAST::Regex, '$!rxtype', $rxtype);
nqp::bindattr_s($node, QAST::Regex, '$!subtype', $subtype);
$node.set(%options) if %options;
$node
}

method name($value = NO_VALUE) { $!name := $value unless $value =:= NO_VALUE; $!name }
method rxtype($value = NO_VALUE) {
Expand Down
9 changes: 9 additions & 0 deletions src/QAST/SVal.nqp
@@ -1,5 +1,14 @@
class QAST::SVal is QAST::Node {
has str $!value;

method new(:$value, *%options) {
my $node := nqp::create(self);
nqp::bindattr_s($node, QAST::SVal, '$!value', $value);
nqp::bindattr($node, QAST::Node, '$!returns', str);
$node.set(%options) if %options;
$node
}

method value($value = NO_VALUE) { $!value := $value unless $value =:= NO_VALUE; $!value }

method count_inline_placeholder_usages(@usages) { }
Expand Down
9 changes: 8 additions & 1 deletion src/QAST/Stmt.nqp
@@ -1,6 +1,13 @@
class QAST::Stmt is QAST::Node {
class QAST::Stmt is QAST::Node does QAST::Children {
has $!resultchild;

method new(*@children, *%options) {
my $node := nqp::create(self);
nqp::bindattr($node, QAST::Stmt, '@!children', @children);
$node.set(%options) if %options;
$node
}

method resultchild($value = NO_VALUE) { $!resultchild := $value unless $value =:= NO_VALUE; $!resultchild }

method count_inline_placeholder_usages(@usages) {
Expand Down
9 changes: 8 additions & 1 deletion src/QAST/Stmts.nqp
@@ -1,6 +1,13 @@
class QAST::Stmts is QAST::Node {
class QAST::Stmts is QAST::Node does QAST::Children {
has $!resultchild;

method new(*@children, *%options) {
my $node := nqp::create(self);
nqp::bindattr($node, QAST::Stmts, '@!children', @children);
$node.set(%options) if %options;
$node
}

method resultchild($value = NO_VALUE) { $!resultchild := $value unless $value =:= NO_VALUE; $!resultchild }

method count_inline_placeholder_usages(@usages) {
Expand Down
7 changes: 7 additions & 0 deletions src/QAST/Unquote.nqp
@@ -1,6 +1,13 @@
class QAST::Unquote is QAST::Node {
has int $!position;

method new(int :$position, *%options) {
my $node := nqp::create(self);
nqp::bindattr_i($node, QAST::Unquote, '$!position', $position);
$node.set(%options) if %options;
$node
}

method position(*@value) {
@value ?? ($!position := @value[0]) !! $!position
}
Expand Down
4 changes: 2 additions & 2 deletions src/QAST/VM.nqp
@@ -1,9 +1,9 @@
class QAST::VM is QAST::Node {
class QAST::VM is QAST::Node does QAST::Children {
has %!alternatives;

method new(*@children, *%alternatives) {
my $obj := nqp::create(self);
nqp::bindattr($obj, QAST::Node, '@!array', @children);
nqp::bindattr($obj, QAST::VM, '@!children', @children);
nqp::bindattr($obj, QAST::VM, '%!alternatives', %alternatives);
$obj
}
Expand Down
12 changes: 11 additions & 1 deletion src/QAST/Var.nqp
@@ -1,9 +1,19 @@
class QAST::Var is QAST::Node {
class QAST::Var is QAST::Node does QAST::Children {
has str $!name;
has str $!scope;
has str $!decl;
has int $!slurpy;
has $!default_or_value;

method new(:$name, str :$scope, str :$decl, *@children, *%options) {
my $node := nqp::create(self);
nqp::bindattr($node, QAST::Var, '@!children', @children);
nqp::bindattr_s($node, QAST::Var, '$!name', $name);
nqp::bindattr_s($node, QAST::Var, '$!scope', $scope);
nqp::bindattr_s($node, QAST::Var, '$!decl', $decl);
$node.set(%options) if %options;
$node
}

method name($value = NO_VALUE) {
$!name := $value unless $value =:= NO_VALUE;
Expand Down

0 comments on commit bd41f62

Please sign in to comment.