diff --git a/README b/README
index 10ab5df..96fe515 100644
--- a/README
+++ b/README
@@ -1,8 +1,16 @@
-Partcl - a NQP-based implementation of Tcl
+partcl-nqp
-This is a proof of concept to reimplement partcl (tcl on parrot) using
-the latest compiler tools available for parrot.
+Tcl 8.5 on the parrot VM. This does not use the tcl C library, but is a from-
+scratch implementation using the Parrot Compiler Toolkit.
+
+"nqp" in the name comes from the "nqp-rx" toolkit. NQP is Not Quite Perl 6,
+and is a mini language that is much higher level than PIR. It also provides
+a nice interface to writing mini languages, making it much easier to implement
+the various mini languages inside tcl (globbing, regexen, binary)
See docs/todo.pod for a list of known issues.
See docs/overview.pod for information on how this version works.
+
+See http://github.com/partcl/partcl for the original non-PCT version that
+is more complete, but is only maintained to keep current with parrot changes.
diff --git a/docs/overview.pod b/docs/overview.pod
index 70f3df4..517b630 100644
--- a/docs/overview.pod
+++ b/docs/overview.pod
@@ -2,25 +2,26 @@
partcl-nqp is a tcl 8.5 compiler for the PVM (Parrot Virtual Machine).
-It uses the Parrot Compiler Toolkit (NQP-RX, HLL::Compiler) to generate
+It uses the Parrot Compiler Toolkit (nqp-rx, HLL::Compiler) to generate
PIR (Parrot Assembly), which is then compiled to PBC (Parrot Bytecode),
-which is then bundled into a "fakecutable".
+which is then bundled into a "fakecutable". The fakecutable contains the
+bytecode, and enough C to invoke the VM. It is NOT a JITted version.
-=head1 Architecture
+=head1 Languages
partcl-nqp is written primarily in NQP (Not Quite Perl 6; specifically
-NQP-R), with some PIR.
+nqp-rx), with as little PIR as we can manager.
=head2 Grammars and Actions
There are several Perl 6 Grammars in F; Partcl contains the main
language, src/ARE is the standard tcl regexes, etc.
-Each Grammar.pm file contains the rules (See Perl 6's Synopsis 5) for
-parsing that mini language. The Actions.pm file contains instructions to
+Each F file contains the rules (See Perl 6's Synopsis 5) for
+parsing that mini language. The F file contains instructions to
convert the parse into parrot's AST (Abstract Syntax Tree).
-The small Compiler.pm for each mini language takes advantage of the parrot
+The small F for each mini language takes advantage of the parrot
library to convert the AST to an OST (opcode syntax tree), which is then
converted to PIR, and finally PBC.
@@ -96,10 +97,9 @@ tests in this directory as a prelude to running the spec tests.
=head1 Alternate history
-There is a version of partcl written using PGE & TGE. That version has
+There is a version of partcl written using C & C. That version has
no active development but is maintained minimally so it compiles with the
latest version of parrot. Much of I version includes hand-translated
NQP based on the PIR from that version.
=cut
-
diff --git a/src/Partcl/commands/namespace.pm b/src/Partcl/commands/namespace.pm
index 35a89fc..a993406 100644
--- a/src/Partcl/commands/namespace.pm
+++ b/src/Partcl/commands/namespace.pm
@@ -1,50 +1,175 @@
our sub namespace(*@args) {
- if +@args < 1 {
+ Namespace::dispatch_command(|@args);
+}
+
+module Namespace;
+
+our %Arg_limits;
+our %funcs;
+our %Auto_vivify;
+
+INIT {
+
+ ## Negative limit in "max" position => unlimited.
+ %funcs := Namespace::children;
+ %Arg_limits := [ 0, 2, "?name? ?pattern?" ];
+
+ %funcs := Namespace::code;
+ %Arg_limits := [ 1, 1, "script" ];
+
+ %funcs := Namespace::current;
+ %Arg_limits := [ 0, 0, "" ];
+
+ %funcs := Namespace::delete;
+ %Arg_limits := [ 0, -1, "" ];
+
+ %funcs := Namespace::ensemble;
+ %Arg_limits := [ 1, 0, "subcommand ?arg...?" ];
+
+ %funcs := Namespace::eval;
+ %Arg_limits := [ 2, -1, "name arg ?arg...?" ];
+
+ %funcs := Namespace::exists;
+ %Arg_limits := [ 1, 1, "name" ];
+
+ %funcs := Namespace::export;
+ %Arg_limits := [ 0, 0, "namespace" ];
+
+ %funcs := Namespace::forget;
+ %Arg_limits := [ 0, 0, "namespace" ];
+
+ %funcs := Namespace::import;
+ %Arg_limits := [ 0, -1, "namespace" ];
+
+ %funcs := Namespace::inscope;
+ %Arg_limits := [ 0, 0, "namespace" ];
+
+ %funcs := Namespace::origin;
+ %Arg_limits := [ 0, 0, "namespace" ];
+
+ %funcs := Namespace::parent;
+ %Arg_limits := [ 0, 1, "?name?" ];
+
+ %funcs := Namespace::path;
+ %Arg_limits := [ 0, 1, "namespaceList" ];
+
+ %funcs := Namespace::qualifiers;
+ %Arg_limits := [ 1, 1, "string" ];
+
+ %funcs := Namespace::tail;
+ %Arg_limits := [ 1, 1, "string" ];
+
+ %funcs := Namespace::upvar;
+ %Arg_limits := [ 0, 0, "namespace" ];
+
+ %funcs := Namespace::unknown;
+ %Arg_limits := [ 0, 0, "namespace" ];
+
+ %funcs := Namespace::unknown;
+ %Arg_limits := [ 0, 0, "namespace" ];
+
+ %funcs := Namespace::which;
+ %Arg_limits := [ 0, 0, "namespace" ];
+}
+
+# Parses optional -args, and generates "wrong#args" errors
+# Dispatches to fairly normal NQP subs for the detailed work.
+our sub dispatch_command(*@args) {
+ my $num_args := +@args -1 ; # need option
+
+ if $num_args < 0 {
error('wrong # args: should be "namespace subcommand ?arg ...?"');
}
my @opts := ;
- my $cmd := _tcl::select_option(@opts, @args.shift() );
-
- if $cmd eq 'children' {
- return '';
- } elsif $cmd eq 'code' {
- return '';
- } elsif $cmd eq 'current' {
- return '';
- } elsif $cmd eq 'delete' {
- return '';
- } elsif $cmd eq 'ensemble' {
- return '';
- } elsif $cmd eq 'eval' {
- return '';
- } elsif $cmd eq 'exists' {
- return '';
- } elsif $cmd eq 'export' {
- return '';
- } elsif $cmd eq 'forget' {
- return '';
- } elsif $cmd eq 'import' {
- return '';
- } elsif $cmd eq 'inscope' {
- return '';
- } elsif $cmd eq 'origin' {
- return '';
- } elsif $cmd eq 'parent' {
- return '';
- } elsif $cmd eq 'path' {
- return '';
- } elsif $cmd eq 'qualifiers' {
- return '';
- } elsif $cmd eq 'tail' {
- return '';
- } elsif $cmd eq 'upvar' {
- return '';
- } elsif $cmd eq 'unknkown' {
- return '';
- } elsif $cmd eq 'which' {
- return '';
+ my $cmd := _tcl::select_option(@opts, @args.shift, 'option');
+
+ my @limits := %Arg_limits{$cmd};
+
+ if (@limits[1] >= 0 && $num_args > @limits[1]) || $num_args < @limits[0] {
+ my $msg := @limits[2];
+ $msg := " $msg" unless $msg eq '';
+ error("wrong # args: should be \"namespace $cmd$msg\"")
}
+
+ my &subcommand := %funcs{$cmd};
+ &subcommand(|@args);
}
+my sub children(*@args) {
+ '';
+}
+
+my sub code(*@args) {
+ '';
+}
+
+my sub current(*@args) {
+ '';
+}
+
+my sub delete(*@args) {
+ '';
+}
+
+my sub ensemble(*@args) {
+ '';
+}
+
+my sub eval(*@args) {
+ '';
+}
+
+my sub exists(*@args) {
+ '';
+}
+
+my sub export(*@args) {
+ '';
+}
+
+my sub forget(*@args) {
+ '';
+}
+
+my sub import(*@args) {
+ '';
+}
+
+my sub inscope(*@args) {
+ '';
+}
+
+my sub origin(*@args) {
+ '';
+}
+
+my sub parent(*@args) {
+ '';
+}
+
+my sub path(*@args) {
+ '';
+}
+
+my sub qualifiers(*@args) {
+ '';
+}
+
+my sub tail(*@args) {
+ '';
+}
+
+my sub upvar(*@args) {
+ '';
+}
+
+my sub unknown(*@args) {
+ '';
+}
+
+my sub which(*@args) {
+ '';
+}
+
# vim: filetype=perl6:
diff --git a/t/cmd_namespace.t b/t/cmd_namespace.t
index 6e78fb6..5e76d12 100755
--- a/t/cmd_namespace.t
+++ b/t/cmd_namespace.t
@@ -14,7 +14,7 @@ eval_is {namespace asdf} \
eval_is {namespace children a b c} \
{wrong # args: should be "namespace children ?name? ?pattern?"} \
- {namespace children: too many args} {TODO NQPRX}
+ {namespace children: too many args}
eval_is {namespace children what?} \
{namespace "what?" not found in "::"} \
@@ -38,11 +38,11 @@ is [namespace eval ::audreyt {namespace children}] ::audreyt::Matt \
eval_is {namespace qualifiers} \
{wrong # args: should be "namespace qualifiers string"} \
- {namespace qualifiers: no args} {TODO NQPRX}
+ {namespace qualifiers: no args}
eval_is {namespace qualifiers string string} \
{wrong # args: should be "namespace qualifiers string"} \
- {namespace qualifiers: too many args} {TODO NQPRX}
+ {namespace qualifiers: too many args}
is [namespace qualifiers ::a::b::c] ::a::b {namespace qualifiers: simple} {TODO NQPRX}
is [namespace qualifiers :::a:::b::c] :::a:::b {namespace qualifiers: extra colons} {TODO NQPRX}
@@ -50,11 +50,11 @@ is [namespace qualifiers :::a:::b::c] :::a:::b {namespace qualifiers: extra colo
eval_is {namespace tail} \
{wrong # args: should be "namespace tail string"} \
- {namespace tail: no args} {TODO NQPRX}
+ {namespace tail: no args}
eval_is {namespace tail string string} \
{wrong # args: should be "namespace tail string"} \
- {namespace tail: too many args} {TODO NQPRX}
+ {namespace tail: too many args}
is [namespace tail ::] {} {namespace tail: main}
is [namespace tail {}] {} {namespace tail: empty}
@@ -64,11 +64,11 @@ is [namespace tail :::foo:::bar:::baz] baz {namespace tail: extra colons} {TODO
eval_is {namespace exists} \
{wrong # args: should be "namespace exists name"} \
- {namespace exists: no args} {TODO NQPRX}
+ {namespace exists: no args}
eval_is {namespace exists a a} \
{wrong # args: should be "namespace exists name"} \
- {namespace exists: too many args} {TODO NQPRX}
+ {namespace exists: too many args}
eval_is {namespace exists a} 0 {namespace exists: failure} {TODO NQPRX}
is [namespace exists {}] 1 {namespace exists: global implicit} {TODO NQPRX}
@@ -77,7 +77,7 @@ is [namespace exists ::] 1 {namespace exists: global explicit} {TODO NQPRX}
eval_is {namespace eval foo} \
{wrong # args: should be "namespace eval name arg ?arg...?"} \
- {namespace eval: too few args} {TODO NQPRX}
+ {namespace eval: too few args}
namespace eval foo {
proc bar {} {return ok}
@@ -108,7 +108,7 @@ eval_is {namespace exists foo} 0 {namespace delete} {TODO NQPRX}
eval_is {namespace current foo} \
{wrong # args: should be "namespace current"} \
- {namespace current: too many args} {TODO NQPRX}
+ {namespace current: too many args}
is [namespace current] :: {namespace current: global} {TODO NQPRX}
is [namespace eval foo {namespace current}] ::foo {namespace current: ::foo} {TODO NQPRX}
@@ -116,7 +116,7 @@ is [namespace eval foo {namespace current}] ::foo {namespace current: ::foo} {TO
eval_is {namespace parent foo bar} \
{wrong # args: should be "namespace parent ?name?"} \
- {namespace parent: too many args} {TODO NQPRX}
+ {namespace parent: too many args}
is [namespace parent ""] {} {namespace parent: ::}
is [namespace parent foo] :: {namespace parent: ::foo (explicit)} {TODO NQPRX}