Skip to content

Commit

Permalink
Have a single file for each tcl builtin.
Browse files Browse the repository at this point in the history
(splits up control.pm, list.pm, and main.pm in the commands dir)
  • Loading branch information
coke committed Jul 18, 2010
1 parent 5fefe08 commit 5768bc2
Show file tree
Hide file tree
Showing 60 changed files with 1,275 additions and 418 deletions.
56 changes: 55 additions & 1 deletion build/Makefile.in
Expand Up @@ -27,18 +27,72 @@ GEN_SOURCES = \
src/Partcl/Compiler.pir \
src/Partcl/Grammar.pir \
src/Partcl/Operators.pir \
src/Partcl/commands/after.pir \
src/Partcl/commands/append.pir \
src/Partcl/commands/apply.pir \
src/Partcl/commands/array.pir \
src/Partcl/commands/control.pir \
src/Partcl/commands/binary.pir \
src/Partcl/commands/break.pir \
src/Partcl/commands/catch.pir \
src/Partcl/commands/cd.pir \
src/Partcl/commands/concat.pir \
src/Partcl/commands/continue.pir \
src/Partcl/commands/dict.pir \
src/Partcl/commands/eof.pir \
src/Partcl/commands/error.pir \
src/Partcl/commands/eval.pir \
src/Partcl/commands/exit.pir \
src/Partcl/commands/expr.pir \
src/Partcl/commands/fileevent.pir \
src/Partcl/commands/file.pir \
src/Partcl/commands/flush.pir \
src/Partcl/commands/foreach.pir \
src/Partcl/commands/format.pir \
src/Partcl/commands/for.pir \
src/Partcl/commands/gets.pir \
src/Partcl/commands/global.pir \
src/Partcl/commands/glob.pir \
src/Partcl/commands/if.pir \
src/Partcl/commands/incr.pir \
src/Partcl/commands/info.pir \
src/Partcl/commands/interp.pir \
src/Partcl/commands/join.pir \
src/Partcl/commands/lappend.pir \
src/Partcl/commands/lassign.pir \
src/Partcl/commands/lindex.pir \
src/Partcl/commands/linsert.pir \
src/Partcl/commands/list.pir \
src/Partcl/commands/llength.pir \
src/Partcl/commands/lrange.pir \
src/Partcl/commands/lrepeat.pir \
src/Partcl/commands/lreplace.pir \
src/Partcl/commands/lreverse.pir \
src/Partcl/commands/lset.pir \
src/Partcl/commands/lsort.pir \
src/Partcl/commands/main.pir \
src/Partcl/commands/namespace.pir \
src/Partcl/commands/package.pir \
src/Partcl/commands/proc.pir \
src/Partcl/commands/puts.pir \
src/Partcl/commands/pwd.pir \
src/Partcl/commands/regexp.pir \
src/Partcl/commands/rename.pir \
src/Partcl/commands/return.pir \
src/Partcl/commands/set.pir \
src/Partcl/commands/socket.pir \
src/Partcl/commands/source.pir \
src/Partcl/commands/split.pir \
src/Partcl/commands/string.pir \
src/Partcl/commands/subst.pir \
src/Partcl/commands/switch.pir \
src/Partcl/commands/time.pir \
src/Partcl/commands/trace.pir \
src/Partcl/commands/unset.pir \
src/Partcl/commands/uplevel.pir \
src/Partcl/commands/upvar.pir \
src/Partcl/commands/variable.pir \
src/Partcl/commands/vwait.pir \
src/Partcl/commands/while.pir \
src/TclArray.pir \
src/TclLexPad.pir \
src/TclList.pir \
Expand Down
58 changes: 56 additions & 2 deletions src/Partcl.pir
Expand Up @@ -40,18 +40,72 @@
.include 'src/Partcl/Actions.pir'
.include 'src/Partcl/Compiler.pir'
.include 'src/Partcl/Operators.pir'
.include 'src/Partcl/commands/control.pir'
.include 'src/Partcl/commands/main.pir'
.include 'src/Partcl/commands/after.pir'
.include 'src/Partcl/commands/append.pir'
.include 'src/Partcl/commands/apply.pir'
.include 'src/Partcl/commands/array.pir'
.include 'src/Partcl/commands/binary.pir'
.include 'src/Partcl/commands/break.pir'
.include 'src/Partcl/commands/catch.pir'
.include 'src/Partcl/commands/cd.pir'
.include 'src/Partcl/commands/concat.pir'
.include 'src/Partcl/commands/continue.pir'
.include 'src/Partcl/commands/dict.pir'
.include 'src/Partcl/commands/eof.pir'
.include 'src/Partcl/commands/error.pir'
.include 'src/Partcl/commands/eval.pir'
.include 'src/Partcl/commands/exit.pir'
.include 'src/Partcl/commands/expr.pir'
.include 'src/Partcl/commands/fileevent.pir'
.include 'src/Partcl/commands/file.pir'
.include 'src/Partcl/commands/flush.pir'
.include 'src/Partcl/commands/foreach.pir'
.include 'src/Partcl/commands/format.pir'
.include 'src/Partcl/commands/for.pir'
.include 'src/Partcl/commands/gets.pir'
.include 'src/Partcl/commands/global.pir'
.include 'src/Partcl/commands/glob.pir'
.include 'src/Partcl/commands/if.pir'
.include 'src/Partcl/commands/incr.pir'
.include 'src/Partcl/commands/info.pir'
.include 'src/Partcl/commands/interp.pir'
.include 'src/Partcl/commands/join.pir'
.include 'src/Partcl/commands/lappend.pir'
.include 'src/Partcl/commands/lassign.pir'
.include 'src/Partcl/commands/lindex.pir'
.include 'src/Partcl/commands/linsert.pir'
.include 'src/Partcl/commands/list.pir'
.include 'src/Partcl/commands/llength.pir'
.include 'src/Partcl/commands/lrange.pir'
.include 'src/Partcl/commands/lrepeat.pir'
.include 'src/Partcl/commands/lreplace.pir'
.include 'src/Partcl/commands/lreverse.pir'
.include 'src/Partcl/commands/lset.pir'
.include 'src/Partcl/commands/lsort.pir'
.include 'src/Partcl/commands/main.pir'
.include 'src/Partcl/commands/namespace.pir'
.include 'src/Partcl/commands/package.pir'
.include 'src/Partcl/commands/proc.pir'
.include 'src/Partcl/commands/puts.pir'
.include 'src/Partcl/commands/pwd.pir'
.include 'src/Partcl/commands/regexp.pir'
.include 'src/Partcl/commands/rename.pir'
.include 'src/Partcl/commands/return.pir'
.include 'src/Partcl/commands/set.pir'
.include 'src/Partcl/commands/socket.pir'
.include 'src/Partcl/commands/source.pir'
.include 'src/Partcl/commands/split.pir'
.include 'src/Partcl/commands/string.pir'
.include 'src/Partcl/commands/subst.pir'
.include 'src/Partcl/commands/switch.pir'
.include 'src/Partcl/commands/time.pir'
.include 'src/Partcl/commands/trace.pir'
.include 'src/Partcl/commands/unset.pir'
.include 'src/Partcl/commands/uplevel.pir'
.include 'src/Partcl/commands/upvar.pir'
.include 'src/Partcl/commands/variable.pir'
.include 'src/Partcl/commands/vwait.pir'
.include 'src/Partcl/commands/while.pir'
.include 'src/TclArray.pir'
.include 'src/TclLexPad.pir'
.include 'src/TclList.pir'
Expand Down
7 changes: 7 additions & 0 deletions src/Partcl/commands/after.pm
@@ -0,0 +1,7 @@
our sub after(*@args) {
if +@args < 1 {
error('wrong # args: should be "after option ?arg arg ...?"')
}
pir::sleep__vN(+@args[0] / 1000);
'';
}
30 changes: 30 additions & 0 deletions src/Partcl/commands/append.pm
@@ -0,0 +1,30 @@
our sub append(*@args) {
if +@args < 1 {
error('wrong # args: should be "append varName ?value value ...?"');
}

my $varName := @args.shift;

my $var;

# XXX bug compatibility - tcl errors if the var doesn't exist and there
# is nothing to append. See test file for ticket #.

if !+@args {
$var := set($varName);
} else {
$var := Q:PIR {
.local pmc varname, lexpad
varname = find_lex '$varName'
lexpad = find_dynamic_lex '%LEXPAD'
%r = vivify lexpad, varname, ['TclString']
};
}
my $result := set($varName);
while @args {
$result := ~$result ~ @args.shift;
}

set($varName, $result);
}
6 changes: 6 additions & 0 deletions src/Partcl/commands/apply.pm
@@ -0,0 +1,6 @@
our sub apply(*@args) {
if +@args == 0 {
error('wrong # args: should be "apply lambdaExpr ?arg1 arg2 ...?"');
}
'';
}
23 changes: 23 additions & 0 deletions src/Partcl/commands/binary.pm
@@ -0,0 +1,23 @@
our sub binary(*@args) {
error('wrong # args: should be "binary option ?arg arg ...?"')
if !+@args;

my $subcommand := @args.shift();
if $subcommand eq 'format' {
if +@args < 1 {
error('wrong # args: should be "binary format formatString ?arg arg ...?"');
}
} elsif $subcommand eq 'scan' {
if +@args < 2 {
error('wrong # args: should be "binary scan value formatString ?varName varName ...?"');
}
my $value := @args.shift();
my $formatString := @args.shift();
for @args -> $varName {
set($varName, ''); # XXX placeholder
}
} else {
error("bad option \"$subcommand\": must be format or scan");
}
'';
}
14 changes: 14 additions & 0 deletions src/Partcl/commands/break.pm
@@ -0,0 +1,14 @@
## use bare block to avoid catching control exceptions

INIT {
GLOBAL::break := -> *@args {
if +@args {
error('wrong # args: should be "break"');
}
my $exception := pir::new__ps('Exception');
$exception<type> := 65; # TCL_BREAK / CONTROL_LOOP_LAST
pir::throw($exception);
}
}

# vim: filetype=perl6:
36 changes: 36 additions & 0 deletions src/Partcl/commands/catch.pm
@@ -0,0 +1,36 @@
our sub catch(*@args) {
if +@args < 1 || +@args > 2 {
error('wrong # args: should be "catch script ?resultVarName? ?optionVarName?"');
}
my $code := @args[0];

my $retval := 0; # TCL_OK
my $result;
try {
$result := Partcl::Compiler.eval($code);
CATCH {
$retval := 1; # TCL_ERROR
$result := $!<message>;
}
CONTROL {
my $parrot_type := $!<type>;

# XXX using numeric type ids is fragile.
if $parrot_type == 57 { # CONTROL_RETURN
$retval := 2; # TCL_RETURN
} elsif $parrot_type == 65 { # CONTROL_LOOP_LAST
$retval := 3; # TCL_BREAK
} elsif $parrot_type == 64 { # CONTROL_LOOP_NEXT
$retval := 4; # TCL_CONTINUE
} else {
# This isn't a standard tcl control type. Give up.
pir::rethrow($!);
}
$result := $!<message>;
}
};
if +@args == 2 {
set(@args[1], $result);
}
$retval;
}
14 changes: 14 additions & 0 deletions src/Partcl/commands/cd.pm
@@ -0,0 +1,14 @@
# TODO: implement ~user syntax
our sub cd(*@args) {
if +@args > 1 {
error('wrong # args: should be "cd ?dirName?"');
}
my $dir;
if @args == 1 {
$dir := @args[0];
} else {
$dir := pir::new__ps('Env')<HOME>;
}
my $OS := pir::new__ps('OS');
$OS.chdir($dir);
}
7 changes: 7 additions & 0 deletions src/Partcl/commands/concat.pm
@@ -0,0 +1,7 @@
our sub concat(*@args) {
my $result := @args ?? String::trim(@args.shift) !! '';
while @args {
$result := $result ~ ' ' ~ String::trim(@args.shift);
}
$result;
}
11 changes: 11 additions & 0 deletions src/Partcl/commands/continue.pm
@@ -0,0 +1,11 @@
## use bare block to avoid catching control exceptions

INIT {
GLOBAL::continue := -> $message = '' {
my $exception := pir::new__ps('Exception');
$exception<type> := 64; # TCL_CONTINUE / CONTROL_LOOP_NEXT
pir::throw($exception);
}
}

# vim: filetype=perl6:
54 changes: 0 additions & 54 deletions src/Partcl/commands/control.pm

This file was deleted.

7 changes: 7 additions & 0 deletions src/Partcl/commands/eof.pm
@@ -0,0 +1,7 @@
our sub eof(*@args) {
if +@args != 1 {
error('wrong # args: should be "eof channelId"')
}
my $chan := _getChannel(@args[0]);
0;
}
27 changes: 27 additions & 0 deletions src/Partcl/commands/error.pm
@@ -0,0 +1,27 @@
## use bare block to avoid catching control exceptions

INIT {
GLOBAL::error := -> *@args {
my $message := '';
if +@args < 1 || +@args > 3 {
$message := 'wrong # args: should be "error message ?errorInfo? ?errorCode?"';
} else {
$message := @args[0];
}

if +@args >= 2 {
our %GLOBALS;
%GLOBALS<errorInfo> := @args[1];
my $errorCode := @args[2] // 'NONE';
%GLOBALS<errorCode> := $errorCode;
}

my $exception := pir::new__ps('Exception');
# use EXCEPTION_SYNTAX_ERROR - just a generic type
$exception<type> := 55;
$exception<message> := $message;
pir::throw($exception);
}
}

# vim: filetype=perl6:

0 comments on commit 5768bc2

Please sign in to comment.