It is currently Mon Dec 10, 2018 7:52 am

All times are UTC - 7 hours





Post new topic Reply to topic  [ 160 posts ]  Go to page 1, 2, 3, 4, 5 ... 11  Next
Author Message
PostPosted: Wed Jul 03, 2013 5:47 pm 
Offline
User avatar

Joined: Wed Oct 15, 2008 11:50 am
Posts: 943
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 146 times


Last edited by qbradq on Sat Dec 28, 2013 5:27 pm, edited 12 times in total.
Top
 Profile  
 
PostPosted: Thu Jul 04, 2013 8:31 am 
Offline
User avatar

Joined: Mon Jan 03, 2005 10:36 am
Posts: 3141
Location: Tampere, Finland
My comments:

Code:
; 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:
; 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:
; 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


Top
 Profile  
 
PostPosted: Thu Jul 04, 2013 10:41 am 
Offline
User avatar

Joined: Fri Nov 19, 2004 7:35 pm
Posts: 4108
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!


Top
 Profile  
 
PostPosted: Thu Jul 04, 2013 10:57 am 
Offline
User avatar

Joined: Wed Oct 15, 2008 11:50 am
Posts: 943
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:
; 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:
; 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.


Top
 Profile  
 
PostPosted: Thu Jul 04, 2013 11:10 am 
Offline
User avatar

Joined: Mon Apr 04, 2011 11:49 am
Posts: 2096
Location: WhereverIparkIt, USA
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


Top
 Profile  
 
PostPosted: Thu Jul 04, 2013 11:26 am 
Offline
User avatar

Joined: Sun Jan 02, 2011 11:50 am
Posts: 522
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.


Top
 Profile  
 
PostPosted: Thu Jul 04, 2013 11:57 am 
Offline
User avatar

Joined: Mon Apr 04, 2011 11:49 am
Posts: 2096
Location: WhereverIparkIt, USA
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:
x = function (y, z)


Just adopt a subroutine style/midset that the first/last parameter is 'returned'.
Code:
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


Top
 Profile  
 
PostPosted: Thu Jul 04, 2013 12:44 pm 
Offline
User avatar

Joined: Wed Oct 15, 2008 11:50 am
Posts: 943
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.


Top
 Profile  
 
PostPosted: Thu Jul 04, 2013 1:21 pm 
Offline

Joined: Sun Sep 19, 2004 11:12 pm
Posts: 20851
Location: NE Indiana, USA (NTSC)
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:
word dataPointers[10] in BSS0

export sub doesSomething byte idx, byte offset in CODE7
  ; etc.
end sub


Quote:
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.

Quote:
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.


Top
 Profile  
 
PostPosted: Thu Jul 04, 2013 2:24 pm 
Offline
User avatar

Joined: Thu Jan 19, 2006 5:08 pm
Posts: 753
Location: Shelton, Washington.
The SUB function looks like how QuickBasic and FreeBasic does SUBs,

The same math functions are also featured in the compilers mentioned above!

_________________
AKA SmilyMZX/AtariHacker.


Last edited by Hamtaro126 on Thu Jul 04, 2013 2:28 pm, edited 1 time in total.

Top
 Profile  
 
PostPosted: Thu Jul 04, 2013 2:28 pm 
Offline

Joined: Wed Mar 09, 2005 9:08 am
Posts: 419
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/


Top
 Profile  
 
PostPosted: Thu Jul 04, 2013 4:38 pm 
Offline
User avatar

Joined: Wed Oct 15, 2008 11:50 am
Posts: 943
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 :)


Top
 Profile  
 
PostPosted: Thu Jul 04, 2013 4:47 pm 
Offline
User avatar

Joined: Fri Nov 19, 2004 7:35 pm
Posts: 4108
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!


Top
 Profile  
 
PostPosted: Thu Jul 04, 2013 4:54 pm 
Offline
User avatar

Joined: Mon Apr 04, 2011 11:49 am
Posts: 2096
Location: WhereverIparkIt, USA
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


Top
 Profile  
 
PostPosted: Thu Jul 04, 2013 6:48 pm 
Offline
User avatar

Joined: Wed Oct 15, 2008 11:50 am
Posts: 943
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.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 160 posts ]  Go to page 1, 2, 3, 4, 5 ... 11  Next

All times are UTC - 7 hours


Who is online

Users browsing this forum: Google [Bot], Great Hierophant and 3 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group