uc65, a Mid-Level Language Compiler READY FOR USE!

Discuss technical or other issues relating to programming the Nintendo Entertainment System, Famicom, or compatible systems. See the NESdev wiki for more information.

Moderator: Moderators

Post Reply
User avatar
qbradq
Posts: 972
Joined: Wed Oct 15, 2008 11:50 am

uc65, a Mid-Level Language Compiler READY FOR USE!

Post by qbradq »

Update

uc65 is now recommended for use! Please report any bugs, issues or feature requests to this thread or the project's issue tracker.

Status

Micro Code 65 is a mid-level language compiler targeting the cc65 tool chain with a focus on the NES target. The current release candidate of version 0.5 is feature complete and ready for testing for large-scale development. This release candidate is being tested through practical application prior to promotion for release.

The project's source code, documentation and road map can be found on the project site.

Attached to the thread is the latest binary distribution of the compiler along with Windows executables of the cc65 tool chain for your convenience. This package is also hosted on the project's page. The compiler should run on any platform supporting the Java Desktop profile. It has been confirmed to run correctly on 64-bit Linux and 32-bit Windows systems.
Attachments
uc65-release-0.5-rc6.zip
(741 KiB) Downloaded 407 times
Last edited by qbradq on Sat Dec 28, 2013 5:27 pm, edited 12 times in total.
User avatar
thefox
Posts: 3134
Joined: Mon Jan 03, 2005 10:36 am
Location: 🇫🇮
Contact:

Re: uc65, a Mid-Level Language Compiler for the cc65 Toolch

Post by thefox »

My comments:

Code: Select all

; ROM statements tell the compiler what ROM bank to place ROM-able code and data
; into.
rom 0

; RAM statements tell the compiler what RAM bank to place variables into.
ram 1
What's the reason for not using cc65's built-in segmentation ability?

Code: Select all

; Anything declared as extern can be imported from another file
extern byte somePig
I don't like the naming of "extern" here. In C it's used for the exact opposite purpose (importing), and I read the word as "external" in that context. I would rather use "export", but that maybe because I'm so used to ca65's use of that word.

Code: Select all

; Subroutines can have parameters, but do not return values
sub doesNothing byte first byte second
Not really a fan of this format for defining the parameter list, I think the parameters should be separated by something at least (for readability). Or the separator (comma) could be optional, I'm sure some masochists prefer not having it...

Also why no return values? Maybe make it possible to define "in" and "out" parameters.
Download STREEMERZ for NES from fauxgame.com! — Some other stuff I've done: fo.aspekt.fi
User avatar
Dwedit
Posts: 4924
Joined: Fri Nov 19, 2004 7:35 pm
Contact:

Re: uc65, a Mid-Level Language Compiler for the cc65 Toolch

Post by Dwedit »

In C, "static" means don't export it, and no qualifier means export it.
Here come the fortune cookies! Here come the fortune cookies! They're wearing paper hats!
User avatar
qbradq
Posts: 972
Joined: Wed Oct 15, 2008 11:50 am

Re: uc65, a Mid-Level Language Compiler for the cc65 Toolch

Post by qbradq »

Thank you for the feedback TheFox! The rom and ram statements are using segments under the hood. The default code generator used the names "BSSn" and "ROMn" for the respective banks. BSS0 is assumed to be in zero page. Do you have a suggestion for how I could handle this better? It's on the road map to improve this.

I agree on the extern keyword naming. I had intended to name it export and kept confusing myself ;)

As for subroutine parameter lists, we're getting into some forward-looking subjects. Let me run it down for you and see what you think.

Code: Select all

; Declare an array
byte someArray,4

; Reference array members
someArray,0 = someArray,1 + someArray,2

; Call a subroutine
someSub someArray,0 otherParam
As you can see, using the comma for array dimensions means we can't use commas to separate subroutine parameters during a call. I chose this style of array dimensions to reduce the total amount of punctuation and shifts required. With the parser I have now though I'll know in advance if something is an array or not and could handle it that way, but it still looks kinda strange.

Thinking ahead to a few other features I want, maybe this would work better:

Code: Select all

; Declare an array
word dataPointers[10]

; Define a subroutine
export sub doesSomething byte idx, byte offset
    ; Declare a pointer
    address dataAddress

    ; Reference an array
    dataAddress = dataPointers[idx]

    ; Pointer manipulation
    byte val1
    val1 = (dataAddress)
    val1 = (dataAddress),offset
    dataAddress += 1
    val1 = (dataAddress)

    ; Calling other subroutine
    otherSub val1, (dataAddress), dataAddress
end sub
As for not having return values from subroutines, this is part of the language's design as a finite state machine description, much like the early BASIC dialects.

I need to add functions to the road map. Early BASIC dialects allowed single-expression functions as a way to inline a computational expression in an abbreviated form. In uc65, a function will be a special case of subroutine which may only contain assignment and flow control statements and generates inline code.

In this way there are no automatic or "magic" storage or intermediate variables.
User avatar
infiniteneslives
Posts: 2104
Joined: Mon Apr 04, 2011 11:49 am
Location: WhereverIparkIt, USA
Contact:

Re: uc65, a Mid-Level Language Compiler for the cc65 Toolch

Post by infiniteneslives »

very awesome to see things getting started, great work! Looking forward to playing around with this, and future releases.
If you're gonna play the Game Boy, you gotta learn to play it right. -Kenny Rogers
User avatar
Movax12
Posts: 541
Joined: Sun Jan 02, 2011 11:50 am

Re: uc65, a Mid-Level Language Compiler for the cc65 Toolch

Post by Movax12 »

you could limit the return values to the a x y registers. if that is not enough for someone, they can return a pointer or set up a memory buffer somewere else.

or maybe I'm just thinking too low level.
User avatar
infiniteneslives
Posts: 2104
Joined: Mon Apr 04, 2011 11:49 am
Location: WhereverIparkIt, USA
Contact:

Re: uc65, a Mid-Level Language Compiler for the cc65 Toolch

Post by infiniteneslives »

While we all like return variables, it can be easy to get around not having them in your code by passing in the variable/pointer you want modified. Is it pass by reference or value? We're used to pass by value, and I'm guessing this is pass by reference for the global variables at least which makes this simpler.

Instead of this:

Code: Select all

x = function (y, z)
Just adopt a subroutine style/midset that the first/last parameter is 'returned'.

Code: Select all

function (y, z, x)
Are my presumptions correct?
If you're gonna play the Game Boy, you gotta learn to play it right. -Kenny Rogers
User avatar
qbradq
Posts: 972
Joined: Wed Oct 15, 2008 11:50 am

Re: uc65, a Mid-Level Language Compiler for the cc65 Toolch

Post by qbradq »

Passing an address to a subroutine is one way of getting data back. Another is to use a global variable to store the computed result.

There's a key difference in mindset here though. Subroutines are for implementing behavior. Functions are for computing values in a convenient way. This is modeled after the early BASIC environments. This compiler is in many ways a compiled BASIC with a cleaned up syntax.

I value the community input! Thank you all very much.
tepples
Posts: 22708
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: uc65, a Mid-Level Language Compiler for the cc65 Toolch

Post by tepples »

qbradq wrote:Thank you for the feedback TheFox! The rom and ram statements are using segments under the hood. The default code generator used the names "BSSn" and "ROMn" for the respective banks. BSS0 is assumed to be in zero page. Do you have a suggestion for how I could handle this better? It's on the road map to improve this.
Try syntax like this:

Code: Select all

word dataPointers[10] in BSS0

export sub doesSomething byte idx, byte offset in CODE7
  ; etc.
end sub
As for not having return values from subroutines, this is part of the language's design as a finite state machine description, much like the early BASIC dialects.
It's common practice at least in my 6502 programs for assembly language subroutines to act as functions, leaving results in C:A, X, and Y for the caller to pick up, as Movax12 suggested.
Subroutines are for implementing behavior. Functions are for computing values in a convenient way.
At least in my calling conventions, subroutines can also return whether a behavior was performed or not (a "result code"), or the number of behaviors that were performed, or whether a behavior results in other behaviors that need to be performed.
User avatar
Hamtaro126
Posts: 818
Joined: Thu Jan 19, 2006 5:08 pm

Re: uc65, a Mid-Level Language Compiler for the cc65 Toolch

Post by Hamtaro126 »

The SUB function looks like how QuickBasic and FreeBasic does SUBs,

The same math functions are also featured in the compilers mentioned above!
Last edited by Hamtaro126 on Thu Jul 04, 2013 2:28 pm, edited 1 time in total.
AKA SmilyMZX/AtariHacker.
Bananmos
Posts: 552
Joined: Wed Mar 09, 2005 9:08 am
Contact:

Re: uc65, a Mid-Level Language Compiler for the cc65 Toolch

Post by Bananmos »

Any reason why you are writing your own parser backend from scratch? In my humble opinion that choice often leads to lots of headache fixing bugs in your parsing that could be better spent making the compiler itself :)

http://dinosaur.compilertools.net/
User avatar
qbradq
Posts: 972
Joined: Wed Oct 15, 2008 11:50 am

Re: uc65, a Mid-Level Language Compiler for the cc65 Toolch

Post by qbradq »

I've used Lex and Yacc in the past. I wrote my first several compilers with them. Then I read the excellent article series Let's Build a Compiler by Jack Crenshaw. Although dated (with example code in Pascal) it's still the most effective way to write a compiler, in my opinion. Jack even addresses the question of "why not use a parser generator" in the series. That's just the way I prefer to do things now.

I guess I'm going to have to re-think the whole return value thing. Passing a return value through A works very well. Extending that to either the X/Y registers or the stack has a lot of problems though.

So I've researched ca65's .dbg statement and wrote it up here. If anyone knows what the "type" parameters are and what they mean I'd be very interested to know. Also, a clarification of the REGISTER storage type would be helpful.

I've finally finished the second quest of the Legend of Zelda! So I might start making quicker progress on this now :)
User avatar
Dwedit
Posts: 4924
Joined: Fri Nov 19, 2004 7:35 pm
Contact:

Re: uc65, a Mid-Level Language Compiler for the cc65 Toolch

Post by Dwedit »

The thing is, you really have no idea how to effectively use LEX and YACC until after you've attempted to reinvent the wheel, then you see how to use them.
Here come the fortune cookies! Here come the fortune cookies! They're wearing paper hats!
User avatar
infiniteneslives
Posts: 2104
Joined: Mon Apr 04, 2011 11:49 am
Location: WhereverIparkIt, USA
Contact:

Re: uc65, a Mid-Level Language Compiler for the cc65 Toolch

Post by infiniteneslives »

qbradq wrote:I guess I'm going to have to re-think the whole return value thing. Passing a return value through A works very well. Extending that to either the X/Y registers or the stack has a lot of problems though.
While restricting return values to a single byte is limiting, just having that small functionality alone is still pretty convenient/powerful. I'd say imposing that limit is a good way to provide functionality that parallels the hardware, especially since it seems to be working well on your end. Ignoring the mess of X/Y/stack, while it could have a use, it's not as straight forward or efficient so it's not a big loss IMO.
If you're gonna play the Game Boy, you gotta learn to play it right. -Kenny Rogers
User avatar
qbradq
Posts: 972
Joined: Wed Oct 15, 2008 11:50 am

Re: uc65, a Mid-Level Language Compiler for the cc65 Toolch

Post by qbradq »

Dwedit wrote:The thing is, you really have no idea how to effectively use LEX and YACC until after you've attempted to reinvent the wheel, then you see how to use them.
I have done both, and have better success with this method.
Post Reply