whiroth

1.0.1 • Public • Published

Whiroth

npm version Dependency Status devDependency Status Build Status

What is wrong with me? postfix expression evaluator

Why?

I'm keep asking this question for 10 years..

Try?

Here some link click me

How?

Before starting to code, you must learn compiling stuff. If you want to try this out with node.js; type this command to terminal

npm install whiroth --save
var whiroth = require('whiroth'); // es5 syntax
var myExpression = "1 2 + pv";
var compile = whiroth(myExpression);
var result = compile.fn();
console.log(result.out); // 3

if you want to enjoy this in browser;

bower install whiroth --save
var myExpression = "1 2 + pv";
var compile = whiroth(myExpression); // make sure you loaded whiroth.js before this code
var result = compile();
console.log(result.out); // 3

Basic Api

Whiroth function compiles your expression then return an function that has this properties: "fn", "fnPure", "compileTime". Basically compileTime how much milliseconds passed during the compilation. fnPure is compiled string function with whiroth. fn is fnPure's real version that means unlike fnPure this one can be executed. tl;dr fnPure is String, fn is Function

So you want to execute your expression, don't you. call fn with parenthesis. You can give an array to first parameter. Basically this will manipulates stack from beginning. For ex:

var compile = whiroth("+ pv");
var result = compile([4, 6]);
console.log(result.out); // 10

As you can see we did not give any number in expression but while we're executing, we give [4, 6] array.

Also execution returns an object too. It gives you "stack", "out", "executionTime". Basically executionTime is stores how long it takes to execute this expression. stack is remaining elements in stack, if you do not use output you can just stack.pop() to get answer. out means stdout. when you call pv and pc operators text data will appended into this stream.

Language Basics

Expression evaluator basically works with stack. Last result will be your answer

1 2 +

with this expression you will add 1 and 2 to stack, and make addition. Result will be put back to stack. When expression ends one last time pop will executed. You get the answer 3

1 2 + 8

this time you get 8. lets examine..

after addition:

3 8

so after pop you ignore 3 and get 8

1 2 + 8 +

this time result will be 11.

1 2 /

result: 0.5

you can use dot for rational numbers.

0.5 2 *

result: 1

Note: If you ask how i can get this results to yourselfs;

console.log(whiroth("1 2 +")())

Yeah fn returns an object but it's in superposition. It can also be a number.

Operators

Operator Job Stack
+ Addition remove(2) add(1)
- Subtraction remove(2) add(1)
* Multiplication remove(2) add(1)
/ Division remove(2) add(1)
++ Increase modify(1)
-- Decrease modify(1)
^ Bitwise xor remove(2) add(1)
% Modulation remove(2) add(1)
<< Shift left remove(2) add(1)
>> Shift right remove(2) add(1)
> Is bigger remove(2) add(1)
>= Is bigger or equal remove(2) add(1)
< Is smaller remove(2) add(1)
<= Is smaller or equal remove(2) add(1)
== Is equal remove(2) add(1)
!= Is not equal remove(2) add(1)
: Duplicate value add(1)
@ Remove value from stack remove(1)
u Bring value to end of stack remove(1) add(1)
d Bring value to front of stack remove(1) add(1)
! not modify(1)
~ bitwise not modify(1)
r reverse stack modify(all)
iter for current iteration value add(1)
i alias of iter add(1)
init for initialization value add(1)
break breaks for
continue continues for
pc prints char remove(1)
pv prints value remove(1)
swap swaps last two values modify(2)

Native javascript function calls

Call type Syntax Stack change Notes
Double parameter call {Math.min} -1 Parameters replaced by one answer
Shortcut for double parameter call for Math {#min} -1 Parameters replaced by one answer
One parameter call [Math.sin] 0 Parameter replaced by answer
Shortcut for one parameter call for Math [#sin] 0 Parameter replaced by answer
Zero parameter call [=Math.random] 1 Stack now has new item
Shortcut for zero parameter call for Math [=#random] 1 Stack now has new item
10 12 {#min}

result: 10

10 12 : : {#min}

result: 10 (but your previous 10 and 12 values still waiting)

Comments

you can use ; character for comments.

example:

10 20 + ; 30

Conditional Routines

use parenthesis for logical things.

10 10 == if (
    20
) else ( )

result: 20 (because 10 == 10)

stack:

[
    true,
    20
]

You want to do some loops?

2 (
    20
)

result: 20

stack:

[
    20,
    20
]

As you can see value 20 added twice into stack. Basically just parenthesis makes while loop. While loop has 2 alias more.

2 (
    20
)

2 while (
    20
)

2 w (
    20
)

; all same

Note: While and for loops are mostly same. Difference comes with iteration direction. While always go downwards. For always go upwards.

You can use iter and init operators with while and for loops

5 while (
    iter
)

stack:

[
    5,
    4,
    3,
    2,
    1
]
5 for (
    iter
)

stack:

[
    1,
    2,
    3,
    4,
    5
]

Note: iter has alias that named i you can use this too.

so basically with parenthesis we can do both loops and branch.

Heap zone

You can still use heap zone. Simply pop's from stack and set value to wanted variable.

syntax:

10 set<val>

set<val, 10>  ; exacly same as 10 set<val>

#val

example:

set<a, 10>  ; a = 10
#a set<b>   ; b = a
#a #b == if (  ; a == b
  "equal" (pc)
)

Output

Whiroth function returns an object. You can fetch out data from it.

var result = whiroth(text)();
console.log(result.out);

How can i use output? easy

"Hello world!" ; basically writes hello world! text reverse and puts length too
( ; there is length and for each length
  pc ; put char to output
)

If you want to put value use pv

example:

set<a, 10>
set<b, 20>

#a pv " + " (pc) #b pv " = " (pc) #a #b + pv

result: 10 + 20 = 30

Routines

You can create own routines with routine name ( code ) syntax. And execute them with name<>. examples:

routine add (+)
1 2 add<>

result: 3

routine square (
  : : *
)

5 square<> square<>

result: 625

stack:

[
    5,
    25,
    625
]

Note: Routines removes sets when exit. if you want to global set use set_global<name> example:

routine test (
  3 set<a>
)

routine global_test (
  3 set_global<a>
)

test<> #a ; Execution error! : a is not defined
global_test<> #a ; 3

Important! When you say some set value is global then it starts life as undefined example:

#a ; no error just pushes undefined to stack
set_global<a, 10>
#a ; 10

you can check undefined with:

#a undefined == if ( "yeah it's still undefined" (pc) 10 pc )
set_global<a, 10>
#a undefined == else ( "now it's not undefined" (pc) )
#a

Self Calling Routines

There is no control between other routines and themselfs. So you can call anytime any where..

Factorial routine example:

routine factorial (
  : 1 == if (
    1 *
  ) else (
    : -- factorial<> *
  )
)

6 factorial<>

result: 720

But remember! routines won't work fast right now. was working slow..

Self redefining routines and overriding

Normally you can't redefine a routine. it gives you an error, it thought that you are probably making mistake. But if you know what you are doing then, you can tell compiler that nothing is wrong just keep go..

Use hashtag # after routine name.

Let me show you a crazy infinite routine thing..

routine start (
 routine crazy # (
  routine crazy # (
   routine crazy # (
    routine crazy # (
     "last" (pc) 13 pc
     start <>
    )
    "third" (pc) 13 pc
   )
   "second" (pc) 13 pc
  )
  "first" (pc) 13 pc
 )
) start <>

crazy<> ; first
crazy<> ; second
crazy<> ; third
crazy<> ; last
crazy<> ; first
crazy<> ; second
; ...

Example complex calculations

1 Random generation

Generate a thousand random values into stack. Add all of them into one value. Divide it by a thousand and find average random value.

1000 :: ([=#random]) d -- (+) d /

result: ~ 0.5

2 Fibonacci number 15

1 1 15 2 - ( r u : d + uu ) d @

result: 610 ( 1 1 15 .. this 15 can be changed what ever you like )

3 Fibonacci number (all)

20 (
    "fibonacci(" (pc) i pv ") = " (pc)
    1 1 i 2 -
    (
        r u : d + uu
    )

    d @ pv 13 pc
)

result:

fibonacci(20) = 6765
fibonacci(19) = 4181
fibonacci(18) = 2584
fibonacci(17) = 1597
fibonacci(16) = 987
fibonacci(15) = 610
fibonacci(14) = 377
fibonacci(13) = 233
fibonacci(12) = 144
fibonacci(11) = 89
fibonacci(10) = 55
fibonacci(9) = 34
fibonacci(8) = 21
fibonacci(7) = 13
fibonacci(6) = 8
fibonacci(5) = 5
fibonacci(4) = 3
fibonacci(3) = 2
fibonacci(2) = 1
fibonacci(1) = 1

4 Prime finder

set <prime, 23>

#prime  ( init i / : [#floor] - 0 == )
#prime -- (+) 2 - 0 ==
if ( "prime" ) else ( "not prime" ) (pc)

5 factorial without routines

1 6 (i *) ; legendary version of factorial but it needs 1 value before loop

6 (i) 5 (*) ; simplest form of factorial. must change both 6 and 5 for numeric changes

; we want dynamic value.. just change first and it should work

6 (i : 1 == if(init)) -- (*) ; no set no move. works always

; or

6 set<f> #f (i) #f -- (*)  ; uses set. but works always

; or

6 : (i) d -- (*) ; no set. works if stack was empty before calculations

Package Sidebar

Install

npm i whiroth

Weekly Downloads

5

Version

1.0.1

License

MIT

Last publish

Collaborators

  • co3moz