Wow! pretty fun :)

I encourage you to make the nstest program smarter by removing help messages, prompts and others and just keep the read-eval-print loop.

About the language I find it quite nice as in syntax. I wrote a similar virtual machine in 'sal' but it end up being a little messy and close to raw assembly than fortran.

Here'r my thoughts:

* I would probably prefer '"' quote char for strings.
* Remove 'code' in nstest.c and put it as a testcase t/test
* function to execute commands in shell and get output in stack
* floating point support (append '.' or 'f' to each basic math op +. , -. ...)
* Onechar and line input reading
* format string implementation (maybe)
* type check functions (how can I know the type of the last element in the stack? * I will probably swap the order of the conditional clauses: (what do you think about it)
    3 3 == { 'Is equal duppy\n' print } if
  -->
   { 'Is equal duppy\n' print } 3 3 == if

Congratz for the code, it can be cleaned up, but the LOC and use is impressive. I really enjoy it.

--pancake


On 08/25/10 02:24, Nikhilesh S wrote:
On Wed, 25 Aug 2010, yy wrote:

It is difficult to form an opinion about a language if there is no
documentation or any examples, and it is difficult to form an opinion
about the implementation without understanding the language.

What features does it have? How does it look like? How does it compare
to other stack-based languages like toka or raven?

It's not really very big actually. I don't think anyone could (or would
want to) actually /use/ it, so I didn't include much documentation.

But it looks like this -

Comments start with '#' and continue till the end of the line. For now
there are just 5 types - 'boolean', 'integer', 'string', 'function' and
'block'. Strings are delimited by single quotes.

To push the integer 2 onto the stack:-

     2

'print' will pop and print the last object on the stack

     2 print # prints '2'

'+' pops the last two integers on the stack, and pushes their sum
(implementation-wise it just pops and adds the last integer into the
second-last)

     2 3 + print # prints '5'

Preceding a name with '$' will create a variable with that name and pop
and assign the last thing on the stack to it. Simply a name will push
the value of the variable with that name onto the stack (if it's not
executable, we're getting to executables soon).

     3 $var 2 5 var + print  # prints '8', 2 is left on stack

Putting code between '{' and '}' will push a block onto the stack, with
that code in it. This can be used with, for example, the 'repeat'
function, like this

     { 'hi' print } 3 repeat # prints 'hihihi'

You can make your own functions by assigning blocks to variables. When
you write a name, and it refers to a variable that's executable (a
block) then it gets executed.

     { 3 + print } $print3greater

     5 print3greater # prints '8'

You can push a block-variable onto the stack without executing it by
prefixing it with an '&'. This can be done for built-in functions too.

     1 2 3 4 &add 3 repeat print # prints '10'

Here's some example factorial code:-

{ dup 0 == { 1 + } { 1 rot { dup 1 + } rot 1 - dup $oneless repeat &* oneless repeat } ifelse } $fact

    10 fact print # prints 10 factorial, that is '3628800'

'==' pops two objects, and pushes back 'true' if they are equal, else
'false'

'dup' duplicates the last object on the stack

'ifelse' executes the block at 1 on the stack if boolean at 2 is true,
else executes the block at 0 (the last object on stack is at 0, the
second last at 1, and so on).

'rot' swaps the last two objects on the stack

'fact' works by pushing 1 to n onto the stack first and then multiplying them
together at the end. For 0 it just gives 1.

There's a clearer version of 'fact' with comments in nstest.c. (it
doesn't work for '0' input though - I will update the code).



Reply via email to