As many already know by now, Grammer is a programming language with much to offer. The App version has more commands and features present and it also works as a shell. It is a work in progress and probably will never be "finished."

Math:
Grammer currently handles up to 16-bit inputs (so integers 0 to 65535). Some math commands return data in 2 16-bit vars called pointer vars or pvars (so multiplication could output a 32-bit result). Here are supported math commands:

Code:

• / is used to divide two numbers. The remainder is stored in theta prime.
• * is used to multiply two values. The lower 16 bits are stored to "Ans" and the upper 16 bits (for the 32-bit value) are stored in theta prime.
• - is used to subtract two numbers. Numbers below 0 are calculated as if 65536 was added. For example, 3-6 would result in -3 which is 65536-3 or 65533. If the number goes below 0, theta prime is 1, else it is 0.
• + is used to add two numbers. If the number exceeds 65535, 65536 is subtracted from it and theta prime is 1. Otherwise, theta prime is 0. For example, 65534+99 would return 97, and theta prime as 1.
• 2 multiplies a number by itself
• √( takes the square root of the number
• √(' takes the rounded square root of the number
• sin( takes the sine of a number. This has a period of 256 and returns a value from -127 to 127.
• cos( takes the cosine of a number. This has a period of 256 and returns a value from -127 to 127.
• abs( returns the absolute value of a number. If the number is greater than or equal to 32768 (2^15), this returns 65536 minus the number. For example, abs(65533) would return 65536-65533=3.
• min( returns the lower of two values. For example, min(3,A) returns 3 if A is larger than 3 or the value of A if A is less than 3.
• max( returns the larger of two values.
• gcd( returns the Greatest Common Divisor of two numbers
• lcm( returns the Least Common Multiple of two numbers
• nCr will perform the operation n choose r.


There are also a bunch of drawing commands (there is also much to ask for .__.):

Code:

• Pt-On( is used to draw tiles to the graph screen. These can be multiples of 8 bytes wide (up to 96) and 1 to 64 pixels tall. These are tiles as they can only be drawn at every 8th pixel in the X direction. Also worth noting, there are 6 methods currently of drawing a sprite in this mode as well as an input option of straight data or hex.
• Pt-Off( is used to draw sprites to the graph screen at pixel coordinates. There are only 5 options for drawing the sprite, here.
• Line( is used to draw rectangles. There are 12 rectangle drawing methods available
• Line(' is used to draw an actual line. There are 3 options here
• Pxl-On(
• Pxl-Off(
• Pxl-Change(
• pxl-Test(
• DispGraph draws the current drawing buffer to the LCD
• Disp changes the location of the drawing buffer
• Circle( draws a circle (there are 3 options)
• ClrDraw wipes the drawing buffer clean
• Tangent( shifts the screen a number of pixels in a given direction
• Text( has a bunch of options that would take a while to list here XD
• Fill( is a bunch of sub commands that do a bunch of things dealing with buffers (there are a little over 20 commands here)


And there are then a bunch of memory features and fun features (like the particle commands). You can make OS variables, delete them, edit them, archive them or unarchive them, copy them to RAM as needed, read from them, execute them, use Assembly programs, use subroutines by jumping or calling them, use subprograms, comment code, as well as a slew of other commands and features.

So that is all good and great and yummy and tasty and all, but what you probably want to know is, what can it do? Well, I believe technically anything with enough time and memory, even without the available aid of assembly. So I will instead show what it has been able to do:
Congrats, Xeda!
This is looking very impressive. I hope you'll help us settle a bit of a disagreement we were having in the ClrHome topic: is Grammer parsed by a fully-custom parser, as Deep Thought, or does it use a ParserHook to hook into the TI-BASIC parrser, as I argued?
Shock
Grammer is a full parser that I built. The only case where a parser hook is used is with the App when a program is going to be called from the homescreen. Then, it only checks if it is a Grammer program or not to figure out if the BASIC parser should be used or the Grammer parser.
Xeda112358 wrote:
Shock
Grammer is a full parser that I built. The only case where a parser hook is used is with the App when a program is going to be called from the homescreen. Then, it only checks if it is a Grammer program or not to figure out if the BASIC parser should be used or the Grammer parser.
Then I was completely mistaken, my apologies. Perhaps I'm thinking of BatLib, then? That was a parserhook, correct?
Yes, BatLib was a Parser hook and the included ReCode was like Grammer. Smile
Xeda112358 wrote:
Yes, BatLib was a Parser hook and the included ReCode was like Grammer. Smile
Right, that's what I'm thinking of; sorry for not keeping them properly straight in my mind. Sad Anyway, this is looking very fun and fast from the screenshots, and I'm happy that TI-83+/84+ programmers now have two primary and two secondary languages that they can weigh and choose from, or three secondary if OPIA gets further along. Smile
Thanks ^-^ And I still think Axe and Grammer are on the same level as TI-BASIC at least >.> TI-BASIC has a lot more advanced commands, but Axe and Grammer have tons of features not available in BASIC.

Anywho, the latest update has a simple tilemapping command (the first of several I plan to include)

Grammer.8xk Download
A few randomly generated maps that are used to show off the scrolliness:

A Map Editor:
It looked like there was a map editor in the first batch of screen shots. What did you add to this version to make that different?
Didn't notice the topic here on Cemetech... Well...
*YAY* Grammer!!!!! Smile
Ah, the first version used Grammer code that would manually draw an 8x12 tilemap. This version of Grammer has a built in tilemap routine written in assembly that can display a portion of a large map. As you can see, it is very fast even in 6MHz mode, so it will be extremely valuable to RPG programs. The editor just makes it easy to create tilemaps of whatever size.

I am currently using a slightly modified version that isn't nearly as sensitive to keypresses to draw an outline for an RPG, actually >.>
Those scrolling screenshots look super-fast, very nice. Smile Do you have anyone lined up to write a demo RPG or two using those features?
No, i don't have anybody quite yet, but if anybody wants to, that would be great! I would be glad to help with code, too!
I might try after I'm done with MuseInc. XD
So folks, I have made plenty of updates including these (plus a few more that I have not mentioned here x.x):
length(<<varname>> will return the size of a variable
length('DataStart,Size,LineNumber[,linebyte will let you search for a specific "line" in a set of data and returns the size and location. For example, you can use this to do line searching in a BASIC program.
inString(Offset,SearchStart,SearchString will search for a string in a set of data and return the size and location.
conj(Duration,'Value[i] will play sound using the BatLib technique (which isn't too great). This command is likely to change, by the way, as will the rest of the conj( commands.
conj([i]Duration,DataLoc,DataSize

conj('Time,'Freq Uses the Axe sound routine.
conj('Time,DataLoc,Size Uses the Axe sound routine but it reads data directly to save time (intead of converting numbers on the fly). Size is the size of the data in words, not bytes.
>Frac is used to factor and test for primality. Its outputs are the smallest factor in Ɵ' and the result of Ans divided by that in Ans. So for example, if the output Ɵ' is 1, that means the number is prime.
and , or , xor , and not( , perform bit operations.


So now that housekeeping is finished there, here is what I am actually excited about... For the duration of yesterday and this morning, I was working on rewriting certain sections of Grammer and the parser itself. The result? I got one simple algorithm to run 8 times faster and most of the games made in Grammer run faster. And faster does not mean a 10% speed increase or even a 25% speed increase. Faster means around a 50% to 300% speed increase.

So anyways, here are two screenies of this ridiculousness:




Now if I happen to make that compiler I should get within 5% of assembly speed Smile
The speed increasment is just awesome! This makes grammer in my opinion much more awesome. Its just unbelivable how fast a interprated language on a TI84+ can be if compare that with TI-Basic. Great job!
Thanks! And now I can get back to working on some games >.>
Xeda112358 wrote:
Thanks! And now I can get back to working on some games >.>
From a technical standpoint, I'm very curious about that huge speedup. Had you been doing something very slow, which you managed to track down? Or did you instead find some crazy and cool optimization trick to perform?
There were two big optimisations and various minor optimisations. Originally, I had decided to forgo using a lookup table to direct parsing because only a few tokens were used and I didn't want to add 512 or 768 bytes of code to the program. However, I looked at the costs and benefits and realised the benefits now really outweighed the costs:

costs:
I assumed about 70 tokens were used, now, so that was about 280 bytes being used as it is. The lookup table would use 512 bytes, so this would cost about 220 bytes.

Benefits:
-I had about 3400 bytes left on the page, 220 bytes wasn't much.
-There was anywhere from 70 to 1400 cycles of overhead for each token. Using a LUT, I could reduce that to 97 cycles of over head as a constant.
-Using an LUT would make it easier to include a parser for compiled Grammer code

The second major improvement I made was in the code for converting numbers. I was using code that I wrote a long time ago, so I decided to write a new version without looking at the code I had (so that my coding was not guided). I came up with a much simpler, smaller, and faster code. Instead of taking about 380 cycles per digit, this version takes about 130 cycles per digit.

So to give an idea, every number was converted about 1250 to 2250 cycles faster and every LCD update is about 1000 cycles faster. Using the LUT saves 44236800 cycles per minute and the number conversion could save as much as 82944000 cycles per minute. That adds up.

So this tells me that I probably have a few more areas to speed up. For example, I am rewriting the search routine because I could really speed that up x.x
I'm very happy to hear you're willing to take the time for such extensive code overhauls for the sake of speed and performance! Keep up the great work, and I'm sure some of us would be happy to glance over sections of your code if you ever wanted help. Smile
  
Register to Join the Conversation
Have your own thoughts to add to this or any other topic? Want to ask a question, offer a suggestion, share your own programs and projects, upload a file to the file archives, get help with calculator and computer programming, or simply chat with like-minded coders and tech and calculator enthusiasts via the site-wide AJAX SAX widget? Registration for a free Cemetech account only takes a minute.

» Go to Registration page
Page 1 of 4
» All times are UTC - 5 Hours
 
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 vote in polls in this forum

 

Advertisement