{"id":23383353,"url":"https://github.com/blagojeblagojevic/blang","last_synced_at":"2025-10-29T09:30:29.721Z","repository":{"id":261316432,"uuid":"883941455","full_name":"BlagojeBlagojevic/blang","owner":"BlagojeBlagojevic","description":"Fort like lang","archived":false,"fork":false,"pushed_at":"2025-02-06T20:54:31.000Z","size":426,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-02-06T21:34:32.985Z","etag":null,"topics":["bytecode","bytecode-interpreter","c","concatenative-language","concatenative-programming-language","esoteric-language","esoteric-programming-language","forth","forth-like","lexer","parser","programming-language","std","vm"],"latest_commit_sha":null,"homepage":"","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/BlagojeBlagojevic.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-11-05T21:09:12.000Z","updated_at":"2025-02-03T10:49:33.000Z","dependencies_parsed_at":"2024-12-12T18:19:14.424Z","dependency_job_id":"21642925-26dd-446b-b692-05bfedf24ca2","html_url":"https://github.com/BlagojeBlagojevic/blang","commit_stats":null,"previous_names":["blagojeblagojevic/blang"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BlagojeBlagojevic%2Fblang","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BlagojeBlagojevic%2Fblang/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BlagojeBlagojevic%2Fblang/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BlagojeBlagojevic%2Fblang/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/BlagojeBlagojevic","download_url":"https://codeload.github.com/BlagojeBlagojevic/blang/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":238795745,"owners_count":19531813,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bytecode","bytecode-interpreter","c","concatenative-language","concatenative-programming-language","esoteric-language","esoteric-programming-language","forth","forth-like","lexer","parser","programming-language","std","vm"],"created_at":"2024-12-21T22:20:09.252Z","updated_at":"2025-10-29T09:30:29.714Z","avatar_url":"https://github.com/BlagojeBlagojevic.png","language":"C","funding_links":[],"categories":[],"sub_categories":[],"readme":"\n\n# Blang\n\n**EXTREMELY IMPORTANT! THIS LANGUAGE IS A WORK IN PROGRESS! ANYTHING CAN CHANGE AT ANY MOMENT WITHOUT ANY NOTICE! USE THIS LANGUAGE AT YOUR OWN RISK!**\n\nBlang is a **[Concatenative](https://en.wikipedia.org/wiki/Concatenative_programming_language)**, **[Stack-Oriented](https://en.wikipedia.org/wiki/Stack-oriented_programming)** **[Programming Language](https://en.wikipedia.org/wiki/Programming_language)** for **[Computers](https://en.wikipedia.org/wiki/Computer)**.\n\n*(If you've never heard about this kind of language before, check out [https://concatenative.org/](https://concatenative.org/))*\n\n---\n\n## Development Milestones\n\n- [x] Compiled to a custom instruction set (BVM bytecode)\n- [x] Conditional/selection statements\n- [x] Loops\n- [x] [Turing-complete](./examples/celluarautomata/rule110.blang)\n- [x] Cross-platform\n- [x] Strings support\n- [x] Functions\n- [ ] Self-hosted\n- [ ] Statically typed\n- [ ] Optimized\n- [ ] Implement a VM as a custom CPU for FPGA\n\n\n\n---\n\n## Examples\n\n\n### Hello, World:\n\n```forth\n0 \"HelloWorld\" printstring\nendscript .\n```\n\n### Simple program that prints all uppercase letters:\n\n```forth\n65 ? a\nwhile\n    a charprint \n    89 \u003c if\n        breakloop\n    end \n    1 a + ? a\nendloop\nendscript .\n```\n\n---\n\n## Quick Start\n\n### Compile the project:\n\n```bash\ngcc -O3 lex.c parser.c main.c -o main.out\n```\n\nOR\n\n```bash\nmake all\n```\n\n### Compile to bytecode:\n\n```bash\n./main.out -c \u003cpath-to-program\u003e \u003cpath-to-save\u003e\n```\n\n### Run the bytecode:\n\n```bash\n./main.out -r \u003cpath-to-bytecode\u003e\n```\n\n### Usage:\n\n```bash\nUsage:  Compile -c \u003cpath-to-program\u003e \u003cpath-to-save\u003e\n        Run -r \u003cpath-to-saved\u003e\n```\n\n---\n\n## Language Reference\n\nThis section describes the features supported by the language so far. **Since the language is a work in progress, everything in this section is subject to change.**\n\n### Literals\n\n#### Integer\n\nAn integer is a sequence of decimal digits. When an integer is encountered, it is pushed onto the data stack for processing by the relevant operations.\n\nExample:\n\n```forth\n10 20 +\n```\n\nThe code above pushes `10` and `20` onto the data stack and sums them up with the `+` operation.\n\n#### String\n\nTBD\n\n#### Character\n\nA character is currently used as a variable on the heap. For printing a character, there is a function called `charprint`. For working with strings, there is a function called `printstring`. You must provide an end token, which is `0`.\n\nExample:\n\n```forth\n35 ? taraba \n32 ? space \n10 ? newLine\n```\n\n---\n\n### Intrinsics (Built-in Words)\n\n### Stack Manipulation\n\n| Name    | Signature        | Description                                                                                       |\n| ---     | ---              | ---                                                                                               |\n| `dup`   | `a -- a a`       | Duplicate an element on top of the stack.                                                         |\n| `swap`  | `a b -- b a`     | Swap 2 elements on the top of the stack.                                                          |\n| `drop`  | `a --`           | Remove the top element from the stack.                                                            |\n| `print` | `a --`           | Print the element on top of the stack and remove it.                                              |\n| `over`  | `a b -- a b a`   | Copy the element below the top of the stack.                                                      |\n| `rot`   | `a b c -- b c a` | Rotate the top three stack elements.                                                              |\n\n### Arithmetic\n\n| Name     | Signature                                        | Description                                                                                                              |\n| ---      | ---                                              | ---                                                                                                                      |\n| `+`      | `[a: int] [b: int] -- [a + b: int]`              | Sum up two elements on the top of the stack.                                                                             |\n| `-`      | `[a: int] [b: int] -- [a - b: int]`              | Subtract two elements on the top of the stack.                                                                           |\n| `*`      | `[a: int] [b: int] -- [a * b: int]`              | Multiply two elements on top of the stack.                                                                               |\n| `/`      | `[a: int] [b: int] -- [a / b: int]`              | Divide two elements on top of the stack.                                                                                 |\n| `%`      | `[a: int] [b: int] -- [a % b: int]`              | Modulo two elements on top of the stack.                                                                                 |\n                   \n\n#### Bitwise\n\n| Name  | Signature                            | Description                   |\n| ---   | ---                                  | ---                           |\n| `shr` | `[a: int] [b: int] -- [a \u003e\u003e b: int]` | Right **unsigned** bit shift. |\n| `shl` | `[a: int] [b: int] -- [a \u003c\u003c b: int]` | Left bit shift.               |\n| `or`  | `[a: int] [b: int] -- [a \\| b: int]` | Bitwise `OR`.                 |\n| `and` | `[a: int] [b: int] -- [a \u0026 b: int]`  | Bitwise `AND`.                |\n| `not` | `[a: int] -- [~a: int]`              | Bitwise `NOT`.                |\n\n#### Memory\n\n| Name         | Signature                      | Description                                                                                               |\n| ---          | ---                            | ---                                                                                                       |\n| `?`          | `\u003cstack\u003e let \u003cname\u003e`           | Store a value from `\u003csp\u003e` at the var address. If the var is not declared, create the var on `\u003cstacksize - numofvars - 1\u003e`.  |  \n| `arr`        | `arr \u003cname\u003e \u003csize\u003e`            | Create an array at the first free address on `stacksize - numofvars - 1`.                                 |\n| `\u0026`          | `ptr \u003cname\u003e`                   | Push a memory address of a var onto the top of the stack.                                                 |                         \n| `@`          | `\u003cstack\u003e ptrval`               | Push a value from the memory address on top of the stack onto the top of the stack.                       |\n| `??`         | `\u003cstack\u003e \u003cstack\u003e ptrval`       | Store a value from `\u003csp-1\u003e` to the memory address on `\u003csp\u003e`.                                              |\n\n#### System\n\n- `syscall`:\n\n| Name       | Signature                        | Description                                                                 |\n|------------|----------------------------------|-----------------------------------------------------------------------------|\n| `write`    | `fd ptr len -- result`           | Write `len` bytes from `ptr` to file descriptor `fd`.                       |\n| `close`    | `fd -- result`                   | Close file descriptor `fd`.                                                 |\n| `exit`     | `status --`                      | Terminate the program with exit `status`.                                   |\n| `truncate` | `fd length -- result`            | Truncate file descriptor `fd` to `length` bytes.                            |\n| `isatty`   | `fd -- result`                   | Check if `fd` refers to a terminal. Returns 1 if true, 0 otherwise.         |\n| `read`     | `fd ptr len -- bytes_read`       | Read up to `len` bytes from `fd` into `ptr`. Returns number of bytes read.  |\n| `sleep`    | `seconds --`                     | Sleep for `seconds` seconds.                                                |\n| `system`   | `command_ptr -- exit_code`       | Execute shell command specified by `command_ptr`.                           |\n| `dupF`     | `fd -- new_fd`                   | Duplicate file descriptor `fd`.                                             |\n| `dup2`     | `old_fd new_fd -- new_fd`        | Duplicate `old_fd` to `new_fd`, closing `new_fd` first if open.             |\n| `halt`     | `--`                             | Immediately halt the program execution.                                     |\n\n\n---\n\n## Foreign Function Interface (FFI)\n\nBlang provides FFI capabilities through its VM implementation, allowing interaction with C libraries and system calls. This enables low-level operations and integration with existing libraries.\n![Screencastfrom2025-03-0116-14-28-ezgif com-video-to-gif-converter](https://github.com/user-attachments/assets/bbf1c106-7b46-489c-bf83-51db5bb9c1f1)\n\n\n### Basic Usage\nFFI operations are handled through the `DRIVER` instruction and system call intrinsics. Here's how it works:\n\n### Device Interface Example\nThe VM supports device registration for hardware/software interactions. Here's a C-side device implementation template:\n\n```c\n#ifndef DEVICE_H\n#define DEVICE_H\n//#define BVM_IMPLEMENTATION\n//#define SDL_DEVICE\n#include \"bvm_type.h\"\n#ifdef SDL_DEVICE\n#include\u003cSDL2/SDL.h\u003e\n\ntypedef enum {\n    INIT_SDL,\n    CHECK_EVENT,\n    PUSH_EVENT_FROM_QUEUE,\n    RENDERER_CLEAR,\n    SET_RENDER_DRAW_COLOR,\n    SDL_RENDER_FILL_RECT,\n    SDL_RENDER_PRESENT,\n    SDL_DELAY,\n    SDL_MOUSE,\n    NUM_OF_DEVICES\n}DeviceType;\n\nstatic const char* device_name[] = {\n    \"initSdl\",\n    \"checkEvent\",\n    \"pushEvent\",\n    \"renderClear\",\n    \"drawColor\",\n    \"renderRect\",\n    \"renderPresent\",\n    \"sdlDelay\",\n    \"sdlMouse\",\n    \"NUM_OF_DEVICES\",\n};\n\ntypedef struct device{\n    void (*func_pointer)(Stack*);\n    int stackSize; \n}Devices;\n \nstatic volatile Devices devices[NUM_OF_DEVICES];\n\nstatic SDL_Window *window;\nstatic SDL_Renderer *renderer;\n\n#define WIDTH  800\n#define HEIGHT 600\n\n//(WIDTH HEIGHT --)\nstatic inline void initSdl(Stack *stack){\n    //Stack *s;\n    printf(\"Inited sdl!!!\\n\");\n    Word width = stackPop(stack);\n    Word height = stackPop(stack);\n    printf(\"Width: %d Height %d\\n\", width._asI64, height._asI64);\n    SDL_CreateWindowAndRenderer(width._asI64, height._asI64, NULL, \u0026window, \u0026renderer);\n    //while(1){\n\n    //}\n    return;\n}\n\n//(-- key event.type)\nstatic inline void pushEventFromQueue(Stack *stack){\n    //Word typeOfEvent = stackPop(stack);\n    SDL_Event event;\n    if(SDL_PollEvent(\u0026event)){\n        stackPush(stack, (i64)event.key.keysym.sym);\n        stackPush(stack, (i64)event.type);\n \n    }\n    else{\n        stackPush(stack, -1);\n        stackPush(stack, -1); //NO EVENT IN A QUEUE\n    }\n}\n\n//(err +)\nstatic inline void renderClear(Stack *stack){\n    int err = SDL_RenderClear(renderer);//MAYBE PUSHES ERROR CODE \n    stackPush(stack, (i64)err);\n}\n\n\n//(Event +)\nstatic inline void checkEventInLoop(Stack *stack){\n    Word typeOfEvent = stackPop(stack);\n    \n    SDL_Event event;\n    //printf(\"Event loop\\n\");\n    if(SDL_PollEvent(\u0026event)){\n        if(event.type == typeOfEvent._asI64){\n            //MAYBE SEND DATA TO A STACK\n            exit(-1);\n\n        }\n    }\n}\n//(a, g, b, r ----)\nstatic inline void drawColor(Stack *stack){\n    Word a = stackPop(stack);\n    Word b = stackPop(stack);\n    Word g = stackPop(stack);\n    Word r = stackPop(stack);\n    SDL_SetRenderDrawColor(renderer, (u8)r._asI64, (u8)g._asI64, (u8)b._asI64, (u8)a._asI64);\n}\n//(h,w,y,x ----)\nstatic inline void rednerRect(Stack *stack){\n    Word h = stackPop(stack);\n    Word w = stackPop(stack);\n    Word y = stackPop(stack);\n    Word x = stackPop(stack);\n    SDL_Rect r;\n    r.h =  (int)h._asI64; \n    r.w =  (int)w._asI64;\n    r.y =  (int)y._asI64; \n    r.x =  (int)x._asI64;\n    if(SDL_RenderFillRect(renderer, \u0026r) != 0){\n        printf(\"Error in drawing of a rectangle\\n\");\n    }\n    //SDL_Delay(1);\n}\n//(--)\nstatic inline void renderPresent(Stack *stack){\n    //printf(\"Drawing\\n\");\n    SDL_RenderPresent(renderer);\n    //printf(\"Drawing\\n\"); \n}\n//DELAY(dealy --) \nstatic inline void sdlDelay(Stack *stack){\n    Word a = stackPop(stack);\n    SDL_Delay((u32)a._asI64);\n}\n//MOUSE(-- x, y)\nstatic inline void sdlMouse(Stack *stack){\n    int X, Y;\n    \n    SDL_GetMouseState(\u0026X, \u0026Y);\n    stackPush(stack, (i64)X);\n    stackPush(stack, (i64)Y);\n    \n}\n\n\n\nstatic inline void initDevices(Stack *stack){\n    printf(\"Devices init\\n\");\n   //INIT SDL\n    devices[INIT_SDL].func_pointer = \u0026initSdl;\n    devices[INIT_SDL].stackSize = -2;\n   //CHECK EVENT\n    devices[CHECK_EVENT].func_pointer = \u0026checkEventInLoop;\n    devices[CHECK_EVENT].stackSize = -1;\n   //PUSH EVENT FROM QUUES\n    devices[PUSH_EVENT_FROM_QUEUE].func_pointer = \u0026pushEventFromQueue;\n    devices[PUSH_EVENT_FROM_QUEUE].stackSize = +2;\n   //CLEAR RENDERER\n    devices[RENDERER_CLEAR].func_pointer = \u0026renderClear;\n    devices[RENDERER_CLEAR].stackSize = +1;\n   //SET DRAW COLOR\n    devices[SET_RENDER_DRAW_COLOR].func_pointer = \u0026drawColor;\n    devices[SET_RENDER_DRAW_COLOR].stackSize = -4;\n  //DRAW RECR\n    devices[SDL_RENDER_FILL_RECT].func_pointer = \u0026rednerRect;\n    devices[SDL_RENDER_FILL_RECT].stackSize = -4;\n  //RENDER *renderer\n    devices[SDL_RENDER_PRESENT].func_pointer = \u0026renderPresent;\n    devices[SDL_RENDER_PRESENT].stackSize = 0;\n  //DELAY Sdl_Delay\n    devices[SDL_DELAY].func_pointer = \u0026sdlDelay;\n    devices[SDL_DELAY].stackSize = -1;\n\n  //MOUSE Sdl_Delay\n    devices[SDL_MOUSE].func_pointer = \u0026sdlMouse;\n    devices[SDL_MOUSE].stackSize = +2;\n    \n    \n}\n#endif\n```\n\n\n### Example: SDL Integration\n```forth\n0\nword SDL_ERROR\n    0 swap \u003c if\n    0 \"SdlError\" 10 exit\n    end\nendword\n\nword w 119 endword\nword a 97  endword\nword s 115 endword \nword d 100 endword\n\n\nword SDL_QUIT            256 endword\nword SDL_KEYDOWN         768  endword\nword SDL_MOUSEMOVED      1024 endword\nword SDL_MOUSEBUTTONDOWN 1025 endword       \nword SDL_MOUSEBUTTONUP   1026 endword       \nword SDL_MOUSEWHEEL      1027 endword\n\n\n100 ? x drop\n100 ? y drop\n\n10 \n600 800 initSdl\nwhile\n    pushEvent dup SDL_QUIT = if\n        0 10 \"Quiting\" printstring 10 exit\n    end\n    dup SDL_KEYDOWN = if\n        swap \n        dup  w = if y -5 + ? y drop end\n        dup  s = if y  5 + ? y drop end\n        dup  a = if x -5 + ? x drop end\n        dup  d = if x  5 + ? x drop end\n    end\n\tdup SDL_MOUSEBUTTONDOWN = if\n\t\tsdlMouse\n\t\t? y drop\n\t\t? x drop\n\tend\n    drop\n    drop \n    255 0 0 0   drawColor \n    x y 30 30   renderRect \n    0 0 0 0     drawColor\n    renderPresent\n    renderClear SDL_ERROR\n    \n    \n\nendloop\n10 printstack\nendscript .\n```\n\n\n\n### Important Notes\n1. The FFI system is **experimental** and subject to change\n2. Memory management between Blang and C is manual\n3. Type conversions must be handled explicitly\n4. Device IDs correspond to their registration order in `devices[]`\n\nSee the [device.h](device.h) implementation for more examples of FFI integration with SDL.\n\n\n---\n\n### Control Flow\n\n#### If-Condition\n\nSimple `if`:\n\n```html\n\u003cComparison\u003e if\n  \u003cbody\u003e \nend\n```\n\n`If/else`:\n\n```html\n\u003cComparison\u003e dup if\n  \u003cbody\u003e \nend\nelse\n  \u003cbody\u003e\nend\n```\n\nExample:\n\n```forth\n0 10 \n= dup\nif\n    20 print\n    30 40 = dup\n    if \n        30 print\n    end\n    else \n        50 print\n    end\nend\nelse\n    30 print\nend\n40 print\nendscript .\n```\n\n#### While-Loop\n\nInfinite loop:\n\n```html\nwhile \n   \u003cbody\u003e\nendloop\n```\n\nConditional loop (use `breakloop` to exit):\n\n```html\nwhile\n  \u003cbody\u003e\n  \u003cComparison\u003e if\n    \u003cbody\u003e\n    breakloop \n  end\nendloop\n```\n\n---\n\n### Procedures and Functions\n\nThe `word` keyword declares a procedure or function. Values can be passed through the stack or the heap.\n\nExample:\n\n```forth\nword printString \n    while\n        dup @ charprint \n        0 = if\n            breakloop\n        end\n        1 + \n    endloop\n    drop\nendword\n\n\u0026 H printString\n```\n\n#### Procedure Pointers\n\nTBD\n\n---\n\n### Constants\n\nConstants are declared like this:\n\n```forth\nword pi 3.1415 endword\n```\n\n---\n\n### Memory\n\nThe heap is built on top of the stack. Variables are global for the entire duration of the program.\n\n---\n\n### Type Checking\n\nThere are 4 types: `int64`, `float64`, `uint64`, and `ch` (basically `uint64`, but used in strings). The type is inferred for math operations based on the last element on the stack. For example, if we have `10 10.2` on the stack and we perform the `+` operation, the `+` operation will use the `float` type as the operand.\n\n---\n\n## Example Programs\n\n### Memory Copy Example\n\n```forth\n0\narr toCopyInto 50 \n\nword memcpy\n    ? memcpySize\n    drop\n    ? memcpySrc\n    drop\n    ? memcpyDest\n    drop\n    SP ? memcpySP\n    drop\n    while\n        memcpySrc @ memcpyDest ??\n        memcpySrc 1 + ? memcpySrc \n        memcpyDest 1 + ? memcpyDest\n        memcpySize 0 = if\n            breakloop\n        end\n        memcpySize -1 + ? memcpySize\n    endloop\n    memcpySP SET\t\nendword\n\nword memmove memcpy endword\n\nSP ? temp\ndrop\n\n0 \"HelloWorld\" 10 \n\u0026 toCopyInto0 temp 12 memcpy\n\n1 \u0026 toCopyInto0 12 write \n0 \u0026 toCopyInto0 12 read \n1 \u0026 toCopyInto0 6 write \n10 sleep \n1 \u0026 toCopyInto0 6 write\nendscript .\n```\n\n### Game of Life Implementation\n![Screenshot_7](https://github.com/user-attachments/assets/570c8376-1456-491c-8ac7-4f36eb254b77)\n\n\n\n\n```forth\n0\n\n50 ? MAX_X_POS \n35 ? MAX_Y_POS \nword BACKGROUND_CHAR 32 endword  \nword CELL_CHAR 35 endword   \nword SLEEP_TIME 1 endword\n\narr checkCoords 100\n\narr mainMatrix 1800\n\n\n\narr neighborCountBuffer 1800\n\n\n\nword increment 1 + endword\n\nword matrixIndex  MAX_X_POS updateCell_y * updateCell_x +   endword\nword matrixIndexP MAX_X_POS printCells_y * printCells_x +   endword\nword matrixIndexC MAX_X_POS tempY        *        tempX +   endword\n\nword matrixInit\n\t0 ? printCells_x\n\t0 ? printCells_y\n\tSP ? printCells_SP\n\t\n\twhile MAX_Y_POS printCells_y loopBreak\n\t\tprintCells_y 1 + ? printCells_y\n\t\t\n\t\t0 ? printCells_x\n\t\t\n\t\twhile printCells_x MAX_X_POS  loopBreak\n\t\t\tprintCells_x 1 + ? printCells_x\n\t\t\tBACKGROUND_CHAR\n\t\t\t\u0026 mainMatrix0 matrixIndexP + ??  \n\t\tendloop\n\tendloop\n\t0 SET\nendword\n\n\nword loopBreak \n\t\t\t= if\n\t\t\t\tbreakloop\n\t\t\tend  \nendword\n\n\nword updateCell \n\t\n\t0 ? updateCell_x\n\tMAX_Y_POS ? updateCell_y\n\tSP ? upadteCell_SP\n\t\n\twhile 0 updateCell_y loopBreak\n\t\tupdateCell_y -1 + ? updateCell_y\n\t\t\n\t\t0 ? updateCell_x\n\t\t\n\t\twhile updateCell_x MAX_X_POS  loopBreak\n\t\t\tupdateCell_x 1 + ? updateCell_x\n\t\t\t\t\n\t\t\t3 \u0026 neighborCountBuffer0 matrixIndex + @   \n\t\t\t= if\n\t\t\t\t\t\tCELL_CHAR\n\t\t\t\t\t\t\u0026 mainMatrix0 matrixIndex + ??\t\t\t\n\t\t\tend\n\t\t\t3 \u0026 neighborCountBuffer0 matrixIndex + @ \u003e  \n\t\t\t2 \u0026 neighborCountBuffer0 matrixIndex + @ \u003c\n\t\t\tor\n\t\t\t1 = if\n\t\t\t\t\t\tBACKGROUND_CHAR \n\t\t\t\t\t\t\u0026 mainMatrix0 matrixIndex + ??\n\t\t\t\t\t\t\t\n\t\t\tend\n\t\tendloop\n\t\t\t\n\tendloop\n\t \n\tupadteCell_SP SET\nendword\n\n\nword countNeighbors\n\t\n\t? posY\n\tdrop\n\t \n\t? posX\n\tdrop\n\t\n\tSP ? countNeighbors_SP\n\t\n\t\n\t1 posY  + ? checkCoords0\n -1 posX  + ? checkCoords1\n\t\n\t1 posY  + ? checkCoords2\n\t0 posX  + ? checkCoords3\n\t\n\t1 posY  + ? checkCoords4\n\t1 posX  + ? checkCoords5\n\n\t0 posY  + ? checkCoords6\n\t1 posX  + ? checkCoords7\n\n -1 posY  + ? checkCoords8\n\t1 posX  + ? checkCoords9\n\t\n -1 posY  + ? checkCoords10\n\t0 posX  + ? checkCoords11\n\t\n -1 posY  + ? checkCoords12\n -1 posX  + ? checkCoords13\n\t\n\t0 posY  + ? checkCoords14\n -1 posX  + ? checkCoords15\n\t\n\t0 ? i\n\t0 ? neighbors\n\t\n\t\n\twhile\n\t\t\u0026 checkCoords0 i + @ ? tempY\t\n\t\t\u0026 checkCoords1 i + @ ? tempX\n\t\t\n\t\t0 tempX \u003c if\n\t\t\tMAX_X_POS -1 + ? tempX \n\t\tend\n\t\t\n\t\tMAX_X_POS -1 + tempX \u003e if\n\t\t\t0 ? tempX \n\t\tend\n\t\t\n\t\t0 tempY \u003c if\n\t\t\tMAX_Y_POS -1 + ? tempY \n\t\tend\n\t\t\n\t\tMAX_Y_POS -1 + tempY \u003e if\n\t\t\t0 ? tempY \n\t\tend\n\t\t\n\t\t\t\t\n\t\t\u0026 mainMatrix0 matrixIndexC + @ CELL_CHAR = if\n\t\t\tneighbors 1 + ? neighbors\t\n\t\tend\n\t\t\n\t\t\t\t\t\n\t\ti 2 + ? i \n\t\ti 16 = if \n\t\t\tneighbors \n\t\t\tbreakloop\n\t\tend\n\tendloop\n\n\tcountNeighbors_SP SET\n\tneighbors\n\t \n\t\nendword\n\n\nword printCells \n\t\n\t0 ? printCells_x\n\tMAX_Y_POS ? printCells_y\n\tSP ? printCells_SP\n\t\n\twhile printCells_y 0  loopBreak\n\t\tprintCells_y -1 + ? printCells_y\n\t\t\n\t\t-1 ? printCells_x\n\t\t\n\t\twhile printCells_x MAX_X_POS  loopBreak\n\t\t\tprintCells_x 1 + ? printCells_x\n\t\t\t\u0026 mainMatrix0 matrixIndexP + @\n\t\t\tcharprint 0\n\t\t\tprintCells_x printCells_y\tcountNeighbors\n\t\t\t\u0026 neighborCountBuffer0 matrixIndexP + ?? \t\t\n\t\tendloop\n\t\t10 charprint\n\tendloop\n\t \n\t printCells_SP SET\nendword\n\n\nword convayLoop\n\n\tSP print\n\twhile\n\t\t\n\t\t0 SET\n\t\t0 \"cls\" system\n\t\t0 10 10 9 9 \"GameOfLife\" 10 9 9 9 9 \"By:\" 32 \"B.B.\" printstring\n\t\tprintCells\n\t\tupdateCell\t\t\t\n\t\tSLEEP_TIME sleep\n\t\t\n\tendloop\n\n\t\nendword\n\n\n\n0 SET \n\n\nmatrixInit\n\n0 \"color\" 32 \"3\" system\n\nCELL_CHAR ? mainMatrix925  \nCELL_CHAR ? mainMatrix926  \nCELL_CHAR ? mainMatrix927\n\n\n\nCELL_CHAR ? mainMatrix120  \nCELL_CHAR ? mainMatrix170  \nCELL_CHAR ? mainMatrix220\n\n\nCELL_CHAR ? mainMatrix1025  \nCELL_CHAR ? mainMatrix1026  \nCELL_CHAR ? mainMatrix1075\nCELL_CHAR ? mainMatrix1076\n\n\n\nconvayLoop\n\nendscript . \n```\n\n---\n\n\n\n## Contributing\n\nContributions are welcome! If you'd like to contribute, please follow these steps:\n\n1. Fork the repository.\n2. Create a new branch for your feature or bugfix.\n3. Commit your changes.\n4. Push your branch to your fork.\n5. Submit a pull request.\n\n---\n\n## License\n\nThis project is licensed under the MIT License. See the [LICENSE](LICENSE) file for details.\n\n---\n\n## Acknowledgments\n\n- Inspired by concatenative and stack-oriented languages like Forth and Factor.\n- Special thanks to the [concatenative.org](https://concatenative.org/) community for their resources and inspiration.\n\n---\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fblagojeblagojevic%2Fblang","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fblagojeblagojevic%2Fblang","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fblagojeblagojevic%2Fblang/lists"}