Author: leo
Date: Wed Aug 10 01:29:12 2005
New Revision: 8900
Added:
branches/leo-ctx5/languages/tcl/t/cmd_switch.t (props changed)
- copied unchanged from r8899, trunk/languages/tcl/t/cmd_switch.t
Modified:
branches/leo-ctx5/MANIFEST
branches/leo-ctx5/build_tools/parrotdef.pl
branches/leo-ctx5/config/gen/makefiles/m4.in
branches/leo-ctx5/config/init/data.pl
branches/leo-ctx5/docs/intro.pod
branches/leo-ctx5/editor/pir-mode.el
branches/leo-ctx5/languages/m4/t/basic/003_getopt.t
branches/leo-ctx5/languages/m4/t/basic/012_eval.t
branches/leo-ctx5/languages/m4/t/builtins/010_sysval.t
branches/leo-ctx5/languages/m4/t/freezing/002_many_files.t
branches/leo-ctx5/languages/tcl/TODO
branches/leo-ctx5/languages/tcl/lib/commands/array.pir
branches/leo-ctx5/languages/tcl/lib/commands/for.pir
branches/leo-ctx5/languages/tcl/lib/commands/if.pir
branches/leo-ctx5/languages/tcl/lib/commands/proc.pir
branches/leo-ctx5/languages/tcl/lib/commands/while.pir
branches/leo-ctx5/languages/tcl/lib/expression.pir
branches/leo-ctx5/languages/tcl/t/cmd_array.t
branches/leo-ctx5/languages/tcl/t/cmd_list.t
branches/leo-ctx5/languages/tcl/t/cmd_proc.t
Log:
merge -r8884:8899 from trunk
Modified: branches/leo-ctx5/MANIFEST
==============================================================================
--- branches/leo-ctx5/MANIFEST (original)
+++ branches/leo-ctx5/MANIFEST Wed Aug 10 01:29:12 2005
@@ -1465,6 +1465,7 @@ languages/tcl/t/cmd_return.t
languages/tcl/t/cmd_set.t [tcl]
languages/tcl/t/cmd_source.t [tcl]
languages/tcl/t/cmd_string.t [tcl]
+languages/tcl/t/cmd_switch.t [tcl]
languages/tcl/t/cmd_time.t [tcl]
languages/tcl/t/cmd_unset.t [tcl]
languages/tcl/t/cmd_while.t [tcl]
Modified: branches/leo-ctx5/build_tools/parrotdef.pl
==============================================================================
--- branches/leo-ctx5/build_tools/parrotdef.pl (original)
+++ branches/leo-ctx5/build_tools/parrotdef.pl Wed Aug 10 01:29:12 2005
@@ -244,7 +244,7 @@ my @funcnames = qw(
scratchpad_store_by_index
scratchpad_get_current
lexicals_mark
- scratchpad_delete
+ scratchpad_delete
Parrot_register_HLL
Parrot_register_HLL_type
Parrot_get_HLL_id
@@ -269,6 +269,8 @@ my @funcnames = qw(
Parrot_call_method
string_replace
Parrot_make_COW_reference
+ Parrot_switch_to_cs
+ PackFile_Segment_new_seg
);
push @funcnames, "PMCNULL DATA";
push @funcnames, "Parrot_base_vtables DATA";
Modified: branches/leo-ctx5/config/gen/makefiles/m4.in
==============================================================================
--- branches/leo-ctx5/config/gen/makefiles/m4.in (original)
+++ branches/leo-ctx5/config/gen/makefiles/m4.in Wed Aug 10 01:29:12 2005
@@ -19,6 +19,8 @@ WARN = ${ccwarn}
LD = ${ld}
LDFLAGS = ${ldflags}
LD_SHARE_FLAGS = ${ld_share_flags} # e.g. -shared
+#CONDITIONED_LINE(parrot_exe_def):LIBPARROT = ${build_dir}/parrot${a}
+#INVERSE_CONDITIONED_LINE(parrot_exe_def):LIBPARROT =
# some constants
M4_EVAL_COMPILER_SO =
..${slash}..${slash}runtime${slash}parrot${slash}dynext${slash}m4_eval_compiler${share_ext}
@@ -56,7 +58,7 @@ m4.pbc: src/m4.pir
$(M4_EVAL_COMPILER_SO): src/eval.c
$(CC) $(CFLAGS) $(CC_SHARED) $(DEBUG) $(WARN) -c src/eval.c
- $(LD) $(LD_SHARE_FLAGS) $(LDFLAGS) ${ld_out}$@ eval$(O)
+ $(LD) $(LD_SHARE_FLAGS) $(LDFLAGS) ${ld_out}$@ eval$(O) $(LIBPARROT)
src/m4.pir: src/builtin.pir src/freeze.pir src/input.pir src/macro.pir
src/output.pir
touch $@
Modified: branches/leo-ctx5/config/init/data.pl
==============================================================================
--- branches/leo-ctx5/config/init/data.pl (original)
+++ branches/leo-ctx5/config/init/data.pl Wed Aug 10 01:29:12 2005
@@ -137,6 +137,8 @@ sub runstep {
cp => 'cp',
lns => $Config{lns}, # soft link
+ # On all platform slash == slash_exec, except with MinGW
+ # slash_exec is needed by pathname of executable in test or makefile
slash => '/',
slash_exec => '/',
Modified: branches/leo-ctx5/docs/intro.pod
==============================================================================
--- branches/leo-ctx5/docs/intro.pod (original)
+++ branches/leo-ctx5/docs/intro.pod Wed Aug 10 01:29:12 2005
@@ -1,4 +1,4 @@
-# Copyright: 2001-2004 The Perl Foundation. All Rights Reserved.
+# Copyright: 2001-2005 The Perl Foundation. All Rights Reserved.
# $Id$
=head1 NAME
@@ -7,419 +7,415 @@ docs/intro.pod - The Parrot Primer
=head1 Welcome to Parrot
-This is an update to the article 'Parrot: Some Assembly Required'
-which appeared on http://www.perl.com for the 0.0.2 release of Parrot. It's
-intended as being the best way for the newcomer to Parrot to learn
-what Parrot is and how to use it.
+This document provides a gentle introduction to the Parrot virtual machine for
+anyone considering writing code for Parrot by hand, writing a compiler that
+targets Parrot, getting involved with Parrot development or simply wondering
+what on earth Parrot is.
=head1 What is Parrot?
-First, though, what is Parrot, and why are we making such a fuss about
-it? Well, if you haven't been living in a box for the past years, you'll
-know that the Perl community has embarked on the design and
-implementation of a new version of Perl, both the language and the
-interpreter.
-
-Parrot is related to Perl 6, but it is not Perl 6. To find out
-what it actually is, we need to know a little about how Perl works.
-When you feed your program into C<perl>, it is first compiled into an
-internal representation, or bytecode; then this bytecode is fed to an
-almost separate subsystem inside C<perl> to be interpreted. So there
-are two distinct phases of C<perl>'s operation - compilation to
-bytecode, and interpretation of bytecode. This is not unique to Perl;
-other languages following this design include Python, Ruby, Tcl and,
-believe it or not, even Java.
-
-In previous versions of Perl, this arrangement has been pretty I<ad
-hoc>: there hasn't been any overarching design to the interpreter or
-the compiler, and the interpreter has ended up being pretty reliant on
-certain features of the compiler. Nevertheless, the interpreter (some
-languages call it a Virtual Machine) can be thought of as a software
-CPU - the compiler produces "machine code" instructions for the virtual
-machine, which it then executes, much like a C compiler produces
-machine code to be run on a real CPU.
-
-Perl 6 plans to separate out the design of the compiler and the
-interpreter. This is why we've come up with a subproject, which we've
-called Parrot, which has a certain, limited amount of independence from
-Perl 6. Parrot is destined to be the Perl 6 Virtual Machine, the
-software CPU on which we will run Perl 6 bytecode. We're working on
-Parrot before we work on the Perl 6 compiler because it's much easier
-to write a compiler once you've got a target to compile to!
-
-The name "Parrot" was chosen after the 2001 April Fool's Joke which
-had Perl and Python collaborating on the next version of their
-interpreters. This is meant to reflect the idea that we'd eventually
-like other languages to use Parrot as their VM; in a sense, we'd like
-Parrot to become a "common language runtime" for dynamic languages.
-
-=head2 Where we're at
-
-It should be stressed we're still in the early stages of
-development.
-
-But don't let that put you off! Parrot is still very much usable; we've already
-a lot of languages (in different state of completeness) which compile down to
-Parrot bytecode. Please have a look at the F<languages/> subdirectory.
-
-At the moment, it's possible to write simple programs in Parrot
-assembly language, use an assembler to convert them to machine code and
-then execute them on a test interpreter. We have support for a wide
-variety of ordinary and transcendental mathematical operations, some
-rudimentary string support, and some conditional operators.
-
-=head2 How to get it
-
-So let's get ourselves a copy of Parrot, so that we can start
-investigating how to program in the Parrot assembler.
-
-Periodic, numbered releases will appear on CPAN (we're currently on
-version 0.2.3), but at this stage of the project an awful lot is
-changing between releases. To really keep up to date with Parrot,
-we should get our copy from the SVN repository. Here's how we do that:
+=head2 Virtual Machines
+
+Parrot is a virtual machine. To understand what a virtual machine is, consider
+what happens when you write a program in a language such as Perl, the run it
+with the applicable interpreter (in the case of Perl, the perl executable).
+First, the program you have written in a high level language is turned into
+simple instructions, for example I<fetch the value of the variable named x>,
+I<add 2 to this value>, I<store this value in the variable named y>, etc. A
+single line of code in a high level language may be converted into tens of
these
+simple instructions. This stage is called I<compilation>.
+
+The second stage involves executing these simple instructions. Some languages
+(for example, C) are often compiled to instructions that are understood by the
+CPU and as such can be executed by the hardware. Other languages, such as Perl,
+Python and Java, are usually compiled to CPU-independent instructions. A
+I<virtual machine> (sometimes known as an I<interpreter>) is required to
+execute those instructions.
+
+While the central role of a virtual machine is to efficiently execute
+instructions, it also performs a number of other functions. One of these is to
+abstract away the details of the hardware and operating system that a program
is
+running on. Once a program has been compiled to run on a virtual machine, it
+will run on any platform that the VM has been implemented on. VMs may also
+provide security by allowing more fine-grained limitations to be placed on a
+program, memory management functionality and support for high level language
+features (such as objects, data structures, types, subroutines, etc).
+
+=head2 Design goals
+
+Parrot is designed with the needs of dynamically typed languages (such as Perl
+and Python) in mind, and should be able to run programs written in these
+languages more efficiently than VMs developed with static languages in mind
(JVM,
+.NET). Parrot is also designed to provide interoperability between languages
that
+compile to it. In theory, you will be able to write a class in Perl, subclass
it
+in Python and then instantiate and use that subclass in a Tcl program.
+
+Historically, Parrot started out as the runtime for Perl 6. Unlike Perl 5, the
+Perl 6 compiler and runtime (VM) are to be much more clearly separated. The
name
+I<Parrot> was chosen after the 2001 April Fool's Joke which had Perl and Python
+collaborating on the next version of their languages. The name reflects the
+intention to build a VM to run not just Perl 6, but also many other languages.
+
+
+=head1 Parrot concepts and jargon
+
+=head2 Instruction formats
+
+Parrot can currently accept instructions to execute in four forms. PIR (Parrot
+Intermediate Representation) is designed to be written by people and generated
+by compilers. It hides away some low-level details, such as the way parameters
+are passed to functions. PASM (Parrot Assembly) is a level below PIR - it is
+still human readable/writable and can be generated by a compiler, but the
author
+has to take care of details such as calling conventions and register spilling.
+PAST (Parrot Abstract Syntax Tree) enables Parrot to accept an abstract syntax
+tree style input - useful for those writing compilers.
+
+All of the above forms of input are automatically converted inside Parrot to
PBC
+(Parrot Bytecode). This is much like machine code, but understood by the Parrot
+interpreter. It is not intended to be human-readable or human-writable, but
+unlike the other forms execution can start immediately, without the need for an
+assembly phase. Parrot bytecode is platform independent.
+
+=head2 The instruction set
+
+The Parrot instruction set includes arithmetic and logical operators, compare
+and branch/jump (for implementing loops, if...then constructs, etc), finding
and
+storing global and lexical variables, working with classes and objects, calling
+subroutines and methods along with their parameters, I/O, threads and more.
+
+=head2 Registers and fundamental data types
+
+The Parrot VM is register based. This means that, like a hardware CPU, it has a
+number of fast-access units of storage called registers. There are 4 types of
+register in Parrot: integers (I), numbers (N), strings (S) and PMCs (P). There
+are 32 of each of these, named I0..I31, N0..N31, etc. Integer registers are the
+same size as a word on the machine Parrot is running on and number registers
also
+map to a native floating point type.
+
+=head2 PMCs
+
+PMC stands for Parrot Magic Cookie. PMCs represent any complex data structure
or
+type, including aggregate data types (arrays, hash tables, etc). A PMC can
+implement its own behaviour for arithmetic, logical and string operations
+performed on it, allowing for language-specific behaviour to be introduced.
PMCs
+can be built in to the Parrot executable or dynamically loaded when they are
+needed.
+
+=head2 Garbage Collection
+
+Parrot provides garbage collection, meaning that Parrot programs to do not need
+to free memory explicitly; it will be freed when it is no longer in use (that
is,
+no longer referenced) whenever the garbage collector runs.
+
+
+=head1 Obtaining, building and testing Parrot
+
+=head2 Where to get Parrot
+
+Periodic, numbered releases will appear on CPAN. At this stage of the project,
+an awful lot is changing between releases. You can get a copy of the latest
+Parrot from the SVN repository. This is done as follows:
svn co https://svn.perl.org/parrot/trunk parrot
You can find more instructions at: http://www.parrotcode.org/source.html
-Now we have downloaded Parrot, we need to build it; so:
-
- % cd parrot
- % perl Configure.pl
- Parrot Configure
- Copyright (C) 2001-2003 The Perl Foundation. All Rights Reserved.
-
- Since you're running this script, you obviously have
- Perl 5--I'll be pulling some defaults from its configuration.
- ...
-
-The Configure script will then attempt to discover your local
-configuration automatically; you can supply the --ask switch if
-you wish to configure the build manually. You might also have a
-look at:
-
- % perl Configure.pl --help
-
-Once Configure has finished successfully, type C<make> (or the name of your
-local C<make> program). With any luck, Parrot will successfully build. (If it
-doesn't, the address to complain to is at the end of this introduction...)
-
-=head2 The test suite
-
-Now we should run some tests; so type C<make test> and you should see a
-readout like the following:
-
- perl t/harness --gc-debug --running-make-test -b t/op/*.t t/pmc/*.t \
- t/native_pbc/*.t imcc/t/*/*.t t/src/*.t
- t/op/00ff-dos...........ok
- t/op/00ff-unix..........ok
- ...
- All tests successful, 40 subtests skipped.
- Files=95, Tests=1386, 125 wallclock secs (56.96 cusr + 23.71 csys = 80.67 CPU)
-
-(Of course, there might be more tests than this, but you get the idea;
-tests may be skipped - for one reason or another - but none of them should
-fail!)
-
-=head2 Reporting Problems
-
-If you have problems with parrot, please send a message to
[EMAIL PROTECTED] with a description of your problem. Please
-include the myconfig file that was generated as part of the build
-process.
-
-=head1 Parrot Concepts
-
-Before we dive into programming Parrot assembly, let's take a brief
-look at some of the concepts involved.
-
-=head2 Types
-
-The Parrot CPU has four basic data types:
-
-=over 4
-
-=item C<INTVAL>
-
-An integer type; guaranteed to be wide enough to hold a pointer.
-
-=item C<FLOATVAL>
-
-An architecture-independent floating point type.
-
-=item C<STRING>
-
-An abstracted, encoding-independent string type.
-
-=item C<PMC>
-
-Other types like a (perl) scalar or an array.
-
-=back
-
-The first three types are pretty much self-explanatory; the final
-type, Parrot Magic Cookies, are slightly more difficult to understand.
-But that's OK! We'll talk more about PMCs at the end of the article.
-
-=head2 Registers
-
-The current Perl 5 virtual machine is a stack machine - it communicates
-values between operations by keeping them on a stack. Operations load
-values onto the stack, do whatever they need to do, and put the result
-back onto the stack. This is very easy to work with, but it's very
-slow: to add two numbers together, you need to perform three stack
-pushes and two stack pops. Worse, the stack has to grow at runtime, and
-that means allocating memory just when you don't want to be allocating
-it.
-
-So Parrot's going to break with the established tradition for virtual
-machines, and use a register architecture, more akin to the
-architecture of a real hardware CPU. This has another advantage: we can
-use all the existing literature on how to write compilers and
-optimizers for register-based CPUs for our software CPU!
-
-Parrot has specialist registers for each type: 32 INTVAL registers,
-32 FLOATVAL registers, 32 string registers and 32 PMC registers. In Parrot
-assembler, these are named C<I0>...C<I31>, C<N0>...C<N31>,
-C<S0>...C<S31>, C<P0>...C<P31>.
-
-Now let's look at some assembler. We can set these registers with the
-C<set> operator:
-
- set I1, 10
- set N1, 3.1415
- set S1, "Hello, Parrot"
-
-
-All Parrot ops have the same format: the name of the operator, the
-destination register, and then the operands.
-
-=head2 Operations
-
-There are a variety of operations you can perform: the file
-F<docs/core_ops.pod> documents them, along with a little more
-about the assembler syntax. For instance, we can print out the contents
-of a register, or a constant:
-
- print "The contents of register I1 is: "
- print I1
- print "\n"
-
-
-Or we can perform mathematical functions on registers:
-
- add I1, I1, I2 # Add the contents of I2 to the contents of I1
- mul I3, I2, I4 # Multiply I2 by I4 and store in I3
- inc I1 # Increment I1 by one
- dec N3, 1.5 # Decrement N3 by 1.5
-
-
-We can even perform some simple string manipulation:
-
- set S1, "fish"
- set S2, "bone"
- concat S1, S2 # S1 is now "fishbone"
- substr S4, S1, 0, 1, "w" # S1 is now "wishbone"
- length I1, S1 # I1 is 8
- end
+=head2 Building Parrot
-=head2 Branches
+The first step to building Parrot is to run the F<Configure.pl> program, which
+looks at your platform and decides how Parrot should be built. This is done by
+typing:
+
+ perl Configure.pl
+
+Once this is complete, run the C<make> program (sometimes called C<nmake> or
+C<dmake>). This should complete, giving you a working Parrot executable.
+
+Please report any problems that you encounter while building Parrot so the
+developers can fix them. You can do this by sending a message to
+L<[EMAIL PROTECTED]> containing a description of your problem. Please
+include the F<myconfig> file that was generated as part of the build process
and
+any errors that you observed.
+
+=head2 The Parrot test suite
+
+Parrot has an extensive regression test suite. This can be run by typing:
+
+ make test
+
+Substituting make for the name of the make program on your platform. The output
+will look something like this:
+
+ C:\Perl\bin\perl.exe t\harness --gc-debug --running-make-test
+ t\library\*.t t\op\*.t t\pmc\*.t t\run\*.t t\native_pbc\*.t
+ imcc\t\*\*.t t\dynclass\*.t t\p6rules\*.t t\src\*.t t\perl\*.t
+ t\library\dumper...............ok
+ t\library\getopt_long..........ok
+ ...
+ All tests successful, 4 test and 71 subtests skipped.
+ Files=163, Tests=2719, 192 wallclock secs ( 0.00 cusr + 0.00 csys = 0.00
CPU)
+
+It is possible that a number of tests may fail. If this is a small number, then
+it is probably little to worry about, especially if you have the latest Parrot
+from the SVN repository. However, please do not let this discourage you from
+reporting test failures, using the same method as described for reporting build
+problems.
+
+
+=head1 Some simple Parrot programs
+
+=head2 Hello world!
+
+Create a file called F<hello.pir> that contains the following code.
+
+ .sub _main
+ print "Hello world!\n"
+ end
+ .end
+
+Then run it by typing:
+
+ parrot hello.pir
+
+As expected, this will display the text C<Hello world!> on the console,
followed
+by a new line (due to the C<\n>).
+
+Let's take the program apart. C<.sub _main> states that the instructions that
+follow make up a subroutine named C<_main>, until a C<.end> is encountered. The
+second line contains the C<print> instruction. In this case, we are calling the
+variant of the instruction that accepts a constant string. The assembler takes
+care of deciding which variant of the instruction to use for us. The third line
+contains the C<end> instruction, which causes the interpreter to terminate.
+
+=head2 Using registers
+
+We can modify hello.pir to first store the string C<Hello world!\n> in a
+register and then use that register with the print instruction.
+
+ .sub _main
+ set S0, "Hello world!\n"
+ print S0
+ end
+ .end
+
+Here we have stated exactly which register to use. However, by replacing C<S0>
+with C<$S0> we can delegate the choice of which register to use to Parrot, and
+itwill take care of any register spilling that needs to be done for us. It is
+also possible to use an C<=> notation instead of writing the C<set>
instruction.
+
+ .sub _main
+ $S0 = "Hello world!\n"
+ print $S0
+ end
+ .end
+
+To make PIR even more readable, named registers can be used. These are later
+mapped to real numbered registers.
+
+ .sub _main
+ .local string hello
+ hello = "Hello world!\n"
+ print hello
+ end
+ .end
+
+The C<.local> directive indicates that the named register is only needed inside
+the current compilation unit (that is, between C<.sub> and C<.end>). Following
+C<.local> is a type. This can be C<int> (for I registers), C<float> (for N
+registers), C<string> (for S registers), C<pmc> (for P registers) or the name
+of a PMC type.
+
+=head2 PIR vs PASM
+
+PIR can be turned into PASM by running:
+
+ parrot -o hello.pasm hello.pir
+
+The PASM for the final example looks like this:
+
+ _main:
+ set S30, "Hello world!\n"
+ print S30
+ end
+
+PASM does not handle register allocation or provide support for named
registers.
+It also does not have the C<.sub> and C<.end> directives, instead replacing
them
+with a label at the start of the instructions.
+
+=head2 Summing squares
+
+This example introduces some more instructions and PIR syntax. Lines starting
+with a C<#> are comments.
+
+ .sub _main
+ # State the number of squares to sum.
+ .local int maxnum
+ maxnum = 10
+
+ # Some named registers we'll use. Note how we can declare many
+ # registers of the same type on one line.
+ .local int i, total, temp
+ total = 0
+
+ # Loop to do the sum.
+ i = 1
+ loop:
+ temp = i * i
+ total += temp
+ inc i
+ if i <= maxnum goto loop
+
+ # Output result.
+ print "The sum of the first "
+ print maxnum
+ print " squares is "
+ print total
+ print ".\n"
+ end
+ .end
+
+PIR provides a bit of syntactic sugar that makes it look more high level than
+assembly. For example:
+
+ temp = i * i
+
+Is just another way of writing the more assembly-ish:
+
+ mul temp, i, i
+
+And:
+
+ if i <= maxnum goto loop
+
+Is the same as:
+
+ le i, maxnum, loop
+
+And:
+
+ total += temp
+
+Is the same as:
+
+ add total, temp
+
+As a rule, whenever a Parrot instruction modifies the contents of a register,
+that will be the first register when writing the instruction in assembly form.
+
+As is usual in assembly languages, loops and selection are implemented in terms
+of conditional branch statements and labels, as shown above. Assembly
programming
+is one place where using goto is not bad form!
+
+=head2 Recursively computing factorial
+
+In this example we define a factorial function and recursively call it to
+compute factorial.
+
+ .sub _fact
+ # Get input parameter.
+ .param int n
+
+ # return (n > 1 ? n * _fact(n - 1) : 1)
+ .local int result
+
+ if n > 1 goto recurse
+ result = 1
+ goto return
+
+ recurse:
+ $I0 = n - 1
+ result = _fact($I0)
+ result *= n
+
+ return:
+ .return (result)
+ .end
+
+
+ .sub _main @MAIN
+ .local int f, i
+
+ # We'll do factorial 0 to 1.
+ i = 0
+ loop:
+ f = _fact(i)
+
+ print "Factorial of "
+ print i
+ print " is "
+ print f
+ print ".\n"
+
+ inc i
+ if i <= 10 goto loop
+
+ # That's it.
+ end
+ .end
+
+Let's look at the C<_fact> sub first. A point that was glossed over earlier is
+why the names of subroutines all start with an underscore. This is done simply
+as a way of showing that the label is global rather than scoped to a particular
+subroutine. This is significant as the label is then visible to other
+subroutines.
+
+The first line, C<.param int n>, specifies that this subroutine takes one
+integer parameter and that we'd like to refer to the register it was passed in
by
+the name C<n> for the rest of the sub.
+
+Much of what follows has been seen in previous examples, apart from the line
+reading:
+
+ result = _fact($I0)
+
+This single line of PIR actually represents quite a few lines of PASM. First,
+the value in register C<$I0> is moved into the appropriate register for it to
be
+received as an integer parameter by the C<_fact> function. Other calling
+related registers are then set up, followed by C<_fact> being invoked. Then,
+once C<_fact> returns, the value returned by C<_fact> is placed into the
+register given the name C<result>.
+
+Right before the C<.end> of the C<_fact> sub, a C<.return> directive is used to
+ensure the value held in the register named C<result> is placed into the
correct
+register for it to be seen as a return value by the code calling the sub.
+
+The call to C<_fact> in main works in just the same was as the recursive call
+to C<_fact> within the sub C<_fact> itself. The only remaining bit of new
+syntax is the C<@MAIN>, written after C<.sub _main>. By default, PIR assumes
+that execution begins with the first sub in the file. This behaviour can be
+changed by making the sub to start in with C<@MAIN>.
+
+=head2 Compiling to PBC
+
+To compile PIR to bytecode, use the C<-o> flag and specify an output file with
+the extension F<.pbc>.
+
+ parrot -o factorial.pbc factorial.pir
+
+
+=head1 Where next?
+
+=head2 Documentation
+
+What documentation you read next depends upon what you are looking to do with
+Parrot. The opcodes reference and built-in PMCs reference are useful to dip
into
+for pretty much everyone. If you intend to write or compile to PIR then there
+are a number of documents about PIR that are worth a read. For compiler
writers,
+the Compiler FAQ is essential reading. If you want to get involved with Parrot
+development, the PDDs (Parrot Design Documents) contain some details of the
+internals of Parrot; a few other documents fill in the gaps. One way of helping
+Parrot development is to write tests, and there is a document entitled
I<Testing
+Parrot> that will help with this.
+
+=head2 The Parrot Mailing List
+
+Much Parrot development and discussion takes place on the perl6-internals
+mailing list. You can subscribe by sending an email to
+L<[EMAIL PROTECTED]> or read the perl6-internals NNTP archive.
-Code gets a little boring without flow control; for starters, Parrot
-knows about branching and labels. The C<branch> op is equivalent to
-Perl's C<goto>:
+=head2 IRC
- branch TERRY
- JOHN: print "fjords\n"
- branch END
- MICHAEL: print " pining"
- branch GRAHAM
- TERRY: print "It's"
- branch MICHAEL
- GRAHAM: print " for the "
- branch JOHN
- END: end
-
-
-It can also do simple tests for whether or not a register contains a
-true value:
-
- set I1, 12
- set I2, 5
- mod I3, I1, I2
- if I3, REMAIND
- print "5 is an integer divisor of 12"
- branch DONE
- REMAIND: print "5 divides 12 with remainder "
- print I3
- DONE: print "\n"
- end
-
-Note that C<if> branches to C<REMAIND> if C<I3> contains a true
-(i.e. non-zero) value; if C<I3> is zero, execution falls through to the
-next statement. Here's what that would look like in Perl, for comparison:
-
- $i1 = 12;
- $i2 = 5;
- $i3 = $i1 % $i2;
- if ($i3) {
- print "5 divides 12 with remainder ";
- print $i3;
- } else {
- print "5 is an integer divisor of 12";
- }
- print "\n";
- exit;
-
-
-And speaking of comparison, we have the full range of numeric
-comparators: C<eq>, C<ne>, C<lt>, C<gt>, C<le> and C<ge>. Note that you
-can't use these operators on arguments of disparate types; you may even
-need to add the suffix C<_i> or C<_n> to the op to tell it what type of
-argument you are using - although the assembler ought to divine this
-for you, by the time you read this.
-
-=head1 Some Parrot Programs
-
-Now let's have a look at a few simple Parrot programs to give you a
-feel for the language.
-
-=head2 Displaying the Time
-
-This little program displays the Unix epoch time every second: (or so)
-
- set I3, 3000000
- REDO: time I1
- print I1
- print "\n"
- set I2, 0
- SPIN: inc I2
- le I2, I3, SPIN
- branch REDO
- end
-
-First, we set integer register 3 to contain 3 million - that's a
-completely arbitrary number, due to the fact that Parrot averages a
-massive six million ops per second on my machine. Then the program
-consists of two loops: the outer loop stores the current Unix time in
-integer register 1, prints it out, prints a new line, and resets
-register 2 to zero. The inner loop increments register 2 until it
-reaches the 3 million we stored in register 3. When it is no longer
-less than (or equal to) 3 million, we go back to the C<REDO> of the
-outer loop. In essence, we're just spinning around a busy loop to waste
-some time.
-
-How do we run this? Copy the assembler to a
-file F<showtime.pasm>, and inside your Parrot directory, run:
-
- parrot showtime.pasm
-
-This will assemble and run the code in F<showtime.pasm>. You can also
-create an assembled bytecode from the assembler by running:
-
- parrot -o showtime.pbc showtime.pasm
-
-(C<.pbc> is the file extension for Parrot bytecode.)
-
-To run this bytecode type
-
- parrot showtime.pbc
-
-=head2 Finding a Fibonacci number
-
-The Fibonacci series is defined like this: take two numbers, 1 and 1.
-Then repeatedly add together the last two numbers in the series to make
-the next one: 1, 1, 2, 3, 5, 8, 13, and so on. The Fibonacci number
-C<fib(n)> is the n'th number in the series. Here's a simple Parrot
-assembler program which finds the first 20 Fibonacci numbers:
-
- # Some simple code to print some Fibonacci numbers
- # Leon Brocard <[EMAIL PROTECTED]>
-
- print "The first 20 fibonacci numbers are:\n"
- set I1, 0
- set I2, 20
- set I3, 0
- set I4, 1
- REDO: set I5, I4
- add I4, I3, I4
- set I3, I5
- print I3
- print "\n"
- inc I1
- lt I1, I2, REDO
- DONE: end
-
-This is the equivalent code in Perl:
-
- print "The first 20 fibonacci numbers are:\n";
- my $i = 0;
- my $target = 20;
- my $a = 0;
- my $b = 1;
- until ($i == $target) {
- my $num = $b;
- $b += $a;
- $a = $num;
- print $a,"\n";
- $i++;
- }
-
-=head2 Further examples
-
-Additional examples of what can be done with Parrot assembler can be
-found in the F<parrot/examples/> subdirectory, and on the web at
-http://www.parrotcode.org/examples/.
-
-=head1 Where Next?
-
-Parrot is obviously developing very rapidly, and we've still got a long
-way to go before we are ready to a compiler to this platform. This
-section is for those who are interested in helping us take Parrot
-further.
-
-=head2 Vtable datatypes
-
-PMCs are almost like Perl 5's SVs and Python's Objects, only more so.
-A PMC is an object of some type, which can be instructed to perform
-various operations. So when we say
-
- inc P1
-
-to increment the value in PMC register 1, the C<increment> method is
-called on the PMC - and it's up to the PMC how it handles that method.
-
-PMCs are how we plan to make Parrot language-independent - a Perl PMC
-would have different behavior from a Python PMC or a Tcl PMC. The
-individual methods are function pointers held in a structure called a
-B<vtable>, and each PMC has a pointer to the vtable which implements
-the methods of its "class". Hence a Perl interpreter would link in a
-library full of Perl-like classes and its PMCs would have Perl-like
-behaviour.
-
-The PMC types available are described in F<doc/vtables.pod>; you can
-create a new PMC with
-
- new P0, <typename>
-
-and then use any of the instructions in F<ops/core.ops> and F<ops/pmc.ops>
-which support PMCs. F<doc/vtables.pod> also tells you how to implement
-your own PMC vtable classes.
-
-=head2 Getting involved
-
-We've got a good number of people working away on Parrot, but we could
-always use a few more. To help out, you'll need a subscription to the
-perl6-internals mailing list, (C<[email protected]>), where all
-the development takes place. You should also keep up to date with the SVN
-version of Parrot; if you want to be alerted to SVN commits,
-you can subscribe to the cvs-parrot mailing list (C<[email protected]>).
-SVN commit access is given to those who take
-responsibility for a particular area of Parrot, or who often submit
-high-quality patches.
-
-The projects home page is L<http://www.parrotcode.org>.
-
-So don't delay - pick up a Parrot today!
+The Parrot IRC channel is hosted on irc.perl.org and is named C<#parrot>.
=cut
+
Modified: branches/leo-ctx5/editor/pir-mode.el
==============================================================================
--- branches/leo-ctx5/editor/pir-mode.el (original)
+++ branches/leo-ctx5/editor/pir-mode.el Wed Aug 10 01:29:12 2005
@@ -9,8 +9,8 @@
;; put this file in your `load-path' and add the following lines
;; to your `.emacs' file:
-;; (autoload 'pir-mode \"pir-mode\" nil t)
-;; (add-to-list 'auto-mode-alist '("\\.imc\\'" . pir-mode))
+;; (autoload 'pir-mode "pir-mode" nil t)
+;; (add-to-list 'auto-mode-alist '("\\.\\(imc\\|pir\\)\\'" . pir-mode))
;; If you have any problems with this, you're on your own,
;; You could always try asking on [EMAIL PROTECTED]
Modified: branches/leo-ctx5/languages/m4/t/basic/003_getopt.t
==============================================================================
--- branches/leo-ctx5/languages/m4/t/basic/003_getopt.t (original)
+++ branches/leo-ctx5/languages/m4/t/basic/003_getopt.t Wed Aug 10 01:29:12 2005
@@ -4,10 +4,11 @@ use strict;
use FindBin;
use lib "$FindBin::Bin/../../lib", "$FindBin::Bin/../../../../lib";
+use Parrot::Config;
use Test::More tests => 25;
my $real_out;
-my $parrot_m4 = 'cd .. && ./parrot languages/m4/m4.pbc';
+my $parrot_m4 = "cd .. && .$PConfig{slash_exec}parrot$PConfig{exe}
languages/m4/m4.pbc";
my $examples_dir = 'languages/m4/examples';
Modified: branches/leo-ctx5/languages/m4/t/basic/012_eval.t
==============================================================================
--- branches/leo-ctx5/languages/m4/t/basic/012_eval.t (original)
+++ branches/leo-ctx5/languages/m4/t/basic/012_eval.t Wed Aug 10 01:29:12 2005
@@ -4,10 +4,11 @@ use strict;
use FindBin;
use lib "$FindBin::Bin/../../lib", "$FindBin::Bin/../../../../lib";
+use Parrot::Config;
use Test::More tests => 1;
my $real_out;
-my $parrot = 'cd .. && ./parrot';
+my $parrot = "cd .. && .$PConfig{slash_exec}parrot$PConfig{exe}";
$real_out = `$parrot languages/m4/examples/eval.imc 2>&1`;
is( $real_out, << 'END_OUT', 'single expression' );
Modified: branches/leo-ctx5/languages/m4/t/builtins/010_sysval.t
==============================================================================
--- branches/leo-ctx5/languages/m4/t/builtins/010_sysval.t (original)
+++ branches/leo-ctx5/languages/m4/t/builtins/010_sysval.t Wed Aug 10
01:29:12 2005
@@ -8,9 +8,9 @@ use Parrot::Test tests => 1 + 1;
SKIP:
{
+ skip( "`false' not available on $^O", 1 ) if ($^O =~ /MSWin32/);
skip( "difference between running a process in a fork, or with system()", 1
);
-
- language_output_is( 'm4', <<'CODE', <<'OUT', 'substring in middle of string'
);
+ language_output_is( 'm4', <<'CODE', <<'OUT', 'output of "false"' );
syscmd(`false')
sysval()
CODE
@@ -20,7 +20,9 @@ OUT
}
{
- language_output_is( 'm4', <<'CODE', <<'OUT', 'substring in middle of string'
);
+ skip( "`true' not available on $^O", 1 ) if ($^O =~ /MSWin32/);
+
+ language_output_is( 'm4', <<'CODE', <<'OUT', 'output of "true"' );
syscmd(`true')
sysval()
CODE
Modified: branches/leo-ctx5/languages/m4/t/freezing/002_many_files.t
==============================================================================
--- branches/leo-ctx5/languages/m4/t/freezing/002_many_files.t (original)
+++ branches/leo-ctx5/languages/m4/t/freezing/002_many_files.t Wed Aug 10
01:29:12 2005
@@ -4,10 +4,11 @@ use strict;
use FindBin;
use lib "$FindBin::Bin/../../lib", "$FindBin::Bin/../../../../lib";
+use Parrot::Config;
use Test::More tests => 3;
my $real_out;
-my $parrot_m4 = 'cd .. && ./parrot languages/m4/m4.pbc';
+my $parrot_m4 = "cd .. && .$PConfig{slash_exec}parrot$PConfig{exe}
languages/m4/m4.pbc";
#--------------------------------------------
Modified: branches/leo-ctx5/languages/tcl/TODO
==============================================================================
--- branches/leo-ctx5/languages/tcl/TODO (original)
+++ branches/leo-ctx5/languages/tcl/TODO Wed Aug 10 01:29:12 2005
@@ -5,13 +5,15 @@
=item interactive tclsh
new parser breaks ability to send interactive commands to the shell, add it
-back
+back. Even better, come up with a way to *test* the thing.
=item PIR Tree
From autrijus's talk.
can we use this instead of the current string-based compilation.
+"Um, perhaps Autrijus can tell me what I meant by this." -Coke
+
=item Makefile deps
Should be more explicit about the PMC dependencies in the makefile. *something*
@@ -32,7 +34,7 @@ Still have to:
=item [interpinfo name]
-how to do this from inside parrot? RT#36277
+how to do this from inside parrot? [#36277]
=item migrate all these issues to RT or TODO tests
@@ -134,6 +136,10 @@ to get any that require int-only args, a
even if we cannot specify them. This is all supportable by MMD - we just
need to specify the correct errors to throw.
+=item [pwd]
+
+need parrot support for this.
+
=back
=cut
Modified: branches/leo-ctx5/languages/tcl/lib/commands/array.pir
==============================================================================
--- branches/leo-ctx5/languages/tcl/lib/commands/array.pir (original)
+++ branches/leo-ctx5/languages/tcl/lib/commands/array.pir Wed Aug 10
01:29:12 2005
@@ -164,7 +164,10 @@ pre_loop:
.local int loop
loop = 0
.local string key
- .local string val
+ .local pmc val
+
+ .local pmc set
+ set = find_global "_Tcl", "__set"
isnull the_array, new_array
goto set_loop
@@ -177,14 +180,16 @@ set_loop:
inc loop
val = elems[loop]
inc loop
- the_array[key] = val
- if loop < count goto set_loop
-
- # set the actual variable
- .local pmc set
- set = find_global "_Tcl", "__set"
- (return_type, retval) = set(array_name, the_array)
+
+ # = makes an alias :-(
+ assign $S0, array_name
+ $S0 .= "("
+ $S0 .= key
+ $S0 .= ")"
+ (return_type, retval) = set($S0, val)
if return_type == TCL_ERROR goto done
+
+ if loop < count goto set_loop
retval = new String
retval = ""
Modified: branches/leo-ctx5/languages/tcl/lib/commands/for.pir
==============================================================================
--- branches/leo-ctx5/languages/tcl/lib/commands/for.pir (original)
+++ branches/leo-ctx5/languages/tcl/lib/commands/for.pir Wed Aug 10
01:29:12 2005
@@ -62,7 +62,8 @@ continue:
#print "\n"
#print "FOR_CONTINUE2:\n"
# then check condition
- (return_type,test_parsed) = expression_p(test_p)
+ $S0 = test_p
+ (return_type,test_parsed) = expression_p($S0)
#print "RETURN_TYPE ="
#print return_type
#print "\n"
Modified: branches/leo-ctx5/languages/tcl/lib/commands/if.pir
==============================================================================
--- branches/leo-ctx5/languages/tcl/lib/commands/if.pir (original)
+++ branches/leo-ctx5/languages/tcl/lib/commands/if.pir Wed Aug 10 01:29:12 2005
@@ -15,7 +15,7 @@
elseifs = new TclList
.local pmc retval,condition
.local string code
- .local pmc condition
+ .local string condition
.local string body
.local string else
.local int return_type
Modified: branches/leo-ctx5/languages/tcl/lib/commands/proc.pir
==============================================================================
--- branches/leo-ctx5/languages/tcl/lib/commands/proc.pir (original)
+++ branches/leo-ctx5/languages/tcl/lib/commands/proc.pir Wed Aug 10
01:29:12 2005
@@ -46,10 +46,10 @@ got_args:
register parsed_body
# XXX these need to go away - for now, we'll just escape
- # the code portion and put it, escaped, into the proc
+ # the code portion and put it, escaped, into the proc
# definition. The arg list will be used to generate the proc's
# indvidual argument handling code.
-
+
# Now, shove the parsed routine into the global hash...
$P0 = find_global "_Tcl", "proc_parsed"
$P0[name] = parsed_body
@@ -71,62 +71,120 @@ got_args:
.local string proc_body
proc_body = ".namespace [\"Tcl\"]\n.sub \""
proc_body .= name
- proc_body .= "\"\n.param pmc args\nargs = foldup\nnew_pad 1\n"
- proc_body .= ".local pmc call_level\ncall_level = find_global \"_Tcl\",
\"call_level\"\ninc call_level\n"
- .local int arg_count
+ proc_body .= "\"\n .local pmc args\n args = foldup\n new_pad 1\n "
+ proc_body .= ".local pmc call_level\n call_level = find_global \"_Tcl\",
\"call_level\"\n inc call_level\n "
+ .local int arg_count
arg_count = args_p
- .local int ii
+ .local int ii,is_slurpy
+ is_slurpy = 0
ii = 0
+ if arg_count == 0 goto arg_loop_done
+ $I0 = arg_count - 1
+ $S0 = args_p[$I0]
+
+ .local int last_arg
+ last_arg = arg_count
+
+ if $S0 != "args" goto check_args
+ is_slurpy = 1
+ dec last_arg
+
+check_args:
+ proc_body .= ".local int argc\n argc=args\n "
+
+ if is_slurpy goto slurpy_arg_count
+ proc_body .= "if argc != "
+ $S0 = arg_count
+ proc_body .= $S0
+ proc_body .= " goto BAD_ARGS\n\n"
+ goto arg_loop
+
+
+slurpy_arg_count:
+ proc_body .= "if argc < "
+ $I0 = arg_count - 1
+ $S0 = $I0
+ proc_body .= $S0
+ proc_body .= " goto BAD_ARGS\n "
+
arg_loop:
- if ii == arg_count goto arg_loop_done
+ if ii == last_arg goto arg_loop_done
$S1 = ii
proc_body .= "$P1 = args["
proc_body .= $S1
- proc_body .= "]\nstore_lex -1,\""
+ proc_body .= "]\n "
+ proc_body .= "store_lex -1,\"$"
# XXX This should be Escape'd
$S1 = args_p[ii]
proc_body .= $S1
- proc_body .= "\", $P1\n"
+ proc_body .= "\", $P1\n "
ii = ii + 1
goto arg_loop
+
arg_loop_done:
+ unless is_slurpy goto body
+
+ # Convert the remaining elements returned by foldup into a TclList
+ # XXX This code lifted from Tcl::&list - eventually factor this out.
+ proc_body .= ".local int cnt,jj\n cnt = "
+ $I0 = ii
+ $S0 = $I0
+ proc_body .= $S0
+ proc_body .= "\n jj = 0\n "
+ #proc_body .= "$I0 = argc - 1\n "
+ proc_body .= "if cnt == argc goto NO_SLURPY_ARGS\n "
+
+ proc_body .= ".local pmc arg_list\n arg_list = new .TclList\n "
+ proc_body .= "\n\nSLURPY_LOOP:\n "
+ proc_body .= "if cnt >= argc goto DONE\n "
+ proc_body .= "$P0 = args[cnt]\n "
+ proc_body .= "arg_list[jj] = $P0\n "
+ proc_body .= "inc cnt\n "
+ proc_body .= "inc jj\n "
+ proc_body .= "goto SLURPY_LOOP\n\n"
+ proc_body .= "NO_SLURPY_ARGS:\n arg_list= new .TclString\n
arg_list=\"\"\n\n"
+ proc_body .= "DONE:\n "
+ proc_body .= "store_lex -1, \"$args\", arg_list\n "
- proc_body .= ".local pmc interpret\ninterpret = find_global \"_Tcl\",
\"__interpret\"\n.local pmc proc_body\n$P0 = find_global \"_Tcl\",
\"proc_parsed\"\nproc_body=$P0[\""
+
+body:
+ proc_body .= ".local pmc interpret\n interpret = find_global \"_Tcl\",
\"__interpret\"\n .local pmc proc_body\n $P0 = find_global \"_Tcl\",
\"proc_parsed\"\n proc_body=$P0[\""
proc_body .= esc_name
- proc_body .= "\"]\nif I3 == "
- $S1 = arg_count
- proc_body .= $S1
- proc_body .= " goto args_ok\nbad_args:\n.return(1,\"wrong # args: should be
\\\""
+ proc_body .= "\"]\n "
+
+done_args:
+ proc_body .= " goto ARGS_OK\n\nBAD_ARGS:\n $P1=new String\n "
+ proc_body .= "$P1=\"wrong # args: should be \\\""
proc_body .= name
proc_body .= " "
proc_body .= args
- proc_body .= "\\\"\")\nargs_ok:\n"
+ proc_body .= "\\\"\"\n .return(1,$P1)\n\nARGS_OK:\n "
# XXX Is the pop_pad necessary, or would it be handled as a side
# effect of the .return?
-
+
# a TCL_RETURN (2) from a sub body should be transformed into a TCL_OK (0)
# to stop propagation outward. XXX Should use the real constants here
- proc_body .= "($I0,$P0) = interpret(proc_body)\nif $I0 != 2 goto done\n$I0 =
0\ndone:\npop_pad\ndec call_level\n.return($I0,$P0)\n.end\n"
+ proc_body .= "($I0,$P0) = interpret(proc_body)\n if $I0 != 2 goto done\n
$I0 = 0\n done:\n pop_pad\n dec call_level\n .return($I0,$P0)\n.end\n"
#print "PROC_BODY=\n"
#print proc_body
#print "\n--\n"
-
+
.local pmc pir_compiler
pir_compiler = compreg "PIR"
- $P0 = compile pir_compiler, proc_body
+ $P0 = compile pir_compiler, proc_body
# XXX because of the current implementation of the PIR compiler, we must
save a reference
# to our newly compiled function or run the risk of having it garbage
collected
$P1 = find_global "_Tcl", "proc_exec"
$P1[name] = $P0
-
+
retval = new String
retval = ""
goto done
-
+
error:
return_type = TCL_ERROR
retval = new String
Modified: branches/leo-ctx5/languages/tcl/lib/commands/while.pir
==============================================================================
--- branches/leo-ctx5/languages/tcl/lib/commands/while.pir (original)
+++ branches/leo-ctx5/languages/tcl/lib/commands/while.pir Wed Aug 10
01:29:12 2005
@@ -33,7 +33,8 @@
register parsed_code
while_loop:
- (return_type,retval) = expression_p(cond_p)
+ $S0 = cond_p
+ (return_type,retval) = expression_p($S0)
if return_type == TCL_ERROR goto done_done
(return_type,retval) = expression_i(retval)
if return_type == TCL_ERROR goto done_done
Modified: branches/leo-ctx5/languages/tcl/lib/expression.pir
==============================================================================
--- branches/leo-ctx5/languages/tcl/lib/expression.pir (original)
+++ branches/leo-ctx5/languages/tcl/lib/expression.pir Wed Aug 10 01:29:12 2005
@@ -18,7 +18,8 @@ however, then we're returning the invoka
.sub __expression_parse
.param string expr
-
+ .param pmc foo
+
.local int return_type # TCL return code
return_type = TCL_OK
.local pmc retval # TCL return value
@@ -28,6 +29,7 @@ however, then we're returning the invoka
.local pmc precedences # Global list of operator precedence
precedences = find_global "_Tcl", "precedence"
+got_arg:
.local pmc undef
undef = new Undef
@@ -99,10 +101,8 @@ get_paren_done:
inc chunk_start
substr $S1, expr, chunk_start, $I0
- $P9 = new String
- $P9 = $S1
# XXX this is now officially braindead. Fissit.
- (return_type,retval) = __expression_parse($P9)
+ (return_type,retval) = __expression_parse($S1)
if return_type == TCL_ERROR goto die_horribly
(return_type,retval) = __expression_interpret(retval)
if return_type == TCL_ERROR goto die_horribly
@@ -916,10 +916,8 @@ loop_done:
len_operand = $I1
substr $S1, expr, start_paren_pos, len_operand
- $P9 = new String
- $P9 = $S1
# XXX should be checking return value here.
- ($I9,operand) = __expression_parse($P9)
+ ($I9,operand) = __expression_parse($S1)
($I9,operand) = __expression_interpret(operand)
$P10 = new FixedPMCArray
$P10 = 2
Modified: branches/leo-ctx5/languages/tcl/t/cmd_array.t
==============================================================================
--- branches/leo-ctx5/languages/tcl/t/cmd_array.t (original)
+++ branches/leo-ctx5/languages/tcl/t/cmd_array.t Wed Aug 10 01:29:12 2005
@@ -2,7 +2,7 @@
use strict;
use lib qw(tcl/t t . ../lib ../../lib ../../../lib);
-use Parrot::Test tests => 18;
+use Parrot::Test tests => 25;
use vars qw($TODO);
language_output_is("tcl",<<'TCL',<<OUT,"array, no args");
@@ -135,3 +135,53 @@ language_output_is("tcl",<<'TCL',<<'OUT'
TCL
OUT
+
+language_output_is("tcl",<<'TCL',<<'OUT',"array set not array");
+ set a 44
+ array set a {1 2 3 4}
+TCL
+can't set "a(1)": variable isn't array
+OUT
+
+TODO: {
+ local $TODO = "unimplemented";
+
+language_output_is("tcl",<<'TCL',<<'OUT',"array get");
+ array set a [list a b]
+ puts [array get a]
+TCL
+a b
+OUT
+
+language_output_is("tcl",<<'TCL',<<'OUT',"array get, with pattern");
+ array set a [list a b c d]
+ puts [array get a a]
+TCL
+a b
+OUT
+
+language_output_is("tcl",<<'TCL',<<'OUT',"array get, with pattern");
+ array set a [list apple 1 orange 2 aardvark 3]
+ puts [array get a a*]
+TCL
+apple 1 aardvark 3
+OUT
+
+language_output_is("tcl",<<'TCL',<<'OUT',"array get, bad array");
+ puts [array get a]
+TCL
+
+OUT
+
+language_output_is("tcl",<<'TCL',<<'OUT',"array get, bad array with pattern");
+ puts [array get a a]
+TCL
+
+OUT
+
+language_output_is("tcl",<<'TCL',<<'OUT',"array get, too many args");
+ array get a b c
+TCL
+wrong # args: should be "array get arrayName ?pattern?"
+OUT
+}
Modified: branches/leo-ctx5/languages/tcl/t/cmd_list.t
==============================================================================
--- branches/leo-ctx5/languages/tcl/t/cmd_list.t (original)
+++ branches/leo-ctx5/languages/tcl/t/cmd_list.t Wed Aug 10 01:29:12 2005
@@ -2,7 +2,8 @@
use strict;
use lib qw(tcl/t t . ../lib ../../lib ../../../lib);
-use Parrot::Test tests => 15;
+use Parrot::Test tests => 16;
+use vars qw($TODO);
language_output_is("tcl",<<'TCL',<<OUT,"no elements");
puts [list]
@@ -94,3 +95,12 @@ language_output_is("tcl",<<'TCL',<<'OUT'
TCL
\]
OUT
+
+TODO: {
+ local $TODO = "need smarter string to list processing.";
+language_output_is("tcl",<<'TCL',<<'OUT',"extra characters after close brace");
+ list {a}a
+TCL
+extra characters after close brace
+OUT
+}
Modified: branches/leo-ctx5/languages/tcl/t/cmd_proc.t
==============================================================================
--- branches/leo-ctx5/languages/tcl/t/cmd_proc.t (original)
+++ branches/leo-ctx5/languages/tcl/t/cmd_proc.t Wed Aug 10 01:29:12 2005
@@ -2,8 +2,7 @@
use strict;
use lib qw(tcl/t t . ../lib ../../lib ../../../lib);
-use Parrot::Test tests => 5;
-use vars qw($SKIP $TODO);
+use Parrot::Test tests => 9;
language_output_is("tcl",<<'TCL',<<OUT,"return value");
set a [proc me {} {
@@ -45,8 +44,35 @@ TCL
3
OUT
-TODO: {
-local $TODO = "not done yet, but doable";
+language_output_is("tcl",<<'TCL',<<OUT,"too many args");
+ proc me {a b} {
+ puts $a
+ puts $b
+ }
+ me 2 3 4
+TCL
+wrong # args: should be "me a b"
+OUT
+
+language_output_is("tcl",<<'TCL',<<OUT,"too few args");
+ proc me {a b} {
+ puts $a
+ puts $b
+ }
+ me 2
+TCL
+wrong # args: should be "me a b"
+OUT
+
+language_output_is("tcl",<<'TCL',<<OUT,"bad varargs");
+ proc me {a b args} {
+ puts $a
+ puts $b
+ }
+ me 2
+TCL
+wrong # args: should be "me a b args"
+OUT
language_output_is("tcl",<<'TCL',<<OUT,"vararg");
proc me {a args} {
@@ -58,7 +84,17 @@ TCL
2
3 4 5 6
OUT
-}
+
+language_output_is("tcl",<<'TCL',<<OUT,"vararg empty");
+ proc me {a args} {
+ puts $a
+ puts $args
+ }
+ me 2
+TCL
+2
+
+OUT
__END__