From: | "Veli-Pekka Tätilä" <vtatila@mail.student.oulu.fi> |
Newsgroups: | comp.compilers |
Date: | 7 Oct 2005 21:45:56 -0400 |
Organization: | "University of Oulu" |
References: | 05-10-013 05-10-049 |
Keywords: | courses |
Posted-Date: | 07 Oct 2005 21:45:56 EDT |
James T. Sprinkle wrote:
> the same problem. Written in Pascal and emits non x86 assembly code.
> I decided as I read through it, I would convert the pascal code to c
> code and convert the assembly code to x86.
Ah nice. I chose Perl because it is more high-level and it is a little
quicker to test the code I've written. I managed to read through the first
four chapters just fine and got working PErl code out.
But now that he's getting into control flow such as if and while statements,
I'm not sure how I should proceed. That is, so far though I've run my Perl
code through eval, I've tried to rely on eval as littel as possible using
more portable constructs that might work in C, too. So I'm using a hash to
hold the registers and an array as the stack, for example. I've been
interpreting all instructions in real time, emiting and evaling the perl
code that would be produced.
The only reason for me to use eval so far is to have easy means of printing
the code I'm producing and running. There's nothing in my current way of
supporting registers and the stack that would prevent it from running in a
language not supporting eval, such as Java.
Some code snippets follow:
my @s; # The emulated stack.
my %v; # Variable names.
my %r = (D0 => 0); # Set of virtual registers (lacking M68k asm).
<snip>
sub Run($)
{ # Print and evaluate a Perl expression.
local $_ = shift;
my $retval = eval;
Emit $_;
Emit " # $retval" if defined $retval;
EmitLn '';
die "$@" if $@ ne '';
} # sub
And examples of using run:
Run '$r{D0} = GetNum' # Variable to D0.
Run 'push @s, $r{D0}'; # PUsh D0 on the stack.
Run '$r{D0} += pop @s'; # Pop stuff from the stack and add to D0.
Run '$r{D0} = $v{' . $var . '}'}; # Move the value of a variable to D0.
However, so far I have no idea on how I should implement control structures.
The assembler version uses labels which are supported by the Assembler
directly. One way to do it would be to first emit all of the Perl code with
labels and such and then run the code in a separate pass.
This seems silly. If I'm producing perl code that only runs when it is
evaled separately, I might as well use all the other features of Perl
directly, such as evaluating expressions, working with strings and so on.
The same tac doesn't work with the assembler as it is a lot more low-level.
So in stead I'd like to interpret and run the code while it is encountered
as I've been successfully doing so far. Now flow control is a bit more
involved. I would need to support jumps and labels in interpreted code
somehow. ANy tips or tutorials on how such things are done?
Another problem is that I would need some way of representing all the
instructions that are in a block in such a way that my perl code knows how
to interpret them. Again this seems mind-boggling at first. Having to
implement a virtual machine of some kind has crossed my mind but I've never
done anything like it before. Do simple interpreters rely on some sort of
virtual machine internally?
Lastly, it seems I would need to lookahead a little so that I know the whole
block I ought to be running, repeating, skipping over and so on. So the
method of directly emiting the code that would be run will no longer work.
Single-character input also seems awfully limiting, as Perl's got great
string support. Do I need to create some parse tree first and run my
interpreted code afterwords?
> didn't finish the
> tutorial, (very very busy I am) but I did get a good way into it
> I'll see if I can find my old code
Thanks, please e-mail me directly if you do.
Hope this all makes sense. I'm rather new to compiling and parsing of any
kind apart from regexp and string processing.
--
With kind regards Veli-Pekka Tätilä (vtatila@mail.student.oulu.fi)
Accessibility, game music, synthesizers and programming:
http://www.student.oulu.fi/~vtatila/
Return to the
comp.compilers page.
Search the
comp.compilers archives again.