Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
[dotnet] bunches of integer expression (binary operations returning i…
…nt & bool) code-generators

incremental progress on regex dynamic register (for integer variables & labels) generation
fix typo in DNST::Class
slight adjustments in Cursor
fix plan count in 28-subclass.t
  • Loading branch information
diakopter committed Nov 24, 2010
1 parent f443c7e commit c46ad28
Show file tree
Hide file tree
Showing 5 changed files with 180 additions and 21 deletions.
9 changes: 9 additions & 0 deletions common/NQP/P6Objects.pm
Expand Up @@ -95,6 +95,7 @@ class Regex::Cursor {
has $.target is rw;
has $.from is rw;
has $.pos is rw;
has $.off is rw;
has $.match is rw;
has $.names is rw;
has $.debug is rw;
Expand Down Expand Up @@ -128,6 +129,12 @@ class Regex::Cursor {
nqp::instance_of(self)
}

# index representing 'off the end of the string'
# (or 1-based length)
method eos() {
nqp::length_str($!target)
}

# Return this cursor's current Match object, generating a new one
# for the Cursor if one hasn't been created yet.
method MATCH() {
Expand Down Expand Up @@ -229,9 +236,11 @@ class Regex::Cursor {
my $cur := nqp::instance_of(self);
$cur.target($target);
if nqp::repr_defined($c) {
$cur.off($c);
$cur.from($CURSOR_FAIL);
$cur.pos($c);
} else {
$cur.off(0);
$cur.from($p);
$cur.pos($p);
}
Expand Down
27 changes: 26 additions & 1 deletion dotnet/compiler/DNST.pm
Expand Up @@ -262,9 +262,17 @@ class DNST::Throw is DNST::Node {
}

class DNST::If is DNST::Node {
method new(*@children) {
has $!bool;

method bool($set?) {
if $set { $!bool := $set }
$!bool
}

method new(:$bool, *@children) {
my $obj := self.CREATE;
$obj.set_children(@children);
$obj.bool($bool);
$obj;
}
}
Expand Down Expand Up @@ -367,6 +375,23 @@ class DNST::Literal is DNST::Node {
}
}

class DNST::BinaryOp is DNST::Node {
method new(*@children) {
my $obj := self.CREATE;
$obj.set_children(@children);
$obj;
}
}

class DNST::Add is DNST::BinaryOp { }
class DNST::Subtract is DNST::BinaryOp { }
class DNST::GT is DNST::BinaryOp { }
class DNST::LT is DNST::BinaryOp { }
class DNST::GE is DNST::BinaryOp { }
class DNST::LE is DNST::BinaryOp { }
class DNST::EQ is DNST::BinaryOp { }
class DNST::NE is DNST::BinaryOp { }

class DNST::Local is DNST::Node {
has $!name;

Expand Down
50 changes: 46 additions & 4 deletions dotnet/compiler/DNST2CSharp.pm
Expand Up @@ -33,7 +33,7 @@ our multi sub cs_for(DNST::Using $using) {
our multi sub cs_for(DNST::Class $class) {
my $code := '';
if $class.namespace {
$code := $code ~ 'namespace ' ~ $class.namespce ~ " \{\n";
$code := $code ~ 'namespace ' ~ $class.namespace ~ " \{\n";
}
$code := $code ~ 'class ' ~ $class.name ~ " \{\n";
for @($class) {
Expand Down Expand Up @@ -197,7 +197,7 @@ our multi sub cs_for(DNST::If $if) {
my $code := cs_for((@($if))[0]);
$code := $code ~
" RakudoObject $if_result = null;\n" ~
" if ($*LAST_TEMP != 0) \{\n";
" if ($*LAST_TEMP" ~ ($if.bool ?? "" !! " != 0") ~ ") \{\n";

# Compile branch(es).
$*LAST_TEMP := 'null';
Expand Down Expand Up @@ -256,8 +256,50 @@ our multi sub cs_for(DNST::Literal $lit) {
}

our multi sub cs_for(DNST::Local $loc) {
$*LAST_TEMP := get_unique_id('result');
return " RakudoObject $*LAST_TEMP = " ~ $loc.name ~ ";\n";
$*LAST_TEMP := $loc.name;
return '';
}

sub lhs_rhs_op(@ops, $op) {
my $code := cs_for(@ops[0]);
my $lhs := $*LAST_TEMP;
$code := $code ~ cs_for(@ops[1]);
my $rhs := $*LAST_TEMP;
$*LAST_TEMP := get_unique_id('expr_result');
# @ops[2] is the type
return "$code " ~ @ops[2] ~ " $*LAST_TEMP = $lhs $op $rhs;\n";
}

our multi sub cs_for(DNST::Add $ops) {
lhs_rhs_op(@($ops), '+')
}

our multi sub cs_for(DNST::Subtract $ops) {
lhs_rhs_op(@($ops), '-')
}

our multi sub cs_for(DNST::GT $ops) {
lhs_rhs_op(@($ops), '>')
}

our multi sub cs_for(DNST::LT $ops) {
lhs_rhs_op(@($ops), '<')
}

our multi sub cs_for(DNST::GE $ops) {
lhs_rhs_op(@($ops), '>=')
}

our multi sub cs_for(DNST::LE $ops) {
lhs_rhs_op(@($ops), '<=')
}

our multi sub cs_for(DNST::EQ $ops) {
lhs_rhs_op(@($ops), '==')
}

our multi sub cs_for(DNST::NE $ops) {
lhs_rhs_op(@($ops), '!=')
}

our multi sub cs_for(DNST::Throw $throw) {
Expand Down
113 changes: 98 additions & 15 deletions dotnet/compiler/PAST2DNSTCompiler.pm
Expand Up @@ -1172,21 +1172,56 @@ our multi sub dnst_for(PAST::Regex $r) {
my $pasttype := $r.pasttype;
pir::die("Don't know how to compile toplevel regex pasttype $pasttype.") if $pasttype ne 'concat';
my $stmts := PAST::Stmts.new;

# cursor register
my $re_cur_tmp := DNST::Temp.new(
:name(get_unique_id('re_cur')), :type('RakudoObject'),
dnst_for(PAST::Var.new( :name('self'), :scope('lexical')))
);
my $*re_cur := DNST::Local.new($re_cur_tmp.name);
$stmts.push($re_cur_tmp);
my $re_pos_tmp := DNST::Temp.new(
:name(get_unique_id('re_pos')), :type('RakudoObject'),

# current position register
my $re_pos := emit_unbox_int(dnst_for(PAST::Op.new(
:pasttype('callmethod'), :name('pos'),
$*re_cur
)));
$stmts.push($re_pos);
my $*re_pos := $re_pos.name;

# end of string register
my $re_eos := emit_unbox_int(dnst_for(PAST::Op.new(
:pasttype('callmethod'), :name('eos'),
$*re_cur
)));
$stmts.push($re_eos);
my $*re_eos := $re_eos.name;

# original offset register
my $re_off := emit_unbox_int(dnst_for(PAST::Op.new(
:pasttype('callmethod'), :name('off'),
$*re_cur
)));
$stmts.push($re_off);
my $*re_off := $re_off.name;

# target (string) register
my $re_tgt_tmp := DNST::Temp.new(
:name(get_unique_id('re_tgt')), :type('RakudoObject'),
dnst_for(PAST::Op.new(
:pasttype('callmethod'), :name('pos'),
:pasttype('callmethod'), :name('target'),
$*re_cur
))
);
my $*re_pos := DNST::Local.new($re_pos_tmp.name);
$stmts.push($re_pos_tmp);
my $*re_tgt := DNST::Local.new($re_tgt_tmp.name);
$stmts.push($re_tgt_tmp);

# fail label
my $re_fail_label := get_unique_id('re_fail');
my $*re_fail := DNST::Goto.new(:label($re_fail_label));
$stmts.push(DNST::Label.new(:name($re_fail_label)));
# inject failure handling code here.

for @($r) {
$stmts.push(dnst_regex($_));
}
Expand All @@ -1198,41 +1233,37 @@ our multi sub dnst_for(PAST::Regex $r) {

# Regex nodes reached inside a regex
our multi sub dnst_regex(PAST::Regex $r) {
my $res;
my $pasttype := $r.pasttype;
my $stmts := PAST::Stmts.new;
if $pasttype eq 'concat' {
# Handle a concatenation of regexes.
my $stmts := PAST::Stmts.new;
for @($r) {
$stmts.push(dnst_regex($_));
}
$res := dnst_for($stmts);
}
elsif $pasttype eq 'scan' {
# Code for initial regex scan.
my $stmts := PAST::Stmts.new;

$res := dnst_for($stmts)
}
elsif $pasttype eq 'literal' {
# Code for literal characters. Faked/stubbed.
my $stmts := PAST::Stmts.new;
$stmts.push(dnst_for(PAST::Op.new(
:pasttype('callmethod'), :name('pos'),
$*re_cur,
PAST::Val.new( :value(1) )
)));
$res := dnst_for($stmts)
}
elsif $pasttype eq 'pass' {
# Code for success
my $stmts := PAST::Stmts.new;
$res := dnst_for($stmts)

$stmts.push(DNST::Return.new(
$*re_cur
));
}
else {
pir::die("Don't know how to compile regex pasttype $pasttype.");
}
$res
dnst_for($stmts)
}

# Emits a lookup of a lexical.
Expand Down Expand Up @@ -1276,3 +1307,55 @@ sub emit_dynamic_lookup($name) {
}
$lookup
}

# Emits the printing of something # C# only, silly.
sub emit_say($arg) {
DNST::MethodCall.new(
:on('Console'), :name('WriteLine'),
:void(1),
$arg
)
}

# Emits the unboxing of an int
sub emit_unbox_int($arg) {
DNST::Temp.new(
:name(get_unique_id('int')), :type('int'),
dnst_for(DNST::MethodCall.new(
:on('Ops'), :name('unbox_int'), :type('int'),
'TC', $arg
))
);
}

sub plus($l, $r, $type?) {
DNST::Add.new($l, $r, pir::defined($type) ?? $type !! 'int')
}

sub minus($l, $r, $type?) {
DNST::Subtract.new($l, $r, pir::defined($type) ?? $type !! 'int')
}

sub gt($l, $r, $type?) {
DNST::GT.new($l, $r, pir::defined($type) ?? $type !! 'int')
}

sub lt($l, $r, $type?) {
DNST::LT.new($l, $r, pir::defined($type) ?? $type !! 'int')
}

sub ge($l, $r, $type?) {
DNST::GE.new($l, $r, pir::defined($type) ?? $type !! 'int')
}

sub le($l, $r, $type?) {
DNST::LE.new($l, $r, pir::defined($type) ?? $type !! 'int')
}

sub eq($l, $r, $type?) {
DNST::EQ.new($l, $r, pir::defined($type) ?? $type !! 'int')
}

sub ne($l, $r, $type?) {
DNST::NE.new($l, $r, pir::defined($type) ?? $type !! 'int')
}
2 changes: 1 addition & 1 deletion t/nqp/28-subclass.t
Expand Up @@ -2,7 +2,7 @@

# class inheritance

plan(8);
plan(10);

class ABC {
method foo() {
Expand Down

0 comments on commit c46ad28

Please sign in to comment.