On Aug 28, 2012, at 2:50 AM, openbios-request@openbios.org wrote:
Message: 1 Date: Mon, 27 Aug 2012 21:18:08 -0400 From: Tarl Neustaedter tarl-b2@tarl.net To: The OpenBIOS Mailinglist openbios@openbios.org Subject: Re: [OpenBIOS] [PATCH] Adds local variable support to OpenBIOS. Message-ID: 503C1C50.408@tarl.net Content-Type: text/plain; charset=ISO-8859-1; format=flowed
[...]
And don't use CamelCase.
Is this some official naming convention, or your own taste?
In general (at least in the 1275 world), Forth is case-insensitive. The rare cases where it is made case sensitive (there are a couple in Sun's Openboot - see dropins.src) make use of mixed case very painful. The general standard is that methods and variables are lower case, defined constants and structure offsets are upper case. In some code, even they are lower case.
Mixed-case is generally confined to comments.
Are you saying my-variable is better than myVariable?
Factor this? You shouldn't ever use a variable that is used as a temp inside a word.
I'm not sure why you suggest this. It is just such a pain having to deal with the stack.
Because using a global variable gets you in trouble in recursion or when the same code is called at alarm level. As for stack being a pain, yes, that's forth. Stack manipulation as a way of life. Personally, I prefer "2over nip" rather than "2 pick" :-)
How do global variables get you in trouble in recursion? Do you have an example?
I am not familiar with this alarm level. Could you explain what it is?
+48 CONSTANT localTableSize
+\ Declare the local variable table +localTableSize ARRAY localVariableTable
You have 48 but can only access 12?
That is four fields per local variable: 48 / 4 = 12.
At a minimum, any derived constants should be derived explicitly. Like:
12 constant #local-variables \ Feels right. If you need more, add more code after Locals11. 4 constant /local-variable \ Datastructures require four cells #local-variables /local-variable * constant locals-table-size \ Size in cells, not bytes.
Ah. That points out another convention. When mashing together multiple words for a method or variable name, we tend to use dashes as separators (and please, don't use underscores. There is someone I know who *mixes* underscores and dashes in variable names!). Another is that sizes of things are usually /object (such as /n, /l, ...) and counts of objects are usually #object.
Ok. Sounds reasonable.
+: getLocalRecordCount +arrayCount 4 / +;
Oh. Use a struct?
The little documentation on struct I found did not indicate it was a better replacement for Array.
Struct will allow you define what the four separate words used in each local variable entry are used for. If you use structs, I'd expect to see something like:
struct /n field >LOCAL-INIT /n field >LOCAL-ORDER /n field >LOCAL-LEN /n field >LOCAL-ADDR constant /local-variable 12 constant #local-variables /local-variable #local-variables constant locals-table-size
Note that the above provides the table size in bytes, rather than cells.
To use the above (assuming you are still using alloc-mem), you'd see something like:
locals-table-size alloc-mem ( table ) #local-variables 0 do ( table ) i /local-variable * ( table entry ) 0 over >LOCAL-INIT ! ( table entry ) 0 over >LOCAL-ORDER ! ( table entry ) 0 over >LOCAL-LEN ! ( table entry ) 0 swap >LOCAL-ADDR ! ( table )
loop ( table )
That looks very unfriendly. There is no way I am using structs.
On 2012-Aug-31 09:50 , Programmingkid wrote:
Are you saying my-variable is better than myVariable?
Yes.
How do global variables get you in trouble in recursion? Do you have an example?
Not off-hand, we learn to avoid doing that. To construct one - let's take a method doing recursion properly, and break it:
\ Correct way, using stack manipulation : fibonacci ( fib -- return ) recursive dup 2 >= if ( fib ) dup 1- fibonnaci ( fib fib-1 ) swap 2 - fibonnaci ( fib-1 fib-2 ) + ( fib ) then ( fib ) ;
\ Incorrect way - using variable "fib", which will get overwritten during recursion 0 value fib; : fibonnaci ( fib -- return ) recursive to fib \ to avoid stack manipulation fib 2 < if fib exit then fib 1- fibonnaci ( fib-1) fib 2 - fibonnaci ( fib-1 fib-2 ) + ( fib ) ;
I am not familiar with this alarm level. Could you explain what it is?
In IEEE 1275, you can set an "alarm" for a device. This will be called asynchronously when the condition in question triggers (usually a timer expiring). If you were in the middle of something else using global variables, you can get in trouble if those global variables area also used in the alarm code. The Serial driver for openboot uses alarms, for example.