Walter Roberson wrote:
:Perdantick bast.
Hmmm, according to OED, “bast” means “sanctuary, refuge, asylum”.
:Imagine if parrot could understand all currently- and popularly-
:implemented interpreted languages.Such as Forth, Word Perfect Macros, Microsoft Visual Basic,
and Befunge?? (You haven’t been very specific on the meaning of
‘popularly’.)
Is it (currently) possible to put Word Perfect macros into a file, and
run that file as a script?
And I think that it’s actually highly probable that a translator from
MSVB to Parrot will be written… or rather, a translator from MSIL or
from .NET to Parrot.
Now, Parrot is intended for interpreted languages, right? And
the fundamental feature of such languages is that you should
be able to compute a string and then execute the string as
a statement. So Parrot will have to know how to execute statements
in arbitrary source languages.
Well, not parrot itself … you’ll have a compiler (written in parrot)
which translates the other language to parrot bytecode. When some piece
of code does eval $string, it calls to the translator, then runs the
resultant bytecode.
This means that it isn’t enough to have a (say) bash-to-parrot
translator that translates the program and hands it off to parrotd:
the entire translator is going to have to be input along with the
translated source.
Fortuantly, parrot is able to defer loading of modules until they’re
needed. You hand off the translated source, and as soon as it runs into
an eval $string operation, it loads up the translator, then runs the
translator and continues on it’s merry way.
This indirectly raises an interesting point. If parrotd is glued into
the operating system as part of exec() as has been proposed (as
opposed to the counter proposal to just let #! do its standard job)
then the implication is that there is only one parrot implimentation
per system.
Yes, this does sound like what was being proposed.
However, nothing prevents you from having more than one parrot kernel
plugin, the selection of which would be distinguished by a version
number in the header of the bytecode file.
How would one then test new versions of Parrot?
Well, instead of typing in “bytecodeprogram” at the commandline, you
would have to type in “parrot bytecodeprogram”, where “parrot” is your
path to your newer version of parrot.
Or perhaps you would do:
parrot_daemon --nokernel &
parrot_send_to_daemon bytecodeprogram
(or something like that)
Obviously this won’t be quite the same environment as the kernel’s
plugged-in parrot interpreter daemon, but it will be sufficiently close
for most forms of testing.
With #! it’s easy: you just name the path to the alternative
interpreter and the kernel invokes it. But if parrotd is built right
into exec() then in order to support multiple versions of Parrot, you
would have to build the new versions -in- Parrot and pass them in as
yet another layer of interpreter.
I don’t understand what you mean by this.
e.g., parrotd version 6.302 is running and it has been passed a copy
of the bash2parrot 4.19 translator
Err, no. You would have a program which was originally written in bash,
then translated into parrot bytecode. All places where strings need to
be translated at runtime (via the eval command) are set up to load up
the bash translator, then translate that string, then run the string.
The bash2parrot translator would not be included in the translated
bytecode, though – only the name of the module, or maybe the filename
of the module. Vaguely like how one shared object can depend on another
one, or even whole reams of other ones – but they don’t get loaded
until functions in them get called.
in case it needs to interpret a computed string that invokes a program
Ok, at this point, stop, and take a breath. When your translated bash
program wants to “invoke a program”, how that program’s guts work is
beyond it’s concern – it merely calls fork and exec and wait.
The fact that the exec() may send the filename and args and environment
to a different parrot daemon is irrelevant to that process.
that needs to layer on the experimental parrotd 6.4.9 interpreter that
What do you mean ‘layer on’ ?
has to be passed the perl2parrot translator in case it needs to
Again, nothing is passing around translators – they only get loaded
when they are needed.
interpret a computed string that invokes a program
that needs to have -another copy- of parrotd 6.302 layered on [you
can’t count on parrotd 6.4.9 running parrotd 6.302 programs the same
way that parrotd 6.302 would run them] that has the <etc.> interpeter
layered on to run <etc.>.
Your confusion seems to mainly stem from three things: You’re not
paying attention to process boundaries, and you think that every
translated program in language X has the translator for X to parrot
embedded into it, and exec() doesn’t invoke a sub-process, it replaces
the current process with a new process (That’s why you have to fork()
first if you want a sub-process).
Once you have a better understanding of the unix process model, the
problems you’ve sketched will disappear.
Scheme is right at home at dealing with these kinds of layering
issues, using a process called “reflection” [well developed by Brian
Reid and Jeem Desriviers]. They aren’t straight-forward issues: think
about debugging, and think about re-entrancy, and think about problems
in cross-layer pollution – you don’t want a wild pointer in the fifth
layer down to affect your third layer, right?
Fortuantly for us, seperate processes have their own memory address
spaces, so this isn’t a concern.
Speaking of layers: I take it that some thought has been put into
how to do operating-system escapes? So that one can (for example)
handle graphics? Or even just sockets? Seeing as some of the most
popular interpreted languages are by no means restricted to text-only
and have networking capabilities?
Remember, the parrot interpreter is written in C… it has to be.
Obviously, one would have parrot opcodes which result in calls to C
functions, which perform socket operations or graphics or whatever.
But of course the appropriate calls could come within one of the
computed strings, so any escape cannot be absolute and must instead be
handled via the interpretation layer (c.f. the above in which I showed
that parrotd must be built in Parrot if you want parrotd to be handled
at the exec() level…)
You can’t write parrotd in parrot – you have to write it in something
which runs on the hardware (elf or a.out).
Writing parrotd in parrot is similar to writing a turing machine VM in
the language you use to write descriptions of turing machines, and then
having exec() detect when you’re running a compiled turing machine and
handing it off to the turing machine VM … if it doesn’t get passed off
to something running on the actual hardware, it’s going to loop
forever.
···
In article aqbimo$a36$1@news.ox.ac.uk, Frodo Morris <“”> wrote:
–
my $n = 2; print +(split //, ‘e,4c3H r ktulrnsJ2tPaeh’
…“\n1oa! er”)[map $n = ($n * 24 + 30) % 31, (42) x 26]