____ ____ ____ ____ ||n |||i |||m |||f || ||__|||__|||__|||__|| |/__\|/__\|/__\|/__\|
With the interpreter running, it is probably a good idea to talk about syntax. Or at least it would be if this were a non-concatenative language. As it stands there is not much syntax to speak of, but we will go over a few things that may prove important.
What other programming languages may call functions, procedures, or subroutines, nimf (and most other forth-like languages) call "words". Everything in nimf is either a number, a word, a character litteral, or a string litteral.
Words are executed sequentially, left to right. Whitespace is mostly insignificant. I say mostly because whitespace is used to separate words and words themselves cannot have whitespace in their names. However, any amount of whitespace can be used in-between words and it can be just about any whitespace (space, newline, tab, etc).
Since words are executed sequentially, conditional statements and loops will have their conditions evaluated before the word if or loop, for example. This is the inverse of many programming languages where the keyword, if for example, would come first and the condition would follow.
Similarly, math works in this left to right manner differently than you might expect. This will be gone over in more detail in the next section of this guide, but as an example take the following code:
2 3 +
In most programming languages you would write something like this to achieve the same effect:
var a int = 2 + 3
In nimf the data storage is implicitly the stack, so there is no need for a declaration (unless you absolutely need one) and the numbers come before the opperation to be performed on them.
Anything between the word ( and the word ) is a comment. Comments can span multiple lines, but may not themselves contain comments.
( I am
a multiline comment )
3 4 + ( I am an inline comment )
There is no different syntax for inline comments vs multiline comments. Comments can even go in the middle of a line of code:
3 4 ( now we will add the numbers together ) +
It is common for word definitions to document what the new word takes from and leaves on the stack. This is done with a comment inside the word definition, just after the word name and takes the following form:
: square ( n -- n^2 ) dup * ;
In the above code you can see that the word takes in one value: n (a number) and leaves that number to the power of 2 on the stack. n is a common shorthand, but you will also see things like flag (a boolean style value), ptr (a pointer to a memory address), sptr (a pointer to a memory address containing a string), ch (an integer representing a character), and many others. Sometimes you will see values enumerated: n1, n2, etc. Use whatever you think will provide the most clarity. If your word does not eat something from the stack or leave something on it, use an _ like so:
: print-$ ( _ -- _ ) `$ emit ;
Don't worry about the words you don't know yet. The important part is to know that the word print-$ does not take anything from the stack or leave anything on it.
The left to right execution is very reliable in nimf, to the point that it means there is not much in the way of syntax to the language.
The major exception to the left to right execution is variable and word naming. When the :, see, var, or svar keywords are used the next word entered is used as the name of the thing being interacted with (word, var, svar). Almost everywhere else in nimf the word would come first to put its reference onto the stack and then get acted on by another word.
The reason this is an exception is that nimf will not recognize the new name you are entering without the words :, see, var, or svar to notify the system that there will be a strange word coming in and it is ok to not throw and error when it is encountered. Those three words also let the interpreter know what to do with that new word (in all three cases it will add the new word to the dictionary and arrange new memory of some sort, but the how varried from word to word).
var myvar
25 myvar set
"hello" svar hi
: say-hi-25 hi str.print space myvar get . ;
In the above code var is followed by myvar and svar is followed by hi. The interpreter does not know the words myvar or hi and would throw an error if they were not preceeded by one of the three creation words. The same is true of say-hi-25 (which is a new word that prints the value of the string contained in our new hi variable and the number 25 stored in our new var myvar).
Many editors provide syntax highlighting features. This can be useful when looking at a wall of code. nimf code can get quite wordy, and having some highlighting to point out different language features can be very helpful.
At present, there is a syntax highlighting plugin for Vim available here (instructions for its installation can be found in its readme file):
Emacs and nano highlight files are coming soon, I hope.