New interpreter for YodaScript that isn't held back by the same flaws of the old one. This version of YodaScript is not backwards compatible with the old one however the syntax should be familiar.
The syntax is different from most other other langauges. Although there are some shortcuts that emulate infix/prefix notation, the spelled out form is always postfix.
> # add 1 and 2 together
> 1 2 +
3
> 1 2 + 4 *
12
This is probably the most confusing part of YodaScript, to summarize, apart from literals, everything is a reference. This includes anything assignable.
Variables start with a $
. Although YodaScript isn't very strict about how you use variables, if you want to avoid problems you should use them as described here. All variables are empty
until given a value ($var ~ empty ==
). The copy operator ~
is required to convert from references to values.
let
: declare variable in current scope and push a reference to it onto stack=
: (value change) alter the value that variable refers to=:
: (reference change) make the variable reference a different value~
: (copy) get value from a reference
In the following example, the value that a refers to is changed from empty
and set to the integer 5. We then change 5 into the string "hello". Because we left a reference to $a on the stack it stays there after the reassignment and we see the value update after the reassignment.
> $a let 5 =
> $a
5
> $a 'hello' =
"hello"
We can declare a reference before using it by naming it and then using let
. The ;
is used to remove the reference from the stack. References can refer to other references. Here we use the reference change operator (:=
) to make $b reference $a (from previous example).
> $b let ;
> # $b->$a->5
> $b $a :=
> $b print
hello
Notice that if we use the value change operator on b, it changes the value that a references
> $b 1.23 =
> $a print
1.23
If we want to copy a variable by value we have to deference it using the copy operator ~
.
# $c->1.23 $b->$a->1.23
> $c let $b ~ =
> $b $c ==
0
> $b ~ $c ~ ==
1
Macros are a datatype used to store code. Use the @
operator to execute macros.
> $macro let {
. "hi" print
. } =
> $macro @
hi
Eventually I'll add old YodaScript's if statement syntactic sugar. For now you can use cond
which acts the same way as before.
> $gpa let input float =
3.863
> {
. { "You can do better than that" print }
. { "C's get degrees" print } $gpa 2 >=
. { "That's great" print } $gpa 3 >=
. { "WOW!" print } $gpa 4 >=
. } cond
Thats great
Lists are Arrays of references and behave about like you'd expect with indicies starting at zero.
> $values let (1, "dog", 1.2, empty, { "hi" print }) =
> $values 1 ] "cat" =
> $values 1 ] print
cat
> $values -1 ] @
hi
> /* list currently has it's relevant operators in a namespace.
. * This is likely temporary, see namespaces
. */
> List
{
"map" <native> @define
"for_each" <native> @define
"push" <native> @define
"pop" <native> @define
} namespace
Lambdas are like macros but with some extra infastructure attached. They are basically just anonymous functions. Lambdas take a list of arguments
as references defined in a new scope when the @
operator is called.
- Note: the
arguments
operator replaces old YodaScript missing handlers and variable arguments
> $add {
$v1 $v2 + return
. } ($v1, $v2) lambda =
> (1,2) $add @ print
3
While loops are like C but backwards
- Note:
++
is internally defined as1 +=
> $n let 0 =
> {
. $n ++
. $n ',' + print
. } { $n 10 < } while
1,2,3,4,5,6,7,8,9
Run same macro a given number of times
> {
. "hip hip hooray! " print
. } 4 repeat
hip hip hooray! hip hip hooray! hip hip hooray! hip hip hooray!
I'm currently deciding on how how best to change this. Although I recognize that iterables are pretty cool, I like JavaScript/C/C++ more than Python. (also note that List:map
also exists)
> $letters let ('a', 'b', 'c') =
> {
. $letter ' ' + print
. $index ' ' + print
. $list '\n' + print
. } ($letter, $index, $list) lambda $letters List:for_each
a 0 ("a", "b", "c")
b 1 ("a", "b", "c")
c 2 ("a", "b", "c")
You can define new keywords. The run by default option might be removed or reworked in future releases. Several built-in operators are actually defined in terms of other operators by the interpreter.
> "five" 5 define
> five five + print
10
> "@is_even?" { 2 % 0 == } define
> five is_even?
0
> five five + is_even?
1
Immutable key-value set. There are several useful global namespaces defined by the interpreter.
> $num {
. "five" 5 define
. "@sum" {+} define
. } namespace =
> $num:five print
5
> $num "five" : print
5
> $num:five $num :five $num:sum print
10
Mutable key-value set (hashtable). Note
> $account {
. self.balance 0 =
. self.deposit {
. self.balance $amount +=
. } ($amount) lambda
. } object =
>
After taking a few months break from the language I've come to recognize that there are some flaws with the langauge. In it's current form. Although it has a lot of features, many of these features make the language harder to grasp and serve purposes provided by other langauge components. I think I need to focus on yodascript's strengths and trim down the language spec so I can focus on optimizing what I have. In addition there are some flaws I need to work out which will likely involve major implementation changes.
I've come to the following realizations:
- I've added a lot of features (it's essentially like javascript with all the features of C++)
- I think I need to strip down the langauge to it's bare essentials
- And then expand on these to provide the rest of the desired functionality