Current
Snapshot of Code (Updated May 17, 2010) Version 0.06
Link to the
Assembler I wrote for the
ACTION! cross compiler.
Comming Soon: Linker
Original Reference Manual. This is
something I found on the web. I have no idea where I found it,
but somebody wanted it, and it is too big to email it, and too
difficult for me to find again. So, I am going to repost it here.
My appologies if I have stepped on somebodys toes.
Definitive Action Manual
Now, if you would like something better than the scanned version, I
have just completed turning the manual back into text. So, what
you will find here is both a microsoft WORD 2010 docx file and a PDF
file of the original manual. I used an OCR program to convert the
scanned version you see above back into a text file. That was the
easy part. I then imported the text file into Microsoft WO
RD 2010, and set to work making it readable. I started that
back in June, and only finished today, August 17, 2012. It was a
lot more work than I anticipated, but I did it. For right now,
just docx and pdf versions. I wanted to post an Html version as
well, but Microsoft WORD really sucks as far as saving HTML.
Action Manual (docx)
Action manual (pdf) I would like to thank Clinton Parker for being a good sport about aloowing me to post these files.
June 30, 2012
It has been over a year since I have done much with this compiler, but
I have never forgotten it. I heard from a gentleman in France who
wanted to know if I would make changes to suit his needs. Sure,
what the heck, but the durn thing isn't even done yet. So, I
figured now would be a good time to get things cleaned up a bit.
I am mostly working on the assembler and linker at the moment.
The Linker is just plain not even close to completion, and the
assembler had a lot of loose ends that needed to be tied up. As
soon as I get the assembler up to snuff, I should be able to complete
the linker. Then I will bet back to the compiler. First
thing I need to do is put in the code generator for Multiply, Divide
and Mod operations. These will be all handled by runtime library
functions.
June 7, 2011
I have added code to the assembler to more or less
output a relocateable object file. This is the first step to
creating a linker. I still have a few things to do yet on the
object file outoput, but most of the work is done. Not ready yet
to repost the source and executable.
I have also begun to think avbout code generation
options for the ACTION! compiler itself. I am thinking of making
it that functions can be made reentrant, if desired. The
disadvantage is that the code will be larger and slower doing
this. I will have to create a fake data stack to do this, and the
poor little 6502 has to work very hard at this. Here is a snippet
of code that shows the basics of creating a Frame Pointer.
CLC
LDA STACK_POINTER
STA BASE_POINTER
ADC >#LOCAL_SIZE
STA STACK_POINTER
LDA STACK_POINTER+1
STA BASE_POINTER+1
ADC <#LOCAL_SIZE
STA STACK_POINTER+1
This code assumes that the parameters have allready
been pushed onto the STACK, so we just need to make space for the local
variables, save the current position of the stack pointer into a base
pointer, and there we go. You will need to subtract off an offset
from the BASE_POINTER to get to the parameters, and add an offset to
the BASE_POINTER to get to the local variables. It should be
noted that STACK_POINTER and BASE_POINTER are memory locations
somewhere in PAGE0 of the 6502 memory space. You would use them
like this:
;access one of the parameters on the stack
SEC
LDA BASE_POINTER
SBC >#PARAM_OFFSET
STA SCRATCH_POINTER
LDA BASE_POINTER+1
SBC <#PARAM_OFFSET
STA SCRATCH_POINTER+1
LDY #0
LDA (SCRATCH_POINTER),Y ;we finally have loaded the value of interest
....etc...
June 1, 2011
It has been way too long since I have looked at this
project. Well, I have gotten another resurgence of interest in
the old Atari computers. So, what I am currently doing is
starting a linker for the assembler I wrote above, and I am going to
start going through the code generator and finishing up the spots that
have not been completed yet. I am also trying to find a little
box that will do a good job of converting the composite video from my
Atari 800 into RGB that can be plugged into an LDC monitor. No
more CRTs for this monkey boy. Anyway, the linker will have a
linker script that will alow you to write a script to ararnge the
various code sections in memory. This is needed so that the
output can be put into either ROM or RAM. This was not something
that the original ACTION! compiler did very well.
I am also contemplating added a new keyword to the ACTION! language,
EXTERN, so that ACTION! programs can be better modularized. I am
not sure what to do about recursion. Adding this keyword will
allow recursion, which just will not work very good using the
traditional code generation. I may have to think about adding a
REENTRANT keyword as well, but that does not sound at all fun.
July 16, 2010
It has been a couple of months since I was able to do much on this
project. Hopefully, I will get to do more regular work on this.
I have made only minor changes to the previous posting. I
have added just a tad more code generation. One big problem I am
having at this moment is trying to remember just exactly it was I was
doing. Just be assured I have not given up on this.
One of the main things I have been busy with since May was the process
of moving my mother in law from her home into our home. It has
been very labor intensive. Add to that that my vision is
extremely bad, has made for a very exhauusting two months.
May 17, 2010
Tonight, I made some canges to how the symbol table is handled.
Local variables and arguments for a proceedure or function are
added to the symbol table, but after we are done with that function, we
need to remove those symbols so they won't get confused with locals and
arguments is other functions. The first way I tried to do this
did not work. I modified the grammar a little bit, but that
reintroduced some parsing bugs I had in the erarly days. So, I
had to be a little more clever about how I accomplished this.
Anyway, I am getting closer inch by inch to having a releasable project.
May 14, 2010
Tonight, I made the parser clean up the symbol table by removing local
variables as soon as the code for the proceedure or function is
generated.
I hope, again, to be done with
this theng real soon. I am playing with the real action compiler
to compare how it operates compared to mine. So, far, it is
comparing fairly well. And again, I really need to take my hat
off to the guy who wrote the original.. It is really amaizing
that he got the thing running in such a small memorty footprint.
May 11, 2010
Did a bit more work on the code generation for arrays. I found a
few boo-boos in various parts of the code generation. I am sure I
will be finding those for quite a while yet.
I am hoping that I will
be able to wrap this thing up shortly. This project was supposed
to be more about making a 6502 core rather than a compiler...but first
things first.
May 8, 2010
At the momemnt, I seem to now have all of the basic structured
programming code sequences working.. Now, it is time to get down
to the nitty gritty. I am now going back and re-examining record
types and arrays and pointers. This is probably going to be the
most complex of the code generation routines in the whole bunch.
At least now I have a way of seeing just how the real ACTION!
compiler handles this.
May 6, 2010
Well,. tonight I got the If-Then-Else code generation working.
For a simple example, it at least generates code that is very
close to the original. There is still a lot of work to do on the
code generator. My next step is to get the logical operators AND
and OR to work correctly. Anyway, here is the output I got from
the compiler tonight:
ACTION! Ver 0.04 cross compiler for the 6502
Copyright (c) 2010 by Jim Patchell
This program is free for any use
Get Input From Consol
.SECTION "temps",$80
__TEMP_var0: .DS 16
.SECTION "args",$a0
__ARGS: .DS 16
.SECTION "code",$2000
module
proc aproc(card a,b)
card c
if a < b then c = 1
elseif a = b then c = 2
else c = 3
fi
return
NUMB DOWN NEXT
; 22 21 -1 +-PROC aproc
; 21 -1 19 +-PROCLOCALS c
; 19 7 20 +-IFSTMT
; 7 3 14 | +-IF
; 3 1 6 | | +-LT
; 1 -1 2 | | | +-IDENT a
; 2 -1 -1 | | | +-IDENT b
; 6 4 -1 | | +-EQUALS
;
4 -1 5 | |
+-IDENT c
;
5 -1 -1 | | +-CONSTANT 1
; 14 10 18 | +-ELSEIF
; 10 8 13 | | +-EQ
; 8 -1 9 | | | +-IDENT a
; 9 -1 -1 | | | +-IDENT b
; 13 11 -1 | | +-EQUALS
; 11 -1 12 | | +-IDENT c
;
12 -1 -1 | | +-CONSTANT
2
; 18 17 -1 | +-ELSE
; 17 15 -1 | +-EQUALS
;
15 -1 16 |
+-IDENT c
;
16 -1 -1 |
+-CONSTANT 3
; 20 -1 -1 +-RETURN
^Z
Processing Nodes 22:PROC
aproc_ARG__a: .DS 2
aproc_ARG__b: .DS 2
aproc:
STA aproc_ARG__a
STX aproc_ARG__a+1
STY aproc_ARG__a+2
LDA $A0+3
STA aproc_ARG__a+3
JMP aproc_Lab0
aproc_c: .DS 2
aproc_Lab0:
;If Statement
LDA aproc_ARG__a+0
CMP aproc_ARG__b+0
LDA aproc_ARG__a+1
SBC aproc_ARG__b+1
BCC aproc_true__Lab3
JMP aproc_false__Lab2
aproc_true__Lab3:
LDA #1
STA aproc_c+0
LDA #0
STA aproc_c+1
JMP aproc_exit__Lab1
aproc_false__Lab2:
;If Statement
LDA aproc_ARG__a+0
EOR aproc_ARG__b+0
BNE aproc_false__Lab4
ORA aproc_ARG__a+1
EOR aproc_ARG__b+1
BEQ aproc_true__Lab5
JMP aproc_false__Lab4
aproc_true__Lab5:
LDA #2
STA aproc_c+0
LDA #0
STA aproc_c+1
JMP aproc_exit__Lab1
aproc_false__Lab4:
LDA #3
STA aproc_c+0
LDA #0
STA aproc_c+1
aproc_exit__Lab1:
RTS
Attributes in type field are: upel
unsigned (. for signed)-----+|||
private (. for public)------+||
extern (. for common)-------+|
long (. for short )--------+
name
rname
lev next type
a 0 int FIX (NO OCLS) u...
aproc 0 void FIX (NO OCLS) ....()
Arguments of aproc
a 0 int FIX (NO OCLS) u...
b 0 int FIX (NO OCLS) u...
End of Arguments of aproc
b 0 int FIX (NO OCLS) u...
c 0 int FIX (NO OCLS) u...
Structure table:
D:\Projects\Action>
May 2, 2010
Well, today I optimized the code generation a bit more. I finally
got around to trying to solve the problem I noted back on April 10,
2010. It turns out it was a lot easier to fix that I thought it
would be. So now when one does an assign, I no longer have all
those extra temp variables being used..
May 1, 2010
I made some minor improvements in the code generator today.
Thanks to a gentleman named Eric, I got some real code generated
by a real ACTION! compiler. I was able to see how it did certain
things and incorporated those into my compiler. Also, I was
pointed to a really nice Atari800 simulator and an ACTION! cartridge to
run in it. So, as soon as I can figure out how to get these
things to work on my computer (my screen reader interfers), I will be
able to do some major reverse enginering. Right now I am working
on relational and logical operators. I had some real klugy code
before (and still), but I am working on getting that changed.
After I get that working, it will be back to writing the code
generation for Arrays and Record types.
Things to do yet include getting rid of local symbols from the symbol
table at the end of a proceedure or function being generated. But
every time I can work on it, it starts looking more and more like a
compiler.
April 26, 2010
Last night I discovered another mistake in the actiin grammar.
This is a mistake that is in the action manual itself.
According to the BNF script, the only place that you can have a
RETURN is at the end of a function or proceedure. I remember
thinking when I saw this that this was not at all true. But I
assumed that my memory was bad. Well, it turns out my memory was
OK after all. Reading the action manual revealed that a RETURN is
supposed to be able to go anywhere.. Now, the bad thing is that
this adds another abiguity to the grammar. Like I needed another
one like I need a hole in my head. So, to solve this, I did the
following. I reallized that the only place that made sense (that
I could see at least) to put a RETURN statement was inside of an if
statement.....for instance:
IF a > 6 THEN RETURN
ELSE <do something else> FI
It makes no sense to have a return anywhere else, so this is the
restriction I made. Now it may turn out that I was wrong, so I
may have to rethink things a bit.
April 24, 2010
I have made the keywords so that they are no longer case sensitive.
This is a bit more like the original action. So PROC and
proc now do the same thing. However, Identifiers are case
senistive, so MYINT and myint are two distinct objects. This is
not the same as thre real action.
I am also
starting to work on some of the finer details of action. Such as
initializisations. I am still trying to figure out the
rules for just how this applies to PROC and FUNC declarations.
April 19, 2010
The code hasn't really changed much. I have been cleaning the
files up a bit, adding commnts where needed, and such..
The code is still nowhere near being ready to anounce. I still
have a lot of work to do on the code that generates Array and Type
references. I also need to work on the code where the compiler
defines the address that function, proceedures and variables are
located at.
I still have not visited the optimazations I
outlined below. I am not going to worry yet about really stupid
assembly code being generated.
April 17, 2010
Just don't have as much time to work on this thing right now. We
are in the process of trying to sell my Mother-InLaaws home. It
is kind of sad.
Anyway, I have been
doing a lot of work cleaning up the code a bit. I am starting to
make sure that the created values are released when they should be.
Previous version leaked resourcses like a sieve. It still
leaks, but not as bad. Anyway, it looks like it is time to get
back to actually tesing generated code again. Hopefully, in a few
more weeks I can start working on the multiply and divide functions..
April 10,2010
Well, things are still going forward.. I am trying to think of
ways to optimize the code that is generated. I think I might be
able to do this by adding an extra value to a lot of the code
generation proceedures. For example:
A = B + C
Generateds a parse thre lke thins,:
EQUALS
+ IDENT A
+ ADD
+IDENT B
+IDENT C
Generates code like:
LDA _B
CLC
ADC _C
STA TEMP
LDA TEMP
STA _A
Very obviously could be written as:
LDA _B
CLC
ADC _C
STA _A
I think this can be accomplished by letting the BINARY_OP code know
that instead of storing the valye in a temp, it can just go ahead and
store it in the final destination. Not reallty sure how I am
going to do this,but I think I should be able to look at the syntax
tree and figure that out, somehow.
April 9, 2010
Did some more work tonight on the code generator. Things
are a bit chaos in there since I am basically learning how to write a
code generator as I go. Stupid things that compilers do are
becoming a lot more clear to me now. It is not easy to fix those
things. That is why real compiler writers get paid those big
bucks I guess. Still, I am trying to make the code generator do
the best it can.. The biggest problem area are relational
operators.
I also fixed a bug in the Lexical
Analyzer. It was not correctly tokenizing '==RSH', ==LSH','==MOD'
assignment operators.
April 6, 2010
I am in the process now of checking code generation. I
write a very simple Action program and then check the results with a
6502 simulator that runs on the PC. I am hoping that in a few
months, I will actually be able to test thie code on a real atari 800.
Up to now, I think I have gotten simple relation operators to
function correctly, and BINARY operators and assignments work.
And DO - OD generates an infinate loop just like it should.
The code is not going to be very optimal. If I can get the
code generator debugged, I might see what I can do to elimnate some tf
the code ineficianties.
.
March 20, 2010
Still making progress, sort of. I am back tracking a litttle bit.
I worte some code to manage the 6502 resources (I mean the A, X
and Y reg :-) ). Hopefully, this is going to make it a bit easier
to do the code generarator. Writing the code generation for
ARRAYS seems to be about the most difficult task I have encountered so
far.
I finally also managed to disasemble my only copy of real
ACTION object code I have and managed to relearn a few things/ I
am probably not going to end up generating exactly the same code that
ACTION did. But, if somebody really wants that...well, they can
rewrite the code generator.
I have also changed the way I am
distributing the code. I used to upload a snap shoot every few
days, but that was really getting cumbersom. So now, I have a
link at the top of the page where you can get the code.
March 18, 2010
Progress is slowing a bit. My eyesight has deteriorated just a
bit making it more difficult to program. However, I
have gotten the mechinisms in place for doing proceedure calls and
passing parammeters. Parameter passing was pretty simple in
action. There was some space set aside on page zero that the data
was stored in and then recovered byt the called routine. I also
seem to recall that the first 3 bytes were stored in the A,X,Y register
respectfully. This seems to make things more complicated. I
might change this.
March 15, 2010
I now have a good portion of the code generator written. I am
sure there are some major problems in it, but I am confident I can work
those out.. It really is cool to see source code being translated
into assembly language. I am really feeling a lot more respect
for compiler writers. My effort is really a very simple
implementation. How one could optimize the code is beyond
me. I have found some good books on the subject, but right now,
reading is not very easy for me.
I still need to write a fair amount of code generator code. I
still have to do function calls, passing arguments, array and structure
access code.
No code upload this time. I should do so again in a few days.
I am also thinking about rewriting all of the Holub routines I am using right now. just to avoid....proglems.
March 10, 2010
Still making good progress. I have the compiler now generating
assembly code that one can recognize as a program. At the moment,
I have only code generation for BYTE types. This turned out to be
a good plan from the standpoint that I am learning a lot about
genererating code. This is a lot more difficult and tedious than
I imagined. There have been some minor fixes to the grammar, and
a lot of redundent code has been written. As soon as I get the
thing working, I will go in and clean up this monstrosity.
March 6, 2010
Still making progress. So far today, I have written the code
generation routines for getting arguments that are passed to a
function. This is the hardest part, since I am very rusty at
writing 6502 code. (I am much more adept these days at writing
AVR code).
March 5, 2010
Progress is being made. I have the rudiments of a "code
generator" going. Well, I output the assembly declarations for
data and varaibles. This is the easy part. Sure was a lot
more difficult than I thought. Anyway, now I will start working
on the actual code generator. This is going to be tough. As
I don't have access to any of my 6502 assembly language books...well,
even if I did, it would be difficult to read them....since I am blind.
It does look like I will complete this thing in one form or another.
I am hoping by next week to have all of the code generation code
written. This isi a pretty tall order. Trying to figure out
what all the differnt combinations are for various sequences of code is
not going to be easy.
Also, I may have to write my own assembler.
March 4, 2010
It looks like I have the parser more or less done now. I have the
skeleton code for the abstract syntax tree processor completed, so it
looks like I can actually start writing code generation routines.
This means I need to pick an assembler, I suppose. Or
finsish one I started to write a long time ago. Still, this is
pretty exciting. Considering all of the false starts I had to go
through to get here. So, it looks like I will be settling on
using a parser written using the ANAGRAM parser generator. I
would still like to write a parser using the recursive decent methode,
but for now, that will be a project I may get back to. Using
Anagram makes it a lot easier to add features to the compiler.
One feature I want to add is an inline assembly feature.
March 2, 2010
Things are still progressing. I am fully committed now to the
ANAGRAM parser. It seems to be working pretty good now that I
have all of the grammar problems fixed.
Another problem I had to
fix recently was learning to deal with the token contxt feature.
After I figured that out, it was pretty easy to understand and
you will find it implemented in the parser now.
Another problem
I noticed is that my Lexical Analyzer has some problems, more than
likely created by the fact I can't see a whole lot any longer. I
will fix those in my next session.
Hopefully, in a few
more days I will actually start on the Abstract Syntax Tree processing,
wchich is where I begin to generate code.
Feb 28, 2010Several problems have cropped up since the last entry..
1.
The parser generator ACCENT turns out to have one major flaw.
It will not parse grammars where the tokens need to be modified
by semantic actions. I am not entirely giving up on ACCENT, but,
until I can think of a way to get around this limitation, I am back
using ANAGRAM as the parser generator.
2. An alternative parser
generator, BISON, could also do the job. But I installed the
latest version and it gives some obscure error that I have not been
able to find out what is wrong. The error occurs in the m4 macro
processor. This is too bad, because BISON has a GLR parser
generator which would also be able to parse an ambigous grammar like
ACTION!.
3. Even using ANAGRAM, the problem I have is that
there is still some sort of an ambiguity in the grammar. I have
manage to fix some of them, and therse were due mostly to mistakes that
were made in the grammar description in the ACTION! manual itself.
I will be updating the grammar specification doc to reflect this.
But right now, the main conflict seems to arise from these
statements:
MODULE
BYTE one,two,three
BYTE POINTER pone,ptwo,pthree
BYTE ARRAY aone,atwo,athree
BYTE FUNC afunc()
I changed the grammar just a little bit to require the following:
MODULE
BYTE one,two,three
BYTE POINTER pone,ptwo,pthree
BYTE ARRAY aone,atwo,athree
MODULE
BYTE FUNC afunc()
(Please note, the current grammar does not have this problem .... Jim March 20,2010)
This
seems to make the code parsable but not compatable 100% with the
original ACTION!. Although, this is a lot closer than I have been
in the past.
4. Another parrallel path I am taking is trying to
write a recursive decent parser for ACTION!. The problem with
this is that a recursive decnet parser is an LL(k) parser, which means
I cannot have any left recursion. For example:
IdentList: Ident
| IdentLst Ident
;
Needs to be
IdentList: Ident IdentList
;
This
means I need to remove all of the left recursion from the grammar.
This is funny, because in an LALR grammar, right recursion needs
to be avoided (because it uses up lots of stack).
Last Minute update!It
looks like I have fixed all of the known amibuities in the grammar.
So, now all I need to do is start to fill in the rest of
the code that actually does things. One thing for sure, I have
learned a lot more about parsers in the last month. And I thought
I was already pretty good.
Anyway, what I need to do now is
finish up the code for doing the declarations and symbol tables, which
is one of the more tedious parts of the project.
Feb 21, 2010I
am making good progress on the compiler. Right now, I have it
generating an abstract syntax tree for the code sections and a very
good portion of the declarator section working. The TYPE
productions generate tables describing the custom data types, although,
I don't have the part working yet where you can declare those custom
types. I am working on the code for initializing variables and
what not. This is problably one of the hardest things to do when
writing a compiler.
I really like ACCENT. So far, I have
found no problems with it. I thought I was having a problem, but
it turned out to be a mistake in the BNF grammar that was in the
ACTION! manual.
Feb 17, 2010My recent experiences with the ACCENT compiler compiler.
I
have been trying to use the ACCENT parser generator to recreate
ACTION!. The reason for this is that ACTION! seems to be an
ambiguous grammar. ACCENT is able to deal with amibuous grammars
so it makes a lot of sense. It has not been without its problems
however. Fortunately, this has been because of my ignorance
rather than any real problems with ACEENT. It took me a
little while to figure out how to interface ACCENT with FLEX. My
biggest mistake was that I created a production in FLEX for handling
the end of file event. It seems that ACCENT just did not
understand what my iintentions were. It took me quite a while
before I discovered I was thinking too hard. Then there was
the matter of the semantic actions. For example, dealing with an
DENTIFIER.
In othere parsers, I would have something like this:
lexer
{ID} {return IDENTIFIER;}
parser
name ::= IDENTIFIER { printf("ID is:%s\n",yytext);}
While
this works with just about all of the parser generators I have used in
the past (YACC, BISON, LALR, ANAGRAM), it does not work with ACCENT.
This is because ACCENT reads in and parses the entire source file
before it executes the first semantic action. By that time,
yytext has been pretty thouroghly oblitterated.
Dealing with this is fairly simple, but it was a problem that had to be solved.
So
far, I am pretty impressed with ACCENT. When you consider the
fact that it is free, it can not be beat. Hopefully, I will
complete my first ACTION! parser, and then I will know for sure.
Feb 13, 2010Well,
today I created a Grammar for ACTION! using the BNF script that is in
the back of the ACTION! manual. This was not as easy as I
thought. Turns out there are a few mistakes in that grammar, but
I think I have fixed them. I used Anagram to write the grammar
since this is the most friendly parser generator I have. I was
hoping that maybe this grammar was not ambiguous. FAT chance.
At the moment, this grammar has 16 conflicts. I did a
simple test of the grammar, and it seems to parse more or less
correctly. So, despite the confilict, it may be OK. I can
also try this using ACCENT as well (ACCENT takes care of ambiguous
grammars for you at the cost of bigger parsers). So, this is all
looking more promising. The original BNF for ACTION! sure seems
like it behavwes like the original.
PARSER FILE for ANAGRAMFeb 11, 2010I Have the BNF grammar for ACTION!
OK, today I did not actually work on my own code, but rather, I transcribed
Apendix
A from the Atari ACTION! manual. Somebody on the Atari AGE 8 bit
Atari formum pointed me to a PDF of the scanned manual.
Unfortunately this was all but impossible for me to read
comfortably. But, I was able to read it well enough to retype it
in. What is so special about this appendix? Well, it has
the BNF script in it for the ACTION language. This means that I
will be able now to reproduce a fairly accurate version of the
compiler, at least as far as the language itself goes.
Anyway, here is
Apendix A in PDF form. It is entirely possible it has some typos in it...after all, it was typed in by a blind guy!
You
can compare it to the BNF scripts I have done...I got close in some
instances...was way off base in others. I will be curious to see
how many conflicts there are in this grammar.