Permalink
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...
1 parent 5940076 commit 806e0fb271b304722b04e132422e83a15d2b4d18 @sorear committed Oct 31, 2011
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
@@ -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
@@ -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
@@ -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
@@ -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.

0 comments on commit 806e0fb

Please sign in to comment.