Permalink
Browse files

Finish basic type creation

  • Loading branch information...
1 parent 1e4b501 commit 8a35c4fa6e898a1d6854eaa1d65daf20d70275b2 @sorear committed Sep 29, 2011
Showing with 88 additions and 38 deletions.
  1. +9 −12 TODO
  2. +34 −0 lib/CodeGen.cs
  3. +15 −2 lib/Kernel.cs
  4. +1 −0 lib/ObjModel.cs
  5. +7 −3 src/NieczaBackendDotnet.pm6
  6. +12 −11 src/NieczaPassSimplifier.pm6
  7. +10 −10 src/niecza
View
21 TODO
@@ -6,21 +6,17 @@ items are required for yapsi.
EASY
Add your favorite missing function to the setting, with tests.
- In particular, I could use: sprintf, dir, write, close, split, ...
+ In particular, I could use: write, close, split, ...
Implement Sub.leave and CallFrame.leave
Character class expressions like [[a .. A] & [\W]]
- Fudge and run your favorite spectest file.
-
Stuff spectests are blocking on: "closure for", :16(),
constants in signatures, ::T, ...
MEDIUM
- + qx[]
-
Finish the set of Num operators, includig number-theoretic and
transcedental functions.
@@ -30,8 +26,6 @@ MEDIUM
Design and implement a generic system for multiplexed and non-blocking I/O.
- *CATCH and CONTROL blocks.
-
Jump table optimization for when chains.
*Find out what readonly subs are supposed to do with lists, etc and implement
@@ -41,8 +35,6 @@ MEDIUM
Add Buf bitops.
- Implement warning exceptions.
-
HARD
Design and implement some sort of NFG thing that allows use codes, graphs,
@@ -81,7 +73,12 @@ NASTY
Export Perl 6 code into a CLR .dll
-Other stuff to do after:
- - cnperl6 prototyping...
- - CLR: KISS and then play with async I/O, possibly including soric
+Other stuff to do:
+
- pm's = hack
+ - Stash entries should be smarter, should know the difference between
+ types, constants, subs, and variables
+ - Swappable global contexts containing *all* state
+ - Bounded serialization using global contexts
+ - eval requires splitting RuntimeUnit from SerializationContext;
+ null SerializationContext is in effect at runtime
View
@@ -4987,6 +4987,39 @@ public class DowncallReceiver : CallReceiver {
} else {
return null;
}
+ } else if (cmd == "unit_bind") {
+ string who = (string)args[1];
+ string name = (string)args[2];
+ object item = Handle.Unbox(args[3]);
+ string file = (string)args[4];
+ int line = (int)args[5];
+
+ Variable vitm = null;
+ if (item is STable)
+ vitm = ((STable)item).typeVar;
+ else if (item is SubInfo)
+ vitm = Kernel.NewROScalar(((SubInfo)item).protosub);
+ else if (item == null)
+ vitm = null;
+ else
+ return new Exception("weird thing to bind");
+
+ string err = Backend.currentUnit.NsBind(who, name, vitm, file, line);
+ return err == null ? null : new Exception(err);
+ } else if (cmd == "type_closed") {
+ STable st = (STable)Handle.Unbox(args[1]);
+ // TODO
+ return false;
+ } else if (cmd == "type_close") {
+ STable st = (STable)Handle.Unbox(args[1]);
+ // TODO
+ return null;
+ } else if (cmd == "type_kind") {
+ STable st = (STable)Handle.Unbox(args[1]);
+ return st.mo.rtype;
+ } else if (cmd == "type_name") {
+ STable st = (STable)Handle.Unbox(args[1]);
+ return st.name;
} else if (cmd == "type_create") {
RuntimeUnit ru = (RuntimeUnit)Handle.Unbox(args[1]);
string name = (string)args[2];
@@ -5014,6 +5047,7 @@ public class DowncallReceiver : CallReceiver {
nst.initVar = nst.typeVar;
nst.initObject = nst.typeObject;
+ nst.mo.rtype = type;
return new Handle(nst);
} else if (cmd == "create_sub") {
View
@@ -449,8 +449,17 @@ class IdentityComparer : IEqualityComparer<object> {
FieldAttributes.Static);
}
+ public static Variable MakeAppropriateVar(string name) {
+ if (name.Length >= 1 && name[0] == '@')
+ return Kernel.CreateArray();
+ if (name.Length >= 1 && name[0] == '%')
+ return Kernel.CreateHash();
+ return Kernel.NewTypedScalar(null);
+ }
+
public static string NsMerge(string who, string name,
ref StashEnt nse, StashEnt ose) {
+
P6any nseo = nse.v.Fetch();
P6any oseo = ose.v.Fetch();
bool nseod = nseo.IsDefined();
@@ -490,12 +499,15 @@ class IdentityComparer : IEqualityComparer<object> {
string file, int line) {
string key = (char)who.Length + who + name;
StashEnt nse = new StashEnt();
+ if (var == null)
+ var = MakeAppropriateVar(name);
nse.v = var;
nse.file = file;
nse.line = line;
StashEnt ose;
- globals.TryGetValue(key, out ose);
- string err = NsMerge(who, name, ref nse, ose);
+ string err = null;
+ if (globals.TryGetValue(key, out ose))
+ err = NsMerge(who, name, ref nse, ose);
if (err != null) return err;
globals[key] = nse;
return null;
@@ -3129,6 +3141,7 @@ public struct StashCursor {
((P6opaque)st.typeObject).slots = null;
st.typeVar = st.initVar = Kernel.NewROScalar(st.typeObject);
st.mo.isPackage = true;
+ st.mo.rtype = "package";
// XXX should be PackageHOW
st.how = new BoxObject<STable>(st, Kernel.ClassHOWMO, 0);
st.mo.Revalidate();
View
@@ -127,6 +127,7 @@ public class P6how {
public STable stable;
public bool isRole, isSubset, isPackage;
+ public string rtype = "class"; // XXX used for compiler's inspection
public P6any roleFactory;
public P6any subsetWhereThunk;
public Variable subsetFilter;
@@ -89,7 +89,7 @@ class StaticSub {
method lookup_lex($name, $file?, $line?) {
downcall("sub_lookup_lex", self, $name, $file, $line//0);
}
- method set_outervar($v) { downcall("sub_set_outervar", self, ~$v) }
+ method set_outervar($v) { downcall("sub_set_outervar", self, $v) }
method set_class($n) { downcall("sub_set_class", self, ~$n) }
method set_name($v) { downcall("sub_set_name", self, ~$v) }
method set_methodof($m) { downcall("sub_set_methodof", self, $m) }
@@ -223,8 +223,8 @@ class Type {
method is_package() { downcall("type_is_package", self) }
method closed() { downcall("type_closed", self) }
method close() { downcall("type_close", self) }
- method type_kind() { downcall("type_kind", self) }
- method is_param_role() { downcall("type_is_param_role", self) }
+ method kind() { downcall("type_kind", self) }
+ method name() { downcall("type_name", self) }
}
class Unit {
@@ -241,6 +241,10 @@ class Unit {
method get($pkg, $name) {
downcall("unit_get", $pkg, $name);
}
+ method bind($pkg, $name, $item, :$file, :$line, :$pos) { #OK
+ downcall("unit_bind", ~$pkg, ~$name, $item, ~($file // '???'),
+ $line // 0);
+ }
method create_type(:$name, :$class, :$who) {
downcall("type_create", self, ~$name, ~$class, ~$who);
@@ -141,17 +141,18 @@ sub run_optree($body, $op, $nv) {
my $inv = $op.invocant;
return $op unless $inv.^isa(::Op::Lexical);
my $invname = $inv.name;
- my $inv_lex = $body.find_lex($invname);
- return $op unless $inv_lex && $inv_lex.^isa(::Metamodel::Lexical::SubDef);
-
- if $inv_lex.body.extend<builtin> -> $B {
- return $op unless defined my $args = no_named_params($op);
- return $op unless $args >= $B[1] &&
- (!defined($B[2]) || $args <= $B[2]);
- return ::Op::Builtin.new(name => $B[0], args => $args);
- }
-
- return $op unless $inv_lex.body.unit.is_true_setting;
+ my @inv_lex = $body.lookup_lex($invname);
+ return $op unless @inv_lex && @inv_lex[0] eq 'sub';
+
+# TODO: get extend working again
+# if $inv_lex.body.extend<builtin> -> $B {
+# return $op unless defined my $args = no_named_params($op);
+# return $op unless $args >= $B[1] &&
+# (!defined($B[2]) || $args <= $B[2]);
+# return ::Op::Builtin.new(name => $B[0], args => $args);
+# }
+
+ return $op unless @inv_lex[4].unit.name eq 'CORE';
return $op unless my $func = %funcs{$invname};
$func($body, $nv, $invname, $op);
View
@@ -197,7 +197,7 @@ method explain_mystery() {
self.sorry($m) if $m;
for $*unit.stubbed_stashes -> $pos, $type {
- next if $type.closed || $type.is_package;
+ next if $type.closed || $type.kind eq 'package';
self.cursor($pos).sorry("Package was stubbed but not defined");
}
@@ -436,7 +436,7 @@ method install_sub($/, $sub, :$multiness is copy, :$scope is copy, :$class,
}
if $name ~~ Op && (!defined($method_type) || $scope ne 'has' ||
- !$method_targ.is_param_role) {
+ $method_targ.kind ne 'prole') {
$/.CURSOR.sorry("Computed names are only implemented for parametric roles");
$name = "placeholder";
}
@@ -530,7 +530,7 @@ method open_package_def($, $/ = $*cursor) {
$/.CURSOR.trymop({
die "Augment requires a target" unless $obj;
- die "Illegal augment of a role" if $obj.is_role;
+ die "Illegal augment of a role" if $obj.kind eq 'role' | 'prole';
$sub.set_body_of($obj);
$sub.set_in_class($obj);
@@ -599,7 +599,7 @@ method package_def ($/) {
else {
$/.CURSOR.trymop({ $obj.close; });
- if $obj.is_param_role {
+ if $obj.kind eq 'prole' {
# return the frame object so that role instantiation can
# find the cloned methods
$ast = ::Op::StatementList.new(|node($/), children => [
@@ -650,31 +650,31 @@ method do_new_package($/, :$sub = $*CURLEX<!sub>, :$scope!, :$name!, :$class!,
unless @linfo[0] eq 'package';
$old = @linfo[4];
} elsif defined $pkg {
- $old = $*unit.get($pkg, $head);
+ $old = $*unit.get($pkg.who, $head);
}
my $lexed_already;
- if $old && ($old.?type_kind // '') eq $class && !$old.closed {
+ if $old && ($old.?kind // '') eq $class && !$old.closed {
$npkg = $old;
$lexed_already = True;
} elsif $scope eq 'our' {
my $opkg = $pkg // $sub.cur_pkg;
$npkg = $*unit.create_type(name => $head, :$class,
who => $opkg.who ~ '::' ~ $head);
- $*unit.bind($opkg, $head, $npkg, |mnode($/));
+ $*unit.bind($opkg.who, $head, $npkg, |mnode($/));
} else {
my $id = $*unit.anon_stash;
$npkg = $*unit.create_type(name => $head, :$class,
who => "::$id");
- $*unit.bind($*unit.abs_pkg(), $id, $npkg, |mnode($/));
+ $*unit.bind("", $id, $npkg, |mnode($/));
}
$lexname = (!$lexed_already && $scope ne 'anon' && !defined($pkg))
?? $head !! self.gensym;
- $sub.add_my_stash($lexname, $npkg.xref, |mnode($/));
- $sub.add_exports($head, $npkg.xref, $exports) if $exports;
+ $sub.add_my_stash($lexname, $npkg, |mnode($/));
+ $sub.add_exports($head, $npkg, $exports) if $exports;
});
$lexname, $npkg

0 comments on commit 8a35c4f

Please sign in to comment.