├── README.md
├── _config.yml
├── build.html
├── changes
├── README.md
├── cmd.txt
└── src
│ ├── index.html
│ └── internal
│ ├── base196.js
│ ├── base95.js
│ ├── base98.js
│ ├── characters.js
│ ├── compress_bitpack.js
│ ├── decompress_bitpack.js
│ ├── string.js
│ └── transpiler.js
├── compressor.md
├── docs.css
├── docs.js
├── docs
├── code_page.md
└── posting_challenges.md
├── editor-proto.md
├── editor.md
├── noodel-latest.js
├── noodel.ico
├── noodel.png
├── noodel_commands-latest.txt
├── noodel_commands.txt
├── ppcg.js
├── ppcg.min.js
├── release
├── editor-0.0.md
├── editor-1.0.md
├── editor-1.1.md
├── editor-1.2.md
├── editor-2.0.md
├── editor-2.1.md
├── editor-2.2.md
├── editor-2.3.md
├── editor-2.4.md
├── editor-2.5.md
├── editor-2.6.md
├── editor-2.7.md
├── noodel-0.0.js
├── noodel-1.0.js
├── noodel-1.1.js
├── noodel-1.2.js
├── noodel-2.0.js
├── noodel-2.1.js
├── noodel-2.2.js
├── noodel-2.3.js
├── noodel-2.4.js
├── noodel-2.5.js
├── noodel-2.6.js
├── noodel-2.7.js
├── noodel_commands-0.0.txt
├── noodel_commands-1.0.txt
├── noodel_commands-1.1.txt
├── noodel_commands-1.2.txt
├── noodel_commands-2.0.txt
├── noodel_commands-2.1.txt
├── noodel_commands-2.2.txt
├── noodel_commands-2.3.txt
├── noodel_commands-2.4.txt
├── noodel_commands-2.5.txt
├── noodel_commands-2.6.txt
└── noodel_commands-2.7.txt
└── src
├── internal
├── ARRAY.js
├── NUMBER.js
├── STRING.js
├── base.js
├── characters.js
├── path.js
├── pipe.js
├── props.js
└── token.js
├── noodel-basic_array.js
├── noodel-basic_cast.js
├── noodel-basic_operands.js
├── noodel-basic_pipe.js
├── noodel-basic_print.js
├── noodel-literals.js
├── noodel-loops.js
├── noodel-misc.js
├── noodel-string_manip.js
├── noodel-time.js
└── noodel.js
/README.md:
--------------------------------------------------------------------------------
1 | # Noodel
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 | [_Noodel_](https://tkellehe.github.io/noodel) is a programming language that has the main focus of assisting ASCII Animation code golfing challenges. _Noodel_ has its own [256 character set](docs/code_page.md). There also is an editor designed for _Noodel_ that utilizes its _JavaScript_ parser [here](https://tkellehe.github.io/noodel/editor.html).
12 |
13 | ---
14 |
15 |
16 |
17 | ---
18 |
19 | Since the language is for challenges visit the [issues page](https://github.com/tkellehe/noodel/issues) and post challenges where _Noodel_ was used. This will allow others to learn how to _Noodel_ as well as notice features that could be added to assist with challenges ([Learn more](docs/posting_challenges.md)). This language is still under construction and since I like to code for _Noodel_ from the online editor things may randomly break in the [prototyping editor](https://tkellehe.github.io/noodel/editor-proto.html), features disappear/change, zero comments made on commits, or random issues appear for myself. If there is a need to use an older version of _Noodel_ that was good enough before, visit the [release directory](https://github.com/tkellehe/noodel/tree/master/release) for a list of all of the versions.
20 |
21 |
22 | ## Introduction
23 |
24 | _Noodel_ has three main data types: `NUMBER`, `STRING`, and `ARRAY`. `ARRAY` objects are always passed-by-reference, but the others are passed-by-value [(...)](docs/intro.md)
25 |
26 | A _"Hello World"_ in [_Noodel_](https://tkellehe.github.io/noodel#introduction) is pretty simple: `Hello,¤World!`
27 |
28 | The `STRING` literal is created and placed onto the stack which can be done with any of the [_printable_](docs/code_page.md) characters. At the very end, whatever is on the top of the stack gets printed. Therein, the `Hello,¤World!` gets printed. But what happened to the `¤`? The `¤` is used to represent a space when handling `STRING` types. This allows for the space character to act as a NOP to seperate commands. The same was done with the line feed character which is represented by `¶` [(...)](docs/string_compression.md)
29 |
30 | ---
31 |
32 |
33 |
34 | ---
35 |
36 | ## The Memory Model
37 |
38 | _Noodel_ is a stack-based language with a slight twist. The perspective of the stack can be changed. A simple example of this is if you need to store an object for later but do not want it to be operated on, you can move the top of the stack down. For example: `noodelʠsome¤workƥ`
39 |
40 | ---
41 |
42 |
43 |
44 | ---
45 |
46 | The literal `noodel` gets pushed onto the stack, then the top of the stack gets moved with the `ʠ` command. Then the `STRING` literal `some¤work` gets pushed onto the stack. The command `ƥ` moves the top of the stack back up, therein `noodel` is on top and is printed.
47 |
48 | Now that is kind of cool, but it gets more interesting when there are arrays involved. Let us take this script: `¤noodel¤ȷçıḷẹḍe`
49 |
50 | ---
51 |
52 |
53 |
54 | ---
55 |
56 | It produces the same output as the script `¤noodel¤ḷçẹḍe`, but takes advantage of the fact that `ARRAY` types are pass-by-reference. So, first `¤noodel¤` is pushed onto the stack. Since the stack is merely an `ARRAY`, we call the `ȷ` command which jumps out of the current stack and into the containing stack. The top of this new stack is the stack with the `STRING` literal. So, we print it to the screen using `ç` therein the `ARRAY` object is sitting in the stdout. Then we call `ı` command to jump into the `ARRAY` at the top of the stack to make it the current stack. This allows us to now start operating on the `STRING` live.
57 | Instead of jumping out, printing, and then jumping back we can use `Ð` which pushes the current stack to stdout: `¤noodel¤Ðḷẹḍe`
58 |
59 | ---
60 |
61 |
62 |
63 | ---
64 |
--------------------------------------------------------------------------------
/_config.yml:
--------------------------------------------------------------------------------
1 | theme: jekyll-theme-tactile
--------------------------------------------------------------------------------
/build.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
43 |
44 |
45 |
46 |
47 |
48 |
--------------------------------------------------------------------------------
/changes/README.md:
--------------------------------------------------------------------------------
1 | # Noodel
2 |
3 | ## What is this?
4 |
5 | _Noodel_ has done a good job at getting my feet wet with making a language for code-golfing ASCII-Animation challenges, but I broke
6 | some of my own rules with _Noodel_. There are parts added to _Noodel_ that are not related to ASCII-Animation that actually hurt it
7 | in challenges. This directory is what the next big change to _Noodel_ will be. First there will be a complete re-write of the internal
8 | structure of source code. BUT, before all of that there will be some structure to the documentation! So, without further ado here is
9 | what _Noodel_ will look like:)
10 |
11 | ## Introduction
12 |
13 | [_Noodel_]() is a language designed for code-golfing ASCII-Animation challenges. The name _Noodel_ was supposed to be Noodle, but
14 | I mistyped the name, laughed, and then went with _Noodel_. You can go [here]() for different versions of _Noodel_.
15 | There is an online interpreter for _Noodel_ [here](). You can also find a list of commands [here]().
16 |
17 | ## Versions?
18 |
19 | Rolling the first number means that the new version of _Noodel_ could break old challenges. Rolling the second number means a bug fix
20 | and/or new feature.
21 |
22 | ## Hello, World!
23 |
24 | Here is a simple `Hello, World!` in _Noodel_:
25 |
26 | ```
27 | Hello,¤World!
28 | ```
29 |
30 | To get started _Noodel_ uses the following characters as the __printable__ characters:
31 |
32 | ```
33 | 𬶤!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~
34 | ```
35 |
36 | These characters are what are used to create string literals in _Noodel_. The character `¤` represents a space and the character
37 | `¶` represents a newline.
38 |
39 | ## Memory Model
40 |
41 |
42 | ## Challenges
43 |
44 | Since _Noodel_ is made for challenges, create an issue each time you use _Noodel_ in a challenge. This helps others learn how to
45 | use _Noodel_ and can help with golfing down the solution. For these issues, name it `TheChallengeTitle - MyUsername` and place a
46 | link to the challenge as well as a link to your answer. Also, place some explanation for as to how it works with a link to
47 | run the script. If it gets golfed down, just place as another comment:)
48 |
--------------------------------------------------------------------------------
/changes/cmd.txt:
--------------------------------------------------------------------------------
1 | chars = 𬶤!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~ẠḄḌẸḤỊḲḶṂṆỌṚṢṬỤṾẈỴẒȦḂĊḊĖḞĠḢİĿṀṄȮṖṘṠṪẆẊẎŻạḅḍẹḥịḳḷṃṇọṛṣṭụṿẉỵẓȧḃċḋėḟġḣŀṁṅȯṗṙṡṫẇẋẏżƁƇƊƑƓƘƝƤƬƲȤɓƈɗƒɠɦƙɱɲƥʠɼʂƭʋȥÆÇÐÑØŒÞßæçıȷñøœþ€¢£¥…µ¡¿×÷¦©®«»‘’“”°¹²³⁴⁵⁶⁷⁸⁹⁺⁻⁼⁽⁾
2 |
3 | ASCII = !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~
4 | specials = 𬶤°¹²³⁴⁵⁶⁷⁸⁹
5 |
6 |
7 | ----------------------------------- Literals -----------------------------------
8 |
9 | - ((?:[ASCII]*[specials]+[ASCII]*)+)
10 | Instantiates a string with the provided characters where the characters 𬶤°¹²³⁴⁵⁶⁷⁸⁹ get translated.
11 | ð : Unused...
12 | ¬ : Unused...
13 | ¶ : Produces a new line.
14 | ¤ : Produces a space.us
15 |
16 | ⁽⁾ : Group a set of characters (open/close not needed if can infer the end/start of the string)
17 | °¹²³⁴⁵⁶⁷⁸⁹ : Repeat the previous set of character(s).
18 |
19 | ------------------------------------- Misc -------------------------------------
20 |
21 | -
22 | A do nothing command.
23 |
24 | -
25 | Exit the current function and return to the function that invoked this one.
26 |
27 | - ¦
28 | Invoke function directly below the one currently executing.
29 |
30 | - ¥
31 | Turn off auto popping. If ran again will ???
32 |
33 | ------------------------------------- Stack ------------------------------------
34 |
35 | -
36 |
37 | ------------------------------------- Print ------------------------------------
38 |
39 | -
40 |
--------------------------------------------------------------------------------
/changes/src/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/changes/src/internal/base196.js:
--------------------------------------------------------------------------------
1 | (function(global, characters){
2 |
3 |
4 | //----------------------------------------------------------------------------------------
5 | var base98_to_base196 = function(s) {
6 | //357 -> 0000 0001 1010 0001 -> 0000 0011 0011 1110
7 |
8 | //196 -> 0000 0001 0000 0000 -> 0000 0002 0000 0000
9 |
10 | //195 -> 0000 0000 1100 0011 -> 0000 0001 0110 0001
11 | //194 -> 0000 0000 1100 0010 -> 0000 0001 0110 0000
12 | //193 -> 0000 0000 1100 0001 -> 0000 0001 0101 1111
13 | //192 -> 0000 0000 1100 0000 -> 0000 0001 0101 1110
14 | //191 -> 0000 0000 1011 1111 -> 0000 0001 0101 1101
15 | //190 -> 0000 0000 1011 1110 -> 0000 0001 0101 1100
16 |
17 | //103 -> 0000 0000 0110 0111 -> 0000 0001 0000 0101
18 | //102 -> 0000 0000 0110 0110 -> 0000 0001 0000 0100
19 | //101 -> 0000 0000 0110 0101 -> 0000 0001 0000 0011
20 | //100 -> 0000 0000 0110 0100 -> 0000 0001 0000 0010
21 | //099 -> 0000 0000 0110 0011 -> 0000 0001 0000 0001
22 | //098 -> 0000 0000 0110 0010 -> 0000 0001 0000 0000
23 | //097 -> 0000 0000 0110 0001 -> 0000 0000 0110 0001
24 |
25 | //011 -> 0000 0000 0000 1011 -> 0000 0000 0000 1011
26 | //010 -> 0000 0000 0000 1010 -> 0000 0000 0000 1010
27 | //009 -> 0000 0000 0000 1001 -> 0000 0000 0000 1001
28 | //008 -> 0000 0000 0000 1000 -> 0000 0000 0000 1000
29 | //007 -> 0000 0000 0000 0111 -> 0000 0000 0000 0111
30 | //006 -> 0000 0000 0000 0110 -> 0000 0000 0000 0110
31 | //005 -> 0000 0000 0000 0101 -> 0000 0000 0000 0101
32 | //004 -> 0000 0000 0000 0100 -> 0000 0000 0000 0100
33 | //003 -> 0000 0000 0000 0011 -> 0000 0000 0000 0011
34 | //002 -> 0000 0000 0000 0010 -> 0000 0000 0000 0010
35 | //001 -> 0000 0000 0000 0001 -> 0000 0000 0000 0001
36 | //000 -> 0000 0000 0000 0000 -> 0000 0000 0000 0000
37 | return s
38 | }
39 |
40 |
41 | //----------------------------------------------------------------------------------------
42 | var base196_to_base98 = function(s) {
43 | return s
44 | }
45 |
46 |
47 | //----------------------------------------------------------------------------------------
48 | global.base196 = {
49 | to: base98_to_base196,
50 | from: base196_to_base98
51 | }
52 |
53 |
54 | })(this, this.characters)
55 |
--------------------------------------------------------------------------------
/changes/src/internal/base95.js:
--------------------------------------------------------------------------------
1 | (function(global, characters){
2 |
3 |
4 | //----------------------------------------------------------------------------------------
5 | var to_base95 = function(x) {
6 | x = Math.abs(x)
7 | if(x == 0)
8 | return characters.printables[0]
9 | var digits = []
10 | while(x) {
11 | digits.push(characters.printables[x % 95])
12 | x = Math.floor(x /= 95)
13 | }
14 | digits.reverse()
15 | return digits.join("")
16 | }
17 |
18 |
19 | //----------------------------------------------------------------------------------------
20 | var from_base95 = function(s) {
21 | var x = 0;
22 | for(var i = 0, l = s.length; i < l; ++i)
23 | x += characters.char_to_int(s[l - i - 1]) * Math.pow(95, i);
24 | return x;
25 | }
26 |
27 |
28 | //----------------------------------------------------------------------------------------
29 | global.base95 = {
30 | to: to_base95,
31 | from: from_base95
32 | }
33 |
34 |
35 | })(this, this.characters)
--------------------------------------------------------------------------------
/changes/src/internal/base98.js:
--------------------------------------------------------------------------------
1 | (function(global, characters){
2 |
3 |
4 | //----------------------------------------------------------------------------------------
5 | var to_base98 = function(x) {
6 | x = Math.abs(x)
7 | if(x == 0)
8 | return characters.int_to_char(0)
9 | var digits = []
10 | while(x) {
11 | digits.push(characters.int_to_char(x % 98))
12 | x = Math.floor(x /= 98)
13 | }
14 | digits.reverse()
15 | return digits.join("")
16 | }
17 |
18 |
19 | //----------------------------------------------------------------------------------------
20 | var from_base98 = function(s) {
21 | var x = 0;
22 | for(var i = 0, l = s.length; i < l; ++i)
23 | x += characters.char_to_int(s[l - i - 1]) * Math.pow(98, i);
24 | return x;
25 | }
26 |
27 |
28 | //----------------------------------------------------------------------------------------
29 | global.base98 = {
30 | to: to_base98,
31 | from: from_base98
32 | }
33 |
34 |
35 | })(this, this.characters)
--------------------------------------------------------------------------------
/changes/src/internal/characters.js:
--------------------------------------------------------------------------------
1 | (function(global){
2 |
3 |
4 | //----------------------------------------------------------------------------------------
5 | var chars = '\u00b0\u00b9\u00b2\u00b3\u2074\u2075\u2076\u2077\u2078\u2079\u00b6\u00d7\u00f7\u207a\u207b\u207c\u2260\u2264\u2265\u2261\u2248\u207d\u207e\u221e\u00bf\u00a1\u203c\u2026\u20ac\u00a2\u00a3\u00a5\u00a4\u0021\u0022\u0023\u0024\u0025\u0026\u0027\u0028\u0029\u002a\u002b\u002c\u002d\u002e\u002f\u0030\u0031\u0032\u0033\u0034\u0035\u0036\u0037\u0038\u0039\u003a\u003b\u003c\u003d\u003e\u003f\u0040\u0041\u0042\u0043\u0044\u0045\u0046\u0047\u0048\u0049\u004a\u004b\u004c\u004d\u004e\u004f\u0050\u0051\u0052\u0053\u0054\u0055\u0056\u0057\u0058\u0059\u005a\u005b\u005c\u005d\u005e\u005f\u0060\u0061\u0062\u0063\u0064\u0065\u0066\u0067\u0068\u0069\u006a\u006b\u006c\u006d\u006e\u006f\u0070\u0071\u0072\u0073\u0074\u0075\u0076\u0077\u0078\u0079\u007a\u007b\u007c\u007d\u007e\u1ea0\u1e04\u1e0c\u1eb8\u1e24\u1eca\u1e32\u1e36\u1e42\u1e46\u1ecc\u1e5a\u1e62\u1e6c\u1ee4\u1e7e\u1e88\u1ef4\u1e92\u1ea1\u1e05\u1e0d\u1eb9\u1e25\u1ecb\u1e33\u1e37\u1e43\u1e47\u1ecd\u1e5b\u1e63\u1e6d\u1ee5\u1e7f\u1e89\u1ef5\u1e93\u0226\u1e02\u010a\u1e0a\u0116\u1e1e\u0120\u1e22\u0130\u013f\u1e40\u1e44\u022e\u1e56\u1e58\u1e60\u1e6a\u1e86\u1e8a\u1e8e\u017b\u0227\u1e03\u010b\u1e0b\u0117\u1e1f\u0121\u1e23\u0140\u1e41\u1e45\u022f\u1e57\u1e59\u1e61\u1e6b\u1e87\u1e8b\u1e8f\u017c\u0181\u0187\u018a\u0191\u0193\u0198\u019d\u01a4\u01ac\u01b2\u0224\u0253\u0188\u0257\u0192\u0260\u0199\u0272\u01a5\u01ad\u028b\u0225\u00ab\u00bb\u2018\u2019\u201c\u201d\u0266\u0271\u02a0\u027c\u0282\u00a6\u00a9\u00ae\u00c6\u00c7\u00d1\u00d8\u00de\u00e6\u00e7\u00f1\u00f8\u00fe\u0131\u0237\u0020\u000a'
6 |
7 |
8 | //----------------------------------------------------------------------------------------
9 | var char_to_int = {};
10 | (function(){for(var i = chars.length; i--;) char_to_int[chars[i]] = i })();
11 |
12 |
13 | //----------------------------------------------------------------------------------------
14 | var printable_to_int = {};
15 |
16 |
17 | //----------------------------------------------------------------------------------------
18 | var encode = function(string) {
19 | var r = ""
20 | for(var i = string.length; i--;)
21 | r = String.fromCharCode(char_to_int[string[i]]) + r;
22 | return r
23 | }
24 |
25 |
26 | //----------------------------------------------------------------------------------------
27 | var decode = function(string) {
28 | var r = ""
29 | for(var i = string.length; i--;)
30 | r = chars.charAt(string[i].charCodeAt(i)) + r;
31 | return r
32 | }
33 |
34 |
35 | //----------------------------------------------------------------------------------------
36 | var chars_regexified = '\\u00b0\\u00b9\\u00b2\\u00b3\\u2074\\u2075\\u2076\\u2077\\u2078\\u2079\\u00b6\\u00d7\\u00f7\\u207a\\u207b\\u207c\\u2260\\u2264\\u2265\\u2261\\u2248\\u207d\\u207e\\u221e\\u00bf\\u00a1\\u203c\\u2026\\u20ac\\u00a2\\u00a3\\u00a5\\u00a4\\u0021\\u0022\\u0023\\u0024\\u0025\\u0026\\u0027\\u0028\\u0029\\u002a\\u002b\\u002c\\u002d\\u002e\\u002f\\u0030\\u0031\\u0032\\u0033\\u0034\\u0035\\u0036\\u0037\\u0038\\u0039\\u003a\\u003b\\u003c\\u003d\\u003e\\u003f\\u0040\\u0041\\u0042\\u0043\\u0044\\u0045\\u0046\\u0047\\u0048\\u0049\\u004a\\u004b\\u004c\\u004d\\u004e\\u004f\\u0050\\u0051\\u0052\\u0053\\u0054\\u0055\\u0056\\u0057\\u0058\\u0059\\u005a\\u005b\\u005c\\u005d\\u005e\\u005f\\u0060\\u0061\\u0062\\u0063\\u0064\\u0065\\u0066\\u0067\\u0068\\u0069\\u006a\\u006b\\u006c\\u006d\\u006e\\u006f\\u0070\\u0071\\u0072\\u0073\\u0074\\u0075\\u0076\\u0077\\u0078\\u0079\\u007a\\u007b\\u007c\\u007d\\u007e\\u1ea0\\u1e04\\u1e0c\\u1eb8\\u1e24\\u1eca\\u1e32\\u1e36\\u1e42\\u1e46\\u1ecc\\u1e5a\\u1e62\\u1e6c\\u1ee4\\u1e7e\\u1e88\\u1ef4\\u1e92\\u1ea1\\u1e05\\u1e0d\\u1eb9\\u1e25\\u1ecb\\u1e33\\u1e37\\u1e43\\u1e47\\u1ecd\\u1e5b\\u1e63\\u1e6d\\u1ee5\\u1e7f\\u1e89\\u1ef5\\u1e93\\u0226\\u1e02\\u010a\\u1e0a\\u0116\\u1e1e\\u0120\\u1e22\\u0130\\u013f\\u1e40\\u1e44\\u022e\\u1e56\\u1e58\\u1e60\\u1e6a\\u1e86\\u1e8a\\u1e8e\\u017b\\u0227\\u1e03\\u010b\\u1e0b\\u0117\\u1e1f\\u0121\\u1e23\\u0140\\u1e41\\u1e45\\u022f\\u1e57\\u1e59\\u1e61\\u1e6b\\u1e87\\u1e8b\\u1e8f\\u017c\\u0181\\u0187\\u018a\\u0191\\u0193\\u0198\\u019d\\u01a4\\u01ac\\u01b2\\u0224\\u0253\\u0188\\u0257\\u0192\\u0260\\u0199\\u0272\\u01a5\\u01ad\\u028b\\u0225\\u00ab\\u00bb\\u2018\\u2019\\u201c\\u201d\\u0266\\u0271\\u02a0\\u027c\\u0282\\u00a6\\u00a9\\u00ae\\u00c6\\u00c7\\u00d1\\u00d8\\u00de\\u00e6\\u00e7\\u00f1\\u00f8\\u00fe\\u0131\\u0237\\u0020\\u000a'
37 |
38 |
39 | //----------------------------------------------------------------------------------------
40 | var printables = '\u00b6\u00a4\u0021\u0022\u0023\u0024\u0025\u0026\u0027\u0028\u0029\u002a\u002b\u002c\u002d\u002e\u002f\u0030\u0031\u0032\u0033\u0034\u0035\u0036\u0037\u0038\u0039\u003a\u003b\u003c\u003d\u003e\u003f\u0040\u0041\u0042\u0043\u0044\u0045\u0046\u0047\u0048\u0049\u004a\u004b\u004c\u004d\u004e\u004f\u0050\u0051\u0052\u0053\u0054\u0055\u0056\u0057\u0058\u0059\u005a\u005b\u005c\u005d\u005e\u005f\u0060\u0061\u0062\u0063\u0064\u0065\u0066\u0067\u0068\u0069\u006a\u006b\u006c\u006d\u006e\u006f\u0070\u0071\u0072\u0073\u0074\u0075\u0076\u0077\u0078\u0079\u007a\u007b\u007c\u007d\u007e'
41 |
42 |
43 | //----------------------------------------------------------------------------------------
44 | var printable_to_int = {};
45 | (function(){for(var i = printables.length; i--;) printable_to_int[printables[i]] = i })();
46 |
47 |
48 | //----------------------------------------------------------------------------------------
49 | var printables_regexified = '\\u00b6\\u00a4\\u0021\\u0022\\u0023\\u0024\\u0025\\u0026\\u0027\\u0028\\u0029\\u002a\\u002b\\u002c\\u002d\\u002e\\u002f\\u0030\\u0031\\u0032\\u0033\\u0034\\u0035\\u0036\\u0037\\u0038\\u0039\\u003a\\u003b\\u003c\\u003d\\u003e\\u003f\\u0040\\u0041\\u0042\\u0043\\u0044\\u0045\\u0046\\u0047\\u0048\\u0049\\u004a\\u004b\\u004c\\u004d\\u004e\\u004f\\u0050\\u0051\\u0052\\u0053\\u0054\\u0055\\u0056\\u0057\\u0058\\u0059\\u005a\\u005b\\u005c\\u005d\\u005e\\u005f\\u0060\\u0061\\u0062\\u0063\\u0064\\u0065\\u0066\\u0067\\u0068\\u0069\\u006a\\u006b\\u006c\\u006d\\u006e\\u006f\\u0070\\u0071\\u0072\\u0073\\u0074\\u0075\\u0076\\u0077\\u0078\\u0079\\u007a\\u007b\\u007c\\u007d\\u007e'
50 |
51 |
52 | //----------------------------------------------------------------------------------------
53 | var compressables = '\u00f0\u00ac\u00b6\u00a4\u0021\u0022\u0023\u0024\u0025\u0026\u0027\u0028\u0029\u002a\u002b\u002c\u002d\u002e\u002f\u0030\u0031\u0032\u0033\u0034\u0035\u0036\u0037\u0038\u0039\u003a\u003b\u003c\u003d\u003e\u003f\u0040\u0041\u0042\u0043\u0044\u0045\u0046\u0047\u0048\u0049\u004a\u004b\u004c\u004d\u004e\u004f\u0050\u0051\u0052\u0053\u0054\u0055\u0056\u0057\u0058\u0059\u005a\u005b\u005c\u005d\u005e\u005f\u0060\u0061\u0062\u0063\u0064\u0065\u0066\u0067\u0068\u0069\u006a\u006b\u006c\u006d\u006e\u006f\u0070\u0071\u0072\u0073\u0074\u0075\u0076\u0077\u0078\u0079\u007a\u007b\u007c\u007d\u007e\u1ea0\u1e04\u1e0c\u1eb8\u1e24\u1eca\u1e32\u1e36\u1e42\u1e46\u1ecc\u1e5a\u1e62\u1e6c\u1ee4\u1e7e\u1e88\u1ef4\u1e92\u0226\u1e02\u010a\u1e0a\u0116\u1e1e\u0120\u1e22\u0130\u013f\u1e40\u1e44\u022e\u1e56\u1e58\u1e60\u1e6a\u1e86\u1e8a\u1e8e\u017b\u1ea1\u1e05\u1e0d\u1eb9\u1e25\u1ecb\u1e33\u1e37\u1e43\u1e47\u1ecd\u1e5b\u1e63\u1e6d\u1ee5\u1e7f\u1e89\u1ef5\u1e93\u0227\u1e03\u010b\u1e0b\u0117\u1e1f\u0121\u1e23\u0140\u1e41\u1e45\u022f\u1e57\u1e59\u1e61\u1e6b\u1e87\u1e8b\u1e8f\u017c\u0181\u0187\u018a\u0191\u0193\u0198\u019d\u01a4\u01ac\u01b2\u0224\u0253\u0188\u0257\u0192\u0260\u0266\u0199\u0271';
54 |
55 |
56 | //----------------------------------------------------------------------------------------
57 | var compressables_regexified = '\\u00f0\\u00ac\\u00b6\\u00a4\\u0021\\u0022\\u0023\\u0024\\u0025\\u0026\\u0027\\u0028\\u0029\\u002a\\u002b\\u002c\\u002d\\u002e\\u002f\\u0030\\u0031\\u0032\\u0033\\u0034\\u0035\\u0036\\u0037\\u0038\\u0039\\u003a\\u003b\\u003c\\u003d\\u003e\\u003f\\u0040\\u0041\\u0042\\u0043\\u0044\\u0045\\u0046\\u0047\\u0048\\u0049\\u004a\\u004b\\u004c\\u004d\\u004e\\u004f\\u0050\\u0051\\u0052\\u0053\\u0054\\u0055\\u0056\\u0057\\u0058\\u0059\\u005a\\u005b\\u005c\\u005d\\u005e\\u005f\\u0060\\u0061\\u0062\\u0063\\u0064\\u0065\\u0066\\u0067\\u0068\\u0069\\u006a\\u006b\\u006c\\u006d\\u006e\\u006f\\u0070\\u0071\\u0072\\u0073\\u0074\\u0075\\u0076\\u0077\\u0078\\u0079\\u007a\\u007b\\u007c\\u007d\\u007e\\u1ea0\\u1e04\\u1e0c\\u1eb8\\u1e24\\u1eca\\u1e32\\u1e36\\u1e42\\u1e46\\u1ecc\\u1e5a\\u1e62\\u1e6c\\u1ee4\\u1e7e\\u1e88\\u1ef4\\u1e92\\u0226\\u1e02\\u010a\\u1e0a\\u0116\\u1e1e\\u0120\\u1e22\\u0130\\u013f\\u1e40\\u1e44\\u022e\\u1e56\\u1e58\\u1e60\\u1e6a\\u1e86\\u1e8a\\u1e8e\\u017b\\u1ea1\\u1e05\\u1e0d\\u1eb9\\u1e25\\u1ecb\\u1e33\\u1e37\\u1e43\\u1e47\\u1ecd\\u1e5b\\u1e63\\u1e6d\\u1ee5\\u1e7f\\u1e89\\u1ef5\\u1e93\\u0227\\u1e03\\u010b\\u1e0b\\u0117\\u1e1f\\u0121\\u1e23\\u0140\\u1e41\\u1e45\\u022f\\u1e57\\u1e59\\u1e61\\u1e6b\\u1e87\\u1e8b\\u1e8f\\u017c\\u0181\\u0187\\u018a\\u0191\\u0193\\u0198\\u019d\\u01a4\\u01ac\\u01b2\\u0224\\u0253\\u0188\\u0257\\u0192\\u0260\\u0266\\u0199\\u0271';
58 |
59 |
60 | //----------------------------------------------------------------------------------------
61 | var tiny_digits = '\u00b0\u00b9\u00b2\u00b3\u2074\u2075\u2076\u2077\u2078\u2079';
62 |
63 |
64 | //----------------------------------------------------------------------------------------
65 | var tiny_digits_regexified = '\\u00b0\\u00b9\\u00b2\\u00b3\\u2074\\u2075\\u2076\\u2077\\u2078\\u2079';
66 |
67 |
68 | //----------------------------------------------------------------------------------------
69 | var correct = function(char) { return char.charAt(char.length - 1) }
70 |
71 |
72 | //----------------------------------------------------------------------------------------
73 | var is_char = function(char) { return char_to_int[char] !== undefined }
74 |
75 |
76 | //----------------------------------------------------------------------------------------
77 | var is_printable = function(char) {
78 | char = char_to_int[char]
79 | return char !== undefined && 0 <= char && char < 98
80 | }
81 |
82 |
83 | //----------------------------------------------------------------------------------------
84 | var is_tiny_digit = function(char) {
85 | char = char_to_int[char]
86 | return char !== undefined && 239 <= char && char < 249
87 | }
88 |
89 |
90 | //----------------------------------------------------------------------------------------
91 | var digit_to_tiny = {
92 | "0": tiny_digits[0],
93 | "1": tiny_digits[1],
94 | "2": tiny_digits[2],
95 | "3": tiny_digits[3],
96 | "4": tiny_digits[4],
97 | "5": tiny_digits[5],
98 | "6": tiny_digits[6],
99 | "7": tiny_digits[7],
100 | "8": tiny_digits[8],
101 | "9": tiny_digits[9],
102 | }
103 |
104 |
105 | //----------------------------------------------------------------------------------------
106 | var tiny_to_digit = {};
107 | (function(){for(var i = tiny_digits.length; i--;) tiny_to_digit[i+""] = tiny_digits[i] })()
108 |
109 |
110 | //----------------------------------------------------------------------------------------
111 | var bitify_char = function(char) {
112 | var a = [], v = '0000000' + characters.char_to_int(char).toString(2);
113 | v = v.substr(v.length-8)
114 | for(var i = v.length; i--;) a.unshift(+v[i]);
115 | return a
116 | }
117 |
118 |
119 | //----------------------------------------------------------------------------------------
120 | var bitify_string = function(string) {
121 | var a = [];
122 | for(var i = 0, l = string.length; i < l; ++i)
123 | a = a.concat(bitify_char(string[i]))
124 | return a
125 | }
126 |
127 |
128 | //----------------------------------------------------------------------------------------
129 | var debitify_char = function(array) {
130 | return chars.charAt(parseInt(array.join(""), 2));
131 | }
132 |
133 |
134 | //----------------------------------------------------------------------------------------
135 | var debitify_string = function(array) {
136 | var s = ""
137 | for(var i = 0, l = array.length; i < l; i += 8)
138 | s += debitify_char(array.slice(i, i+8))
139 | return s
140 | }
141 |
142 |
143 | //----------------------------------------------------------------------------------------
144 | function pad_n(num, n, c)
145 | {
146 | var s = "" + num;
147 | var m = s.length;
148 | while(s.length < n) s = c + s;
149 | return s.substr(m);
150 | }
151 |
152 |
153 | //----------------------------------------------------------------------------------------
154 | function pad0_n(num, n)
155 | {
156 | var s = "" + num;
157 | var m = s.length;
158 | while(s.length < n) s = "0" + s;
159 | return s.substr(m);
160 | }
161 |
162 |
163 | //----------------------------------------------------------------------------------------
164 | function pad0_max(num, n)
165 | {
166 | // 60 is the current speed max.
167 | var s = "000000000000000000000000000000000000000000000000000000000000" + num;
168 | return s.substr(s.length - n);
169 | }
170 |
171 |
172 | //----------------------------------------------------------------------------------------
173 | function pad0_4(num)
174 | {
175 | var s = "0000" + num;
176 | return s.substr(s.length - 4);
177 | }
178 |
179 |
180 | //----------------------------------------------------------------------------------------
181 | function char_array(s) {
182 | return s.split(/(?=(?:[\0-\t\x0B\f\x0E-\u2027\u202A-\uD7FF\uE000-\uFFFF]|[\uD800-\uDBFF][\uDC00-\uDFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF]))/);
183 | }
184 |
185 |
186 | //----------------------------------------------------------------------------------------
187 | function reverse_string(s) {
188 | var t = "";
189 | for(var i = s.length; i--;) t += s[i];
190 | return t;
191 | }
192 |
193 |
194 | //----------------------------------------------------------------------------------------
195 | global.characters = {
196 | encode: encode,
197 | decode: decode,
198 | chars: chars,
199 | chars_regexified: chars_regexified,
200 | printables: printables,
201 | printables_regexified: printables_regexified,
202 | compressables: compressables,
203 | compressables_regexified: compressables_regexified,
204 | tiny_digits: tiny_digits,
205 | tiny_digits_regexified: tiny_digits_regexified,
206 | is_char: is_char,
207 | is_printable: is_printable,
208 | is_printable: is_printable,
209 | is_tiny_digit: is_tiny_digit,
210 | int_to_char: function(i) { return chars.charAt(i) },
211 | char_to_int: function(char) { return char_to_int[char] },
212 | tiny_to_number: function(string) {
213 | var result = ""
214 | for(var i = string.length; i--;)
215 | result = tiny_to_digit[string[i]] + result
216 | return result
217 | },
218 | number_to_tiny: function(string) {
219 | var result = ""
220 | for(var i = string.length; i--;)
221 | result = digit_to_tiny[string[i]] + result
222 | return result
223 | },
224 | bitify_char: bitify_char,
225 | bitify_string: bitify_string,
226 | debitify_char: debitify_char,
227 | debitify_string: debitify_string,
228 | pad_n: pad_n,
229 | char_array: char_array,
230 | reverse_string: reverse_string,
231 | }
232 |
233 |
234 | })(this);
235 |
--------------------------------------------------------------------------------
/changes/src/internal/compress_bitpack.js:
--------------------------------------------------------------------------------
1 | (function(global, characters){
2 |
3 |
4 | //----------------------------------------------------------------------------------------
5 | var compress_bitpack7 = function(s) {
6 | var a = [], packed_count = 0
7 | // Every 9th character will get compressed into the previous 7 characters where
8 | // the 1st gets a bit set indicating that the next seven have a character hidden within.
9 | for(var i = 0; i < s.length; ++i) {
10 | // Gets the character in bit form.
11 | var bits = characters.bitify_char(s[i]);
12 |
13 | // If the 9th character compress, else do normal left shifting.
14 | if((i+1)%9 !== 0) {
15 | // Rotate the bits (place a zero in the back).
16 | // This allows for only the compressable characters to be used in the string.
17 | bits.push(bits.shift());
18 | a = a.concat(bits);
19 | } else {
20 | // We only need the last seven bits because the largest value is 97.
21 | bits.shift();
22 | // Tells that there is a character compressed in the next 7 characters.
23 | a[((i - 8 - packed_count) * 8) + 7] = 1;
24 | for(var j = (i - 7 - packed_count) * 8, k = 0, l = (i - 1 - packed_count) * 8; j <= l; j+=8) {
25 | // Places the bits into the unused bits of the next 7 characters.
26 | a[j + 7] = bits[k++];
27 | }
28 | ++packed_count;
29 | }
30 | }
31 | return characters.debitify_string(a);
32 | };
33 |
34 |
35 | //----------------------------------------------------------------------------------------
36 | global.compress_bitpack = function(N, string) {
37 | // If it requires 7 bits to encode each character in the string, the best compression is the basic one.
38 | if(N === 7) return compress_bitpack7(string)
39 |
40 | var all_bits = [], packed_index = 0;
41 | for(var i = 0; i < string.length; ++i) {
42 | // Get the character in its bit format.
43 | var bits = characters.bitify_char(string[i]),
44 | // Used to determine whether or not the character must be packed into the previous N+1 characters.
45 | is_compressed = false;
46 |
47 | // 7 - N characters can be packed into the previous N+1 characters.
48 | var j = 7 - N;
49 | while(0 < j) {
50 | // If the current position is properly divisable by eight given offset j, then it can be packed.
51 | if((i+j)%8 === 0) {
52 | is_compressed = true;
53 | break;
54 | };
55 | // Move j.
56 | j--;
57 | }
58 |
59 | if(is_compressed) {
60 | // The offset into which bit holds the data in the characters being packed into.
61 | var offset = 8 - j - N;
62 | // Indicate that the next N characters hold a packed character.
63 | all_bits[((packed_index - N - 1)*8) + offset] = 1;
64 | // Loop through each of the bits in the character to be packed.
65 | for(var k = N; 0 < k; --k)
66 | // Places the bits into the correct location.
67 | all_bits[((packed_index - k)*8) + offset] = bits[8 - k];
68 | } else {
69 | // No packing required, therein just append on the bits.
70 | all_bits = all_bits.concat(bits);
71 | // Increment the packed_index, beause added a new character that can hold characters.
72 | packed_index++;
73 | }
74 | }
75 |
76 | // Can now turn the bits into actual characters.
77 | return characters.debitify_string(all_bits);
78 | };
79 |
80 |
81 | })(this, this.characters)
--------------------------------------------------------------------------------
/changes/src/internal/decompress_bitpack.js:
--------------------------------------------------------------------------------
1 | (function(global, characters){
2 |
3 |
4 | //----------------------------------------------------------------------------------------
5 | var decompress_bitpack7 = function(s) {
6 | var bits = characters.bitify_string(s), r = "";
7 | for(var i = 0; i < bits.length;) {
8 | if(bits[i+7] === 1) {
9 | var first = bits.slice(i, i+8);
10 | // Correct all of the bits.
11 | first.pop();
12 | first.unshift(0);
13 | r += characters.debitify_char(first);
14 | i += 8;
15 | // Figure out the compressed character and decode the others.
16 | var compressed = [];
17 | for(var j = 7; j--;) {
18 | var c = bits.slice(i, i+8);
19 | compressed.push(c.pop());
20 | // Correct the bit shift.
21 | c.unshift(0);
22 | r += characters.debitify_char(c);
23 | // Jump to the start of the next character.
24 | i += 8;
25 | }
26 | compressed.unshift(0);
27 | r += characters.debitify_char(compressed);
28 | } else {
29 | // Easiest case.
30 | for(var j = 8; j-- && i < bits.length;) {
31 | var c = bits.slice(i, i+8);
32 | // Correct the bit shift.
33 | c.unshift(c.pop());
34 | r += characters.debitify_char(c);
35 | // Jump to the start of the next character.
36 | i += 8;
37 | }
38 | }
39 | }
40 | return r;
41 | };
42 |
43 |
44 | //----------------------------------------------------------------------------------------
45 | global.decompress_bitpack = function(N, compressed) {
46 | // If N is 7, then just use the basic decompession.
47 | if(N === 7) return decompress_bitpack7(compressed);
48 |
49 | var all_bits = characters.bitify_string(compressed), res = "";
50 |
51 | // Loop through each 8bit chunk in order to look at each character to find the packed characters.
52 | for(var i = 0; i < all_bits.length; i += 8) {
53 | // Grab the bits that we know holds a valid character.
54 | var packed_bits = all_bits.slice(i + (8 - N), i + 8);
55 |
56 | // Fill it with zeros.
57 | for(var c = 8 - N; c--;) packed_bits.unshift(0);
58 | res += characters.debitify_char(packed_bits);
59 |
60 | // If on the last character that could be holding a packed character.
61 | if(((i/8)+1)%(N+1) === 0) {
62 | // Loop back through each character that hold a packed character and get all of the characters packed.
63 | for(var k = 1; k < (8 - N); ++k) {
64 | var bits = [], offset = i - (N*8);
65 | // If the flag bit is set, then the next N characters hold a packed character.
66 | if(all_bits[offset+k] === 1) {
67 | // Fill it with zeros.
68 | for(var c = 8 - N; c--;) bits.push(0);
69 | // Get the packed bits.
70 | for(var j = 0; j < N; ++j)
71 | bits.push(all_bits[offset+k+((j+1)*8)]);
72 | res += characters.debitify_char(bits);
73 | } else {
74 | // Can exit because no others should be one.
75 | break;
76 | }
77 | }
78 | }
79 | }
80 | return res;
81 | };
82 |
83 |
84 | })(this, this.characters)
--------------------------------------------------------------------------------
/changes/src/internal/string.js:
--------------------------------------------------------------------------------
1 | (function(global, characters){
2 |
3 |
4 | //----------------------------------------------------------------------------------------
5 | function STRING(obj) {
6 | this.type = "STRING";
7 | this.is_noodel_type = true;
8 | this.value = obj === undefined ? "" :
9 | (obj.is_noodel_type ? obj.to_string() :
10 | (typeof obj === "string" ? obj : ""))
11 | this.props = {};
12 | }
13 |
14 |
15 | //////////////////////////////////////////////////////////////////////////////////////////
16 | /// These functions return the most primitive representation of the type.
17 | //----------------------------------------------------------------------------------------
18 | STRING.prototype.to_string = function() {
19 | return this.value.toString.apply(this.value, Array.prototype.slice.call(arguments));
20 | }
21 |
22 |
23 | //----------------------------------------------------------------------------------------
24 | STRING.prototype.to_number = function() {
25 | // Problem with converting to a number...
26 | return this.value.valueOf.apply(this.value, Array.prototype.slice.call(arguments));
27 | }
28 |
29 |
30 | //----------------------------------------------------------------------------------------
31 | STRING.prototype.to_array = function() {
32 | return characters.char_array(this.value);
33 | }
34 | //////////////////////////////////////////////////////////////////////////////////////////
35 |
36 |
37 | //////////////////////////////////////////////////////////////////////////////////////////
38 | /// These are operations that can be done to the Noodel types.
39 | //----------------------------------------------------------------------------------------
40 | STRING.prototype.ith_item = function(i) {
41 | return new STRING(this.value[i]);
42 | }
43 |
44 |
45 | //----------------------------------------------------------------------------------------
46 | STRING.prototype.flip = function() {
47 | return new STRING(characters.reverse_string(this.value));
48 | }
49 | //////////////////////////////////////////////////////////////////////////////////////////
50 |
51 |
52 | //////////////////////////////////////////////////////////////////////////////////////////
53 | /// These functions are basic operators that can be used with other Noodel types.
54 | //----------------------------------------------------------------------------------------
55 | STRING.prototype.add_item_onto_the_right = function(item) {
56 | return new STRING(this.value + item.to_string());
57 | }
58 |
59 |
60 | //----------------------------------------------------------------------------------------
61 | STRING.prototype.add_item_onto_the_left = function(item) {
62 | return new STRING(item.to_string() + this.value);
63 | }
64 |
65 |
66 | //----------------------------------------------------------------------------------------
67 | STRING.prototype.remove_item_from_the_right = function(item) {
68 | // This is done such that is removed in the same as the item.
69 | return new STRING(characters.reverse_string(characters.reverse_string(this.value).replace(characters.reverse_string(item.to_string()), "")));
70 | }
71 |
72 |
73 | //----------------------------------------------------------------------------------------
74 | STRING.prototype.remove_item_from_the_left = function(item) {
75 | return new STRING(this.value.replace(item.to_string(), ""));
76 | }
77 | //////////////////////////////////////////////////////////////////////////////////////////
78 |
79 |
80 | //----------------------------------------------------------------------------------------
81 | global.STRING = STRING;
82 |
83 |
84 | })(this, this.characters);
85 |
--------------------------------------------------------------------------------
/changes/src/internal/transpiler.js:
--------------------------------------------------------------------------------
1 | (function(global){
2 |
3 |
4 | //----------------------------------------------------------------------------------------
5 | var REGEXIFY = function(string) { return new RegExp("^" + string + "$") }
6 |
7 |
8 | //----------------------------------------------------------------------------------------
9 | global.transpiler = {
10 | REGEXIFY: REGEXIFY
11 | };
12 |
13 | })(this);
--------------------------------------------------------------------------------
/compressor.md:
--------------------------------------------------------------------------------
1 | [HOME](README.md)
2 |
3 | Click [_Noodel_](https://tkellehe.github.io/noodel/compressor.html) to actually see the compressor if not on the _Noodel_ page:)
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 | ## Basic Compression
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 | ## Occurance Compression
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 | ## Range Compression
53 |
54 |
55 |
56 |
57 |
58 |
59 |
--------------------------------------------------------------------------------
/docs.css:
--------------------------------------------------------------------------------
1 | textarea.noodel-editor {
2 | width:100%;
3 | height:5em;
4 | box-sizing: border-box; /* For IE and modern versions of Chrome */
5 | -moz-box-sizing: border-box; /* For Firefox */
6 | -webkit-box-sizing: border-box; /* For Safari */
7 | resize: vertical;
8 | font-family: monospace;
9 | outline: none;
10 | color: white;
11 | background-color: black;
12 | overflow: auto;
13 | }
14 |
15 | textarea.noodel-output {
16 | width:100%;
17 | height:5em;
18 | box-sizing: border-box; /* For IE and modern versions of Chrome */
19 | -moz-box-sizing: border-box; /* For Firefox */
20 | -webkit-box-sizing: border-box; /* For Safari */
21 | resize: vertical;
22 | font-family: monospace;
23 | outline: none;
24 | color: white;
25 | background-color: black;
26 | overflow: auto;
27 | }
28 |
29 | textarea.noodel-input {
30 | width:100%;
31 | height:2em;
32 | box-sizing: border-box; /* For IE and modern versions of Chrome */
33 | -moz-box-sizing: border-box; /* For Firefox */
34 | -webkit-box-sizing: border-box; /* For Safari */
35 | resize: vertical;
36 | font-family: monospace;
37 | outline: none;
38 | color: white;
39 | background-color: black;
40 | overflow: auto;
41 | }
42 |
43 | div.noodel-chars {
44 | width:100%;
45 | height:26em;
46 | box-sizing: border-box; /* For IE and modern versions of Chrome */
47 | -moz-box-sizing: border-box; /* For Firefox */
48 | -webkit-box-sizing: border-box; /* For Safari */
49 | font-family: monospace;
50 | overflow-y: hidden;
51 | overflow-x: auto;
52 | white-space: nowrap;
53 | word-wrap: none;
54 | }
55 |
56 | div.noodel-chars a {
57 | padding-left: 5px;
58 | padding-right: 5px;
59 | margin: 5px;
60 | cursor: pointer;
61 | border-radius: 3px;
62 | background-color: #dddddd;
63 | color: black;
64 |
65 | -webkit-touch-callout: none; /* iOS Safari */
66 | -webkit-user-select: none; /* Chrome/Safari/Opera */
67 | -khtml-user-select: none; /* Konqueror */
68 | -moz-user-select: none; /* Firefox */
69 | -ms-user-select: none; /* Internet Explorer/Edge */
70 | user-select: none;
71 | }
72 |
73 | div.noodel-char_table {
74 | width:100%;
75 | height:26em;
76 | box-sizing: border-box; /* For IE and modern versions of Chrome */
77 | -moz-box-sizing: border-box; /* For Firefox */
78 | -webkit-box-sizing: border-box; /* For Safari */
79 | font-family: monospace;
80 | overflow-y: hidden;
81 | overflow-x: auto;
82 | white-space: nowrap;
83 | word-wrap: none;
84 | }
85 |
86 | div.noodel-char_table span {
87 | padding-left: 5px;
88 | padding-right: 5px;
89 | margin: 5px;
90 | border-radius: 3px;
91 | background-color: #dddddd;
92 | color: black;
93 | cursor: default;
94 | }
95 |
--------------------------------------------------------------------------------
/docs.js:
--------------------------------------------------------------------------------
1 | function DOCS_ARG_HANDLER() {
2 | var a = [];
3 | for(var i = 0; i < arguments.length; ++i) {
4 | a.push(arguments[i]);
5 | }
6 | return a;
7 | };
8 |
9 | function DOCS_HANDLE_ENCODING(string) {
10 | if(noodel.encode) {
11 | return noodel.encode(string);
12 | }
13 | return string;
14 | };
15 |
16 | function DOCS_HANDLE_DECODING(string) {
17 | if(noodel.decode) {
18 | return noodel.decode(string);
19 | }
20 | return string;
21 | };
22 |
23 | (function(global, $, noodel, STRING, NUMBER, ARRAY, characters){
24 |
25 | var nbs = String.fromCharCode(160),
26 | space = String.fromCharCode(32);
27 |
28 | var nbsRemoveRegex = new RegExp(nbs,"g");
29 | function nbsRemove(string) {
30 | if(!string) return "";
31 | return string.replace(nbsRemoveRegex, space);
32 | };
33 | var nbsAddRegex = new RegExp(space,"g");
34 | function nbsAdd(string) {
35 | if(!string) return "";
36 | return string.replace(nbsAddRegex, nbs);
37 | };
38 |
39 | (function ($) {
40 | $.fn.getCursorPosition = function() {
41 | var el = $(this).get(0);
42 | var pos = 0;
43 | if('selectionStart' in el) {
44 | pos = el.selectionStart;
45 | } else if('selection' in document) {
46 | el.focus();
47 | var Sel = document.selection.createRange();
48 | var SelLength = document.selection.createRange().text.length;
49 | Sel.moveStart('character', -el.value.length);
50 | pos = Sel.text.length - SelLength;
51 | }
52 | return pos;
53 | };
54 | $.fn.cursorPos = function(pos) {
55 | var $this = $(this);
56 | if(pos !== undefined) {
57 | var l = $this.val().length;
58 | $this.attr("cursor_pos", pos < 0 ? 0 : (pos < l ? pos : l));
59 | return this;
60 | } else {
61 | pos = +$this.attr("cursor_pos");
62 | return pos ? pos : 0;
63 | }
64 | };
65 | $.fn.typeInput = function(char) {
66 | var $this = $(this);
67 | var text = $this.val(), pos = $this.cursorPos();
68 | $this.val(text.slice(0, pos) + char + text.slice(pos, text.length));
69 | $this.cursorPos(pos+char.length);
70 | $this.trigger("input");
71 | };
72 | $.makeUrl = function(params) {
73 | return window.location.href.replace(window.location.search,'') + "?" + $.param(params);
74 | };
75 | $.getUrlParam = function(name) {
76 | var results = new RegExp('[\?&]' + name + '=([^]*)').exec(window.location.href);
77 | if (results) {
78 | return results[1] || "";
79 | }
80 | };
81 | $.getUrlParamDecoded = function(name) {
82 | var result = $.getUrlParam(name);
83 | if(result !== undefined) return nbsRemove(decodeURIComponent(result));
84 | return "";
85 | };
86 | })(jQuery);
87 |
88 |
89 | function HtmlEncode(string) {
90 | var el = document.createElement("div");
91 | el.innerText = string;
92 | return el.innerHTML;
93 | };
94 | function HtmlDecode(string) {
95 | var el = document.createElement("div");
96 | el.innerHTML = string;
97 | return el.innerText;
98 | };
99 |
100 | global.forceReload = function() { window.location.reload(true) };
101 |
102 | $(function(){
103 |
104 | /// Make favicon appear.
105 | $("head").append($(''));
106 |
107 | /// Handle all editors in the window.
108 | $(".noodel-exec").each(function(){
109 | var $this = $(this),
110 | $editor = $(''),
111 | $input = $(''),
112 | $output = $(''),
113 | $button = $(''),
114 | $chars = $(''),
115 | $bytes = $(''),
116 | $toggle = $("code pad"),
117 | $container = $(""),
118 | $hider = $("editor");
119 |
120 | if($this.attr("show") !== undefined) $container.prop("hidden", false);
121 |
122 | $this.append($hider).append($container);
123 | $container.append($bytes).append($editor).append($toggle).append($chars).append($button).append($input).append($output);
124 |
125 | $hider.click(function(e){
126 | e.preventDefault();
127 | $container.slideToggle(400);
128 | });
129 |
130 | $editor.val($this.attr("code"));
131 | $input.val($this.attr("input"));
132 |
133 | $editor.focus(function(){
134 | $editor.cursorPos($editor.getCursorPosition());
135 | }).click(function(){
136 | $editor.cursorPos($editor.getCursorPosition());
137 | }).keydown(function(){
138 | $editor.cursorPos($editor.getCursorPosition());
139 | });
140 | $editor.cursorPos(0);
141 |
142 | /// Code Execution.
143 | $output.prop("readonly",true);
144 | $button.text("RUN");
145 |
146 | var prgm;
147 |
148 | function clickRun() {
149 | $button.text("LOADING INPUTS...");
150 | var temp_string = "DOCS_ARG_HANDLER(" + nbsRemove($input.val()) + ")";
151 | var js_inputs = eval("(function(){return "+(temp_string.length ? temp_string : "undefined")+";})()");
152 |
153 | $button.text("PARSING...");
154 | prgm = noodel.apply(this, [DOCS_HANDLE_ENCODING(nbsRemove($editor.val()))].concat(js_inputs));
155 | if(prgm === undefined) return;
156 |
157 | $input.prop("readonly",true);
158 | $editor.prop("readonly",true);
159 |
160 | prgm.onstep = function() {
161 | $output.val(DOCS_HANDLE_DECODING(prgm.printify()));
162 | $output.scrollTop($output[0].scrollHeight);
163 | }
164 | prgm.onend = function() {
165 | $output.val(DOCS_HANDLE_DECODING(prgm.printify()));
166 | $output.scrollTop($output[0].scrollHeight);
167 | clickStop();
168 | }
169 | prgm.onstart = function() {
170 | $button.text("STOP").unbind("click").click(clickStop);
171 | }
172 |
173 | prgm.exec();
174 | };
175 | function clickStop() {
176 | prgm.stop();
177 |
178 | $input.prop("readonly",false);
179 | $editor.prop("readonly",false);
180 |
181 | $button.text("RUN").unbind("click").click(clickRun);
182 | };
183 |
184 | $button.click(clickRun);
185 | if($this.attr("run") !== undefined) $button.trigger("click");
186 |
187 | /// Character selector.
188 | (function(c){
189 | $toggle.click(function(e) {
190 | e.preventDefault();
191 | c.slideToggle(400);
192 | });
193 | })($chars);
194 |
195 | $chars = $($chars.children("center")[0]);
196 |
197 | var $bs = $("bs");
198 | $bs.click(function(e){
199 | e.preventDefault();
200 | var t = $editor.val(), pos = $editor.cursorPos();
201 | if(pos > 0) {
202 | $editor.val(t.slice(0,pos-1) + t.slice(pos, t.length));
203 | $editor.cursorPos(pos - 1);
204 | $editor.trigger("input");
205 | }
206 | });
207 |
208 | var $larrow = $("←");
209 | $larrow.click(function(e){
210 | e.preventDefault();
211 | $editor.cursorPos($editor.cursorPos()-1);
212 | });
213 | var $rarrow = $("→");
214 | $rarrow.click(function(e){
215 | e.preventDefault();
216 | $editor.cursorPos($editor.cursorPos()+1);
217 | });
218 |
219 | $chars.append($larrow).append($bs).append($rarrow).append("
");
220 |
221 | for(var i = 0; i < characters.chars.length; ++i) {(function(){
222 | var char = nbsRemove(characters.chars[i]),
223 | echar = nbsAdd(characters.chars[i]);
224 | if(char === "\n") {
225 | var $letter = $("↵");
226 | } else {
227 | var $letter = $(""+HtmlEncode(echar)+"");
228 | }
229 | $letter.click(function(e){
230 | e.preventDefault();
231 | $editor.typeInput(char);
232 | });
233 | if((i+1) % 16) $chars.append($letter);
234 | else $chars.append($letter).append("
");
235 | })()}
236 |
237 | /// Byte Count
238 | $bytes.text($editor.val().length + " bytes");
239 | $editor.on("input", function() { $bytes.text($editor.val().length + " bytes") });
240 |
241 | }); // End of .noodel-exec regions.
242 |
243 | $(".noodel-share").each(function(){
244 | var $this = $(this),
245 | $container = $(""),
246 | $share = $(""),
247 | $cb_run = $("Start script running.");
248 | $container.append($share).append($cb_run);
249 | $this.append($container);
250 |
251 | // Must be at least one editor.
252 | var $editor = $($(".noodel-exec")[0]),
253 | $input = $($(".noodel-exec div .noodel-input")[0]),
254 | $button = $($(".noodel-exec div button")[0]),
255 | $code = $($(".noodel-exec div .noodel-editor")[0]);
256 |
257 | $share.click(function(){
258 | var url = $.makeUrl({code:nbsRemove($code.val()), input:nbsRemove($input.val()),
259 | run:$cb_run.prop("checked")});
260 | window.location.href = url;
261 | });
262 |
263 | $code.val(nbsAdd($.getUrlParamDecoded("code")));
264 | $code.trigger("input");
265 | $input.val(nbsAdd($.getUrlParamDecoded("input")));
266 | if($.getUrlParam("run") === "true") {
267 | $cb_run.prop("checked", true);
268 | $button.trigger("click");
269 | }
270 |
271 | }); // End of .noodel-share regions.
272 |
273 | $(".noodel-char_table").each(function(){
274 | var $this = $(this),
275 | $container = $("");
276 | $this.append($container);
277 |
278 | for(var i = 0; i < characters.chars.length; ++i) {(function(){
279 | var char = nbsRemove(characters.chars[i]),
280 | echar = nbsAdd(characters.chars[i]);
281 | if(char === "\n") {
282 | var $letter = $("↵");
283 | } else {
284 | var $letter = $(""+HtmlEncode(echar)+"");
285 | }
286 | if((i+1) % 16) $container.append($letter);
287 | else $container.append($letter).append("
");
288 | })()}
289 |
290 | }); // End of .noodel-char_table regions.
291 |
292 | }); // End of the onload function.
293 |
294 | })(this, this.$, this.noodel, this.STRING, this.NUMBER, this.ARRAY, this.characters)
295 |
--------------------------------------------------------------------------------
/docs/code_page.md:
--------------------------------------------------------------------------------
1 | [HOME](https://tkellehe.github.io/noodel/)
2 |
3 | # Code Page
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 | The following is the current 256 different characters that [_Noodel_](https://tkellehe.github.io/noodel/docs/code_page.html) recognizes as the values 0 to 255.
14 |
15 |
16 |
17 | The first 98 characters _Noodel_ considers normal printable chars (ends at `~`).
18 |
19 | The `¶`and `¤` are `\n`, and
respectively. This is done to allow the parser to use the whitespace characters to separate commands.
20 |
21 | The first 196 characters _Noodel_ considers compressable chars (ends at `ɱ`). These chars are used for strings that contain compressed text.
22 |
23 | The last 60 characters _Noodel_ considers noncompressable chars (starts at `ɲ`).
24 |
--------------------------------------------------------------------------------
/docs/posting_challenges.md:
--------------------------------------------------------------------------------
1 | [HOME](https://tkellehe.github.io/noodel/)
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 | # Posting Challenges
11 |
12 | This page discusses how to post challenges that use [_Noodel_](https://tkellehe.github.io/noodel/docs/posting_challenges.html).
13 |
14 | ## Posting
15 |
16 | To post, visit the [issues page](https://github.com/tkellehe/noodel/issues) and create a new issue. Name the issue the title of the challenge followed by your name: __TheChallengeName - UserName__
17 | Then add the label __challenge__ and any others that apply (if there is a label that you must have just ask). In the body of the issue,
18 | place a link to the challenge and a link to your answer. Also, include the number of bytes/score along with the script. Include a link to
19 | a test program where the script can be ran. Finally, include some kind of description explaining how it works.
20 |
21 | ## Other Notes
22 |
23 | If you have a stroke of genious that reduces the number of bytes, fixes the answer, or anything else that changes the origional post,
24 | merely add a comment with the number of bytes/score, explanation, link to example, and the new script.
25 |
26 | If you happen to beat all of the others in the challenge please put the __won__ label on there so I can cry tears of joy:)
27 |
--------------------------------------------------------------------------------
/editor-proto.md:
--------------------------------------------------------------------------------
1 | [HOME](README.md)
2 |
3 | __THIS EDITOR USES THE SRC OF NOODEL DIRECTLY (CAN BREAK)__
4 |
5 | Click [_Noodel_](https://tkellehe.github.io/noodel/editor-proto.html) to actually see the editor if not on the _Noodel_ page:)
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/editor.md:
--------------------------------------------------------------------------------
1 | [HOME](README.md)
2 |
3 | __USES THE LATEST RELEASED VERSION OF NOODEL (2.7)__
4 |
5 | Click [_Noodel_](https://tkellehe.github.io/noodel/editor.html) to actually see the editor if not on the _Noodel_ page:)
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/noodel.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tkellehe/noodel/7fb5a1d14b2cfd142f92f695f855a5e64616cc93/noodel.ico
--------------------------------------------------------------------------------
/noodel.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tkellehe/noodel/7fb5a1d14b2cfd142f92f695f855a5e64616cc93/noodel.png
--------------------------------------------------------------------------------
/ppcg.js:
--------------------------------------------------------------------------------
1 | function DOCS_ARG_HANDLER() {
2 | var a = [];
3 | for(var i = 0; i < arguments.length; ++i) {
4 | a.push(arguments[i]);
5 | }
6 | return a;
7 | };
8 |
9 | function DOCS_HANDLE_ENCODING(string) {
10 | if(noodel.encode) {
11 | return noodel.encode(string);
12 | }
13 | return string;
14 | };
15 |
16 | function DOCS_HANDLE_DECODING(string) {
17 | if(noodel.decode) {
18 | return noodel.decode(string);
19 | }
20 | return string;
21 | };
22 |
23 | (function(){
24 |
25 | var html_noodel = document.getElementById("noodel");
26 |
27 | var input = html_noodel.getAttribute("input"),
28 | code = html_noodel.getAttribute("code");
29 |
30 | var nbs = String.fromCharCode(160),
31 | space = String.fromCharCode(32);
32 |
33 | var nbsRemoveRegex = new RegExp(nbs,"g");
34 | function nbsRemove(string) {
35 | if(!string) return "";
36 | return string.replace(nbsRemoveRegex, space);
37 | };
38 |
39 | input = nbsRemove(input);
40 | input = eval("(function(){ return DOCS_ARG_HANDLER(" + (input.length ? input : "undefined") + ");})()");
41 |
42 | code = nbsRemove(code);
43 | var prgm = noodel.apply(this, [DOCS_HANDLE_ENCODING(code)].concat(input));
44 |
45 | var output = document.createElement("textarea");
46 | output.cols = html_noodel.getAttribute("cols");
47 | output.rows = html_noodel.getAttribute("rows");
48 |
49 | output.style.color = "white";
50 | output.style.backgroundColor = "black";
51 | output.style.outline = "none";
52 |
53 | prgm.onstep = function() {
54 | output.value = DOCS_HANDLE_DECODING(prgm.printify());
55 | output.scrollTop = output.scrollHeight;
56 | }
57 | prgm.onend = function() {
58 | output.value = DOCS_HANDLE_DECODING(prgm.printify());
59 | output.scrollTop = output.scrollHeight;
60 | }
61 |
62 | html_noodel.appendChild(output);
63 | prgm.exec();
64 |
65 | })()
66 |
--------------------------------------------------------------------------------
/ppcg.min.js:
--------------------------------------------------------------------------------
1 | function DOCS_ARG_HANDLER(){for(var a=[],b=0;b
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/release/editor-1.0.md:
--------------------------------------------------------------------------------
1 | [HOME](README.md)
2 |
3 | __USES THE VERSION 1.0 OF NOODEL__
4 |
5 | Click [_Noodel_](https://tkellehe.github.io/noodel/release/editor-1.0.html) to actually see the editor if not on the _Noodel_ page:)
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/release/editor-1.1.md:
--------------------------------------------------------------------------------
1 | [HOME](README.md)
2 |
3 | __USES THE VERSION 1.1 OF NOODEL__
4 |
5 | Click [_Noodel_](https://tkellehe.github.io/noodel/release/editor-1.1.html) to actually see the editor if not on the _Noodel_ page:)
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/release/editor-1.2.md:
--------------------------------------------------------------------------------
1 | [HOME](README.md)
2 |
3 | __USES THE VERSION 1.2 OF NOODEL__
4 |
5 | Click [_Noodel_](https://tkellehe.github.io/noodel/release/editor-1.2.html) to actually see the editor if not on the _Noodel_ page:)
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/release/editor-2.0.md:
--------------------------------------------------------------------------------
1 | [HOME](README.md)
2 |
3 | __USES THE VERSION 2.0 OF NOODEL__
4 |
5 | Click [_Noodel_](https://tkellehe.github.io/noodel/release/editor-2.0.html) to actually see the editor if not on the _Noodel_ page:)
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/release/editor-2.1.md:
--------------------------------------------------------------------------------
1 | [HOME](README.md)
2 |
3 | __USES THE VERSION 2.1 OF NOODEL__
4 |
5 | Click [_Noodel_](https://tkellehe.github.io/noodel/release/editor-2.1.html) to actually see the editor if not on the _Noodel_ page:)
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/release/editor-2.2.md:
--------------------------------------------------------------------------------
1 | [HOME](README.md)
2 |
3 | __USES THE VERSION 2.2 OF NOODEL__
4 |
5 | Click [_Noodel_](https://tkellehe.github.io/noodel/release/editor-2.2.html) to actually see the editor if not on the _Noodel_ page:)
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/release/editor-2.3.md:
--------------------------------------------------------------------------------
1 | [HOME](README.md)
2 |
3 | __USES THE VERSION 2.3 OF NOODEL__
4 |
5 | Click [_Noodel_](https://tkellehe.github.io/noodel/release/editor-2.3.html) to actually see the editor if not on the _Noodel_ page:)
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/release/editor-2.4.md:
--------------------------------------------------------------------------------
1 | [HOME](README.md)
2 |
3 | __USES THE VERSION 2.4 OF NOODEL__
4 |
5 | Click [_Noodel_](https://tkellehe.github.io/noodel/release/editor-2.4.html) to actually see the editor if not on the _Noodel_ page:)
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/release/editor-2.5.md:
--------------------------------------------------------------------------------
1 | [HOME](README.md)
2 |
3 | __USES THE VERSION 2.5 OF NOODEL__
4 |
5 | Click [_Noodel_](https://tkellehe.github.io/noodel/release/editor-2.5.html) to actually see the editor if not on the _Noodel_ page:)
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/release/editor-2.6.md:
--------------------------------------------------------------------------------
1 | [HOME](README.md)
2 |
3 | __USES THE VERSION 2.6 OF NOODEL__
4 |
5 | Click [_Noodel_](https://tkellehe.github.io/noodel/release/editor-2.6.html) to actually see the editor if not on the _Noodel_ page:)
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/release/editor-2.7.md:
--------------------------------------------------------------------------------
1 | [HOME](README.md)
2 |
3 | __USES THE VERSION 2.7 OF NOODEL__
4 |
5 | Click [_Noodel_](https://tkellehe.github.io/noodel/release/editor-2.7.html) to actually see the editor if not on the _Noodel_ page:)
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/release/noodel_commands-1.0.txt:
--------------------------------------------------------------------------------
1 | \p => [𬶤ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz.!?,0123456789:;"'_<=>\*\+\-\/\\\@\#\$\%\&\^\|\(\)\[\]\{\}\`\~]
2 | \c => [ẠḄḌẸḤỊḲḶṂṆỌṚṢṬỤṾẈỴẒȦḂĊḊĖḞĠḢİĿṀṄȮṖṘṠṪẆẊẎŻạḅḍẹḥịḳḷṃṇọṛṣṭụṿẉỵẓȧḃċḋėḟġḣŀṁṅȯṗṙṡṫẇẋẏżƁƇƊƑƓƘƝƤƬƲȤɓƈɗƒɠɦƙɱ]
3 | \m => [°¹²³⁴⁵⁶⁷⁸⁹]
4 | \l => [ɲƥʠɼʂƭʋȥÆÇÐÑØŒÞßæçıȷñøœþ€¢£¥…µ¡¿×÷¦©®«»‘’“”°¹²³⁴⁵⁶⁷⁸⁹⁺⁻⁼⁽⁾]
5 | \k => [\p\c\l ]
6 | \a => [\k\n]
7 |
8 |
9 | --- NOPs ---
10 | space - Use to separate commands.
11 | new line - Use to separate commands also ends some scopes of commands.
12 |
13 | --- MISC ---
14 | %[0-9A-F]+ - Use in a STRING to create a Unicode character based off of the hex value.
15 | ɲ` - terminate()
16 | ɲ~ - a = path.first() a.props.clear()
17 | ṛ - a = path.top()
18 | if a is NUMBER =>
19 | max, min
20 | b = path.top()
21 | if b == undefined => max = MAX(0, a.value) min = MIN(0, a.value)
22 | else => max = MAX(a.value, b.value) min = MIN(a.value, b.value)
23 | path.top(NUMBER(random_int(min, max)))
24 | elif a is ARRAY or a is STRING =>
25 | path.top(a)
26 | path.top(NUMBER(random_int(0, a.length() - 1)))
27 | ṛ(\d+) - path.top(NUMBER(random_int(0, valueOf($1)))
28 | ƥ - path.move_up()
29 | ʠ - path.move_down()
30 | (\m)+ƥ - for i = 0, i < valueOf($1), ++i => path.move_up()
31 | (\m)+ʠ - for i = 0, i < valueOf($1), ++i => path.move_down()
32 | µƥ - a = path.top() for i = 0, i < a.integerify().value, ++i => path.move_up()
33 | µʠ - a = path.top() for i = 0, i < a.integerify().value, ++i => path.move_down()
34 | ƥ\* - path.move_to_top()
35 | ʠ\* - path.move_to_bottom()
36 | ı - path.jump_in()
37 | ȷ - path.jump_out()
38 | ɲo - a = path.first()
39 | if a is NUMBER => path.top(NUMBER(a.value % 2))
40 | elif a is STRING or a is ARRAY => path.top(NUMBER(a.length() % 2))
41 | ɲe - a = path.first()
42 | if a is NUMBER => path.top(NUMBER((a.value % 2) ? 1 : 0))
43 | elif a is STRING or a is ARRAY => path.top(NUMBER((a.value % 2) ? 1 : 0))
44 | ɲO - a = path.top()
45 | if a is NUMBER => path.top(NUMBER(a.value % 2))
46 | elif a is STRING or a is ARRAY => path.top(NUMBER(a.length() % 2))
47 | ɲE - a = path.top()
48 | if a is NUMBER => path.top(NUMBER((a.value % 2) ? 1 : 0))
49 | elif a is STRING or a is ARRAY => path.top(NUMBER((a.value % 2) ? 1 : 0))
50 | ɲ! - a = path.top()
51 | if a == undefined => path.top(NUMBER(1))
52 | else path.top(a.is_falsy())
53 | ɲ? - a = path.top()
54 | if a == undefined => path.top(NUMBER(0))
55 | else path.top(a.is_truthy())
56 |
57 | --- Literals ---
58 | -- String --
59 | (\p+) - if has_null($1) => path.top(ARRAY(split($1, "ð"))) else => path.top(STRING($1))
60 | “(\c*) - path.top(STRING(decompress_basic($1)))
61 | ”(\c*) - a = string_break(decompress_basic($1)) foreach e in a => e = STRING(e); path.top(ARRAY(a))
62 | (\c+)‘(\c+) - path.top(STRING(decompress_occur($1, $2)))
63 | (\c+)’(\c+) - a = string_break(decompress_occur($1, $2)) foreach e in a => e = STRING(e); path.top(ARRAY(a))
64 | (\p)…(\p) - path.top(STRING($1 +...+ $2))
65 | '(\p)…(\p) - path.top(ARRAY($1 ,..., $2))
66 | #(\d)+…(\d)+ - path.top(ARRAY(valueOf($1) ,..., valueOf($2)))
67 | -- Numeric --
68 | ɲ(-?\d*\.?\d+) - path.top(NUMBER(valueOf($1)))
69 | ɲ(-) - path.top(NUMBER(-1))
70 | ɲ(-?\d*/\d+) - path.top(NUMBER(valueOf($1)))
71 |
72 | --- Operators ---
73 | ⁺ - a = path.top() b = path.top() path.top(a.add(b))
74 | ⁻ - a = path.top() b = path.top() path.top(a.sub(b))
75 | ⁺s - a = path.top() b = path.top() path.top(a.add_flip(b))
76 | ⁻s - a = path.top() b = path.top() path.top(a.sub_flip(b))
77 | (\m+)⁺ - a = path.top() for c = 0, c < valueOf($1) and path.first() != undefined, ++c => a = a.add(path.top()); path.top(a)
78 | (\m+)⁻ - a = path.top() for c = 0, c < valueOf($1) and path.first() != undefined, ++c => a = a.sub(path.top()); path.top(a)
79 | (\m+)⁺s - a = path.top() for c = 0, c < valueOf($1) and path.first() != undefined, ++c => a = a.add_flip(path.top()); path.top(a)
80 | (\m+)⁻s - a = path.top() for c = 0, c < valueOf($1) and path.first() != undefined, ++c => a = a.sub_flip(path.top()); path.top(a)
81 | µ⁺ - a = path.top() b = path.top()
82 | for c = 0, c < a.integerify().value and path.first != undefined, ++c => b = b.add(path.top()); path.top(b)
83 | µ⁻ - a = path.top() b = path.top()
84 | for c = 0, c < a.integerify().value and path.first != undefined, ++c => b = b.sub(path.top()); path.top(b)
85 | µ⁺s - a = path.top() b = path.top()
86 | for c = 0, c < a.integerify().value and path.first != undefined, ++c => b = b.add_flip(path.top()); path.top(b)
87 | µ⁻s - a = path.top() b = path.top()
88 | for c = 0, c < a.integerify().value and path.first != undefined, ++c => b = b.sub_flip(path.top()); path.top(b)
89 | ⁺(\d+) - a = path.top() for c = 0, c < valueOf($1), ++c => a = a.increment(tkn); path.top(a)
90 | ⁻(\d+) - a = path.top() for c = 0, c < valueOf($1), ++c => a = a.decrement(tkn); path.top(a)
91 | ⁺s(\d+) - a = path.top() for c = 0, c < valueOf($1), ++c => a = a.increment_flip(tkn); path.top(a)
92 | ⁻s(\d+) - a = path.top() for c = 0, c < valueOf($1), ++c => a = a.decrement_flip(tkn); path.top(a)
93 | ⁺µ - a = path.top() b = path.top()
94 | if b is NUMBER =>
95 | path.top(NUMBER(b.value * a.integerify().value))
96 | else =>
97 | for c = 0, c < a.integerify().value, ++c => b = b.increment(tkn); path.top(b)
98 | ⁻µ - a = path.top() b = path.top()
99 | if b is NUMBER =>
100 | path.top(NUMBER(b.value / a.integerify().value))
101 | else =>
102 | for c = 0, c < a.integerify().value, ++c => b = b.decrement(tkn); path.top(b)
103 | ⁺sµ - a = path.top() b = path.top()
104 | if b is NUMBER =>
105 | path.top(NUMBER(b.pow(a.integerify().value)))
106 | else =>
107 | for c = 0, c < a.integerify().value, ++c => b = b.increment_flip(tkn); path.top(b)
108 | ⁻sµ - a = path.top() b = path.top()
109 | if b is NUMBER =>
110 | path.top(NUMBER(b.pow(1 / a.integerify().value)))
111 | else =>
112 | for c = 0, c < a.integerify().value, ++c => b = b.decrement_flip(tkn); path.top(b)
113 | ɲ% - a = path.top().integerify() b = path.top()
114 | if b is NUMBER => path.top(NUMBER(b.value % a.value))
115 | elif b is STRING => [split string into a.value equal parts and push on the whole and then the remainder]
116 | elif b is ARRAY => [removes the remainder for the array then pushes the array back on the pushes the remainder]
117 | ɲ%s - a = path.top() b = path.top().integerify()
118 | if a is NUMBER => path.top(NUMBER(a.value % b.value))
119 | elif a is STRING => [split string into b.value equal parts and push on the whole and then the remainder]
120 | elif a is ARRAY => [removes the remainder for the array then pushes the array back on the pushes the remainder]
121 |
122 | --- Array Like Operators ---
123 | ɲ_ - a = path.top()
124 | if a is NUMBER => o.back(NUMBER(a.value * a.value))
125 | elif a is STRING => foreach s in a.value => path.top(STRING(s))
126 | elif a is ARRAY => foreach e in a.value => path.top(e)
127 | ɲl - a = path.top() path.top(NUMBER(a.length())) # For numbers that means abs.
128 | ẹ - a = path.top()
129 | if a is NUMBER => path.top(NUMBER(a.reciprocal()))
130 | elif a is STRING => path.top(STRING(a.value.slice(1, a.length()) + a.value.slice(0, 1)))
131 | elif a is ARRAY => a.value.unshift(a.value.pop()) path.top(a)
132 | Ẹ - a = path.top()
133 | if a is NUMBER => path.top(NUMBER(a.square_root()))
134 | elif a is STRING => len = a.length() path.top(STRING(a.value.slice(len - 1, len) + a.value.slice(0, len - 1)))
135 | elif a is ARRAY => a.value.push(a.value.shift()) path.top(a)
136 | ạ - a = path.top()
137 | index = undefined
138 | delta = undefined
139 | count = undefined
140 | if a is NUMBER => index = a.value delta = a.sign() a = path.top() if a == undefined => path.top(NUMBER(index + delta)) exit
141 | if a is NUMBER => count = a.value a = path.top() if a = undefined => path.top(NUMBER(index + (delta * count))) exit
142 | if a is NUMBER => path.top(NUMBER(abs((index + (delta * count))%a.value)))
143 | elif a is STRING or ARRAY =>
144 | if a is STRING => a = ARRAY(string_break(a.value))
145 | if index == undefined => index = a.props("frame")
146 | if index == undefined => index = 0 delta = 1
147 | if count == undefined => count = a.props("frame_count")
148 | if count == undefined => count = a.length()
149 | if delta == undefined => delta = a.props("frame_delta")
150 |
151 | item = undefined
152 |
153 | if count != 0 =>
154 | index = a.correct_index(index)
155 | item = a.access(index)
156 | index += delta
157 | --count
158 |
159 | if count == 0 =>
160 | a.props("frame_count", undefined)
161 | a.props("frame", undefined)
162 | a.props("frame_delta", undefined)
163 | else =>
164 | a.props("frame_count", count)
165 | a.props("frame", index)
166 | a.props("frame_delta", delta)
167 |
168 | path.top(a)
169 | if item != undefined => path.top(item);
170 | ạ(-?\d*) - a = path.top()
171 | index = $1 == "-" ? -1 : valueOf($1)
172 | delta = $1.contains("-") ? -1 : 1
173 | count = undefined
174 | if a is NUMBER => count = a.value a = path.top() if a = undefined => path.top(NUMBER(index + (delta * count))) exit
175 | if a is NUMBER => path.top(NUMBER(abs((index + (delta * count))%a.value)))
176 | elif a is STRING or ARRAY =>
177 | if a is STRING => a = ARRAY(string_break(a.value))
178 | if a.props("frame") != undefined => index = a.props("frame")
179 | if count == undefined => count = a.props("frame_count")
180 | if count == undefined => count = a.length()
181 |
182 | item = undefined
183 |
184 | if count != 0 =>
185 | index = a.correct_index(index)
186 | item = a.access(index)
187 | index += delta
188 | --count
189 |
190 | if count == 0 =>
191 | a.props("frame_count", undefined)
192 | a.props("frame", undefined)
193 | a.props("frame_delta", undefined)
194 | else =>
195 | a.props("frame_count", count)
196 | a.props("frame", index)
197 | a.props("frame_delta", delta)
198 |
199 | path.top(a)
200 | if item != undefined => path.top(item)
201 | Ạ - a = path.top()
202 | if a is ARRAY =>
203 | b = path.top()
204 | if b is ARRAY =>
205 | if a.props("frame") == undefined => a.props("frame", 0)
206 | item = b.access(a.access(a.props("frame")));
207 | a.props("frame", a.correct_index(a.props("frame") + 1))
208 | path.top(b)
209 | path.top(a)
210 | if item != undefined => path.top(item)
211 |
212 | --- Casting ---
213 | ɲ' - a = path.top()
214 | if a is ARRAY => foreach e in a.value => e = e.stringify(); path.top(a)
215 | elif a is NUMBER path.top(a.stringify())
216 | else path.top(a.reverse())
217 | ɲ" - a = path.top()
218 | if a is STRING => s = "" a = string_null_break(a.value) foreach e in a => s += e; path.top(STRING(s))
219 | else path.top(a.stringify())
220 | ɲ# - a = path.top()
221 | if a is ARRAY => foreach e in a.value => e = e.numberify(); path.top(a)
222 | elif a is STRING path.top(a.numberify())
223 | else path.top(NUMBER(-1 * a.value))
224 | ɲ - a = path.top()
225 | if a is ARRAY => foreach e in a.value => e = e.numberify(); path.top(a)
226 | elif a is STRING => a = ARRAY(string_null_break(a.value))
227 | foreach e in a.value => e = NUMBER(valueOf(e));
228 | if a.length() > 1 => path.top(a) elif a.length == 1 => path.top(a.value[0]) else path.top(NUMBER(0))
229 | elif a is NUMBER => path.top(NUMBER(-1 * a.abs()))
230 | œ - a = [] while path.first() != undefined a.push(path.top()); if a.length() != 0 => path.top(ARRAY(a))
231 | œ(\d+) - a = [] c = valueOf($1) whilec != 0 and path.first() != undefined => a.push(path.top()); if a.length() != 0 => path.top(ARRAY(a))
232 | µœ - a = path.top() if a != undefined => a = a.integerify() b = [] while a.value != 0 and path.first() != undefined => b.push(path.top()) --a.value; path.top(ARRAY(b))
233 | ʋ - a = path.top()
234 | if a is NUMBER => a = ARRAY(factorize_number(a.value)) foreach e in a => e = NUMBER(e); path.top(a)
235 | elif a is STRING => a = string_break(a.value) foreach e in a => e = STRING(e); path.top(ARRAY(a))
236 | elif a is ARRAY => path.top(a.reverse())
237 |
238 | --- Loops ---
239 | ḷ(\k*) - while(true) => $1
240 | Ḷ(\k*) - if tkn.count == undefined => tkn.count = a.integerify().value
241 | while(0 < tkn.count) => $1 tkn.count--
242 | tkn.count = undefined
243 | Ḷ(\d+)(\k*) - if tkn.count == undefined => tkn.count = valueOf($1)
244 | while(0 < tkn.count) => $2 tkn.count--
245 | tkn.count = undefined
246 | ṃ(\k*) - while(path.first().is_truthy().value == 1) $1
247 | Ṃ(\k*) - while(path.top().is_truthy().value == 1) $1
248 | ṇ(\k*) - while(path.first().is_truthy()) $1; path.top()
249 | Ṇ(\k*) - while(path.first().is_truthy()) path.top() $1;
250 | ḅ - break from a loop that is before this command and that does not have a break.
251 | Ḅ - a = path.top() if a != undefined && a.is_truthy().value == 1 => path.top(a) else => ḅ
252 | ɱ - path.top(NUMBER(get_containing_loop_token().loop_count))
253 |
254 | --- Time ---
255 | ḍ - a = path.top() delay_ms(a.integerify().value)
256 | ḍ(\d+) - delay_ms(valueOf($1))
257 | ḍ[shqeto] - if $1 == "s" => delay_ms(1000)
258 | elif $1 == "h" => delay_ms(500)
259 | elif $1 == "q" => delay_ms(250)
260 | elif $1 == "e" => delay_ms(125)
261 | elif $1 == "t" => delay_ms(100)
262 | elif $1 == "o" => delay_ms(10)
263 | ḍ(\d*)/(\d*) - num = 1000 den = 1
264 | if $1.length > 0 => num *= valueOf($1)
265 | if $2.length > 0 => den = valueOf($1)
266 | delay_ms(num / den)
267 | ḍ(\d*)\.(\d*) - delay_ms(valueOf("0" + $1 + "." + $2 + "0") * 1000)
268 |
269 | --- Printing ---
270 | þ - path.stdout(i.first())
271 | Þ - path.stdout(i.front())
272 | ç - path.stdout.clear() path.stdout(path.first())
273 | Ç - path.stdout.clear() path.stdout(path.top())
274 | ñ - path.stdout(path.first()) path.stdout(STRING("¶"))
275 | Ñ - path.stdout(path.top()) path.stdout(STRING("¶"))
276 | Ð - path.stdout(path.stack)
277 | ß - path.stdout.clear()
278 |
279 | --- Pipe Manipulation ---
280 | ḃ - path.top()
281 | Ḃ - path.jump_up() path.top()
282 | ė - path.bottom(path.top())
283 | Ė - path.top(path.bottom())
284 | ṡ - a = path.top() b = path.top() path.top(a) path.top(b)
285 | Ṡ - a = path.bottom() b = path.bottom() path.bottom(a) path.bottom(b)
286 | ḋ - a = path.first() path.top(a.copy())
287 |
288 | --- String Manipulation ---
289 | ɲL - a = path.top()
290 | path.top(a.to_lowercase())
291 | ɲU - a = path.top()
292 | path.top(a.to_uppercase())
293 | ɲS - a = path.top()
294 | path.top(a.switchcase())
295 | ṙ - a = path.top().integerify() b = path.top().integerify() c = path.top()
296 | path.top(c.relocate(a.value, b.value))
297 |
298 | --- All Characters ---
299 | 𬶤ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz.!?,0123456789:;"'_<=>*+-/\@#$%&^|()[]{}`~
300 | ẠḄḌẸḤỊḲḶṂṆỌṚṢṬỤṾẈỴẒȦḂĊḊĖḞĠḢİĿṀṄȮṖṘṠṪẆẊẎŻạḅḍẹḥịḳḷṃṇọṛṣṭụṿẉỵẓȧḃċḋėḟġḣŀṁṅȯṗṙṡṫẇẋẏżƁƇƊƑƓƘƝƤƬƲȤɓƈɗƒɠɦƙɱ
301 | ɲƥʠɼʂƭʋȥÆÇÐÑØŒÞßæçıȷñøœþ€¢£¥…µ¡¿×÷¦©®«»‘’“”°¹²³⁴⁵⁶⁷⁸⁹⁺⁻⁼⁽⁾
302 |
--------------------------------------------------------------------------------
/src/internal/ARRAY.js:
--------------------------------------------------------------------------------
1 | function getRandom(length) { return Math.floor(Math.random()*(length)); }
2 | function getRandomSample(array, size) {
3 | var r, i = array.length, end = i - size, temp, swaps = getRandomSample.swaps;
4 |
5 | while (i-- > end) {
6 | r = getRandom(i + 1);
7 | temp = array[r];
8 | array[r] = array[i];
9 | array[i] = temp;
10 | swaps.push(i);
11 | swaps.push(r);
12 | }
13 |
14 | var sample = array.slice(end);
15 |
16 | while(size--) {
17 | i = swaps.pop();
18 | r = swaps.pop();
19 | temp = array[i];
20 | array[i] = array[r];
21 | array[r] = temp;
22 | }
23 |
24 | return sample;
25 | }
26 | getRandomSample.swaps = [];
27 |
28 | //------------------------------------------------------------------------------------------------------------
29 | function ARRAY(v) {
30 | this.props = make_props();
31 | this.value = v === undefined ? [] : v;
32 | }
33 |
34 | ARRAY.prototype.type = "ARRAY";
35 |
36 | ARRAY.prototype.toString = function() {
37 | return this.stringify().toString();
38 | }
39 |
40 | ARRAY.prototype.copy = function() {
41 | return this;
42 | }
43 |
44 | /// Conversions
45 | ARRAY.prototype.valueify = function() {
46 | var a = [];
47 | for(var i = 0; i < this.value.length; ++i) a.push(this.value[i].valueify());
48 | return a;
49 | }
50 | ARRAY.prototype.stringify = function() {
51 | var s = "";
52 | for(var i = 0; i < this.value.length; ++i) s += this.value[i].stringify().toString() + characters.correct("ð");
53 | // Removes the last block character.
54 | s = s.slice(0, s.length - 1);
55 | return new STRING(s);
56 | }
57 | ARRAY.prototype.arrayify = function() {
58 | return this.copy();
59 | }
60 | ARRAY.prototype.numberify = function() {
61 | var a = [];
62 | for(var i = 0; i < this.value.length; ++i) a.push(this.value[i].numberify());
63 | var sum = 0;
64 | for(i = 0; i < this.value.length; ++i) sum += a[i].value;
65 | return new NUMBER(sum);
66 | }
67 | ARRAY.prototype.integerify = function() {
68 | var a = [];
69 | for(var i = 0; i < this.value.length; ++i) a.push(this.value[i].integerify());
70 | var sum = 0;
71 | for(i = 0; i < this.value.length; ++i) sum += a[i].value;
72 | return new NUMBER(sum);
73 | }
74 | ARRAY.prototype.printify = function() {
75 | var s = "";
76 | for(var i = 0; i < this.value.length; ++i) s += this.value[i].printify() + characters.correct("ð");
77 | // Removes the last block character.
78 | s = s.slice(0, s.length - 1);
79 | return s;
80 | }
81 |
82 | /// Operators
83 | ARRAY.prototype.increment = function(path) {
84 | var f = path.top();
85 | if(f) {
86 | this.value.push(f);
87 | }
88 | return this;
89 | }
90 |
91 | ARRAY.prototype.decrement = function(path) {
92 | var s = this.value.shift();
93 | if(s) path.top(s);
94 | return this;
95 | }
96 |
97 | ARRAY.prototype.increment_flip = function(path) {
98 | var f = path.top();
99 | if(f) {
100 | this.value.unshift(f);
101 | }
102 | return this;
103 | }
104 |
105 | ARRAY.prototype.decrement_flip = function(path) {
106 | var s = this.value.pop();
107 | if(s) path.top(s);
108 | return this;
109 | }
110 |
111 | ARRAY.prototype.add = function(rhs) {
112 | for(var i = 0; i < this.value.length; ++i) {
113 | this.value[i] = this.value[i].add(rhs);
114 | }
115 | return this;
116 | }
117 |
118 | ARRAY.prototype.sub = function(rhs) {
119 | for(var i = 0; i < this.value.length; ++i) {
120 | this.value[i] = this.value[i].sub(rhs);
121 | }
122 | return this;
123 | }
124 |
125 | ARRAY.prototype.add_flip = function(lhs) {
126 | for(var i = 0; i < this.value.length; ++i) {
127 | this.value[i] = this.value[i].add_flip(lhs);
128 | }
129 | return this;
130 | }
131 |
132 | ARRAY.prototype.sub_flip = function(lhs) {
133 | for(var i = 0; i < this.value.length; ++i) {
134 | this.value[i] = this.value[i].sub_flip(lhs);
135 | }
136 | return this;
137 | }
138 |
139 | ARRAY.prototype.mul = function(rhs) {
140 | for(var i = 0; i < this.value.length; ++i) {
141 | this.value[i] = this.value[i].mul(rhs);
142 | }
143 | return this;
144 | }
145 |
146 | ARRAY.prototype.mul_flip = function(lhs) {
147 | for(var i = 0; i < this.value.length; ++i) {
148 | this.value[i] = this.value[i].mul_flip(lhs);
149 | }
150 | return this;
151 | }
152 |
153 | ARRAY.prototype.div = function(rhs) {
154 | for(var i = 0; i < this.value.length; ++i) {
155 | this.value[i] = this.value[i].div(rhs);
156 | }
157 | return this;
158 | }
159 |
160 | ARRAY.prototype.div_flip = function(lhs) {
161 | for(var i = 0; i < this.value.length; ++i) {
162 | this.value[i] = this.value[i].div_flip(lhs);
163 | }
164 | return this;
165 | }
166 |
167 | /// Array specific commands.
168 | ARRAY.prototype.correct_index = function(index) {
169 | // Overkill for what it is actually doing...
170 | return ((index % this.length()) + this.length()) % this.length();
171 | };
172 |
173 |
174 | ARRAY.prototype.access = function(index) {
175 | return this.value[this.correct_index(index)].copy();
176 | };
177 |
178 | ARRAY.prototype.length = function() {
179 | return this.value.length;
180 | };
181 |
182 | /// Misc.
183 |
184 | ARRAY.prototype.to_lowercase = function() {
185 | for(var i = 0; i < this.value.length; ++i) this.value[i] = this.value[i].to_lowercase();
186 | return this;
187 | }
188 |
189 | ARRAY.prototype.to_uppercase = function() {
190 | for(var i = 0; i < this.value.length; ++i) this.value[i] = this.value[i].to_uppercase();
191 | return this;
192 | }
193 |
194 | ARRAY.prototype.switchcase = function() {
195 | for(var i = 0; i < this.value.length; ++i) this.value[i] = this.value[i].switchcase();
196 | return this;
197 | }
198 |
199 | ARRAY.prototype.is_truthy = function() {
200 | return new NUMBER(this.length() ? 1 : 0);
201 | }
202 |
203 | ARRAY.prototype.is_falsy = function() {
204 | return new NUMBER(this.length() ? 0 : 1);
205 | }
206 |
207 | ARRAY.prototype.relocate = function(from, to) {
208 | var s = this.value.splice(this.correct_index(from), 1);
209 | this.value.splice(this.correct_index(to), 0, s[0]);
210 | return this;
211 | }
212 |
213 | ARRAY.prototype.shuffle = function() {
214 | this.value = getRandomSample(this.value, this.length());
215 | return this;
216 | }
217 |
--------------------------------------------------------------------------------
/src/internal/NUMBER.js:
--------------------------------------------------------------------------------
1 | function factorize_number(num) {
2 | var half = Math.floor(num / 2),
3 | array = [1],
4 | i, j;
5 |
6 | // Determine our increment value for the loop and starting point.
7 | num % 2 === 0 ? (i = 2, j = 1) : (i = 3, j = 2);
8 |
9 | for (; i <= half; i += j) {
10 | if(num % i === 0) array.push(i);
11 | }
12 |
13 | array.push(num);
14 | return array;
15 | }
16 |
17 | //------------------------------------------------------------------------------------------------------------
18 | function NUMBER(v) {
19 | this.props = make_props();
20 | v = +v;
21 | this.value = v === v ? v : 0;
22 | }
23 |
24 | NUMBER.numerical_eval = function(o) {
25 | if(o.type === "NUMBER") {
26 | return new STRING(to_base_98(o.value));
27 | }
28 | if(o.type === "STRING") {
29 | return new NUMBER(from_base_98(o.value));
30 | }
31 | if(o.type === "ARRAY") {
32 | for(var i = 0; i < o.length(); ++i) {
33 | o.value[i] = NUMBER.numerical_eval(o.value[i]);
34 | }
35 | return o;
36 | }
37 | }
38 |
39 | NUMBER.numerical_eval_negate = function(o) {
40 | if(o.type === "NUMBER") {
41 | return new STRING(to_base_98(o.value));
42 | }
43 | if(o.type === "STRING") {
44 | return new NUMBER(-1 * from_base_98(o.value));
45 | }
46 | if(o.type === "ARRAY") {
47 | for(var i = 0; i < o.length(); ++i) {
48 | o.value[i] = NUMBER.numerical_eval(o.value[i]);
49 | }
50 | return o;
51 | }
52 | }
53 |
54 | NUMBER.numerical_eval_numbers = function(o) {
55 | if(o.type === "NUMBER") return o;
56 | if(o.type === "STRING") return NUMBER.numerical_eval(o);
57 | if(o.type === "ARRAY") {
58 | for(var i = 0; i < o.length(); ++i) {
59 | o.value[i] = NUMBER.numerical_eval_numbers(o.value[i]);
60 | }
61 | return o;
62 | }
63 | }
64 |
65 | NUMBER.prototype.type = "NUMBER";
66 |
67 | NUMBER.prototype.toString = function() {
68 | return this.value+"";
69 | }
70 |
71 | NUMBER.prototype.copy = function() {
72 | return new NUMBER(this.value);
73 | }
74 |
75 | /// Conversions
76 | NUMBER.prototype.valueify = function() {
77 | return this.value;
78 | }
79 | NUMBER.prototype.stringify = function() {
80 | return new STRING(this.value+"");
81 | }
82 | NUMBER.prototype.arrayify = function() {
83 | return new ARRAY([this.copy()]);
84 | }
85 | NUMBER.prototype.numberify = function() {
86 | return this.copy();
87 | }
88 | NUMBER.prototype.integerify = function() {
89 | return new NUMBER(Math.floor(this.value));
90 | }
91 | NUMBER.prototype.printify = function() {
92 | return this.toString();
93 | }
94 |
95 | /// Operators
96 | NUMBER.prototype.increment = function(path) {
97 | return new NUMBER(this.value + 1);
98 | }
99 |
100 | NUMBER.prototype.decrement = function(path) {
101 | return new NUMBER(this.value - 1);
102 | }
103 |
104 | NUMBER.prototype.increment_flip = function(path) {
105 | return new NUMBER(1 + this.value);
106 | }
107 |
108 | NUMBER.prototype.decrement_flip = function(path) {
109 | return new NUMBER(1 - this.value);
110 | }
111 |
112 | NUMBER.prototype.add = function(rhs) {
113 | var v = rhs.numberify().value;
114 | return new NUMBER(this.value + v);
115 | }
116 |
117 | NUMBER.prototype.sub = function(rhs) {
118 | var v = rhs.numberify().value;
119 | return new NUMBER(this.value - v);
120 | }
121 |
122 | NUMBER.prototype.add_flip = function(lhs) {
123 | var v = lhs.numberify().value;
124 | return new NUMBER(v + this.value);
125 | }
126 |
127 | NUMBER.prototype.sub_flip = function(lhs) {
128 | var v = lhs.numberify().value;
129 | return new NUMBER(v - this.value);
130 | }
131 |
132 | NUMBER.prototype.mul = function(rhs) {
133 | var v = rhs.numberify().value;
134 | return new NUMBER(this.value * v);
135 | }
136 |
137 | NUMBER.prototype.mul_flip = function(lhs) {
138 | var v = lhs.numberify().value;
139 | return new NUMBER(v * this.value);
140 | }
141 |
142 | NUMBER.prototype.div = function(rhs) {
143 | var v = rhs.numberify().value;
144 | return new NUMBER(this.value / v);
145 | }
146 |
147 | NUMBER.prototype.div_flip = function(lhs) {
148 | var v = lhs.numberify().value;
149 | return new NUMBER(v / this.value);
150 | }
151 |
152 | /// Misc.
153 |
154 | NUMBER.prototype.to_lowercase = function() {
155 | return new NUMBER(Math.floor(this.value));
156 | }
157 |
158 | NUMBER.prototype.to_uppercase = function() {
159 | return new NUMBER(Math.ceil(this.value));
160 | }
161 |
162 | NUMBER.prototype.to_switchcase = function() {
163 | return new NUMBER(Math.round(this.value));
164 | }
165 |
166 | NUMBER.prototype.is_truthy = function() {
167 | return new NUMBER(this.value ? 1 : 0);
168 | }
169 |
170 | NUMBER.prototype.is_falsy = function() {
171 | return new NUMBER(this.value ? 0 : 1);
172 | }
173 |
174 | NUMBER.prototype.relocate = function(from, to) {
175 | var string = this.value + "";
176 | from = ((from % string.length) + string.length) % string.length;
177 | to = ((to % string.length) + string.length) % string.length;
178 | var s = string[from];
179 | var slice = string.slice(0, from) + string.slice(from+1, string.length);
180 | slice = slice.slice(0, to) + s + slice.slice(to, slice.length);
181 | return new NUMBER(+slice);
182 | }
183 |
184 | NUMBER.prototype.shuffle = function() {
185 | var s = this.value+"";
186 | var t = "";
187 | if(s[0] === "-") {
188 | s = s.slice(1, s.length);
189 | t = "-";
190 | }
191 | var a = getRandomSample(s.split(""), s.length);
192 | return new NUMBER(+(t + a.join("")));
193 | }
194 |
--------------------------------------------------------------------------------
/src/internal/STRING.js:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------------------------------------
2 | function string_null_break(string) {
3 | return string.split(characters.correct("ð"));
4 | };
5 |
6 | function string_break(string) {
7 | var s = string_null_break(string);
8 | if(s.length === 1) {
9 | s = string.split("");
10 | }
11 | return s;
12 | };
13 |
14 | function string_row_break(string) {
15 | var blocks = string_null_break(string), rows = [];
16 | for(var i = 0; i < blocks.length; ++i) {
17 | var block = blocks[i], row = 0;
18 | for(var j = 0; j < block.length; ++j) {
19 | if(rows[row] === undefined) rows[row] = "";
20 | if(block[j] === characters.correct("¬")) row++;
21 | else rows[row] += block[j];
22 | }
23 | }
24 |
25 | return rows;
26 | };
27 |
28 | function string_escape_regex(str) {
29 | return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
30 | }
31 |
32 | function STRING(v) {
33 | this.props = make_props();
34 | this.value = v === undefined ? "" : (v+"");
35 | }
36 |
37 | STRING.prototype.type = "STRING";
38 |
39 | (function(){
40 | STRING.formats = [];
41 | function format(str) {
42 | var string = "", end = 0, res = "", add = "", temp;
43 | while(end < str.length) {
44 | for(var c = end; c < str.length; ++c) {
45 | string += str[c];
46 | for(var i = 0; i < STRING.formats.length; ++i) {
47 | temp = STRING.formats[i].call(this, string);
48 | if(temp !== undefined) {
49 | add = temp;
50 | }
51 | }
52 | }
53 | end += add.length;
54 | string = "";
55 | res += add;
56 | }
57 | return res;
58 | };
59 | STRING.prototype.format = format;
60 | Object.defineProperty(STRING, "format", {
61 | get: function() { return STRING.formats },
62 | set: function(v) { STRING.formats.push(v) },
63 | enumberable: true
64 | });
65 | STRING.format = function(str) {
66 | if(str.length === 1) return str;
67 | }
68 | })()
69 |
70 | STRING.prototype.toString = function() {
71 | return this.value;
72 | }
73 |
74 | STRING.prototype.copy = function() {
75 | return new STRING(this.value);
76 | }
77 |
78 | /// Conversions
79 | STRING.prototype.valueify = function() {
80 | return this.value;
81 | }
82 | STRING.prototype.stringify = function() {
83 | return this.copy();
84 | }
85 | STRING.prototype.arrayify = function() {
86 | var a = string_break(this.value);
87 | for(var i = 0; i < a.length; ++i) a[i] = new STRING(a[i]);
88 | return new ARRAY(a);
89 | }
90 | STRING.prototype.numberify = function() {
91 | var temp = +this.value;
92 | if(temp !== temp) {
93 | return NUMBER.numerical_eval(this);
94 | }
95 | return new NUMBER(temp);
96 | }
97 | STRING.prototype.integerify = function() {
98 | return (this.numberify()).integerify();
99 | }
100 | STRING.prototype.printify = function() {
101 | return this.format(this.value);
102 | }
103 |
104 | /// Operators
105 | STRING.prototype.increment = function(path) {
106 | var s = "", f = path.top();
107 | if(f) {
108 | s = f.stringify();
109 | }
110 | return new STRING(this.value + s);
111 | }
112 |
113 | STRING.prototype.decrement = function(path) {
114 | var s = this.value.slice(0, 1);
115 | path.top(new STRING(s));
116 | return new STRING(this.value.slice(1, this.value.length));
117 | }
118 |
119 | STRING.prototype.increment_flip = function(path) {
120 | var s = "", f = path.top();
121 | if(f) {
122 | s = f.stringify();
123 | }
124 | return new STRING(s + this.value);
125 | }
126 |
127 | STRING.prototype.decrement_flip = function(path) {
128 | var s = this.value.slice(this.value.length-1, this.value.length);
129 | path.top(new STRING(s));
130 | return new STRING(this.value.slice(0, this.value.length-1));
131 | }
132 |
133 | STRING.prototype.add = function(rhs) {
134 | var v = rhs.stringify().value;
135 | return new STRING(this.value + v);
136 | }
137 |
138 | STRING.prototype.sub = function(rhs) {
139 | var v = rhs.stringify().value;
140 | return new STRING(this.value.replace(v, ""));
141 | }
142 |
143 | STRING.prototype.add_flip = function(lhs) {
144 | var v = lhs.stringify().value;
145 | return new STRING(v + this.value);
146 | }
147 |
148 | STRING.prototype.sub_flip = function(lhs) {
149 | var v = lhs.stringify().value;
150 | return new STRING(this.value.replace(new RegExp(string_escape_string(v.value) + "$"), ""));
151 | }
152 |
153 | STRING.prototype.mul = function(rhs) {
154 | var s = "";
155 | if(rhs.type === "NUMBER") {
156 | for(var c = Math.floor(rhs.value); c--;) {
157 | s += this.value;
158 | }
159 | } else if(rhs.type === "STRING") {
160 | for(var i = 0; i < this.length(); ++i) {
161 | for(var j = 0; j < rhs.length(); ++j) {
162 | s += this.value[i] + rhs.value[j] + characters.correct("ð");
163 | }
164 | }
165 | s = s.slice(0, s.length - 1);
166 | } else if(rhs.type === "ARRAY") {
167 | for(var i = 0; i < rhs.length(); ++i) {
168 | s += this.mul(rhs.value[i]).value;
169 | }
170 | }
171 | return new STRING(s);
172 | }
173 |
174 | STRING.prototype.mul_flip = function(lhs) {
175 | var s = "";
176 | if(lhs.type === "NUMBER") {
177 | var flip = false;
178 | for(var c = Math.floor(lhs.value); c--;) {
179 | s += flip ? this.value.split("").reverse().join("") : this.value;
180 | flip = !flip;
181 | }
182 | } else if(lhs.type === "STRING") {
183 | for(var i = 0; i < this.length(); ++i) {
184 | for(var j = 0; j < lhs.length(); ++j) {
185 | s += lhs.value[j] + this.value[i] + characters.correct("ð");
186 | }
187 | }
188 | s = s.slice(0, s.length - 1);
189 | } else if(lhs.type === "ARRAY") {
190 | for(var i = 0; i < lhs.length(); ++i) {
191 | s = this.mul_flip(lhs.value[i]).value + s;
192 | }
193 | }
194 | return new STRING(s);
195 | }
196 |
197 | STRING.prototype.div = function(rhs) {
198 | var a = [];
199 | if(rhs.type === "NUMBER") {
200 | for(var i = 0, slice = Math.floor(this.length()/rhs.value), l = rhs.value * slice; i < l; i += slice) {
201 | a.push(new STRING(this.value.slice(i, i + slice)));
202 | }
203 | } else if(rhs.type === "STRING") {
204 | a = this.value.split(rhs.value);
205 | for(var i = a.length; i--;)
206 | {
207 | a[i] = new STRING(a[i]);
208 | }
209 | } else if(rhs.type === "ARRAY") {
210 | for(var i = 0; i < rhs.length(); ++i) {
211 | a = a.concat(this.div(rhs.value[i]).value);
212 | }
213 | }
214 | return new ARRAY(a);
215 | }
216 |
217 | STRING.prototype.div_flip = function(lhs) {
218 | var a = [];
219 | if(lhs.type === "NUMBER") {
220 | for(var i = this.length(), slice = Math.floor(this.length()/lhs.value), l = this.length() - (lhs.value * slice); l <= i; i -= slice) {
221 | a.push(new STRING(this.value.slice(i, i + slice)));
222 | }
223 | a = a.reverse();
224 | } else if(lhs.type === "STRING") {
225 | a = this.value.split(lhs.value).split("").reverse().join("");
226 | for(var i = a.length; i--;)
227 | {
228 | a[i] = new STRING(a[i]);
229 | }
230 | } else if(lhs.type === "ARRAY") {
231 | for(var i = 0; i < lhs.length(); ++i) {
232 | a = a.concat(this.div_flip(lhs.value[i]).value);
233 | }
234 | }
235 | return new ARRAY(a);
236 | }
237 |
238 | /// Array specific commands.
239 | STRING.prototype.correct_index = function(index) {
240 | // Overkill for what it is actually doing...
241 | return ((index % this.length()) + this.length()) % this.length();
242 | };
243 |
244 |
245 | STRING.prototype.access = function(index) {
246 | return new STRING(this.value[this.correct_index(index)]);
247 | };
248 |
249 | STRING.prototype.length = function() {
250 | return this.value.length;
251 | };
252 |
253 | /// Misc.
254 |
255 | STRING.prototype.to_lowercase = function() {
256 | return new STRING(this.value.toLowerCase());
257 | }
258 |
259 | STRING.prototype.to_uppercase = function() {
260 | return new STRING(this.value.toUpperCase());
261 | }
262 |
263 | STRING.prototype.switchcase = function() {
264 | var s = "";
265 | for(var i = 0; i < this.value.length; ++i) {
266 | var t = this.value[i];
267 | t = t.toLowerCase();
268 | if(t === this.value[i]) t = t.toUpperCase();
269 | s += t;
270 | }
271 | return new STRING(s);
272 | }
273 |
274 | STRING.prototype.is_truthy = function() {
275 | return new NUMBER(this.length() ? 1 : 0);
276 | }
277 |
278 | STRING.prototype.is_falsy = function() {
279 | return new NUMBER(this.length() ? 0 : 1);
280 | }
281 |
282 | STRING.prototype.relocate = function(from, to) {
283 | from = this.correct_index(from);
284 | to = this.correct_index(to);
285 | var s = this.value[from];
286 | var slice = this.value.slice(0, from) + this.value.slice(from+1, this.value.length);
287 | slice = slice.slice(0, to) + s + slice.slice(to, slice.length);
288 | return new STRING(slice);
289 | }
290 |
291 | STRING.prototype.shuffle = function() {
292 | var a = getRandomSample(string_break(this.value), this.length());
293 | return new STRING(a.join(""));
294 | }
295 |
--------------------------------------------------------------------------------
/src/internal/base.js:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------------------------------------
2 | function to_base_98(x) {
3 | x = Math.abs(x);
4 | if(x == 0) {
5 | return characters.int_to_char(0);
6 | }
7 | var digits = [];
8 | while(x) {
9 | digits.push(characters.int_to_char(x % 98))
10 | x = Math.floor(x /= 98);
11 | }
12 | digits.reverse();
13 | return digits.join("");
14 | };
15 |
16 | //------------------------------------------------------------------------------------------------------------
17 | function to_base_196(x) {
18 | x = Math.abs(x);
19 | if(x == 0) {
20 | return characters.int_to_char(0);
21 | }
22 | var digits = [];
23 | while(x) {
24 | digits.push(characters.int_to_char(x % 196))
25 | x = Math.floor(x /= 196);
26 | }
27 | digits.reverse();
28 | return digits.join("");
29 | };
30 |
31 | //------------------------------------------------------------------------------------------------------------
32 | function from_base_98(s) {
33 | var x = 0;
34 | for(var i = 0; i < s.length; ++i) {
35 | x += characters.char_to_int(s[s.length - i - 1]) * Math.pow(98, i);
36 | }
37 | return x;
38 | };
39 |
40 | //------------------------------------------------------------------------------------------------------------
41 | function from_base_196(s) {
42 | var x = 0;
43 | for(var i = 0; i < s.length; ++i) {
44 | x += characters.char_to_int(s[s.length - i - 1]) * Math.pow(196, i);
45 | }
46 | return x;
47 | };
48 |
49 | //------------------------------------------------------------------------------------------------------------
50 | var base = {};
51 |
52 | base.b98_add_table = {};
53 | (function(){
54 | for(var i = 0; i < 98; ++i) {
55 | var char = characters.int_to_char(i);
56 | base.b98_add_table[char] = {};
57 | for(var j = 0; j < 98; ++j) {
58 | var term = characters.int_to_char(j);
59 | base.b98_add_table[char][term] = {carry:undefined};
60 | var sum;
61 | if(i+j < 98) {
62 | sum = characters.int_to_char(i+j);
63 | base.b98_add_table[char][term].result = sum;
64 | } else {
65 | sum = characters.int_to_char(i+j-98);
66 | base.b98_add_table[char][term].carry = characters.int_to_char(1);
67 | base.b98_add_table[char][term].result = base.b98_add_table[char][term].carry + sum;
68 | }
69 | base.b98_add_table[char][term].sum = sum;
70 | }
71 | }
72 | })();
73 |
74 | base.b196_add_table = {};
75 | (function(){
76 | for(var i = 0; i < 196; ++i) {
77 | var char = characters.int_to_char(i);
78 | base.b196_add_table[char] = {};
79 | for(var j = 0; j < 196; ++j) {
80 | var term = characters.int_to_char(j);
81 | base.b196_add_table[char][term] = {carry:undefined};
82 | var sum;
83 | if(i+j < 196) {
84 | sum = characters.int_to_char(i+j);
85 | base.b196_add_table[char][term].result = sum;
86 | } else {
87 | sum = characters.int_to_char(i+j-196);
88 | base.b196_add_table[char][term].carry = characters.int_to_char(1);
89 | base.b196_add_table[char][term].result = base.b196_add_table[char][term].carry + sum;
90 | }
91 | base.b196_add_table[char][term].sum = sum;
92 | }
93 | }
94 | })();
95 |
96 | //------------------------------------------------------------------------------------------------------------
97 | // Might have to have a smarter functions to handle recursion of the algorithm a lot better...
98 | base.b98_add = function(lhs, rhs) {
99 | if(lhs.length === 0) lhs = characters.int_to_char(0);
100 | if(rhs.length === 0) rhs = characters.int_to_char(0);
101 |
102 | if(lhs.length === 1 && rhs.length === 1) {
103 | var obj = base.b98_add_table[lhs][rhs];
104 | return obj.carry + obj.sum;
105 | }
106 |
107 | // Make lhs and rhs have the same length.
108 | if(lhs.length < rhs.length) {
109 | for(var i = rhs.length - lhs.length; i--;) {
110 | lhs = characters.int_to_char(0) + lhs;
111 | }
112 | } else if(rhs.length < lhs.length) {
113 | for(var i = lhs.length - rhs.length; i--;) {
114 | rhs = characters.int_to_char(0) + rhs;
115 | }
116 | }
117 |
118 | var result = "";
119 |
120 | for(var i = lhs.length; i--;) {
121 | var sum = base.b98_add(lhs[i], rhs[i]);
122 | // No carry occured.
123 | if(sum.length === 1) {
124 | result = sum + result;
125 | } else {
126 | result = sum[1] + result;
127 | }
128 | }
129 |
130 | return result;
131 | };
132 |
--------------------------------------------------------------------------------
/src/internal/path.js:
--------------------------------------------------------------------------------
1 | (function(global, Pipe, Command, Token){
2 |
3 | function Path(code, tkn, parent) {
4 | this.code = code;
5 | this.parent = parent;
6 | this.start = new Token(0, this.code, tkn);
7 | this.start.path = this;
8 | this.current = this.start;
9 | this.end = this.start.tokenize();
10 | this.previous = this.end;
11 | this.onsteps = [];
12 | this.onstarts = [];
13 | this.onends = [];
14 | this.onstops = [];
15 | this.timeout = undefined;
16 | this.rate = 0;
17 | this.kill_this = false;
18 |
19 | var self = this;
20 | function invoke_onsteps() { for(var i = 0, l = self.onsteps.length; i < l; ++i) self.onsteps[i].call(self) };
21 | function invoke_onstarts() { for(var i = 0, l = self.onstarts.length; i < l; ++i) self.onstarts[i].call(self) };
22 | function invoke_onends() { for(var i = 0, l = self.onends.length; i < l; ++i) self.onends[i].call(self) };
23 | function invoke_onstops() { for(var i = 0, l = self.onstops.length; i < l; ++i) self.onstops[i].call(self) };
24 |
25 | Object.defineProperty(self, "onstep", {
26 | get: function() { return invoke_onsteps },
27 | set: function(v) { self.onsteps.push(v) }
28 | });
29 | Object.defineProperty(self, "onstart", {
30 | get: function() { return invoke_onstarts },
31 | set: function(v) { self.onstarts.push(v) }
32 | });
33 | Object.defineProperty(self, "onend", {
34 | get: function() { return invoke_onends },
35 | set: function(v) { self.onends.push(v) }
36 | });
37 | Object.defineProperty(self, "onstop", {
38 | get: function() { return invoke_onstops },
39 | set: function(v) { self.onstops.push(v) }
40 | });
41 |
42 | this.stdin = new Pipe();
43 | this.stdout = new Pipe();
44 | }
45 |
46 | Path.prototype.step = function() {
47 | if(!this.current) return false;
48 | if(this.current === this.start) this.onstart();
49 | this.current.cmd.exec(this);
50 | this.previous = this.current;
51 | this.current = this.current.next();
52 | this.onstep();
53 | return !this.kill_this && !!this.current;
54 | }
55 |
56 | Path.prototype.stop = function() {
57 | if(this.timeout) {
58 | clearTimeout(this.timeout);
59 | this.timeout = undefined;
60 | this.kill_this = true;
61 | this.onstop();
62 | this.onend();
63 | }
64 | }
65 |
66 | Path.prototype.exec = function() {
67 | this.stop();
68 | var self = this;
69 | this.kill_this = false;
70 | self.start_time = (new Date).getTime();
71 | (function loop(){
72 | if(self.step()) {
73 | self.timeout = setTimeout(loop, self.rate);
74 | } else {
75 | self.timeout = undefined;
76 | self.onend();
77 | }
78 | })()
79 | }
80 |
81 | global.Path = Path;
82 |
83 | })(this, this.Pipe, this.Command, this.Token)
84 |
--------------------------------------------------------------------------------
/src/internal/pipe.js:
--------------------------------------------------------------------------------
1 | (function(global){
2 |
3 | function Pipe() {
4 | var self = this;
5 | self.__array__ = [];
6 | self.front = function(v) {
7 | if(arguments.length === 0) return self.front.pop();
8 | self.front.push(v);
9 | return self;
10 | }
11 | self.front.push = function(v) {
12 | self.__array__.unshift(v);
13 | return self;
14 | }
15 | self.front.pop = function() {
16 | return self.__array__.shift();
17 | }
18 |
19 | self.back = function(v) {
20 | if(arguments.length === 0) return self.back.pop();
21 | self.back.push(v);
22 | return self;
23 | }
24 | self.back.push = function(v) {
25 | self.__array__.push(v);
26 | return self;
27 | }
28 | self.back.pop = function() {
29 | return self.__array__.pop();
30 | }
31 | }
32 |
33 | Pipe.prototype.length = function() {
34 | return this.__array__.length;
35 | }
36 |
37 | Pipe.prototype.first = function() {
38 | return this.__array__[0];
39 | }
40 |
41 | Pipe.prototype.last = function() {
42 | return this.__array__[this.length() - 1];
43 | }
44 |
45 | Pipe.prototype.pipe = function(other) {
46 | while(other.length()) this.back(other.front());
47 | return this;
48 | }
49 |
50 | Pipe.prototype.rpipe = function(other) {
51 | while(other.length()) this.front(other.back());
52 | return this;
53 | }
54 |
55 | Pipe.prototype.at = function(i, v) {
56 | if(arguments.length === 1) {
57 | return this.__array__[i];
58 | } else if(arguments.length === 2 && 0 <= i && i < this.length()) {
59 | this.__array__[i] = v;
60 | return this;
61 | }
62 | }
63 |
64 | Pipe.prototype.each = function(f) {
65 | var r = undefined;
66 | for(var i = 0, l = this.length(); i < l && (r === undefined || (typeof r === "boolean" && r)); ++i)
67 | r = f.call(this, this.at(i));
68 | return this;
69 | }
70 |
71 | Pipe.prototype.reverse = function() {
72 | for(var i = 0, l = this.length(); i < l; ++i)
73 | this.front(this.back());
74 | return this;
75 | }
76 |
77 | Pipe.prototype.wipe = function() {
78 | while(this.front());
79 | return this;
80 | }
81 |
82 | Pipe.prototype.remove = function(v) {
83 | for(var i = 0, l = this.length(); i < l; ++i)
84 | if(v === this.__array__[i]) {
85 | this.__array__.splice(i, 1);
86 | return true;
87 | }
88 | return false;
89 | }
90 |
91 | global.Pipe = Pipe;
92 |
93 | })(this)
94 |
--------------------------------------------------------------------------------
/src/internal/props.js:
--------------------------------------------------------------------------------
1 | (function(global){
2 |
3 | function Props() {
4 | function the_props(name, value) {
5 | if(arguments.length === 1) return the_props.__props__[name]
6 | the_props.__props__[name] = value;
7 | return the_props;
8 | }
9 | the_props.__props__ = {};
10 | the_props.clear = function() { the_props.__props__ = {}; return the_props };
11 | the_props.get = function(name) { return the_props.__props__[name] };
12 | the_props.set = function(name, value) { the_props.__props__[name] = value; return the_props; };
13 | return the_props;
14 | }
15 |
16 | global.make_props = Props;
17 |
18 | })(this)
19 |
--------------------------------------------------------------------------------
/src/internal/token.js:
--------------------------------------------------------------------------------
1 | (function(global, Pipe){
2 |
3 | function Command(tkn, f) {
4 | this.tkn = tkn;
5 | this.methods = [];
6 | var self = this;
7 | function invoke() {
8 | for(var i = 0, l = self.methods.length; i < l; ++i)
9 | self.methods[i].apply(self, Array.prototype.slice.call(arguments))
10 | }
11 | Object.defineProperty(self, "exec", {
12 | get: function() { return invoke },
13 | set: function(v) { self.methods.push(v) }
14 | });
15 |
16 | if(f) f(this);
17 | };
18 |
19 | Command.commands = [];
20 | Command.add = function(li, r, f) {
21 | Command.commands.push({literal_index: li+1, regex:r, f:f});
22 | };
23 | function CommandLookUp(res, index) {
24 | this.index = index;
25 | this.literal = res[Command.commands[index].literal_index];
26 | this.params = [];
27 | for(var i = 1; i < res.length; ++i) if(i !== Command.commands[index].literal_index) this.params.push(res[i]);
28 | this.captured = res[0];
29 | };
30 | Command.find = function(text) {
31 | for(var i = Command.commands.length; i--;) {
32 | var res = Command.commands[i].regex.exec(text);
33 | if(res) {
34 | var p = new CommandLookUp(res, i);
35 | return p;
36 | }
37 | }
38 | };
39 |
40 | Command.prototype.tokenize = function() {
41 | this.tkn.branches.front(new Token(this.tkn.end+1, this.tkn.code, this.tkn));
42 | return this.tkn.branches.first();
43 | };
44 |
45 | global.Command = Command;
46 |
47 | ///////////////////////////////////////////////////////////////////////////////
48 |
49 | function Token(start, code, parent) {
50 | this.start = start;
51 | this.code = code;
52 | this.parent = parent;
53 | if(parent) this.path = parent.path;
54 | this.branches = new Pipe();
55 | };
56 |
57 | Token.prototype.tokenize = function() {
58 | Token.parse(this);
59 | if(this.cmd) {
60 | var spawned = this.cmd.tokenize();
61 | return spawned.tokenize();
62 | } else if(this.parent) {
63 | this.parent.branches.remove(this);
64 | return this.parent;
65 | }
66 | }
67 |
68 | Token.prototype.next = function() {
69 | return this.branches.first();
70 | }
71 |
72 | Token.parse = function(tkn) {
73 | var i = tkn.start, string = tkn.code[i], look = undefined;
74 | //while(tkn.code[i] !== "\n" && i < tkn.code.length) {
75 | // Parses entire script to find the best command.
76 | while(i < tkn.code.length) {
77 | var get = Command.find(string);
78 | // If found a command that uses more characters then use that.
79 | if(get !== undefined) {
80 | look = get;
81 | }
82 | string += tkn.code[++i];
83 | }
84 |
85 | if(look) {
86 | tkn.literal = look.literal;
87 | tkn.end = tkn.start + look.captured.length - 1;
88 | tkn.cmd = new Command(tkn, Command.commands[look.index].f);
89 | tkn.params = look.params;
90 | tkn.captured = look.captured;
91 | }
92 | }
93 |
94 | global.Token = Token;
95 |
96 | })(this, this.Pipe)
97 |
--------------------------------------------------------------------------------
/src/noodel-basic_array.js:
--------------------------------------------------------------------------------
1 | (function(global, noodel, Pipe, Command, Token, Path, characters, NUMBER, STRING, ARRAY){
2 |
3 | //------------------------------------------------------------------------------------------------------------
4 | /// Array Based Operators
5 | //------------------------------------------------------------------------------------------------------------
6 |
7 | //------------------------------------------------------------------------------------------------------------
8 | /// Flattens that particular data type (for arrays places into elements, strings turned into char arrays
9 | /// and numbers into integers.
10 | Command.add(0, noodel.commandify(characters.correct("ɲ")+"_"), function(cmd) {
11 | cmd.exec = function(path) {
12 | var f = path.top();
13 | if(f) {
14 | if(f.type === "ARRAY") {
15 | for(var i = 0; i < f.value.length; ++i) path.top(f.value[i]);
16 | } else if(f.type === "NUMBER") {
17 | path.top(new NUMBER(f.value * f.value));
18 | } else if(f.type === "STRING") {
19 | for(var i = 0; i < f.value.length; ++i) path.top(new STRING(f.value[i]));
20 | }
21 | }
22 | }
23 | });
24 |
25 | //------------------------------------------------------------------------------------------------------------
26 | /// Gets magnitude of that particular data type.
27 | Command.add(0, noodel.commandify(characters.correct("ɲ")+"l"), function(cmd) {
28 | cmd.exec = function(path) {
29 | var f = path.top();
30 | if(f) {
31 | if(f.type === "NUMBER") {
32 | path.top(new NUMBER(Math.abs(f.value)));
33 | } else if(f.type === "STRING" || f.type === "ARRAY") {
34 | path.top(f);
35 | path.top(new NUMBER(f.length()));
36 | }
37 | }
38 | }
39 | });
40 |
41 | //------------------------------------------------------------------------------------------------------------
42 | /// Takes the first element of strings/arrays and places it into the back. For numbers, it reciprocates.
43 | Command.add(0, noodel.commandify(characters.correct("ẹ")), function(cmd) {
44 | cmd.exec = function(path) {
45 | var f = path.top();
46 | if(f) {
47 | if(f.type === "ARRAY") {
48 | var e = f.value.shift();
49 | if(e) f.value.push(e);
50 | path.top(f);
51 | } else if(f.type === "NUMBER") {
52 | path.top(new NUMBER(1/f.value));
53 | } else if(f.type === "STRING") {
54 | var s = f.value;
55 | path.top(new STRING(s.slice(1, s.length) + s.slice(0, 1)));
56 | }
57 | } else path.top(f);
58 | }
59 | });
60 |
61 | //------------------------------------------------------------------------------------------------------------
62 | /// Takes the last element of strings/arrays and places it into the front. For numbers, it square roots.
63 | Command.add(0, noodel.commandify(characters.correct("Ẹ")), function(cmd) {
64 | cmd.exec = function(path) {
65 | var f = path.top();
66 | if(f) {
67 | if(f.type === "ARRAY") {
68 | var e = f.value.pop();
69 | if(e) f.value.unshift(e);
70 | path.top(f);
71 | } else if(f.type === "NUMBER") {
72 | path.top(new NUMBER(Math.sqrt(f.value)));
73 | } else if(f.type === "STRING") {
74 | var s = f.value, len = s.length;
75 | path.top(new STRING(s.slice(len-1, len) + s.slice(0, len-1)));
76 | }
77 | } else path.top(f);
78 | }
79 | });
80 |
81 | //------------------------------------------------------------------------------------------------------------
82 | /// Accesses a particular frame of an array/string. If is an integer in the pipe then it will use that as
83 | /// the index and place the accessed first and increment the index for the next frame.
84 | Command.add(0, noodel.commandify(characters.correct("ạ")), function(cmd) {
85 | cmd.exec = function(path) {
86 | var f = path.top();
87 | if(f) {
88 | var index, delta, count;
89 | if(f.type === "NUMBER") {
90 | f = f.integerify();
91 | index = f.value;
92 | delta = index < 0 ? -1 : 1;
93 | f = path.top();
94 | if(!f) {
95 | path.top(new NUMBER(index + delta));
96 | return;
97 | }
98 | }
99 |
100 | if(f.type === "NUMBER") {
101 | f = f.integerify();
102 | count = f.value;
103 | f = path.top();
104 | if(!f) {
105 | path.top(new NUMBER(index + (delta * count)));
106 | return;
107 | }
108 | }
109 |
110 | if(f.type === "NUMBER") {
111 | path.top(new NUMBER(Math.abs((index + (delta * count))) % f.value));
112 | } else {
113 | if(f.type === "STRING") f = f.arrayify();
114 | if(index === undefined) index = f.props("frame");
115 | if(index === undefined) { index = 0; delta = 1; }
116 | if(count === undefined) count = f.props("frame_count");
117 | if(count === undefined) count = f.length();
118 | if(delta === undefined) delta = f.props("frame_delta");
119 |
120 | var item;
121 |
122 | if(count !== 0) {
123 | index = f.correct_index(index);
124 | item = f.access(index);
125 | index += delta;
126 | --count;
127 | }
128 |
129 | if(count === 0) {
130 | f.props("frame", undefined);
131 | f.props("frame_count", undefined);
132 | f.props("frame_delta", undefined);
133 | } else {
134 | f.props("frame", index);
135 | f.props("frame_count", count);
136 | f.props("frame_delta", delta);
137 | }
138 |
139 | path.top(f);
140 | path.top(item);
141 | }
142 | }
143 | }
144 | });
145 |
146 | //------------------------------------------------------------------------------------------------------------
147 | /// Accesses a particular frame of an array/string. If is an integer in the pipe then it will use that as
148 | /// the index and place the accessed first and increment the index for the next frame.
149 | /// The number following the token will be used as the first number.
150 | Command.add(0, new RegExp("^(" + characters.correct("ạ") + ")((?:\\-\\d*)|(?:\\d+))$"), function(cmd) {
151 | cmd.exec = function(path) {
152 | var f = path.top();
153 | if(f) {
154 | var index = this.tkn.index,
155 | count = undefined;
156 | var delta = this.tkn.delta;
157 |
158 | if(f.type === "NUMBER") {
159 | f = f.integerify();
160 | count = f.value;
161 | f = path.top();
162 | if(!f) {
163 | path.top(new NUMBER(index + (delta * count)));
164 | return;
165 | }
166 | }
167 |
168 | if(f.type === "NUMBER") {
169 | path.top(new NUMBER((index + (delta * count))) % f.value);
170 | } else {
171 | if(f.type === "STRING") f = f.arrayify();
172 | if(f.props("frame") !== undefined) index = f.props("frame");
173 | if(count === undefined) count = f.props("frame_count");
174 | if(count === undefined) count = f.length();
175 |
176 | var item;
177 |
178 | if(count !== 0) {
179 | index = f.correct_index(index);
180 | item = f.access(index);
181 | index += delta;
182 | --count;
183 | }
184 |
185 | if(count === 0) {
186 | f.props("frame", undefined);
187 | f.props("frame_count", undefined);
188 | f.props("frame_delta", undefined);
189 | } else {
190 | f.props("frame", index);
191 | f.props("frame_count", count);
192 | f.props("frame_delta", delta);
193 | }
194 |
195 | path.top(f);
196 | path.top(item);
197 | }
198 | }
199 | }
200 |
201 | var old = cmd.tokenize;
202 | cmd.tokenize = function() {
203 | if(this.tkn.params[0] === "-") {
204 | this.tkn.index = -1;
205 | this.tkn.delta = -1;
206 | } else if(this.tkn.params[0] === "-0") {
207 | this.tkn.index = 0;
208 | this.tkn.delta = -1;
209 | } else {
210 | this.tkn.index = +this.tkn.params[0];
211 | this.tkn.delta = this.tkn.index < 0 ? -1 : 1;
212 | }
213 |
214 | return old.call(this);
215 | }
216 | });
217 |
218 | //------------------------------------------------------------------------------------------------------------
219 | /// Accesses a particular frame of an array/string based off of an array.
220 | Command.add(0, noodel.commandify(characters.correct("Ạ")), function(cmd) {
221 | cmd.exec = function(path) {
222 | var f = path.top();
223 | if(f) {
224 | if(f.type === "ARRAY") {
225 | var g = path.top();
226 | if(g) {
227 | if(g.type === "ARRAY") {
228 | if(f.props("frame") === undefined) f.props("frame", 0);
229 | var item = g.access(f.access(f.props("frame")));
230 | f.props("frame", f.correct_index(f.props("frame") + 1));
231 |
232 | path.top(g);
233 | path.top(f);
234 | path.top(item);
235 | }
236 | }
237 | }
238 | }
239 | }
240 | });
241 |
242 | })(this, this.noodel, this.Pipe, this.Command, this.Token, this.Path, this.characters, this.NUMBER, this.STRING, this.ARRAY)
243 |
--------------------------------------------------------------------------------
/src/noodel-basic_cast.js:
--------------------------------------------------------------------------------
1 | (function(global, noodel, Pipe, Command, Token, Path, characters, NUMBER, STRING, ARRAY){
2 |
3 | //------------------------------------------------------------------------------------------------------------
4 | /// Type cast operations.
5 | //------------------------------------------------------------------------------------------------------------
6 |
7 | //------------------------------------------------------------------------------------------------------------
8 | /// Numberifies strings and arrays by elements if already a number it will flip the sign.
9 | Command.add(0, noodel.commandify(characters.correct("ɲ")), function(cmd) {
10 | cmd.exec = function(path) {
11 | var f = path.top();
12 | if(f) {
13 | if(f.type === "ARRAY") {
14 | for(var i = 0; i < f.length(); ++i) {
15 | f.value[i] = f.value[i].numberify();
16 | }
17 | path.top(f);
18 | } else if(f.type === "NUMBER") {
19 | path.top(new NUMBER(-1 * Math.abs(f.value)));
20 | } else if(f.type === "STRING") {
21 | var a = new ARRAY(string_null_break(f.value));
22 | for(var i = 0; i < a.length(); ++i) {
23 | a.value[i] = (new STRING(a.value[i])).numberify();
24 | }
25 | if(a.length() === 0) {
26 | a = new NUMBER(0);
27 | } else if(a.length() === 1) {
28 | a = a.value[0]
29 | }
30 | path.top(a);
31 | }
32 | }
33 | }
34 | });
35 |
36 | //------------------------------------------------------------------------------------------------------------
37 | /// Stringifies the first item in the pipe.
38 | Command.add(0, noodel.commandify(characters.correct("ɲ")+"'"), function(cmd) {
39 | cmd.exec = function(path) {
40 | var f = path.top();
41 | if(f) {
42 | if(f.type === "ARRAY") {
43 | for(var i = 0; i < f.length(); ++i) {
44 | f.value[i] = f.value[i].stringify();
45 | }
46 | path.top(f);
47 | } else if(f.type === "NUMBER") {
48 | path.top(f.stringify());
49 | } else if(f.type === "STRING") {
50 | var s = "";
51 | for(var i = f.length(); i--;) {
52 | s += f.value[i];
53 | }
54 | path.top(new STRING(s));
55 | }
56 | }
57 | }
58 | });
59 |
60 | //------------------------------------------------------------------------------------------------------------
61 | /// Stringifies the first item in the pipe.
62 | Command.add(0, noodel.commandify(characters.correct("ɲ")+'"'), function(cmd) {
63 | cmd.exec = function(path) {
64 | var f = path.top();
65 | if(f) {
66 | if(f.type === "STRING") {
67 | path.top(new STRING(string_null_break(f.value).join("")));
68 | } else {
69 | path.top(f.stringify());
70 | }
71 | }
72 | }
73 | });
74 |
75 | //------------------------------------------------------------------------------------------------------------
76 | /// Numberifies the first item in the pipe.
77 | Command.add(0, noodel.commandify(characters.correct("ɲ")+"#"), function(cmd) {
78 | cmd.exec = function(path) {
79 | var f = path.top();
80 | if(f) {
81 | if(f.type === "ARRAY") {
82 | for(var i = 0; i < f.length(); ++i) {
83 | f.value[i] = f.value[i].numberify();
84 | }
85 | path.top(f);
86 | } else if(f.type === "STRING") {
87 | path.top(f.numberify());
88 | } else if(f.type === "NUMBER") {
89 | path.top(new NUMBER(-1 * f.value));
90 | }
91 | }
92 | }
93 | });
94 |
95 | //------------------------------------------------------------------------------------------------------------
96 | /// Arrayifies the first item in the pipe.
97 | Command.add(0, noodel.commandify(characters.correct("ʋ")), function(cmd) {
98 | cmd.exec = function(path) {
99 | var f = path.top();
100 | if(f) {
101 | if(f.type === "STRING") {
102 | path.top(f.arrayify());
103 | } else if(f.type === "NUMBER") {
104 | f = new ARRAY(factorize_number(f.value));
105 | for(var i = 0; i < f.length(); ++i) f.value[i] = new NUMBER(f.value[i]);
106 | path.top(f);
107 | } else if(f.type === "ARRAY") {
108 | for(var i = f.length(); i--;) f.value.reverse();
109 | path.top(f);
110 | }
111 | }
112 | }
113 | });
114 |
115 | //------------------------------------------------------------------------------------------------------------
116 | /// Collects all of the items in the pipe and creates an array for them.
117 | Command.add(0, noodel.commandify(characters.correct("ȧ")), function(cmd) {
118 | cmd.exec = function(path) {
119 | var a = [];
120 | while(path.first()) a.push(path.top());
121 | if(a.length) path.top(new ARRAY(a));
122 | }
123 | });
124 |
125 | //------------------------------------------------------------------------------------------------------------
126 | /// Collects the number of items specified by the count and creates an array for them.
127 | Command.add(0, noodel.commandify(characters.correct("ȧ"), "\\d+"), function(cmd) {
128 | cmd.exec = function(path) {
129 | var a = [];
130 | for(var i = +this.tkn.params[0]; i-- && path.first();) a.push(path.top());
131 | if(a.length) {
132 | path.top(new ARRAY(a));
133 | }
134 | }
135 | });
136 |
137 | //------------------------------------------------------------------------------------------------------------
138 | /// Collects the number of items specified in the pipe and creates an array for them.
139 | Command.add(0, noodel.commandify(characters.correct("µ") + characters.correct("ȧ")), function(cmd) {
140 | cmd.exec = function(path) {
141 | var f = path.top();
142 | if(f) {
143 | var a = [];
144 | for(var i = f.integerify().value; i-- && path.first();) a.push(path.top());
145 | if(a.length) {
146 | path.top(new ARRAY(a));
147 | }
148 | }
149 | }
150 | });
151 |
152 | //------------------------------------------------------------------------------------------------------------
153 | /// Numerically evalues an item on the stack and pushes the result.
154 | Command.add(0, noodel.commandify(characters.correct("ȥ")), function(cmd) {
155 | cmd.exec = function(path) {
156 | var f = path.top();
157 | if(f) {
158 | path.top(NUMBER.numerical_eval(f));
159 | }
160 | }
161 | });
162 |
163 | //------------------------------------------------------------------------------------------------------------
164 | /// Numerically evalues an item on the stack and pushes the result and negates if a number.
165 | Command.add(0, noodel.commandify(characters.correct("ȥ") + "-"), function(cmd) {
166 | cmd.exec = function(path) {
167 | var f = path.top();
168 | if(f) {
169 | path.top(NUMBER.numerical_eval_negate(f));
170 | }
171 | }
172 | });
173 |
174 | })(this, this.noodel, this.Pipe, this.Command, this.Token, this.Path, this.characters, this.NUMBER, this.STRING, this.ARRAY)
175 |
--------------------------------------------------------------------------------
/src/noodel-basic_pipe.js:
--------------------------------------------------------------------------------
1 | (function(global, noodel, Pipe, Command, Token, Path, characters, NUMBER, STRING, ARRAY){
2 |
3 | //------------------------------------------------------------------------------------------------------------
4 | /// Operations directly to the Pipe.
5 | //------------------------------------------------------------------------------------------------------------
6 |
7 | //------------------------------------------------------------------------------------------------------------
8 | // Removes the current stack.
9 | Command.add(0, noodel.commandify(characters.correct("Ḃ")), function(cmd) {
10 | cmd.exec = function(path) {
11 | path.jump_out();
12 | path.top();
13 | }
14 | });
15 |
16 | //------------------------------------------------------------------------------------------------------------
17 | // Removes the item on the top of the stack.
18 | Command.add(0, noodel.commandify(characters.correct("ḃ")), function(cmd) {
19 | cmd.exec = function(path) {
20 | path.top();
21 | }
22 | });
23 |
24 | //------------------------------------------------------------------------------------------------------------
25 | // Removes the item on the top of the stack.
26 | Command.add(0, noodel.commandify(characters.correct("ḃ"), "\\d+"), function(cmd) {
27 | cmd.exec = function(path) {
28 | var a = [];
29 | for(var i = this.tkn.params[0]; i-- && path.first();) {
30 | a.push(path.top())
31 | }
32 | path.top();
33 | for(var i = a.length; i--;) {
34 | path.top(a[i]);
35 | }
36 | }
37 |
38 | var old = cmd.tokenize;
39 | cmd.tokenize = function() {
40 | this.tkn.params[0] = +this.tkn.params[0];
41 | return old.call(this);
42 | }
43 | });
44 |
45 | //------------------------------------------------------------------------------------------------------------
46 | // Removes the item on the bottom of the stack.
47 | Command.add(0, noodel.commandify(characters.correct("ċ")), function(cmd) {
48 | cmd.exec = function(path) {
49 | path.bottom();
50 | }
51 | });
52 |
53 | //------------------------------------------------------------------------------------------------------------
54 | // Removes the item on the bottom of the stack.
55 | Command.add(0, noodel.commandify(characters.correct("ċ"), "\\d+"), function(cmd) {
56 | cmd.exec = function(path) {
57 | var a = [];
58 | for(var i = this.tkn.params[0]; i-- && path.last();) {
59 | a.push(path.bottom())
60 | }
61 | path.bottom();
62 | for(var i = a.length; i--;) {
63 | path.bottom(a[i]);
64 | }
65 | }
66 |
67 | var old = cmd.tokenize;
68 | cmd.tokenize = function() {
69 | this.tkn.params[0] = +this.tkn.params[0];
70 | return old.call(this);
71 | }
72 | });
73 |
74 | //------------------------------------------------------------------------------------------------------------
75 | // Reverses the stack.
76 | Command.add(0, noodel.commandify(characters.correct("Ċ")), function(cmd) {
77 | cmd.exec = function(path) {
78 | path.reverse_stack();
79 | }
80 | });
81 |
82 | //------------------------------------------------------------------------------------------------------------
83 | // Duplicates the item on the top of the stack.
84 | Command.add(0, noodel.commandify(characters.correct("ḋ")), function(cmd) {
85 | cmd.exec = function(path) {
86 | var f = path.first();
87 | if(f) {
88 | path.top(f.copy());
89 | }
90 | }
91 | });
92 |
93 | //------------------------------------------------------------------------------------------------------------
94 | // Duplicates the item on the top of the stack.
95 | Command.add(1, noodel.commandify(characters.regex.a_tiny_digit + "+", characters.correct("ḋ")), function(cmd) {
96 | cmd.exec = function(path) {
97 | var f = path.first();
98 | if(f) {
99 | for(var c = this.tkn.params[0]; c--;) {
100 | path.top(f.copy());
101 | }
102 | }
103 | }
104 |
105 | var old = cmd.tokenize;
106 | cmd.tokenize = function() {
107 | this.tkn.params[0] = +characters.tiny_num_to_num(this.tkn.params[0]);
108 |
109 | return old.call(this);
110 | }
111 | });
112 |
113 | //------------------------------------------------------------------------------------------------------------
114 | // Places what is on the top of the stack to the bottom.
115 | Command.add(0, noodel.commandify(characters.correct("ė")), function(cmd) {
116 | cmd.exec = function(path) {
117 | var f = path.top();
118 | if(f) path.bottom(f);
119 | }
120 | });
121 |
122 | //------------------------------------------------------------------------------------------------------------
123 | // Places what is on the bottom of the stack and places it on the top.
124 | Command.add(0, noodel.commandify(characters.correct("Ė")), function(cmd) {
125 | cmd.exec = function(path) {
126 | var f = path.bottom();
127 | if(f) path.top(f);
128 | }
129 | });
130 |
131 | //------------------------------------------------------------------------------------------------------------
132 | /// Swaps what is on the top of the stack with the item right below it.
133 | Command.add(0, noodel.commandify(characters.correct("ṡ")), function(cmd) {
134 | cmd.exec = function(path) {
135 | var f = path.top();
136 | if(f) {
137 | var g = path.top();
138 | path.top(f);
139 | if(g) {
140 | path.top(g);
141 | }
142 | }
143 | }
144 | });
145 |
146 | //------------------------------------------------------------------------------------------------------------
147 | /// Swaps what is on the bottom of the stack with the item right above it.
148 | Command.add(0, noodel.commandify(characters.correct("Ṡ")), function(cmd) {
149 | cmd.exec = function(path) {
150 | var f = path.bottom();
151 | if(f) {
152 | var g = path.bottom();
153 | path.bottom(f);
154 | if(g) {
155 | path.bottom(g);
156 | }
157 | }
158 | }
159 | });
160 |
161 | })(this, this.noodel, this.Pipe, this.Command, this.Token, this.Path, this.characters, this.NUMBER, this.STRING, this.ARRAY)
162 |
--------------------------------------------------------------------------------
/src/noodel-basic_print.js:
--------------------------------------------------------------------------------
1 | (function(global, noodel, Pipe, Command, Token, Path, characters, NUMBER, STRING, ARRAY){
2 |
3 | //------------------------------------------------------------------------------------------------------------
4 | /// Operations for printing.
5 | //------------------------------------------------------------------------------------------------------------
6 |
7 | //------------------------------------------------------------------------------------------------------------
8 | /// Clears the path's outputs and copies what is in the front of the pipe into the path's output.
9 | Command.add(0, noodel.commandify(characters.correct("ç")), function(cmd) {
10 | cmd.exec = function(path) {
11 | var f = path.first();
12 | path.stdout.wipe();
13 | if(f) {
14 | path.stdout.back(f.copy());
15 | }
16 | }
17 | });
18 |
19 | //------------------------------------------------------------------------------------------------------------
20 | /// Clears the path's outputs and copies what is in the front of the pipe into the path's output.
21 | Command.add(0, noodel.commandify(characters.correct("ç"), "\\d+"), function(cmd) {
22 | cmd.exec = function(path) {
23 | path.stdout.wipe();
24 | var array = [];
25 | for(var c = this.tkn.params[0]; c-- && path.first();) {
26 | array.push(path.top());
27 | }
28 | if(path.first()) path.stdout.back(path.first().copy());
29 | for(var c = array.length; c--;) {
30 | path.top(array.pop());
31 | }
32 | }
33 |
34 | var old = cmd.tokenize;
35 | cmd.tokenize = function() {
36 | this.tkn.params[0] = +this.tkn.params[0];
37 | return old.call(this);
38 | }
39 | });
40 |
41 | //------------------------------------------------------------------------------------------------------------
42 | /// Clears the path's outputs and places what is in the front of the pipe into the path's output.
43 | Command.add(0, noodel.commandify(characters.correct("Ç")), function(cmd) {
44 | cmd.exec = function(path) {
45 | var f = path.top();
46 | path.stdout.wipe();
47 | if(f) {
48 | path.stdout.back(f);
49 | }
50 | }
51 | });
52 |
53 | //------------------------------------------------------------------------------------------------------------
54 | /// Clears the path's outputs and places what is in the front of the pipe into the path's output.
55 | Command.add(0, noodel.commandify(characters.correct("Ç"), "\\d+"), function(cmd) {
56 | cmd.exec = function(path) {
57 | path.stdout.wipe();
58 | var array = [];
59 | for(var c = this.tkn.params[0]; c-- && path.first();) {
60 | array.push(path.top());
61 | }
62 | if(path.first()) path.stdout.back(path.top());
63 | for(var c = array.length; c--;) {
64 | path.top(array.pop());
65 | }
66 | }
67 |
68 | var old = cmd.tokenize;
69 | cmd.tokenize = function() {
70 | this.tkn.params[0] = +this.tkn.params[0];
71 | return old.call(this);
72 | }
73 | });
74 |
75 | //------------------------------------------------------------------------------------------------------------
76 | /// Copies what is in the front of the pipe into the path's output.
77 | Command.add(0, noodel.commandify(characters.correct("þ")), function(cmd) {
78 | cmd.exec = function(path) {
79 | var f = path.first();
80 | if(f) {
81 | path.stdout.back(f.copy());
82 | }
83 | }
84 | });
85 |
86 | //------------------------------------------------------------------------------------------------------------
87 | /// Copies what is in the front of the pipe into the path's output.
88 | Command.add(0, noodel.commandify(characters.correct("þ"), "\\d+"), function(cmd) {
89 | cmd.exec = function(path) {
90 | var array = [];
91 | for(var c = this.tkn.params[0]; c-- && path.first();) {
92 | array.push(path.top());
93 | }
94 | if(path.first()) path.stdout.back(path.first().copy());
95 | for(var c = array.length; c--;) {
96 | path.top(array.pop());
97 | }
98 | }
99 |
100 | var old = cmd.tokenize;
101 | cmd.tokenize = function() {
102 | this.tkn.params[0] = +this.tkn.params[0];
103 | return old.call(this);
104 | }
105 | });
106 |
107 | //------------------------------------------------------------------------------------------------------------
108 | /// Places what is in the front of the pipe into the path's output.
109 | Command.add(0, noodel.commandify(characters.correct("Þ")), function(cmd) {
110 | cmd.exec = function(path) {
111 | var f = path.top();
112 | if(f) {
113 | path.stdout.back(f);
114 | }
115 | }
116 | });
117 |
118 | //------------------------------------------------------------------------------------------------------------
119 | /// Places what is in the front of the pipe into the path's output.
120 | Command.add(0, noodel.commandify(characters.correct("Þ"), "\\d+"), function(cmd) {
121 | cmd.exec = function(path) {
122 | var array = [];
123 | for(var c = this.tkn.params[0]; c-- && path.first();) {
124 | array.push(path.top());
125 | }
126 | if(path.first()) path.stdout.back(path.top());
127 | for(var c = array.length; c--;) {
128 | path.top(array.pop());
129 | }
130 | }
131 |
132 | var old = cmd.tokenize;
133 | cmd.tokenize = function() {
134 | this.tkn.params[0] = +this.tkn.params[0];
135 | return old.call(this);
136 | }
137 | });
138 |
139 | //------------------------------------------------------------------------------------------------------------
140 | /// Copies what is in the front of the pipe into the path's output followed by a new line.
141 | Command.add(0, noodel.commandify(characters.correct("ñ")), function(cmd) {
142 | cmd.exec = function(path) {
143 | var f = path.first();
144 | if(f) {
145 | path.stdout.back(f.copy());
146 | }
147 | path.stdout.back(new STRING("¶"));
148 | }
149 | });
150 |
151 | //------------------------------------------------------------------------------------------------------------
152 | /// Copies what is in the front of the pipe into the path's output followed by a new line.
153 | Command.add(0, noodel.commandify(characters.correct("ñ"), "\\d+"), function(cmd) {
154 | cmd.exec = function(path) {
155 | var array = [];
156 | for(var c = this.tkn.params[0]; c-- && path.first();) {
157 | array.push(path.top());
158 | }
159 | if(path.first()) path.stdout.back(path.first().copy());
160 | for(var c = array.length; c--;) {
161 | path.top(array.pop());
162 | }
163 | path.stdout.back(new STRING("¶"));
164 | }
165 |
166 | var old = cmd.tokenize;
167 | cmd.tokenize = function() {
168 | this.tkn.params[0] = +this.tkn.params[0];
169 | return old.call(this);
170 | }
171 | });
172 |
173 | //------------------------------------------------------------------------------------------------------------
174 | /// Places what is in the front of the pipe into the path's output followed by a new line.
175 | Command.add(0, noodel.commandify(characters.correct("Ñ")), function(cmd) {
176 | cmd.exec = function(path) {
177 | var f = path.top();
178 | if(f) {
179 | path.stdout.back(f);
180 | }
181 | path.stdout.back(new STRING("¶"));
182 | }
183 | });
184 |
185 | //------------------------------------------------------------------------------------------------------------
186 | /// Places what is in the front of the pipe into the path's output followed by a new line.
187 | Command.add(0, noodel.commandify(characters.correct("Ñ"), "\\d+"), function(cmd) {
188 | cmd.exec = function(path) {
189 | var array = [];
190 | for(var c = this.tkn.params[0]; c-- && path.first();) {
191 | array.push(path.top());
192 | }
193 | if(path.first()) path.stdout.back(path.top());
194 | for(var c = array.length; c--;) {
195 | path.top(array.pop());
196 | }
197 | path.stdout.back(new STRING("¶"));
198 | }
199 |
200 | var old = cmd.tokenize;
201 | cmd.tokenize = function() {
202 | this.tkn.params[0] = +this.tkn.params[0];
203 | return old.call(this);
204 | }
205 | });
206 |
207 | //------------------------------------------------------------------------------------------------------------
208 | // Places the stack into the stdout.
209 | Command.add(0, noodel.commandify(characters.correct("Ð")), function(cmd) {
210 | cmd.exec = function(path) {
211 | path.stdout.back(path.stack);
212 | }
213 | });
214 |
215 | //------------------------------------------------------------------------------------------------------------
216 | // Clears the stdout.
217 | Command.add(0, noodel.commandify(characters.correct("ß")), function(cmd) {
218 | cmd.exec = function(path) {
219 | path.stdout.wipe();
220 | }
221 | });
222 |
223 | //------------------------------------------------------------------------------------------------------------
224 | // Copies what is on top of the stack into the front of stdin.
225 | Command.add(0, noodel.commandify(characters.correct("ø")), function(cmd) {
226 | cmd.exec = function(path) {
227 | var f = path.first();
228 | if(f) {
229 | path.stdin.front(f.copy());
230 | }
231 | }
232 | });
233 |
234 | //------------------------------------------------------------------------------------------------------------
235 | // Copies what is on top of the stack into the front of stdin.
236 | Command.add(0, noodel.commandify(characters.correct("ø"), "\\d+"), function(cmd) {
237 | cmd.exec = function(path) {
238 | var item = path.first_ith(this.tkn.params[0]);
239 | if(item)
240 | {
241 | path.stdin.front(item.copy());
242 | }
243 | }
244 |
245 | var old = cmd.tokenize;
246 | cmd.tokenize = function() {
247 | this.tkn.params[0] = +this.tkn.params[0];
248 | return old.call(this);
249 | }
250 | });
251 |
252 | //------------------------------------------------------------------------------------------------------------
253 | // Pushes what is on the top of the stack into the stdin.
254 | Command.add(0, noodel.commandify(characters.correct("Ø")), function(cmd) {
255 | cmd.exec = function(path) {
256 | var f = path.top();
257 | // If the first token then consume everything in stdin.
258 | if(path.start === this.tkn) {
259 | while(f) {
260 | path.stdin.front(f);
261 | f = path.top();
262 | }
263 | } else if(f) {
264 | path.stdin.front(f);
265 | }
266 | }
267 | });
268 |
269 | //------------------------------------------------------------------------------------------------------------
270 | // Pushes what is on the top of the stack into the stdin.
271 | Command.add(0, noodel.commandify(characters.correct("Ø"), "\\d+"), function(cmd) {
272 | cmd.exec = function(path) {
273 | var item = path.top_ith(this.tkn.params[0]);
274 | if(item)
275 | {
276 | path.stdin.front(item);
277 | }
278 | }
279 |
280 | var old = cmd.tokenize;
281 | cmd.tokenize = function() {
282 | this.tkn.params[0] = +this.tkn.params[0];
283 | return old.call(this);
284 | }
285 | });
286 |
287 | //------------------------------------------------------------------------------------------------------------
288 | // Copies the front of stdin onto the stack.
289 | Command.add(0, noodel.commandify(characters.correct("æ")), function(cmd) {
290 | cmd.exec = function(path) {
291 | var f = path.stdin.first();
292 | if(f) {
293 | path.top(f.copy());
294 | }
295 | }
296 | });
297 |
298 | //------------------------------------------------------------------------------------------------------------
299 | // Copies the front of stdin onto the stack.
300 | Command.add(0, noodel.commandify(characters.correct("æ"), "\\d+"), function(cmd) {
301 | cmd.exec = function(path) {
302 | var array = [];
303 | for(var c = this.tkn.params[0]; c-- && path.stdin.first();) {
304 | array.push(path.stdin.front());
305 | }
306 | if(path.stdin.first()) path.top(path.stdin.first().copy());
307 | for(var c = array.length; c--;) {
308 | path.stdin.front(array.pop());
309 | }
310 | }
311 |
312 | var old = cmd.tokenize;
313 | cmd.tokenize = function() {
314 | this.tkn.params[0] = +this.tkn.params[0];
315 | return old.call(this);
316 | }
317 | });
318 |
319 | //------------------------------------------------------------------------------------------------------------
320 | // Consumes from stdin onto the stack.
321 | Command.add(0, noodel.commandify(characters.correct("Æ")), function(cmd) {
322 | cmd.exec = function(path) {
323 | var f = path.stdin.front();
324 | if(f) {
325 | path.top(f);
326 | }
327 | }
328 | });
329 |
330 | //------------------------------------------------------------------------------------------------------------
331 | // Consumes from stdin onto the stack.
332 | Command.add(0, noodel.commandify(characters.correct("Æ"), "\\d+"), function(cmd) {
333 | cmd.exec = function(path) {
334 | var array = [];
335 | for(var c = this.tkn.params[0]; c-- && path.stdin.first();) {
336 | array.push(path.stdin.front());
337 | }
338 | if(path.stdin.first()) path.top(path.stdin.front());
339 | for(var c = array.length; c--;) {
340 | path.stdin.front(array.pop());
341 | }
342 | }
343 |
344 | var old = cmd.tokenize;
345 | cmd.tokenize = function() {
346 | this.tkn.params[0] = +this.tkn.params[0];
347 | return old.call(this);
348 | }
349 | });
350 |
351 | })(this, this.noodel, this.Pipe, this.Command, this.Token, this.Path, this.characters, this.NUMBER, this.STRING, this.ARRAY)
352 |
--------------------------------------------------------------------------------
/src/noodel-misc.js:
--------------------------------------------------------------------------------
1 | (function(global, noodel, Pipe, Command, Token, Path, characters, NUMBER, STRING, ARRAY){
2 |
3 | //------------------------------------------------------------------------------------------------------------
4 | /// Misc. Commands.
5 | //------------------------------------------------------------------------------------------------------------
6 |
7 | //------------------------------------------------------------------------------------------------------------
8 | /// Terminates the program.
9 | Command.add(0, noodel.commandify(characters.correct("ɲ") + "`"), function(cmd) {
10 | cmd.exec = function(path) {
11 | path.kill_this = true;
12 | }
13 | });
14 |
15 | //------------------------------------------------------------------------------------------------------------
16 | /// Clears the properties that were added to a particulat object.
17 | Command.add(0, noodel.commandify(characters.correct("ɲ") + "~"), function(cmd) {
18 | cmd.exec = function(path) {
19 | var f = path.first(); if(f) f.props.clear();
20 | }
21 | });
22 |
23 | //------------------------------------------------------------------------------------------------------------
24 | /// Pops off and pushes whether or not it is even or odd.
25 | Command.add(0, noodel.commandify(characters.correct("ɲ") + "o"), function(cmd) {
26 | cmd.exec = function(path) {
27 | var f = path.first();
28 | if(f) {
29 | if(f.type === "NUMBER") {
30 | path.top(new NUMBER(f.value % 2));
31 | } else {
32 | path.top(new NUMBER(f.length() % 2));
33 | }
34 | }
35 | }
36 | });
37 |
38 | //------------------------------------------------------------------------------------------------------------
39 | /// Pops off and pushes whether or not it is even or odd.
40 | Command.add(0, noodel.commandify(characters.correct("ɲ") + "O"), function(cmd) {
41 | cmd.exec = function(path) {
42 | var f = path.top();
43 | if(f) {
44 | if(f.type === "NUMBER") {
45 | path.top(new NUMBER(f.value % 2));
46 | } else {
47 | path.top(new NUMBER(f.length() % 2));
48 | }
49 | }
50 | }
51 | });
52 |
53 | //------------------------------------------------------------------------------------------------------------
54 | /// Pops off and pushes whether or not it is even or odd.
55 | Command.add(0, noodel.commandify(characters.correct("ɲ") + "e"), function(cmd) {
56 | cmd.exec = function(path) {
57 | var f = path.first();
58 | if(f) {
59 | if(f.type === "NUMBER") {
60 | path.top(new NUMBER(f.value % 2 ? 1 : 0));
61 | } else {
62 | path.top(new NUMBER(f.length() % 2 ? 1 : 0));
63 | }
64 | }
65 | }
66 | });
67 |
68 | //------------------------------------------------------------------------------------------------------------
69 | /// Pops off and pushes whether or not it is even or odd.
70 | Command.add(0, noodel.commandify(characters.correct("ɲ") + "E"), function(cmd) {
71 | cmd.exec = function(path) {
72 | var f = path.top();
73 | if(f) {
74 | if(f.type === "NUMBER") {
75 | path.top(new NUMBER(f.value % 2 ? 1 : 0));
76 | } else {
77 | path.top(new NUMBER(f.length() % 2 ? 1 : 0));
78 | }
79 | }
80 | }
81 | });
82 |
83 | //------------------------------------------------------------------------------------------------------------
84 | /// Generates a random integer.
85 | Command.add(0, noodel.commandify(characters.correct("ṛ")), function(cmd) {
86 | cmd.exec = function(path) {
87 | var f = path.top();
88 | if(f) {
89 | if(f.type === "NUMBER") {
90 | var max, min;
91 | var g = path.top();
92 | if(g) {
93 | max = Math.max(f.value, g.value);
94 | min = Math.min(f.value, g.value);
95 | } else {
96 | max = Math.max(f.value, 0);
97 | min = Math.min(f.value, 0);
98 | }
99 | path.top(new NUMBER(noodel.random_int(min, max)));
100 | } else {
101 | path.top(f);
102 | path.top(new NUMBER(noodel.random_int(0, f.length() - 1)));
103 | }
104 | }
105 | }
106 | });
107 |
108 | //------------------------------------------------------------------------------------------------------------
109 | /// Generates a random integer.
110 | Command.add(0, noodel.commandify(characters.correct("ṛ"), "\\d+"), function(cmd) {
111 | cmd.exec = function(path) {
112 | path.top(new NUMBER(noodel.random_int(0, this.tkn.params[0])));
113 | }
114 |
115 | var old = cmd.tokenize;
116 | cmd.tokenize = function() {
117 | this.tkn.params[0] = +this.tkn.params[0];
118 |
119 | return old.call(this);
120 | }
121 | });
122 |
123 | //------------------------------------------------------------------------------------------------------------
124 | /// Generates a random number.
125 | Command.add(0, noodel.commandify(characters.correct("Ṛ")), function(cmd) {
126 | cmd.exec = function(path) {
127 | var f = path.top();
128 | if(f) {
129 | if(f.type === "NUMBER") {
130 | var max, min;
131 | var g = path.top();
132 | if(g) {
133 | max = Math.max(f.value, g.value);
134 | min = Math.min(f.value, g.value);
135 | } else {
136 | max = Math.max(f.value, 0);
137 | min = Math.min(f.value, 0);
138 | }
139 | path.top(new NUMBER(noodel.random(min, max)));
140 | } else {
141 | path.top(f);
142 | path.top(f.access(noodel.random_int(0, f.length() - 1)));
143 | }
144 | }
145 | }
146 | });
147 |
148 | //------------------------------------------------------------------------------------------------------------
149 | /// Move the stack ptr up one.
150 | Command.add(0, noodel.commandify(characters.correct("ƥ")), function(cmd) {
151 | cmd.exec = function(path) {
152 | path.move_up();
153 | }
154 | });
155 |
156 | //------------------------------------------------------------------------------------------------------------
157 | /// Move the stack ptr down one.
158 | Command.add(0, noodel.commandify(characters.correct("ʠ")), function(cmd) {
159 | cmd.exec = function(path) {
160 | path.move_down();
161 | }
162 | });
163 |
164 | //------------------------------------------------------------------------------------------------------------
165 | /// Move the stack ptr up one.
166 | Command.add(1, noodel.commandify(characters.regex.a_tiny_digit + "+", characters.correct("ƥ")), function(cmd) {
167 | cmd.exec = function(path) {
168 | var c = this.tkn.params[0];
169 | while(c--) path.move_up();
170 | }
171 |
172 | var old = cmd.tokenize;
173 | cmd.tokenize = function() {
174 | this.tkn.params[0] = +characters.tiny_num_to_num(this.tkn.params[0])
175 |
176 | return old.call(this);
177 | }
178 | });
179 |
180 | //------------------------------------------------------------------------------------------------------------
181 | /// Move the stack ptr down one.
182 | Command.add(1, noodel.commandify(characters.regex.a_tiny_digit + "+", characters.correct("ʠ")), function(cmd) {
183 | cmd.exec = function(path) {
184 | var c = this.tkn.params[0];
185 | while(c--) path.move_down();
186 | }
187 |
188 | var old = cmd.tokenize;
189 | cmd.tokenize = function() {
190 | this.tkn.params[0] = +characters.tiny_num_to_num(this.tkn.params[0])
191 |
192 | return old.call(this);
193 | }
194 | });
195 |
196 | //------------------------------------------------------------------------------------------------------------
197 | /// Move the stack ptr up one.
198 | Command.add(0, noodel.commandify(characters.correct("µ") + characters.correct("ƥ")), function(cmd) {
199 | cmd.exec = function(path) {
200 | var f = path.top();
201 | if(f) {
202 | var c = f.integerify().value;
203 | while(c--) path.move_up();
204 | }
205 | }
206 | });
207 |
208 | //------------------------------------------------------------------------------------------------------------
209 | /// Move the stack ptr down one.
210 | Command.add(0, noodel.commandify(characters.correct("µ") + characters.correct("ʠ")), function(cmd) {
211 | cmd.exec = function(path) {
212 | var f = path.top();
213 | if(f) {
214 | var c = f.integerify().value;
215 | while(c--) path.move_down();
216 | }
217 | }
218 | });
219 |
220 | //------------------------------------------------------------------------------------------------------------
221 | /// Move the stack ptr to the top.
222 | Command.add(0, noodel.commandify(characters.correct("ƥ")+"\\*"), function(cmd) {
223 | cmd.exec = function(path) {
224 | path.move_to_top();
225 | }
226 | });
227 |
228 | //------------------------------------------------------------------------------------------------------------
229 | /// Move the stack ptr to the bottom.
230 | Command.add(0, noodel.commandify(characters.correct("ʠ")+"\\*"), function(cmd) {
231 | cmd.exec = function(path) {
232 | path.move_to_bottom();
233 | }
234 | });
235 |
236 | //------------------------------------------------------------------------------------------------------------
237 | /// Jump into the array at the current position, if there is not an array it will create one.
238 | Command.add(0, noodel.commandify(characters.correct("ı")), function(cmd) {
239 | cmd.exec = function(path) {
240 | path.jump_in();
241 | }
242 | });
243 |
244 | //------------------------------------------------------------------------------------------------------------
245 | /// Jump outof the array, if there is not an array it will create one.
246 | Command.add(0, noodel.commandify(characters.correct("ȷ")), function(cmd) {
247 | cmd.exec = function(path) {
248 | path.jump_out();
249 | }
250 | });
251 |
252 | //------------------------------------------------------------------------------------------------------------
253 | /// Negate the object on the top of the stack.
254 | Command.add(0, noodel.commandify(characters.correct("ɲ") + "\\!"), function(cmd) {
255 | cmd.exec = function(path) {
256 | var f = path.top();
257 | if(f) {
258 | path.top(f.is_falsy());
259 | } else {
260 | path.top(new NUMBER(1));
261 | }
262 | }
263 | });
264 |
265 | //------------------------------------------------------------------------------------------------------------
266 | /// Negate the object on the top of the stack.
267 | Command.add(0, noodel.commandify(characters.correct("ɲ") + "\\?"), function(cmd) {
268 | cmd.exec = function(path) {
269 | var f = path.top();
270 | if(f) {
271 | path.top(f.is_truthy());
272 | } else {
273 | path.top(new NUMBER(0));
274 | }
275 | }
276 | });
277 |
278 | //------------------------------------------------------------------------------------------------------------
279 | /// Checks if there is an item on the stack.
280 | Command.add(0, noodel.commandify(characters.correct("ị")), function(cmd) {
281 | cmd.exec = function(path) {
282 | var f = path.first();
283 | if(f) {
284 | path.top(new NUMBER(1));
285 | } else {
286 | path.top(new NUMBER(0));
287 | }
288 | }
289 | });
290 |
291 | //------------------------------------------------------------------------------------------------------------
292 | /// Checks if the item on top of the stack is a number.
293 | Command.add(0, noodel.commandify(characters.correct("ị") + "#"), function(cmd) {
294 | cmd.exec = function(path) {
295 | var f = path.first();
296 | if(f) {
297 | path.top(new NUMBER(f.type === "NUMBER" ? 1 : 0));
298 | } else {
299 | path.top(new NUMBER(0));
300 | }
301 | }
302 | });
303 |
304 | //------------------------------------------------------------------------------------------------------------
305 | /// Checks if the item on top of the stack is a string.
306 | Command.add(0, noodel.commandify(characters.correct("ị") + '"'), function(cmd) {
307 | cmd.exec = function(path) {
308 | var f = path.first();
309 | if(f) {
310 | path.top(new NUMBER(f.type === "STRING" ? 1 : 0));
311 | } else {
312 | path.top(new NUMBER(0));
313 | }
314 | }
315 | });
316 |
317 | //------------------------------------------------------------------------------------------------------------
318 | /// Checks if the item on top of the stack is a array.
319 | Command.add(0, noodel.commandify(characters.correct("ị") + "@"), function(cmd) {
320 | cmd.exec = function(path) {
321 | var f = path.first();
322 | if(f) {
323 | path.top(new NUMBER(f.type === "ARRAY" ? 1 : 0));
324 | } else {
325 | path.top(new NUMBER(0));
326 | }
327 | }
328 | });
329 |
330 | //------------------------------------------------------------------------------------------------------------
331 | /// Pushes a string of the code of the path.
332 | Command.add(0, noodel.commandify(characters.correct("ḥ")), function(cmd) {
333 | cmd.exec = function(path) {
334 | path.top(new STRING(characters.deprintify_string(path.code)))
335 | }
336 | });
337 |
338 | //------------------------------------------------------------------------------------------------------------
339 | /// Pushes a string of the code of the path.
340 | Command.add(0, noodel.commandify(characters.correct("ḥ") + "\\@"), function(cmd) {
341 | cmd.exec = function(path) {
342 | path.top(new STRING(characters.deprintify_string(this.tkn.path.code)))
343 | }
344 | });
345 |
346 | //------------------------------------------------------------------------------------------------------------
347 | /// Pushes a string of the code of the path.
348 | Command.add(0, noodel.commandify(characters.correct("ḥ") + "\\-"), function(cmd) {
349 | cmd.exec = function(path) {
350 | path.top(new STRING(characters.deprintify_string(this.tkn.parent.literal)))
351 | }
352 | });
353 |
354 | //------------------------------------------------------------------------------------------------------------
355 | /// Pushes a string of the code of the path.
356 | Command.add(0, noodel.commandify(characters.correct("ḥ") + "\\|"), function(cmd) {
357 | cmd.exec = function(path) {
358 | var after = this.tkn.next();
359 | if(after) path.top(new STRING(characters.deprintify_string(after.literal)))
360 | }
361 | });
362 |
363 | //------------------------------------------------------------------------------------------------------------
364 | /// Pushes a string of the code of the path.
365 | Command.add(0, noodel.commandify(characters.correct("ḥ") + "\\\\"), function(cmd) {
366 | cmd.exec = function(path) {
367 | path.top(new STRING(characters.deprintify_string(this.tkn.following_code)))
368 | }
369 |
370 | var old = cmd.tokenize;
371 | cmd.tokenize = function() {
372 | this.tkn.following_code = this.tkn.code.slice(this.tkn.end+1,this.tkn.code.length);
373 | return old.call(this);
374 | }
375 | });
376 |
377 | //------------------------------------------------------------------------------------------------------------
378 | /// Pushes a string of the code of the path.
379 | Command.add(0, noodel.commandify(characters.correct("ḥ") + "\\/"), function(cmd) {
380 | cmd.exec = function(path) {
381 | path.top(new STRING(characters.deprintify_string(this.tkn.preceding_code)))
382 | }
383 |
384 | var old = cmd.tokenize;
385 | cmd.tokenize = function() {
386 | this.tkn.preceding_code = this.tkn.code.slice(0,this.tkn.start);
387 | return old.call(this);
388 | }
389 | });
390 |
391 | //------------------------------------------------------------------------------------------------------------
392 | /// Pops off and pushes on the shuffled version of that object.
393 | Command.add(0, noodel.commandify(characters.correct("ŀ")), function(cmd) {
394 | cmd.exec = function(path) {
395 | var f = path.top();
396 | if(f) {
397 | path.top(f.shuffle());
398 | }
399 | }
400 | });
401 |
402 | //------------------------------------------------------------------------------------------------------------
403 | /// Pushes on "True" of "False" based on the top of the stack.
404 | Command.add(0, noodel.commandify(characters.correct("ɲ") + "t"), function(cmd) {
405 | cmd.exec = function(path) {
406 | var f = path.first();
407 | if(f && f.is_truthy().value) {
408 | path.top(new STRING("True"));
409 | } else {
410 | path.top(new STRING("False"));
411 | }
412 | }
413 | });
414 |
415 | //------------------------------------------------------------------------------------------------------------
416 | /// Pushes on 0 or 1 if the string can be interpreted as "True" or "False".
417 | Command.add(0, noodel.commandify(characters.correct("ɲ") + "T"), function(cmd) {
418 | cmd.exec = function(path) {
419 | var f = path.first();
420 | if(f) {
421 | f = f.stringify().value.toLowerCase();
422 | if(f == "true")
423 | {
424 | path.top(new NUMBER(1));
425 | } else if(f == "false") {
426 | path.top(new NUMBER(0));
427 | }
428 | }
429 | }
430 | });
431 |
432 | //------------------------------------------------------------------------------------------------------------
433 | /// Toggles the auto popping at the end of the script.
434 | Command.add(0, noodel.commandify(characters.correct("¥")), function(cmd) {
435 | cmd.exec = function(path) {
436 | path.auto_popping = !path.auto_popping;
437 | }
438 | });
439 |
440 | //------------------------------------------------------------------------------------------------------------
441 | /// Jumps to a particular line and start running it.
442 | Command.add(1, noodel.commandify(characters.regex.a_tiny_digit + "+", characters.correct("¦")), function(cmd) {
443 | cmd.exec = function(path) {
444 | this.tkn.old_next = this.tkn.next;
445 | var tkn = this.tkn;
446 | this.tkn.next = function() {
447 | var goto = path.lines[tkn.params[0]], result = tkn.old_next();
448 | path.call_stack.push(result);
449 | if(goto) {
450 | result = goto;
451 | }
452 | tkn.next = tkn.old_next;
453 | return result;
454 | }
455 | }
456 |
457 | var old = cmd.tokenize;
458 | cmd.tokenize = function() {
459 | this.tkn.params[0] = +characters.tiny_num_to_num(this.tkn.params[0]);
460 |
461 | return old.call(this);
462 | }
463 | });
464 |
465 | })(this, this.noodel, this.Pipe, this.Command, this.Token, this.Path, this.characters, this.NUMBER, this.STRING, this.ARRAY)
466 |
--------------------------------------------------------------------------------
/src/noodel-string_manip.js:
--------------------------------------------------------------------------------
1 | (function(global, noodel, Pipe, Command, Token, Path, characters, NUMBER, STRING, ARRAY){
2 |
3 | //------------------------------------------------------------------------------------------------------------
4 | /// String Manipulation Commands.
5 | //------------------------------------------------------------------------------------------------------------
6 |
7 | //------------------------------------------------------------------------------------------------------------
8 | /// Converts element into lowercase.
9 | Command.add(0, noodel.commandify(characters.correct("ɲ") + "L"), function(cmd) {
10 | cmd.exec = function(path) {
11 | var f = path.top();
12 | if(f) path.top(f.to_lowercase());
13 | }
14 | });
15 |
16 | //------------------------------------------------------------------------------------------------------------
17 | /// Converts element into uppercase.
18 | Command.add(0, noodel.commandify(characters.correct("ɲ") + "U"), function(cmd) {
19 | cmd.exec = function(path) {
20 | var f = path.top();
21 | if(f) path.top(f.to_uppercase());
22 | }
23 | });
24 |
25 | //------------------------------------------------------------------------------------------------------------
26 | /// Switches case of item.
27 | Command.add(0, noodel.commandify(characters.correct("ɲ") + "S"), function(cmd) {
28 | cmd.exec = function(path) {
29 | var f = path.top();
30 | if(f) path.top(f.switchcase());
31 | }
32 | });
33 |
34 | //------------------------------------------------------------------------------------------------------------
35 | /// Relocates an element in an object.
36 | Command.add(0, noodel.commandify(characters.correct("ṙ")), function(cmd) {
37 | cmd.exec = function(path) {
38 | var f = path.top();
39 | if(f) {
40 | var g = path.top();
41 | if(g) {
42 | var h = path.top();
43 | if(h) {
44 | path.top(h.relocate(f.integerify().value, g.integerify().value));
45 | } else {
46 | path.top(g);
47 | path.top(h);
48 | }
49 | } else {
50 | path.top(f);
51 | }
52 | }
53 | }
54 | });
55 |
56 | //------------------------------------------------------------------------------------------------------------
57 | /// Joins the an array.
58 | Command.add(0, noodel.commandify(characters.correct("İ")), function(cmd) {
59 | cmd.exec = function(path) {
60 | var f = path.top();
61 | if(f) {
62 | if(f.type === "NUMBER") f = f.stringify();
63 | if(f.type === "STRING") {
64 | var g = path.top();
65 | if(g) {
66 | g = g.arrayify();
67 | path.top(new STRING(g.value.join(f.value)));
68 | } else path.top(f);
69 | } else {
70 | var g = path.top();
71 | if(g) {
72 | g = g.stringify();
73 | path.top(new STRING(f.value.join(g.value)));
74 | } else path.top(f);
75 | }
76 | }
77 | }
78 | });
79 |
80 | var alignment_map = {
81 | l: function(string) {
82 | var rows = string_row_break(string);
83 | for(var i = 0; i < rows.length; ++i) {
84 | for(var j = 0; j < rows[i].length; ++j) {
85 | if(rows[i][j] !== characters.correct("¤")) {
86 | break;
87 | }
88 | }
89 | rows[i] = rows[i].slice(j, rows[i]);
90 | }
91 | var s = "";
92 | if(rows.length) {
93 | s = rows[0];
94 | for(var i = 1; i < rows.length; ++i) s += characters.correct("¬") + rows[i];
95 | }
96 | return s;
97 | },
98 | r: function(string, max_length) {
99 | var rows = string_row_break(string);
100 | if(max_length === undefined) {
101 | max_length = 0
102 | for(var i = 0; i < rows.length; ++i) {
103 | if(rows[i].length > max_length) max_length = rows[i].length;
104 | }
105 | }
106 | for(var i = 0; i < rows.length; ++i) {
107 | while(rows[i].length < max_length) {
108 | rows[i] = characters.correct("¤") + rows[i];
109 | }
110 | }
111 | var s = "";
112 | if(rows.length) {
113 | s = rows[0];
114 | for(var i = 1; i < rows.length; ++i) s += characters.correct("¬") + rows[i];
115 | }
116 | return s;
117 | },
118 | c: function(string, max_length) {
119 | var rows = string_row_break(string);
120 | if(max_length === undefined) {
121 | max_length = 0
122 | for(var i = 0; i < rows.length; ++i) {
123 | if(rows[i].length > max_length) max_length = rows[i].length;
124 | }
125 | }
126 | for(var i = 0; i < rows.length; ++i) {
127 | var add = Math.ceil((max_length - rows[i].length)/2);
128 | if(0 < add) {
129 | while(add--) rows[i] = characters.correct("¤") + rows[i];
130 | }
131 | }
132 | var s = "";
133 | if(rows.length) {
134 | s = rows[0];
135 | for(var i = 1; i < rows.length; ++i) s += characters.correct("¬") + rows[i];
136 | }
137 | return s;
138 | }
139 | };
140 |
141 | //------------------------------------------------------------------------------------------------------------
142 | /// Left aligns, right aligns, or centralizes a string.
143 | Command.add(0, noodel.commandify(characters.correct("ụ"), "[lrc]"), function(cmd) {
144 |
145 | cmd.exec = function(path) {
146 | var f = path.top();
147 | if(f) {
148 | if(f.type === "NUMBER") {
149 | var g = path.top();
150 | if(g) {
151 | f = f.integerify();
152 | g = g.stringify();
153 | path.top(new STRING(this.tkn.params[0](g.value, f.value)));
154 | } else path.top(f);
155 | } else {
156 | f = f.stringify();
157 | path.top(new STRING(this.tkn.params[0](f.value)));
158 | }
159 | }
160 | }
161 |
162 | var old = cmd.tokenize;
163 | cmd.tokenize = function() {
164 | this.tkn.params[0] = alignment_map[this.tkn.params[0]];
165 | return old.call(this);
166 | }
167 | });
168 |
169 | //------------------------------------------------------------------------------------------------------------
170 | /// Left aligns, right aligns, or centralizes a string.
171 | Command.add(0, noodel.commandify(characters.correct("ụ"), "[RC]"), function(cmd) {
172 |
173 | cmd.exec = function(path) {
174 | var f = path.top();
175 | if(f) {
176 | var g = path.top();
177 | if(g) {
178 | f = f.integerify();
179 | g = g.stringify();
180 | path.top(new STRING(this.tkn.params[0](g.value, f.value)));
181 | } else path.top(f);
182 | }
183 | }
184 |
185 | var old = cmd.tokenize;
186 | cmd.tokenize = function() {
187 | this.tkn.params[0] = alignment_map[this.tkn.params[0].toLowerCase()];
188 | return old.call(this);
189 | }
190 | });
191 |
192 | //------------------------------------------------------------------------------------------------------------
193 | /// Replace single occurance.
194 | Command.add(0, noodel.commandify(characters.correct("ḳ")), function(cmd) {
195 | cmd.exec = function(path) {
196 | var f = path.top();
197 | if(f) {
198 | var g = path.top();
199 | if(g) {
200 | var h = path.top();
201 | if(h) {
202 | f = f.stringify();
203 | g = g.stringify();
204 | if(h.type === "NUMBER") h = h.stringify();
205 | if(h.type === "ARRAY") {
206 | for(var i = 0; i < h.length(); ++i) {
207 | h.value[i] = h.value[i].stringify();
208 | h.value[i] = new STRING(h.value[i].value.replace(g.value, f.value));
209 | }
210 | } else {
211 | h = new STRING(h.value.replace(g.value, f.value));
212 | }
213 | path.top(h);
214 | } else { path.top(g); path.top(f); }
215 | } else path.top(f);
216 | }
217 | }
218 | });
219 |
220 | //------------------------------------------------------------------------------------------------------------
221 | /// Replace first N occurrances.
222 | Command.add(0, noodel.commandify(characters.correct("ḳ"), "\\d+"), function(cmd) {
223 | cmd.exec = function(path) {
224 | var f = path.top();
225 | if(f) {
226 | var g = path.top();
227 | if(g) {
228 | var h = path.top();
229 | if(h) {
230 | f = f.stringify();
231 | g = g.stringify();
232 | if(h.type === "NUMBER") h = h.stringify();
233 | if(h.type === "ARRAY") {
234 | for(var i = 0; i < h.length(); ++i) {
235 | h.value[i] = h.value[i].stringify();
236 | for(var j = this.tkn.params[0]; j--;) {
237 | h.value[i] = new STRING(h.value[i].value.replace(g.value, f.value));
238 | }
239 | }
240 | } else {
241 | for(var i = this.tkn.params[0]; i--;) {
242 | h = new STRING(h.value.replace(g.value, f.value));
243 | }
244 | }
245 | path.top(h);
246 | } else { path.top(g); path.top(f); }
247 | } else path.top(f);
248 | }
249 | }
250 |
251 | var old = cmd.tokenize;
252 | cmd.tokenize = function() {
253 | this.tkn.params[0] = +this.tkn.params[0];
254 | return old.call(this);
255 | }
256 | });
257 |
258 | //------------------------------------------------------------------------------------------------------------
259 | /// Replace all occurances.
260 | Command.add(0, noodel.commandify(characters.correct("Ḳ")), function(cmd) {
261 | cmd.exec = function(path) {
262 | var f = path.top();
263 | if(f) {
264 | var g = path.top();
265 | if(g) {
266 | var h = path.top();
267 | if(h) {
268 | f = f.stringify();
269 | g = g.stringify();
270 | if(h.type === "NUMBER") h = h.stringify();
271 | if(h.type === "ARRAY") {
272 | for(var i = 0; i < h.length(); ++i) {
273 | h.value[i] = h.value[i].stringify();
274 | h.value[i] = new STRING(h.value[i].value.replace(new RegExp(g.value, "g"), f.value));
275 | }
276 | } else {
277 | h = new STRING(h.value.replace(new RegExp(g.value, "g"), f.value));
278 | }
279 | path.top(h);
280 | } else { path.top(g); path.top(f); }
281 | } else path.top(f);
282 | }
283 | }
284 | });
285 |
286 | })(this, this.noodel, this.Pipe, this.Command, this.Token, this.Path, this.characters, this.NUMBER, this.STRING, this.ARRAY)
287 |
--------------------------------------------------------------------------------
/src/noodel-time.js:
--------------------------------------------------------------------------------
1 | (function(global, noodel, Pipe, Command, Token, Path, characters, NUMBER, STRING, ARRAY){
2 |
3 | //------------------------------------------------------------------------------------------------------------
4 | /// Time.
5 | //------------------------------------------------------------------------------------------------------------
6 |
7 | //------------------------------------------------------------------------------------------------------------
8 | // Delay for number of steps based off of what is in the pipe.
9 | Command.add(0, noodel.commandify(characters.correct("ḍ")), function(cmd) {
10 | cmd.exec = function(path) {
11 | var tkn = this.tkn;
12 | var f = path.first();
13 | if(f) {
14 | if(!tkn.ran) {
15 | tkn.old_next = tkn.next;
16 | tkn.next = function() { return tkn };
17 | tkn.ran = true;
18 | tkn.old_rate = path.rate;
19 | path.rate = f.integerify().value;
20 | } else {
21 | tkn.ran = false;
22 | tkn.next = tkn.old_next;
23 | path.rate = tkn.old_rate;
24 | path.top();
25 | }
26 | }
27 | }
28 | });
29 |
30 | //------------------------------------------------------------------------------------------------------------
31 | // Delay for number of steps.
32 | Command.add(0, noodel.commandify(characters.correct("ḍ"), "\\d+"), function(cmd) {
33 | cmd.exec = function(path) {
34 | var tkn = this.tkn;
35 | if(!tkn.ran) {
36 | tkn.old_next = tkn.next;
37 | tkn.next = function() { return tkn };
38 | tkn.ran = true;
39 | tkn.old_rate = path.rate;
40 | path.rate = tkn.params[0];
41 | } else {
42 | tkn.ran = false;
43 | tkn.next = tkn.old_next;
44 | path.rate = tkn.old_rate;
45 | }
46 | }
47 |
48 | var old = cmd.tokenize;
49 | cmd.tokenize = function() {
50 | this.tkn.params[0] = +this.tkn.params[0];
51 | return old.call(this);
52 | }
53 | });
54 |
55 | //------------------------------------------------------------------------------------------------------------
56 | // Delay for number of steps.
57 | Command.add(0, noodel.commandify(characters.correct("ḍ"), "[shqetoOHT]"), function(cmd) {
58 | var map = { s: 1000, h: 500, q: 250, e: 125, t: 100, o: 10, O: 10000, H: 50000, T: 750 };
59 | function get_rate(c) {
60 | return map[c];
61 | };
62 |
63 | cmd.exec = function(path) {
64 | var tkn = this.tkn;
65 | if(!tkn.ran) {
66 | tkn.old_next = tkn.next;
67 | tkn.next = function() { return tkn };
68 | tkn.ran = true;
69 | tkn.old_rate = path.rate;
70 | path.rate = tkn.params[0];
71 | } else {
72 | tkn.ran = false;
73 | tkn.next = tkn.old_next;
74 | path.rate = tkn.old_rate;
75 | }
76 | }
77 |
78 | var old = cmd.tokenize;
79 | cmd.tokenize = function() {
80 | this.tkn.params[0] = get_rate(this.tkn.params[0]);
81 | return old.call(this);
82 | }
83 | });
84 |
85 | //------------------------------------------------------------------------------------------------------------
86 | // Delay for number of steps using fractions
87 | Command.add(0, new RegExp("^("+characters.correct("ḍ")+")(\\d*)/(\\d*)$"), function(cmd) {
88 | cmd.exec = function(path) {
89 | var tkn = this.tkn;
90 | if(!tkn.ran) {
91 | tkn.old_next = tkn.next;
92 | tkn.next = function() { return tkn };
93 | tkn.ran = true;
94 | tkn.old_rate = path.rate;
95 | path.rate = tkn.params[0];
96 | } else {
97 | tkn.ran = false;
98 | tkn.next = tkn.old_next;
99 | path.rate = tkn.old_rate;
100 | }
101 | }
102 |
103 | var old = cmd.tokenize;
104 | cmd.tokenize = function() {
105 | var num = 1000, den = 1;
106 | if(this.tkn.params[0].length) {
107 | num *= +this.tkn.params[0];
108 | }
109 | if(this.tkn.params[1].length) {
110 | den = +this.tkn.params[1];
111 | }
112 | this.tkn.params[0] = Math.floor(num / den);
113 | return old.call(this);
114 | }
115 | });
116 |
117 | //------------------------------------------------------------------------------------------------------------
118 | // Delay for number of steps using decimals
119 | Command.add(0, new RegExp("^("+characters.correct("ḍ")+")(\\d*)\\.(\\d*)$"), function(cmd) {
120 | cmd.exec = function(path) {
121 | var tkn = this.tkn;
122 | if(!tkn.ran) {
123 | tkn.old_next = tkn.next;
124 | tkn.next = function() { return tkn };
125 | tkn.ran = true;
126 | tkn.old_rate = path.rate;
127 | path.rate = tkn.params[0];
128 | } else {
129 | tkn.ran = false;
130 | tkn.next = tkn.old_next;
131 | path.rate = tkn.old_rate;
132 | }
133 | }
134 |
135 | var old = cmd.tokenize;
136 | cmd.tokenize = function() {
137 | this.tkn.params[0] = Math.floor((+("0"+this.tkn.params[0]+"."+this.tkn.params[1]+"0")) * 1000);
138 | return old.call(this);
139 | }
140 | });
141 |
142 | //------------------------------------------------------------------------------------------------------------
143 | // Delay for number of steps based off of what is in the pipe.
144 | Command.add(0, noodel.commandify(characters.correct("Ḍ")), function(cmd) {
145 | cmd.exec = function(path) {
146 | var tkn = this.tkn;
147 | var f = path.first();
148 | if(f) {
149 | if(!tkn.ran) {
150 | tkn.old_next = tkn.next;
151 | tkn.next = function() { return tkn };
152 | tkn.ran = true;
153 | tkn.old_rate = path.rate;
154 | path.rate = Math.floor(f.numberify().value * 1000);
155 | } else {
156 | tkn.ran = false;
157 | tkn.next = tkn.old_next;
158 | path.rate = tkn.old_rate;
159 | path.top();
160 | }
161 | }
162 | }
163 | });
164 |
165 | //------------------------------------------------------------------------------------------------------------
166 | // Delay for number of steps.
167 | Command.add(0, noodel.commandify(characters.correct("Ḍ"), "\\d+"), function(cmd) {
168 | cmd.exec = function(path) {
169 | var tkn = this.tkn;
170 | var f = path.first();
171 | if(f) {
172 | if(!tkn.ran) {
173 | tkn.old_next = tkn.next;
174 | tkn.next = function() { return tkn };
175 | tkn.ran = true;
176 | tkn.old_rate = path.rate;
177 | path.rate = Math.floor(f.numberify().value + this.tkn.params[0]);
178 | } else {
179 | tkn.ran = false;
180 | tkn.next = tkn.old_next;
181 | path.rate = tkn.old_rate;
182 | path.top();
183 | }
184 | }
185 | }
186 |
187 | var old = cmd.tokenize;
188 | cmd.tokenize = function() {
189 | this.tkn.params[0] = +this.tkn.params[0];
190 | return old.call(this);
191 | }
192 | });
193 |
194 | //------------------------------------------------------------------------------------------------------------
195 | // Delay for number of steps.
196 | Command.add(0, noodel.commandify(characters.correct("Ḍ"), "[shqetoOHT]"), function(cmd) {
197 | var map = { s: 1000, h: 0.5, q: 0.25, e: 0.125, t: 0.1, o: 0.01, O: 100, H: 2, T: 10 };
198 | function get_rate(c) {
199 | return map[c];
200 | };
201 |
202 | cmd.exec = function(path) {
203 | var tkn = this.tkn;
204 | var f = path.first();
205 | if(f) {
206 | if(!tkn.ran) {
207 | tkn.old_next = tkn.next;
208 | tkn.next = function() { return tkn };
209 | tkn.ran = true;
210 | tkn.old_rate = path.rate;
211 | path.rate = Math.floor(f.numberify().value * this.tkn.params[0]);
212 | } else {
213 | tkn.ran = false;
214 | tkn.next = tkn.old_next;
215 | path.rate = tkn.old_rate;
216 | path.top();
217 | }
218 | }
219 | }
220 |
221 | var old = cmd.tokenize;
222 | cmd.tokenize = function() {
223 | this.tkn.params[0] = get_rate(this.tkn.params[0]);
224 | return old.call(this);
225 | }
226 | });
227 |
228 | //------------------------------------------------------------------------------------------------------------
229 | // Delay for number of steps using fractions
230 | Command.add(0, new RegExp("^("+characters.correct("Ḍ")+")(\\d*)/(\\d*)$"), function(cmd) {
231 | cmd.exec = function(path) {
232 | var tkn = this.tkn;
233 | var f = path.first();
234 | if(f) {
235 | if(!tkn.ran) {
236 | tkn.old_next = tkn.next;
237 | tkn.next = function() { return tkn };
238 | tkn.ran = true;
239 | tkn.old_rate = path.rate;
240 | path.rate = Math.floor(f.numberify().value * this.tkn.params[0]);
241 | } else {
242 | tkn.ran = false;
243 | tkn.next = tkn.old_next;
244 | path.rate = tkn.old_rate;
245 | path.top();
246 | }
247 | }
248 | }
249 |
250 | var old = cmd.tokenize;
251 | cmd.tokenize = function() {
252 | var num = 1, den = 1;
253 | if(this.tkn.params[0].length) {
254 | num *= +this.tkn.params[0];
255 | }
256 | if(this.tkn.params[1].length) {
257 | den = +this.tkn.params[1];
258 | }
259 | this.tkn.params[0] = Math.floor(num / den);
260 | return old.call(this);
261 | }
262 | });
263 |
264 | //------------------------------------------------------------------------------------------------------------
265 | // Delay for number of steps using decimals
266 | Command.add(0, new RegExp("^("+characters.correct("Ḍ")+")(\\d*)\\.(\\d*)$"), function(cmd) {
267 | cmd.exec = function(path) {
268 | var tkn = this.tkn;
269 | var f = path.first();
270 | if(f) {
271 | if(!tkn.ran) {
272 | tkn.old_next = tkn.next;
273 | tkn.next = function() { return tkn };
274 | tkn.ran = true;
275 | tkn.old_rate = path.rate;
276 | path.rate = Math.floor(f.numberify().value * this.tkn.params[0]);
277 | } else {
278 | tkn.ran = false;
279 | tkn.next = tkn.old_next;
280 | path.rate = tkn.old_rate;
281 | path.top();
282 | }
283 | }
284 | }
285 |
286 | var old = cmd.tokenize;
287 | cmd.tokenize = function() {
288 | this.tkn.params[0] = (+("0"+this.tkn.params[0]+"."+this.tkn.params[1]+"0"));
289 | return old.call(this);
290 | }
291 | });
292 |
293 | //------------------------------------------------------------------------------------------------------------
294 | /// Gets number of milliseconds since 01/01/1970.
295 | Command.add(0, noodel.commandify(characters.correct("Ƈ")), function(cmd) {
296 | cmd.exec = function(path) {
297 | path.top(new NUMBER((new Date).getTime()));
298 | }
299 | });
300 |
301 | //------------------------------------------------------------------------------------------------------------
302 | /// Gets number of seconds since 01/01/1970.
303 | Command.add(0, noodel.commandify(characters.correct("Ƈ") + "s"), function(cmd) {
304 | cmd.exec = function(path) {
305 | path.top(new NUMBER((new Date).getTime() / 1000));
306 | }
307 | });
308 |
309 | //------------------------------------------------------------------------------------------------------------
310 | /// Gets number of minutes since 01/01/1970.
311 | Command.add(0, noodel.commandify(characters.correct("Ƈ") + "m"), function(cmd) {
312 | cmd.exec = function(path) {
313 | path.top(new NUMBER((new Date).getTime() / 60000));
314 | }
315 | });
316 |
317 | //------------------------------------------------------------------------------------------------------------
318 | /// Gets number of hours since 01/01/1970.
319 | Command.add(0, noodel.commandify(characters.correct("Ƈ") + "h"), function(cmd) {
320 | cmd.exec = function(path) {
321 | path.top(new NUMBER((new Date).getTime() / 3600000));
322 | }
323 | });
324 |
325 | //------------------------------------------------------------------------------------------------------------
326 | /// Handle basic stopwatch timer.
327 | Command.add(0, noodel.commandify(characters.correct("Ṭ")), function(cmd) {
328 | cmd.exec = function(path) {
329 | var t = path.timer(true);
330 | if(t !== undefined) path.top(new NUMBER(t));
331 | }
332 | });
333 |
334 | //------------------------------------------------------------------------------------------------------------
335 | /// Handle basic stopwatch timer.
336 | Command.add(0, noodel.commandify(characters.correct("Ṭ") + "s"), function(cmd) {
337 | cmd.exec = function(path) {
338 | var t = path.timer(true);
339 | if(t !== undefined) path.top(new NUMBER(t / 1000));
340 | }
341 | });
342 |
343 | //------------------------------------------------------------------------------------------------------------
344 | /// Handle basic stopwatch timer.
345 | Command.add(0, noodel.commandify(characters.correct("Ṭ") + "m"), function(cmd) {
346 | cmd.exec = function(path) {
347 | var t = path.timer(true);
348 | if(t !== undefined) path.top(new NUMBER(t / 60000));
349 | }
350 | });
351 |
352 | //------------------------------------------------------------------------------------------------------------
353 | /// Handle basic stopwatch timer.
354 | Command.add(0, noodel.commandify(characters.correct("Ṭ") + "h"), function(cmd) {
355 | cmd.exec = function(path) {
356 | var t = path.timer(true);
357 | if(t !== undefined) path.top(new NUMBER(t / 3600000));
358 | }
359 | });
360 |
361 | //------------------------------------------------------------------------------------------------------------
362 | /// Gets amount of time since start of path execution.
363 | Command.add(0, noodel.commandify(characters.correct("Ƭ")), function(cmd) {
364 | cmd.exec = function(path) {
365 | var end = (new Date).getTime();
366 | path.top(new NUMBER((end - path.start_time)));
367 | }
368 | });
369 |
370 | //------------------------------------------------------------------------------------------------------------
371 | /// Gets amount of time since start of path execution.
372 | Command.add(0, noodel.commandify(characters.correct("Ƭ") + "s"), function(cmd) {
373 | cmd.exec = function(path) {
374 | var end = (new Date).getTime();
375 | path.top(new NUMBER((end - path.start_time) / 1000));
376 | }
377 | });
378 |
379 | //------------------------------------------------------------------------------------------------------------
380 | /// Gets amount of time since start of path execution.
381 | Command.add(0, noodel.commandify(characters.correct("Ƭ") + "m"), function(cmd) {
382 | cmd.exec = function(path) {
383 | var end = (new Date).getTime();
384 | path.top(new NUMBER((end - path.start_time) / 60000));
385 | }
386 | });
387 |
388 | //------------------------------------------------------------------------------------------------------------
389 | /// Gets amount of time since start of path execution.
390 | Command.add(0, noodel.commandify(characters.correct("Ƭ") + "h"), function(cmd) {
391 | cmd.exec = function(path) {
392 | var end = (new Date).getTime();
393 | path.top(new NUMBER((end - path.start_time) / 3600000));
394 | }
395 | });
396 |
397 | //------------------------------------------------------------------------------------------------------------
398 | /// Gets amount of time since start of path execution.
399 | Command.add(0, noodel.commandify(characters.correct("Ƭ") + "b"), function(cmd) {
400 | cmd.exec = function(path) {
401 | path.top(new NUMBER(path.start_time));
402 | }
403 | });
404 |
405 | //------------------------------------------------------------------------------------------------------------
406 | /// Gets amount of time since start of path execution.
407 | Command.add(0, noodel.commandify(characters.correct("Ƭ") + "bs"), function(cmd) {
408 | cmd.exec = function(path) {
409 | path.top(new NUMBER(path.start_time / 1000));
410 | }
411 | });
412 |
413 | //------------------------------------------------------------------------------------------------------------
414 | /// Gets amount of time since start of path execution.
415 | Command.add(0, noodel.commandify(characters.correct("Ƭ") + "bm"), function(cmd) {
416 | cmd.exec = function(path) {
417 | path.top(new NUMBER(path.start_time / 60000));
418 | }
419 | });
420 |
421 | //------------------------------------------------------------------------------------------------------------
422 | /// Gets amount of time since start of path execution.
423 | Command.add(0, noodel.commandify(characters.correct("Ƭ") + "bh"), function(cmd) {
424 | cmd.exec = function(path) {
425 | path.top(new NUMBER(path.start_time / 3600000));
426 | }
427 | });
428 |
429 | //------------------------------------------------------------------------------------------------------------
430 | /// Creates time representation based off of what is on the stack.
431 | Command.add(0, noodel.commandify(characters.correct("ƈ")), function(cmd) {
432 | cmd.exec = function(path) {
433 | var f = path.first();
434 | if(f && f.type === "NUMBER") {
435 | var d = new Date(f.value);
436 | path.top();
437 | path.top(new STRING(d.toString()));
438 | }
439 | }
440 | });
441 |
442 | //------------------------------------------------------------------------------------------------------------
443 | /// Creates time representation based off of what is on the stack.
444 | Command.add(0, noodel.commandify(characters.correct("ƈ"), "[sSmhHdMy]"), function(cmd) {
445 | var map = {
446 | s: function(date) { return date.getMilliseconds() },
447 | S: function(date) { return date.getSeconds() },
448 | m: function(date) { return date.getMinutes() },
449 | h: function(date) { return date.getHours() },
450 | H: function(date) { return (date.getHours() < 12) ? 0 : 1 },
451 | d: function(date) { return date.getDay() },
452 | M: function(date) { return date.getMonth() },
453 | y: function(date) { return date.getFullYear() }
454 | }
455 | cmd.exec = function(path) {
456 | var f = path.first();
457 | if(f && f.type === "NUMBER") {
458 | var d = new Date(f.value);
459 | path.top();
460 | path.top(new NUMBER(this.tkn.params[0](d)));
461 | }
462 | }
463 |
464 | var old = cmd.tokenize;
465 | cmd.tokenize = function() {
466 | this.tkn.params[0] = map[this.tkn.params[0]];
467 | return old.call(this);
468 | }
469 | });
470 |
471 | })(this, this.noodel, this.Pipe, this.Command, this.Token, this.Path, this.characters, this.NUMBER, this.STRING, this.ARRAY)
472 |
--------------------------------------------------------------------------------
/src/noodel.js:
--------------------------------------------------------------------------------
1 | (function(global, Pipe, Command, Token, Path, characters, NUMBER, STRING, ARRAY){
2 |
3 | function insertAt(array, pos, item) {
4 | array.splice(pos, 0, item);
5 | };
6 | function removeAt(array, pos) {
7 | return array.splice(pos, 1)[0];
8 | };
9 |
10 | function handleUnicode(s) {
11 | s = s.replace(/\%([0-9A-F]+)/g, function(c,n) { return String.fromCharCode(parseInt(n, 16)); });
12 | return s;
13 | };
14 |
15 | characters.deprintify_char = function(c) {
16 | if(c === "\n") return characters.correct("¶");
17 | if(c === " ") return characters.correct("¤");
18 | // Handles unicode characters.
19 | if(!characters.printables.is(c)) {
20 | return "%" + c.charCodeAt(0).toString(16).toUpperCase();
21 | }
22 | return c;
23 | };
24 |
25 | characters.deprintify_string = function(s) {
26 | var r = "";
27 | for(var i = 0; i < s.length; ++i) r += characters.deprintify_char(s[i]);
28 | return r;
29 | };
30 |
31 | Path.prototype.printify = function() {
32 | var r = (new ARRAY(this.stdout.__array__)).printify();
33 |
34 | var rows = string_row_break(r);
35 |
36 | r = (rows[0] === undefined ? "" : rows[0]);
37 | for(var i = 1; i < rows.length; ++i) r += "\n" + (rows[i] === undefined ? "" : rows[i]);
38 |
39 | var final = "";
40 | for(var i = 0; i < r.length; ++i) {
41 | if(r[i] === characters.correct("¶")) final += "\n";
42 | else if(r[i] === characters.correct("¤")) final += " ";
43 | else final += r[i];
44 | }
45 |
46 | final = handleUnicode(final);
47 |
48 | return noodel.encode(final);
49 | }
50 |
51 | Path.prototype.first = function() {
52 | return this.stack.value[this.stack.ptr-1]
53 | };
54 |
55 | Path.prototype.first_ith = function(index) {
56 | if((this.stack.ptr-1-index) < 0) index = 0;
57 | else if(this.stack.length() <=( this.stack.ptr-1-index)) index = this.stack.length();
58 | else index = this.stack.ptr-1-index;
59 | return this.stack.value[index];
60 | };
61 |
62 | Path.prototype.last = function() {
63 | return this.stack.value[0]
64 | };
65 |
66 | Path.prototype.top = function(item) {
67 | var pos = this.stack.ptr;
68 | if(arguments.length === 1) {
69 | if(item === undefined) return;
70 | if(item.type === "ARRAY") {
71 | if(item.ptr === undefined) item.ptr = 0;
72 | item.container = this.stack;
73 | }
74 |
75 | insertAt(this.stack.value, pos, item);
76 | this.stack.ptr = pos+1;
77 | } else {
78 | item = removeAt(this.stack.value, pos-1);
79 | if(item) {
80 | if(item.type === "ARRAY") {
81 | item.container = undefined;
82 | }
83 | this.stack.ptr = pos-1;
84 | }
85 | return item;
86 | }
87 | };
88 |
89 | Path.prototype.top_ith = function(index, item) {
90 | var pos = this.stack.ptr;
91 | if(arguments.length === 2) {
92 | if(item === undefined) return;
93 | if(item.type === "ARRAY") {
94 | if(item.ptr === undefined) item.ptr = 0;
95 | item.container = this.stack;
96 | }
97 |
98 | insertAt(this.stack.value, pos-index, item);
99 | this.stack.ptr = pos+1;
100 | } else {
101 | item = removeAt(this.stack.value, pos-1-index);
102 | if(item) {
103 | if(item.type === "ARRAY") {
104 | item.container = undefined;
105 | }
106 | this.stack.ptr = pos-1;
107 | }
108 | return item;
109 | }
110 | };
111 |
112 | Path.prototype.bottom = function(item) {
113 | var pos = this.stack.ptr;
114 | if(arguments.length === 1) {
115 | if(item === undefined) return;
116 | if(item.type === "ARRAY") {
117 | if(item.ptr === undefined) item.ptr = 0;
118 | item.container = this.stack;
119 | }
120 |
121 | insertAt(this.stack.value, 0, item);
122 | this.stack.ptr = pos+1;
123 | } else {
124 | item = removeAt(this.stack.value, 0);
125 | if(item) {
126 | if(item.type === "ARRAY") {
127 | item.container = undefined;
128 | }
129 | this.stack.ptr = pos-1;
130 | }
131 | return item;
132 | }
133 | };
134 |
135 | Path.prototype.move_up = function() {
136 | var pos = this.stack.ptr;
137 | if(0 <= pos && pos < this.stack.length()) {
138 | this.stack.ptr = pos+1;
139 | }
140 | };
141 |
142 | Path.prototype.move_down = function() {
143 | var pos = this.stack.ptr;
144 | if(0 < pos && pos <= this.stack.length()) {
145 | this.stack.ptr = pos-1;
146 | }
147 | };
148 |
149 | Path.prototype.move_to_top = function() {
150 | this.stack.ptr = this.stack.length();
151 | };
152 |
153 | Path.prototype.move_to_bottom = function() {
154 | this.stack.ptr = 0;
155 | };
156 |
157 | Path.prototype.jump_in = function() {
158 | var item = this.top();
159 | if(item === undefined) {
160 | item = new ARRAY();
161 | } else {
162 | item = item.arrayify();
163 | }
164 | this.top(item);
165 |
166 | this.stack = item;
167 | };
168 |
169 | Path.prototype.jump_out = function() {
170 | var container = this.stack.container;
171 | if(container === undefined) {
172 | container = new ARRAY([this.stack]);
173 | this.stack.container = container;
174 | container.ptr = 1;
175 | }
176 |
177 | this.stack = container;
178 | };
179 |
180 | Path.prototype.reverse_stack = function() {
181 | for(var i = 0, l = Math.floor(this.stack.ptr/2); i < l; ++i) {
182 | var temp = this.stack.value[i];
183 | this.stack.value[i] = this.stack.value[this.stack.ptr - i - 1];
184 | this.stack.value[this.stack.ptr - i - 1] = temp;
185 | }
186 | }
187 |
188 | Path.prototype.time_passed = function() {
189 | var end = (new Date).getTime();
190 | return end - this.start_time;
191 | }
192 |
193 | Path.prototype.timer = function(clear) {
194 | var end = (new Date).getTime();
195 | if(this.timer.start === undefined) {
196 | this.timer.start = end;
197 | return undefined;
198 | }
199 | end -= this.timer.start;
200 | if(clear) this.timer.start = undefined;
201 | return end;
202 | }
203 |
204 | // Run time call only.
205 | Path.prototype.current_line = function(tkn) {
206 | var parent = tkn, count = 0;
207 | while(parent.parent) {
208 | if(parent.literal === "\n") ++count;
209 | parent = parent.parent;
210 | }
211 |
212 | return this.lines.length - count - 1;
213 | }
214 |
215 | function parseJsObject(JS) {
216 | if(typeof JS === "string") {
217 | return new STRING(characters.deprintify_string(JS));
218 | } else if(typeof JS === "number") {
219 | return new NUMBER(JS);
220 | } else if(JS instanceof Array) {
221 | var a = [];
222 | for(var i = 0; i < JS.length; ++i) {
223 | var item = parseJsObject(JS[i]);
224 | if(item) a.push(item);
225 | }
226 | return new ARRAY(a);
227 | } else if(typeof JS === "boolean") {
228 | return new NUMBER(JS ? 1 : 0);
229 | }
230 | };
231 |
232 | global.noodel = function noodel(code) {
233 | if(typeof code === "string" && code.length) {
234 | var path = new Path(noodel.decode(code));
235 | path.stack = new ARRAY();
236 | path.stack.ptr = 0;
237 | path.auto_popping = true;
238 | path.onstart = function() { while(this.stdin.first()) this.top(this.stdin.front()) };
239 | path.onend = function() { if(this.first() && this.auto_popping) this.stdout.back(this.top()) };
240 |
241 | path.call_stack = [];
242 |
243 | if(path.lines === undefined) path.lines = [path.start];
244 | else path.lines.unshift(path.start);
245 | path.lines.reverse();
246 | path.start = path.lines[0];
247 | path.current = path.start;
248 |
249 | for(var i = 1; i < arguments.length; ++i) {
250 | var item = parseJsObject(arguments[i]);
251 | if(item) path.stdin.back(item);
252 | }
253 |
254 | return path;
255 | }
256 | };
257 |
258 | noodel.commandify = function(cmd) {
259 | if(arguments.length > 1)
260 | cmd = Array.prototype.join.call(arguments, ")(");
261 | return new RegExp("^(" + cmd + ")$");
262 | };
263 |
264 | noodel.make_error = function(o, path) {
265 | path.exceptions.back(new STRING("¶[EXCEPTION]:")).back(o);
266 | };
267 |
268 | noodel.highest_precision = function(value) {
269 | var string = value+"", decimal = string.indexOf(".");
270 | if(decimal === -1) return 1;
271 | return Math.pow(10, decimal + 1 - string.length);
272 | };
273 |
274 | noodel.random = function(min, max) {
275 | // By adding the small delta allows the max to be included
276 | // but if the max is large (extremely large) then might have a problem.
277 |
278 | // By taking the min of the random and max prevents from getting numbers outside of range
279 | // BUT does mess up the even distribution.
280 | return Math.min(max,((max - min + 0.000000001) * Math.random()) + min);
281 | };
282 |
283 | noodel.random_int = function(min, max) {
284 | min = Math.ceil(min);
285 | return Math.floor((Math.floor(max) - min + 1) * Math.random()) + min;
286 | };
287 |
288 | noodel.encode = function(string) {
289 | var result = "";
290 | for(var i = 0; i < string.length; ++i) {
291 | result += String.fromCharCode(characters.char_to_int(string[i]));
292 | }
293 | return result;
294 | };
295 |
296 | noodel.decode = function(string) {
297 | var result = "";
298 | for(var i = 0; i < string.length; ++i) {
299 | result += characters.int_to_char(string.charCodeAt(i));
300 | }
301 | return result;
302 | };
303 |
304 | //------------------------------------------------------------------------------------------------------------
305 | /// NOPs
306 | Command.add(0, noodel.commandify(" "), function(cmd) {});
307 | Command.add(1, noodel.commandify(characters.regex.a_tiny_digit + "+", " "), function(cmd) {
308 | cmd.exec = function(path) {
309 | if(this.tkn.count === undefined) {
310 | this.tkn.count = this.tkn.params[0];
311 | var temp = this.tkn.old_next;
312 | this.tkn.old_next = this.tkn.next;
313 | this.tkn.next = temp;
314 | }
315 |
316 | if(this.tkn.count-- < 1) {
317 | this.tkn.count = undefined;
318 | var temp = this.tkn.old_next;
319 | this.tkn.old_next = this.tkn.next;
320 | this.tkn.next = temp;
321 | }
322 | }
323 |
324 | var old = cmd.tokenize;
325 | cmd.tokenize = function() {
326 | this.tkn.params[0] = +characters.tiny_num_to_num(this.tkn.params[0]);
327 | var tkn = this.tkn;
328 | this.tkn.old_next = function() { return tkn };
329 | return old.call(this);
330 | }
331 | });
332 |
333 | Command.add(0, noodel.commandify("\n"), function(cmd) {
334 | cmd.exec = function(path) {
335 | var ret = path.call_stack.pop();
336 | if(ret) {
337 | this.tkn.next = function() { return ret }
338 | } else {
339 | this.tkn.next = function() { return undefined }
340 | }
341 | }
342 |
343 | var old = cmd.tokenize;
344 | cmd.tokenize = function() {
345 | var parent_path = this.tkn.path;
346 | while(parent_path.parent) parent_path = parent_path.parent;
347 | if(parent_path.lines === undefined) parent_path.lines = [];
348 | var result = old.call(this);
349 | parent_path.lines.push(this.tkn.next());
350 | return result;
351 | }
352 | });
353 |
354 | })(this, this.Pipe, this.Command, this.Token, this.Path, this.characters, this.NUMBER, this.STRING, this.ARRAY)
355 |
--------------------------------------------------------------------------------