Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Change 'constant' to run at compile time

Also requires some retying of knots for Bool.  Very likely to break CLR
code samples.
  • Loading branch information...
commit 806e0fb271b304722b04e132422e83a15d2b4d18 1 parent 5940076
@sorear authored
Showing with 82 additions and 8 deletions.
  1. +14 −4 lib/CORE.setting
  2. +1 −1  lib/Kernel.cs
  3. +3 −3 src/STD.pm6
  4. +64 −0 src/niecza
View
18 lib/CORE.setting
@@ -145,6 +145,9 @@ sub substr(\$str, $start, $len?, $repl?) is Niecza::builtin('substr3', 3, 3) {
substr($str, $start, $len) = $repl !!
substr($str, $start, $len)
}
+
+# not actually inlined but needed for constant i
+sub sqrt($x) { Q:CgOp { (sqrt {$x}) } }
# }}}
# Fundamental types {{{
my class Mu {
@@ -639,7 +642,7 @@ my class Str is Cool {
method gist() { defined(self) ?? self !! nextsame }
method Numeric() { Q:CgOp { (box Num (str_tonum (obj_getstr {self}))) } }
method perl() {
- defined(self) // nextsame;
+ self // nextsame;
my $str = self;
$str ~~ s:g { <[ " \\ ]> } = '\\' ~ $/;
"\"$str\""
@@ -739,10 +742,17 @@ my class StrBasedEnum is CommonEnum {
} }
}
-my enum Bool < False True >;
-augment class Bool {
+# Using the "enum" type declarator would require a compile time reference
+# to the EnumMap type, which depends on Bool; ick.
+my class Bool is IntBasedEnum is Int {
+ our $_enums;
+ method enums() { $_enums }
+ our constant True = Q:CgOp { (box Bool (bool 1)) };
+ our constant False = Q:CgOp { (box Bool (bool 0)) };
method ACCEPTS(\$t) { defined(self) ?? self !! $t.^does(self) }
}
+my constant True = Q:CgOp { (box Bool (bool 1)) };
+my constant False = Q:CgOp { (box Bool (bool 0)) };
# }}}
# Fundamental scalar operators {{{
sub infix:<~> is Niecza::absprec<r=> is assoc<list> (\|$bits) { Q:CgOp {
@@ -1308,6 +1318,7 @@ my class EnumMap {
method at_key($k) { self{$k} }
method exists_key($k) { self{$k}:exists }
}
+BEGIN { $Bool::_enums ::= EnumMap.new("False" => 0, "True" => 1) }
my class Junction is Mu {
has $!kind_;
@@ -1949,7 +1960,6 @@ sub conjugate($x) { $x.conjugate }
sub round($x, $scale=1) { floor($x / $scale + 0.5) * $scale }
sub truncate($x) { $x.Int }
sub sign($x) { $x < 0 ?? -1 !! $x > 0 ?? 1 !! 0 }
-sub sqrt($x) { Q:CgOp { (sqrt {$x}) } }
multi sub exp($x) { $x.exp }
multi sub exp($x, $base) { $base ** $x }
# XXX 'Order' type
View
2  lib/Kernel.cs
@@ -864,7 +864,7 @@ public sealed class RuntimeUnit : IFreeze {
}
// no conflict if items are identical
- if (!ose.v.rw && !nse.v.rw && oseo == nseo) {
+ if (ose.v == nse.v || !ose.v.rw && !nse.v.rw && oseo == nseo) {
nse = ose;
return null;
}
View
6 src/STD.pm6
@@ -1401,7 +1401,7 @@ grammar P6 is STD {
[ <.spacey> <arglist> ]?
]
<.ws>
- <.explain_mystery>
+ <.explain_mystery(True)>
}
@@ -1410,7 +1410,7 @@ grammar P6 is STD {
<sym> <.ws>
<module_name>[<.spacey><arglist>]?
<.ws>
- <.explain_mystery>
+ <.explain_mystery(True)>
}
@@ -1498,7 +1498,7 @@ grammar P6 is STD {
}
rule statement_control:default {<sym> <block> }
- token statement_prefix:BEGIN { :my %*MYSTERY; <sym> <blast> <.explain_mystery> }
+ token statement_prefix:BEGIN { :my %*MYSTERY; <sym> <blast> <.explain_mystery(True)> }
token statement_prefix:CHECK { <sym> <blast> }
token statement_prefix:INIT { <sym> <blast> }
token statement_prefix:START { <sym> <blast> }
View
64 src/niecza
@@ -18,6 +18,61 @@ use Sig;
use STD;
augment grammar STD {
+method explain_mystery($nested?) {
+ my %post_types;
+ my %unk_types;
+ my %unk_routines;
+ my $m = '';
+ for keys(%*MYSTERY) {
+ my $p = %*MYSTERY{$_}.<lex>;
+ if self.is_name($_, $p) {
+ # types may not be post-declared
+ %post_types{$_} = %*MYSTERY{$_};
+ next;
+ }
+
+ next if self.is_known($_, $p) or self.is_known('&' ~ $_, $p);
+
+ # just a guess, but good enough to improve error reporting
+ if $_ lt 'a' {
+ %unk_types{$_} = %*MYSTERY{$_};
+ }
+ else {
+ %unk_routines{$_} = %*MYSTERY{$_};
+ }
+ }
+ if %post_types {
+ my @tmp = sort keys(%post_types);
+ $m ~= "Illegally post-declared type" ~ ('s' x (@tmp != 1)) ~ ":\n";
+ for @tmp {
+ $m ~= "\t'$_' used at line " ~ %post_types{$_}.<line> ~ "\n";
+ }
+ }
+ if %unk_types {
+ my @tmp = sort keys(%unk_types);
+ $m ~= "Undeclared name" ~ ('s' x (@tmp != 1)) ~ ":\n";
+ for @tmp {
+ $m ~= "\t'$_' used at line " ~ %unk_types{$_}.<line> ~ "\n";
+ }
+ }
+ if %unk_routines {
+ my @tmp = sort keys(%unk_routines);
+ $m ~= "Undeclared routine" ~ ('s' x (@tmp != 1)) ~ ":\n";
+ for @tmp {
+ $m ~= "\t'$_' used at line " ~ %unk_routines{$_}.<line> ~ "\n";
+ }
+ }
+ self.sorry($m) if $m;
+
+ unless $nested {
+ for $*unit.stubbed_stashes -> $pos, $type {
+ next if $type.closed || $type.kind eq 'package';
+ self.cursor($pos).sorry("Package was stubbed but not defined");
+ }
+ }
+
+ self;
+}
method nibbler() {
my @nibbles;
my $from = self.pos;
@@ -102,6 +157,15 @@ method statement_prefix:BEGIN ($/) {
$<blast>.ast.run_BEGIN;
make ::Op::StatementList.new;
}
+method init_constant($con, $rhs) {
+ my $body = self.thunk_sub(
+ ::Op::LexicalBind.new(name => $con.name, :$rhs),
+ name => "$con.name() init");
+ $body.outer.create_static_pad;
+ $body.run_BEGIN;
+ $con.init = True;
+ $con;
+}
method blockoid($/) {
# XXX horrible cheat, but my data structures aren't up to the task of
# $::UNIT being a class body &c.
Please sign in to comment.
Something went wrong with that request. Please try again.