This page is a mirror of Tepples' nesdev forum mirror (URL TBD).
Last updated on Oct-18-2019 Download

lazymake/lazy65 - a ca65 pre-parser

lazymake/lazy65 - a ca65 pre-parser
by on (#128353)
Hey folks,

I got fed up with having to write header files and ca65's limitations when working with scopes so I created this little tool.
This is what it allows you to do:

File: Module.z
Code:
.segment "CODE"
func1:

.proc func2
   var1: .reszp 1
.endproc

.macro someMacro arg1, arg2
.endmacro

File: main.z
Code:
.use Module

main:
   jsr Module.func1
   
   lda #0
   sta Module.func2.var
   jsr Module.func2
   
   Module.someMacro 1, 2

Code:
> lazy65 Module
> lazy65 main

This will generate ca65-compatible header and source files that you can integrate into your build process. However, a generic build script (lazymake) is also included which can take care of everything for you.
Python 2 is required.

==============
DOWNLOAD
lazy65 V0.1.4 (current) (May 13, 2015)
lazy65 V0.1.3 (May 18, 2014)
lazy65 V0.1.2 (May 11, 2014)
lazy65 V0.1.1 (May 3, 2014)
lazy65 V0.1.0
==============

Planned features
    - python macros (.pymacro)
    - automatic generation of linker config files for common mappers
    - maybe a couple of extra commands that make life easier

The tool is still in a somewhat early stage and currently identifies and replaces symbols in a rather lazy way which may result in cryptic error messages, I'm hoping to fix that in a later version. If you decide to give it a try, please let me know if you encounter any problems. There may be unresolved bugs with certain ca65 commands (.struct?) that need fixing.
Re: lazy65 - a ca65 pre-parser
by on (#128355)
I did a kind of hacky thing with macros to scope macros that are a part of a header interface:
viewtopic.php?p=112437#p112437

Not sure if I will keep it, but the idea isn't too messy and it does work, with the only downside being you can't access a variable constant, as in:
myscope::foo .set 1
Since it will be interpreted as a macro call. Also, if there is an error in a macro call you'll get a couple of extra error messages as the errors trace through the macro calls. (You may need higher verbosity setting to see this.)
Re: lazy65 - a ca65 pre-parser
by on (#128358)
Seems cool.

I don't know if I'm in the minority here, but when I installed Python on Windows, it didn't by default associate .py files to run with Python. So just typing "lazymake.py" doesn't work here (I have .py associated with a text editor).

One way to fix that could be to provide lazy65.cmd and lazymake.cmd (for Windows) and lazy65 and lazymake shell scripts (for *nix) in the base directory. Then a simple "lazy65" or "lazymake" could be used to invoke the scripts.

lazy65.cmd and lazymake.cmd could look like this:
Code:
@echo off
python %~dpn0.py %*

Not sure what the *nix counterparts would be. Also need to change LAZY65 in lazymake.py from lazy65.py to lazy65. I think I may have missed some other place where it tries to run lazy65.py, because when I run lazymake, lazy65.py opens in my text editor. :)

Aaaand, not sure if I just messed something up with my changes, but when I run lazymake, it occasionally picks a different compilation order and fails to compile the "basic" example.

Here's a run that failed (didn't compile Graphics before main):
Code:
C:\Users\f\Downloads\lazy65-0.1.0\examples\basic>lazymake
lazy65 -s "src" -o "obj" Global
lazy65 -s "src" -o "obj" Module
lazy65 -s "src" -o "obj" Graphics.Sprite
lazy65 -s "src" -o "obj" Graphics.Tile
lazy65 -s "src" -o "obj" main
Traceback (most recent call last):
  File "C:\Users\f\Downloads\lazy65-0.1.0\lazy65.py", line 92, in <module>
    main()
  File "C:\Users\f\Downloads\lazy65-0.1.0\lazy65.py", line 80, in main
    lines = parser.parse() #2nd pass
  File "C:\Users\f\Downloads\lazy65-0.1.0\src\tempy.py", line 46, in parse
    self.lineCallback()
  File "C:\Users\f\Downloads\lazy65-0.1.0\lazy65.py", line 20, in lineCallback
    asm.parse()
  File "C:\Users\f\Downloads\lazy65-0.1.0\src\Assembler.py", line 185, in parse
    self.command(tok.text)
  File "C:\Users\f\Downloads\lazy65-0.1.0\src\Assembler.py", line 385, in command
    self.importModule(moduleName, scopeName, True, True)
  File "C:\Users\f\Downloads\lazy65-0.1.0\src\Assembler.py", line 115, in importModule
    self.importSingleModule(moduleName, scopeName, generateIncludes)
  File "C:\Users\f\Downloads\lazy65-0.1.0\src\Assembler.py", line 85, in importS
ingleModule
    with open(symfile,'rb') as f:
IOError: [Errno 2] No such file or directory: 'obj/Graphics.sym'
lazymake.py: Error 1

And here's a one that succeeded (I did lazymake clean inbetween):
Code:
C:\Users\f\Downloads\lazy65-0.1.0\examples\basic>lazymake
lazy65 -s "src" -o "obj" Global
lazy65 -s "src" -o "obj" Module
lazy65 -s "src" -o "obj" Graphics.Sprite
lazy65 -s "src" -o "obj" Graphics.Tile
lazy65 -s "src" -o "obj" Graphics
lazy65 -s "src" -o "obj" main
ca65 "obj/Global.s" -o "obj/Global.o"
ca65 "obj/main.s" -o "obj/main.o"
ca65 "obj/Module.s" -o "obj/Module.o"
ca65 "obj/Graphics/Sprite.s" -o "obj/Graphics/Sprite.o"
ca65 "obj/Graphics/Tile.s" -o "obj/Graphics/Tile.o"
ca65 "obj/Graphics.s" -o "obj/Graphics.o"
ld65 -o "basic.nes" -C linker.cfg "obj/Global.o" "obj/main.o" "obj/Module.o" "ob
j/Graphics/Sprite.o" "obj/Graphics/Tile.o" "obj/Graphics.o"
basic.nes: Build complete
Re: lazy65 - a ca65 pre-parser
by on (#128365)
Movax12 wrote:
I did a kind of hacky thing with macros to scope macros that are a part of a header interface:
viewtopic.php?p=112437#p112437

Oh, I never checked that topic again. Interesting. A bit of nasty boilerplate code, but still, it goes to show how powerful ca65 really is.

thefox wrote:
lazy65.cmd and lazymake.cmd could look like this...

Thanks, added them!

thefox wrote:
Aaaand, not sure if I just messed something up with my changes, but when I run lazymake, it occasionally picks a different compilation order and fails to compile the "basic" example.

It was most likely a race condition with the multi-threaded compilation going on. Anyway, thanks for your feedback, I added dependency file generation and based the build system around it which will hopefully eliminate these errors.

Updated download link in first post.
Re: lazy65 - a ca65 pre-parser
by on (#128366)
Trivial error on line 85 in Assembler.py:
Code:
C:\Users\f\Downloads\lazy65-011\examples\basic>lazymake
lazy65 --sym-only -s "src" -o "obj" Module
Traceback (most recent call last):
  File "C:\Users\f\Downloads\lazy65-011\lazy65.py", line 8, in <module>
    from src.Assembler import Assembler
  File "C:\Users\f\Downloads\lazy65-011\src\Assembler.py", line 85
    raise tempy.Error('Could not create symbol file for module '+moduleName+')
                                                                             ^
SyntaxError: EOL while scanning string literal
lazymake.py: Error 1


And if you want to add *nix support, this "npm" shell script from node.js may be a good template to base "lazy65" and "lazymake" on:
Code:
#!/bin/sh

basedir=`dirname "$0"`

case `uname` in
    *CYGWIN*) basedir=`cygpath -w "$basedir"`;;
esac

if [ -x "$basedir/node.exe" ]; then
  "$basedir/node.exe" "$basedir/node_modules/npm/bin/npm-cli.js" "$@"
else
  node "$basedir/node_modules/npm/bin/npm-cli.js" "$@"
fi

EDIT: In hindsight, I'm not sure if this script is the same one that ships with the *nix installations of node.js.
Re: lazy65 - a ca65 pre-parser
by on (#128367)
Woops, fixed.
Cool. I am going to look into that.
Re: lazy65 - a ca65 pre-parser
by on (#128368)
*nix support should just involve having the right #! line in the original python script... and preferably not having ".py" in the command name, which is probably best solved with symlinks.
Re: lazy65 - a ca65 pre-parser
by on (#128369)
lidnariq wrote:
*nix support should just involve having the right #! line in the original python script... and preferably not having ".py" in the command name, which is probably best solved with symlinks.

How do you plan to put a symlink in a zip file?
Re: lazy65 - a ca65 pre-parser
by on (#128371)
Zip doesn't preserve the executable bit either, so it already requires finessing: zip is poorly suited to unixy things. The options are "accept having .py at your command line", "use a different compressor" (tgz, 7z, rar), or "rename the files to not end with .py"
Re: lazy65 - a ca65 pre-parser
by on (#128372)
lidnariq wrote:
Zip doesn't preserve the executable bit either

True.
Re: lazy65 - a ca65 pre-parser
by on (#128650)
Updated. Fixed a couple of bugs and added the custom commands .reszp and .resbss.

This:
Code:
.proc func
    .segment "ZEROPAGE"
        localvar: .res 1
    .segment "CODE"
    rts
.endproc

can now be written like this:
Code:
.proc func
    localvar: .reszp 1
    rts
.endproc

.reszp and .resbss use the ca65 commands .pushseg and .popseg when translated so the segment you are in will be automatically restored.

I also got rid of the .py extensions so now the tools can be called the same way in both Windows and Linux (by just typing "lazy65" or "lazymake").
Re: lazy65 - a ca65 pre-parser
by on (#128666)
I like the res command. I did that too (macros):

Code:
 ; Example of declaring variables using .struct syntax.
        resZP { \
                foo     .byte ,     \
                bar     .word ,     \
                test    .addr 6     \
        }
 
        resBSS { myVar  .byte, yourVar  .addr 4 }
        resBSS  baz     .byte