nypl
v1.0.1
Published
Poor man's JavaScript
Downloads
3
Readme
The Nypl Language Guide v0.3
Designed for Simo™
A Forth-like, almost concatenative language with functional features, inspired by Factor, JavaScript, Lisp, IBNIZ and APL.
Examples
To compute sum of two numbers, push the literals 1
and 2
on the stack and then call the +
word to sum them. Finally .
word is executed to print the top of the stack.
> 1 2 + .
3
To calculate the product of two sums 5 + 6 and 1 + 2:
> 1 2 + 5 6 + * .
34
What happened here was that first numbers 1
and 2
were pushed on the stack, and +
was called:
_________ _____
| 1 | 2 | -> call word + -> | 3 |
--------- -----
The sum of numbers 5
and 6
were pushed to the stack and added too:
_____________ __________
| 3 | 5 | 6 | -> call word + -> | 3 | 11 |
------------- ----------
Then *
was invoked. It popped off the two topmost items 3
and 11
off the stack and pushed in the product of them back in:
__________ ______
| 3 | 11 | -> call word * -> | 33 |
---------- ------
Recursion
A terrible tail recursion for loop that prints the numbers 2, 1, 0:
3(s-1+d. d(0=)("done".)(sdi)?)di
Stack state during the computation. f
is the quotation (s-1+d. d(0=)("done".)(sdi)?)
. g
, h
and k
are also quotations. On the right hand side the command that has executed is shown.
STACK COMMANDS
3 -- 3
3f -- f
3ff -- d
3f -- i
f3 -- s
f2 -- -1 + # decrease by one
f2 -- d. # prints the number
f22 -- d
f22ghk -- (0=)("done".)(sdi) # condition, if and else quotations for ? combinator
f22 -- ?
f20 -- 0= # does not equal to zero, push false = 0
f2 -- ? pops off the result and checks it
2f -- s # the "else" part of the ? combinator was taken
2ff -- d
2f -- i # recursion back to quotation f
... recurse until number is 0
1f -- # the last iteration of recursion
f0 -- s-1+
f0 -- d. # print 0
f00ghk -- push the arguments for ?
f00 -- ?
f01 -- 0=
f0"done" -- push string "done"
f0 -- . # print string "done"
In this case two values f
and 0
were left on stack after exit. These could've been removed with xx
. There's also an easier way to do loops, see Looping.
There's an explicit parameter stack that the programmer uses to call words - basically subroutines - and an implicit call stack provided by the implementation.
Define a word S
that duplicates (d) and then multiply the two values
so it's square(x) -> x^2. ;
ends the word definition
:Sd*;
I can be then called like this:
> 5 S
25
Stack manipulation
Stack effect declarations
In the documentation the stack effects are written in the following form:
(input -- output)
Where input
is the stack state before calling the word and output
is the end state, respectively. For example (n --)
would mean that one argument is expected and none returned, and (a b -- x)
that two arguments are expected and one returned.
Stack manipulation operators
s = swap `(a b -- b a)`
r = rot `(a b c -- c a b)`
d = dup `(a -- a a)`
x = drop `(a -- )`
Math operators
/ = division ( a b -- a/b )
+ = addition ( a b -- sum )
- = subtraction ( a b -- difference )
* = multiplication ( a b -- product )
= = equality ( a b -- true_if_equal )
< = less than ( a b -- a < b )
> = less than ( a b -- a > b )
I/O operators
. = print the value on top of the stack
Word definitions
: = begin a new word definition
; = end a word definition
User defined words must be a single capital letter. All builtin words are one character long, too.
Checks if given number is even.
Define word E
as the following: get the result of n mod 2
, check if 0:
"(n -- is_even)"x
:E2%0=;
Now the user defined word E
can be used the following way:
> 5E
b:false
> 6E
b:true
Whitespace
Whitespace can be used to separate immediates and words, but isn't always necessary.
For example 1 2 + 3 *
and 1 2+3*
are equivalent.
Comments
There is no special syntax for comments but one way to add annotations to code is to add string literals that are dropped off the stack immediately afterwards:
"This is kind of a comment."x
Data types
Real numbers
All numbers are double precision floating point numbers.
Boolean values
A number of value 0
is considered falsy and 1
true.
Strings
Strings are written in double quotes. Supported escape characters are the following: \"
, \n
, \t
.
> "oot aika \"ihana\"".
oot aika "ihana"
Inline code
Quotations are fragments of code that can be passed around and executed. Simply wrap some code in parentheses.
This example code pushes 3
on the stack, pushes the quotation (d*)
on the stack, pops the quotation and executes it via the i
word and then prints the result.
> 3 (d*) i.
9
Combinators
Words that take in quotations (code) as inputs are called combinators.
Flow control
The ?
combinator can be used for conditional execution of code.
? = conditional (condition)(then)(else)
The following code returns 6, since 4 > 3. Otherwise it would've returned 0.
> 4(d3>)(2+)(x0)?
Looping
The times, or t
combinator can be used to repeat a quotation.
t = times (a b -- ) quotation b gets repeated 'a' times
Example: print hi
five times:
> 5("hi".)t
Lists
TODO
- lists vs. quotations
- native objects
- unified element access
- wrap & unwrap
Interfacing with JavaScript
TODO
- document the
_
command - implementing callbacks