As announced over on Omnimaga, I will not have internet after May 7th (possibly sooner than that), so this means I will have lots of coding time. With Grammer 2 coming near a close as it approaches the 1 page maximum that I have set for it, I will be ushering in the next phase of the Grammer Project-- Grammer 3. I have a basic set of features that I would like to be included, but if others have ideas or requests, please comment. Before I leave for the summer, I will make a copy of the topics for reference material. Anyways, what I plan to do:

[+] Grammer 3 will be a two page App.
[+] It will feature its own program editor, menus, and command lists and token sets.
[+] The program editor will possibly have a copy/paste function, search/replace
[+] It will have quick keys and at least one customisable menu
[+] Programs will be "tokenised," so to speak, like the TI-89 does it, before being executed. This will boost speed a bit.
[+] A legacy mode will be available to run older programs. These will also be tokenised, so older programs will run faster.
[+] The programming language will allow you to load in custom command sets (up to eight at a time per program)
[+] The programming language will manage its own custom variable types, too. For example, string structures, sprite images, bitmaps, matrices, and a few others if you people can think of them.

I'm not sure if I have missed anything else, but again, feel free to post ideas or comments. A few ideas from Omnimaga have actually made it into Grammer 2, as well.
This sounds very ambitious, but very awesome. What kinds of language constructs will Grammer 3 have? Same as Grammer 2? I'd really like easy primitive drawing with user-defied patterns, so you could do something like:
DrawRect(5,5,50,50,{5,2,3,2})
And that would draw a 50x50 square at 5,5 with a pattern of 5 pixels on, 2 pixels off, 3 pixels on, 2 pixels off, and then repeats that pattern. I would have a lot fun with that.

Will this still be using the same file format? I ask for the sake of TokenIDE working with it. If the files are given to Grammer already tokenized, will it still process them? (Does that question make sense?)

I had some more things to add, too, but I forgot them... I'll let you know.
Hmm, the token set will not be at all the same for most tokens. I am still working on the whole token set, but the most basic outline is:

00~EF will be one-byte tokens
F0~F7 two-byte tokens. Each set will have a common theme
F8~FF two-byte tokens. Each set will be based on a custom token set form the custom command set. For example, say you load a command set for physics commands. The command set will have its own tokens. Grammer 3 will assign the first byte as F8 or whatever, followed by the corresponding byte. These bytes will be assigned a token name.

As for the drawing idea, I have been toying with that and I am pretty sure I could do that Smile I've already got a rudimentary implementation in the Circle( command that lets you use a byte pattern for off and on pixels.
Why not add a command that displays an insult at the TI-Nspire?
Because you can just write your own code for that Razz But I might still need to add in an easter egg somewhere...

That does remind me that I should make local and global pointers and allow arguments to be passed to subroutines.
Will you be allowing lambdas and function pointers?
Could you explain what they do and how they are used?
merthsoft wrote:
Will you be allowing lambdas and function pointers?


Definitely seconding this question; I find them extremely fun to play around with in programming languages.

Xeda112358 wrote:
Could you explain what they do and how they are used?


You can have a pointer to a function, and pass it around as simply as any other pointer; but, you can call it later as a function. For random psuedocode:


Code:
define abc() { };
d = abc;

d.call(); // would call abc();
Ah, then I think the answer is Yes. Currently, the way Grammer works is you can store the pointer to the function and call it that way. This is what you mean, right? For example, in Grammer 2:

Code:

Lbl "abc→A
<<code>>
prgmA
GotoA
.abc
<<function code>>
A lambda is an anonymous function--basically just a function without a name. A useful example in C# would be removing all dead enemies from a list (all this is made up, but you can see how it would be useful, I'm sure):

Code:
enemyList.RemoveAll(e => e.Health <= 0);


A function pointer is just a pointer to a function, this is handy for jump tables and such. Say you have possible functions you could call based on an int, you could do, say:

Code:
switch (theIntThatHasStuff) {
  case 1: func1(); break;
  case 2: func2(); break;
  case 3: func3(); break;
  case 4: func4(); break;
  case 5: func5(); break;
}

If you just have pointers to those functions, you could put it in an array and just index into it, something like:

Code:
array = {func1, func2, func3, func4, func5};
array[theIntThatHasStuff]();
Hmm, I still don't understand the lambda idea :/
Xeda112358 wrote:
Because you can just write your own code for that Razz But I might still need to add in an easter egg somewhere...


What about:
Edit by Kerm: maturity, please.
Yeah, it took me a while to understand it, too. The best way to really grasp it would be to play around with it. Python might be a good intro for that, since it's such a simple language. I can provide some more insight, though, by maybe showing you more code.
I showed you this:

Code:
enemyList.RemoveAll(e => e.Health <= 0);

Here's maybe a more fleshed out version:

Code:
class Enemy {
  // Whatever stuff your enemy object has in it
  int Health;
  // More stuff in the object
}

List<Enemy> enemies = new List<Enemy>(); // This is a list of all the enemies in the game right now

// Lots of code to drive the game and blah blah blah
// But then you need to remove all the dead enemies from the game, 'cause they're dead
// Here's the lambda way:
enemies .RemoveAll(enemy => enemy.Health <= 0);
// RemoveAll is a function that takes in a function that takes in an enemy and returns a bool. If the returned bool is true, it removes the enemy from the list.
// You could do it this way, too:
List<Enemy> newEnemyList = new List<Enemy>();
foreach (Enemy enemy in enemies) {
  if (enemy.Health > 0) {
    newEnemyList.Add(enemy);
  }
}

enemies = newEnemyList;

So, there's a bit of a paradigm shift with either way, and they both do the same thing, but the lambda way is nice and short and concise. (There are, of course, other ways to do that, too, this is just what I picked.)
I think that is rather vulgar for an easter egg, but I'll come up with something Razz You could also make your own function that does that >.> Once I figure out the command set, I could give an example.

EDIT: @Merth: I still don't quite get it, but I will look it up on google and try to have it understood at least by the time I leave. Thanks!

I also need these ideas because it will help me layout the command parser nicely so I don't have to rewrite it or add in all sorts of crazy syntaxes later XD
I must be honest that I didn't follow Grammer 2 as close as I should have. My understanding was that Grammer 1 was an interpreter, and Grammer 2 was a compiler, which would make me confused why Grammer 3 would need to add tokenization. Are you saying that programs were stored as plaintext and just-in-time assembled in Grammer 2? Do you have a a semi-full language spec somewhere?
Hmm, Grammer 1 and 2 were both just interpreters, but I was thinking of adding in a tokeniser. Actually, now that I think about it, I think I have my terminology wrong. Preparser, perhaps? It will go through the source and convert numbers into direct data and whatnot.

And I don't think I have a full language spec anywhere, yet x.x
I have a program that I am working on now (a side project) that has a few features I want to add to the next version of Grammer. Mainly, it accesses all the RAM available on your calculator, including any extra RAM pages (At least 1 extra for all TI-84+ models, 8 on a few TI-83+SE and TI-84+/SE models). It currently has a working file system format, you can store data, name them (up to 255 byte names), access them, and delete them through the use of the program I am working on. It right now supports sprites, strings, tilemaps, and bitmaps, but I am going to add in support for FP numbers that the OS uses, arrays (elements can be any variable type, including more arrays), and integers. I think it would be a cool feature to have in Grammer Smile

Also, it automatically detects how many RAM pages you have. I am aware of the issue of using certain apps and programs that use these RAM areas, too. However, the program I am working on only uses it temporarily. (like for use with a game that requires lots of images, graphics, strings, and other things)

For assembly programmers, I have some routines that are key for this to all work properly:
-I have a routine that can look for a variable by name
-I have a routine to store new variables (they can cross page boundaries)
-I have a routine to delete data from a variable (for resizing). This has to allow for 17-bit addressing (so I used 24- and 32-bit stuff).
-I have a routine to delete a variable.

Now I need to make a routine to insert data and it will be just about set.
Hurray, a progress update! I think you'll need to tread carefully with this; I know that as you say, many apps and programs run willy-nilly over the extra RAM pages. You'll need a bunch of guards that detect when memory has been overwritten, but that won't help the loss of data. Hopefully these will be more temporary data used in the course of programs execution, perhaps (for example) a space where compressed levels can be decompressed as a matrix, eg?
Yes, I think that is a good idea. I will try to make sure people use this area more as temporary data storage, such as loading data or programs from archive and running algorithms that require lots of RAM (like large neural networks or something).
I started to actually put work into the Grammer 3 editor today and I just posted an update elsewhere, so I will share with a cross-post Smile




In Grammer 3, there will be a few variable types such as:
Sprites - These get stored at the end of the file and have a size automatically associated with them. This means that the sprite command will work like this: Sprite(ptr,Y,X,Buffer)
Strings - These will have two forms, ASCII or Tokens.
Arrays - There will be a few forms such as fixed size arrays or the more flexible variable arrays (each element can be any variable type, including strings, numbers, sprites, or other arrays)
Integers - There will be signed, unsigned, and different sizes. Currently it only has 8-bit and 16-bit unsigned.
Fixed Point - These will be used for extra precision and will allow you to store numbers such as 2.3125

The actual details are really cool and I started working on the program editor earlier today. For example, the attached image (I made it in paint; it is not real) shows how sprites will be in-line and you will be able to directly edit them. But the really cool part is that the two sprites are the same sprite. Editing one automatically edits the other and any other instances of the sprite in the program. Here is how it works:

There will be local and global variables. Local variables will have a bunch of data stored about them within the program such as their name and the actual data. Local variables include labels, too. Each variable will have a 2-byte ID. When the editor reads the bytes, it will display the name of the variable if it has one. If it does not have a name, the contents of the variable are shown instead. In the editor, if you have highlighted the variable name/data, you will be able to edit the variable data (the program editor will know which var to edit based on the ID). So this means you can edit the name of the variable and all instances in the program will be changed automatically since it is only referred to by an ID. This also means if you use the same string multiple times, changing it in one place changes it everywhere else (as an example).

When running the program, if it is already in RAM, it will just be run directly. If the program is in archive, only the essential data will be copied to RAM. I am still trying to figure out what counts as 'Essential', though. Obviously the variable/label names wouldn't need to be copied since that is just for the editor. But as long as everything else is static data, I might be able to have Grammer keep the whole program in archive.

Oh, also, subroutines are a type of variable. For example, "Repeat " won't be a real command. Internally, it will just be stored as:

Code:

Lbl Repeat
     Call Subroutine
     If <condition>
          Goto Repeat

But in the editor, it will look like a Repeat loop.


Here is the mockup referenced:

So now this is out of the cross-post. With what I made this morning, there are no functioning input routines yet. Instead, I wrote the code that handles input for the various commands such as for inputting arguments. If arguments are supposed to be of a given type, then that will be displayed somehow (I have not yet figured it out). If the user inputs a variable of the wrong type, an error is thrown. Now I need to write the actual input routines. These will consist of routines for code block input, inputs for arguments, and inputs for strings/arrays/sprites. Numbers will be computed and stored internally in a given format but will appear in the editor in base 10.
  
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 2
» 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