{"id":43451650,"url":"https://github.com/vldr/cyth","last_synced_at":"2026-05-25T06:09:18.514Z","repository":{"id":336137663,"uuid":"889327626","full_name":"vldr/Cyth","owner":"vldr","description":"A fast and simple, embeddable programming language that targets WebAssembly, x86-64, and ARM64.","archived":false,"fork":false,"pushed_at":"2026-04-18T03:31:32.000Z","size":146259,"stargazers_count":6,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2026-04-18T05:41:26.002Z","etag":null,"topics":["arm64","compiler","jit","programming-language","wasm","webassembly","x86-64"],"latest_commit_sha":null,"homepage":"https://cyth.vldr.org/","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/vldr.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","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,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2024-11-16T04:50:52.000Z","updated_at":"2026-04-18T03:27:13.000Z","dependencies_parsed_at":"2026-02-25T02:04:06.094Z","dependency_job_id":"c4f00f51-9119-44b9-a994-25e6581371fb","html_url":"https://github.com/vldr/Cyth","commit_stats":null,"previous_names":["vldr/cyth"],"tags_count":46,"template":false,"template_full_name":null,"purl":"pkg:github/vldr/Cyth","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vldr%2FCyth","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vldr%2FCyth/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vldr%2FCyth/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vldr%2FCyth/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/vldr","download_url":"https://codeload.github.com/vldr/Cyth/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vldr%2FCyth/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32120402,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-22T00:31:26.853Z","status":"online","status_checked_at":"2026-04-22T02:00:05.693Z","response_time":58,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["arm64","compiler","jit","programming-language","wasm","webassembly","x86-64"],"created_at":"2026-02-03T02:09:31.594Z","updated_at":"2026-04-22T04:00:47.211Z","avatar_url":"https://github.com/vldr.png","language":"C","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n    \u003cimg src='logo.svg?raw=true' height=\"140px\"\u003e\n\u003c/p\u003e\n\n---\nA fast and simple, embeddable programming language that targets WebAssembly, x86-64, and ARM64.\n\n- [Try it out](#try-it-out)\n- [Motivation](#motivation)\n- [Binaries](#binaries)\n- [Examples](#examples)\n- [Building](#building)\n  - [Linux](#linux)\n  - [MacOS](#macos)\n  - [Windows](#windows)\n  - [Web](#web)\n- [Contributing](#contributing)\n- [Overview](#overview)\n\n## Try it out\n\nYou can try out Cyth in the web playground:\n[https://cyth.vldr.org](https://cyth.vldr.org)\n\n## Motivation\nSuppose we want to call a native C function from Cyth; for example, to `print` the 12th fibonacci number.\n\nIn Cyth, you just use the `print` function:\n\n```jai\nint fibonacci(int n)\n  if n \u003c= 1\n    return n\n  else\n    return fibonacci(n - 2) + fibonacci(n - 1)\n\nprint(\"Fibonacci = \" + fibonacci(12))\n```\n\nOn the C side, we initialize the Cyth runtime, provide our implementation of `print` and run the program:\n\n```cpp\n#include \u003cstdio.h\u003e\n#include \u003ccyth.h\u003e\n\nvoid print(CyString* text) {\n  printf(\"%s\\n\", text-\u003edata);\n}\n\nint main(int argc, char* argv[]) {\n  CyVM* vm = cyth_init();\n  cyth_load_function(vm, \"void print(string text)\", (uintptr_t)print);\n  cyth_load_file(vm, argv[1]);\n  cyth_compile(vm);\n  cyth_run(vm);\n  cyth_destroy(vm);\n\n  return 0;\n}\n```\n\nThat is it. With just a few lines of code, Cyth can call into C, and C can call back into Cyth.\n\nIf you're interested, you can look at some of the [examples](#examples) or read through the [overview](#overview) of the language.\n\n## Binaries\n\nPrecompiled binaries are available in [Releases](https://github.com/vldr/Cyth/releases/latest).\n\n## Examples\n\n- [GFX](https://github.com/vldr/CythGFX)  \nA graphical example program.\n\n- [CGI](https://github.com/vldr/CythCGI)  \nA server-side scripting environment for the Cyth programming language, written in Rust.\n\n## Building\n\nTo build Cyth, you will need to have [CMake](https://cmake.org/) and gcc/clang/MSVC installed. To run the test suite, you will need to have [Node.js](https://nodejs.org/) (v20 or higher) installed.\n\nIf you want to build the WASM backend, provide the `-DWASM=1` flag to CMake.\n\n_Note:_ The supported platforms for the JIT compiler are:\n- Windows x64 and ARM64\n- Linux x64 and ARM64\n- MacOS x64 and ARM64\n\n### Linux\n\nRun the following commands from the root directory (in a terminal):\n\n_Debug_:  \n```bash\ncmake -DCMAKE_BUILD_TYPE=Debug -DBUILD_SHARED_LIBS=1 -DCMAKE_EXPORT_COMPILE_COMMANDS=1 -S . -B build\ncd build\nmake\n```\n\n_Release_:  \n```bash\ncmake -DCMAKE_BUILD_TYPE=Release -S . -B build\ncd build\nmake\n```\n\n_Manual C compilation_:  \n`cc third_party/mir/mir.c third_party/mir/mir-gen.c third_party/bdwgc/extra/gc.c src/jit.c src/checker.c src/environment.c src/main.c src/memory.c src/lexer.c src/map.c src/parser.c -Ithird_party/mir -Ithird_party/bdwgc/include -fsigned-char -O3 -o cyth`\n\n### MacOS\n\nRun the following commands from the root directory (in a terminal):\n\n_Xcode project_:  \n```\ncmake -S . -B xbuild -G Xcode\n```\n\nThen, in the `xbuild` directory, open `cyth.xcodeproj` in Xcode.\n\n_Makefile (Debug)_:  \n```bash\ncmake -DCMAKE_BUILD_TYPE=Debug -DBUILD_SHARED_LIBS=1 -DCMAKE_EXPORT_COMPILE_COMMANDS=1 -S . -B build\ncd build\nmake\n```\n\n_Makefile (Release)_:  \n```bash\ncmake -DCMAKE_BUILD_TYPE=Release -S . -B build\ncd build\nmake\n```\n\n### Windows\n\nRun the following commands from the root directory (in a terminal):\n\n_Visual Studio 2022 project_:  \n```\ncmake.exe -S . -B winbuild -G \"Visual Studio 17 2022\"\n```\n\n_Visual Studio 2026 project_:  \n```\ncmake.exe -S . -B winbuild -G \"Visual Studio 18 2026\"\n```\n\nThen, in the `winbuild` directory, open `cyth.sln` / `cyth.slnx` in Visual Studio.\n\n_Manual C compilation_:  \n`cl.exe third_party/mir/mir.c third_party/mir/mir-gen.c third_party/bdwgc/extra/gc.c src/jit.c src/checker.c src/environment.c src/main.c src/memory.c src/lexer.c src/map.c src/parser.c /Ithird_party/mir /Ithird_party/bdwgc/include /Ox /Fecyth`\n\n### Web\nFor web builds, you will need to have [Emscripten](https://emscripten.org/docs/getting_started/downloads.html) installed.\n\nRun the following commands from the root directory (in a terminal):\n\n_Debug_:  \n```\nemcmake cmake -DCMAKE_BUILD_TYPE=Debug -S . -B embuild\ncd embuild\nmake\n``` \n\n_Release_:  \n```\nemcmake cmake -DCMAKE_BUILD_TYPE=Release -S . -B embuild\ncd embuild\nmake\n```\n\n## Contributing\n\nIf you would like to contribute to the project or simply provide feedback and ask questions, please email [cyth@vldr.org](mailto:cyth@vldr.org)\n\n## Overview\n\n- [Primitive Types](#primitive-types)\n  - [`bool`](#bool)\n  - [`char`](#char)\n  - [`int`](#int)\n  - [`float`](#float)\n- [Types](#types)\n  - [`string`](#string)\n  - [`any`](#any)\n  - [Array](#array)\n  - [Object](#object)\n  - [Function Pointers](#function-pointers)\n- [Variables](#variables)\n- [Functions](#functions)\n- [Generics](#generics)\n  - [Functions](#functions-1)\n  - [Objects](#objects)\n- [Overloading](#overloading)\n- [`if` statement](#if-statement)\n- [`while` loop](#while-loop)\n- [`for` loop](#for-loop)\n- [`break` statement](#break-statement)\n- [`continue` statement](#continue-statement)\n\n### Primitive Types\n#### `bool`\nPossible values: `false` or `true`  \nDefault value: `false`  \n\n_Example:_\n```cpp\nbool myBool = true\n```\n\n#### `char`\nPossible values: `0` to `255`  \nDefault value: `'\\0'`  \n\n_Example:_\n```cpp\nchar myChar = 'a'\n```\n\n#### `int`\nPossible values: `-2147483648` to `2147483647`  \nDefault value: `0`  \n\n_Example:_\n```cpp\nint myInt = 10\n```\n\n#### `float`\nPossible values: `± 1.5 x 10−45` to `± 3.4 x 1038`  \nDefault value: `0.0`  \n\n_Example:_\n```cpp\nfloat myFloat = 12.25\n```\n\n### Types\n\n#### `string`\nPossible values: UTF-8 text  \nDefault value: `\"\"` (empty string)  \n\n- All types can be cast to a `string`, which will convert to the type's string representation; casting `any` to a string will attempt to convert the `any` to the underlying string type rather than its string representation.\n\n_Example:_\n```jai\nstring myString = \"hello world\"\n```\n\n### `any`\nPossible values: `null`, `string`, [Array](#array) or [Object](#object)   \nDefault value: `null` \n- Casting `any` to the incorrect underlying type will trigger a panic. \n\n_Example:_\n```jai\nany myAny = \"hello world\"\nstring myString = (string)myAny\n```\n\n#### Array\nPossible values: `[]` (empty list) or a list with one or more elements.  \nDefault value: `[]` (empty list)   \n\n- Arrays can be multi-dimensional.\n- All arrays are dynamic, meaning they can be resized.\n\n_Example:_\n\n```jai\nint[] myArray\nmyArray.push(1)\nmyArray.push(2)\nmyArray.push(3)\n\nstring[][] myArray2D = [[\"I'm\", \"multidimensional\"]]\n```\n\n#### Object\nPossible values: `null` or a valid pointer (reference).  \nDefault value: `null`  \n\n_Example:_\n\n```jai\nclass Vector\n  float x\n  float y\n  float z\n\n  void __init__(int x, int y, int z)\n    this.x = x\n    this.y = y\n    this.z = z\n\nVector myVector = Vector(10, 20, 30)\n```\n\nAlthough the keyword `class` is used, there is no support for inheritance or other common object-oriented concepts in Cyth.\n\nObjects in Cyth closely resemble structs rather than traditional classes. The key difference is that they can have **method functions**, which are functions that include an implicit `this` parameter.\n\n_Example:_\n\n```cpp\nclass Vector\n  float x\n  float y\n  float z\n\n  float length()\n    return (x*x  + y*y + z*z).sqrt()\n```\n\n\u003e Cyth objects are compatible with C structs. In C, the Vector object would look like:\n\u003e ```c\n\u003e struct Vector {\n\u003e   float x;\n\u003e   float y;\n\u003e   float z;\n\u003e };\n\u003e ```\n\u003e \n\u003e Calling the `length` method function from C would look like:\n\u003e ```c\n\u003e typedef float (*LengthFunc)(Vector*);\n\u003e\n\u003e LengthFunc length = (LengthFunc) cyth_get_function(vm, \"Vector.length.float()\");\n\u003e \n\u003e Vector* vector = (Vector*) cyth_alloc(true, sizeof(Vector));\n\u003e vector-\u003ex = 1;\n\u003e vector-\u003ey = 2;\n\u003e vector-\u003ez = 3;\n\u003e\n\u003e float len = 0.0f;\n\u003e cyth_try_catch(vm, { \n\u003e   len = length(vector);\n\u003e });\n\u003e ```\n\u003e\n\nObjects have special method functions:\n\n*Constructors*\n```cpp\nvoid __init__()\n```\n\n*Index overload*\n```cpp\nV __get__(T index)\n```\n\n*Index and assign overload*\n```cpp\nV __set__(T index, U value)\n```\n\n*Operator overloads*\n```python\nV __add__(T other)\nV __sub__(T other)\nV __div__(T other)\nV __mul__(T other)\nV __mod__(T other)\nV __and__(T other)\nV __or__(T other)\nV __xor__(T other)\nV __lshift__(T other)\nV __rshift__(T other)\nV __lt__(T other)\nV __le__(T other)\nV __gt__(T other)\nV __ge__(T other)\nV __eq__(T other)\nV __ne__(T other)\nV __str__(T other)\n```\n\n#### Function Pointers\nPossible values: `null` or a valid pointer (reference).  \nDefault value: `null`  \n\n- Function pointers cannot be placed into `any` (limitation added due to WASM not supporting them).\n- Function pointers in Cyth are compatible with C function pointers.\n\n_Example:_\n\n```cpp\nint adder(int a, int b)\n  return a + b\n\nint(int, int) myFunctionPointer = adder\nmyFunctionPointer(10, 20)\n```\n\n_Example (Function Member):_\n\n```cpp\nclass Vector\n  float x\n  float y\n  float z\n\n  float length()\n    return (x * x  + y * y + z * z).sqrt()\n\nVector myVector = Vector()\n\nfloat(Vector) myFunctionPointer = Vector.length\nmyFunctionPointer(myVector)\n```\n\n## Variables\n\nYou can declare variables like this:\n\n```jai\nint myVariable = 12\nfloat mySecondVariable\n```\n\nIf you do not initialize a variable, a default value is assigned automatically. For example, `mySecondVariable` will be set to `0.0`.\n\nYou can declare variables in the top-level scope of your program which will make them a global variable. \n\n\u003e You can access global variables from C using `cyth_get_variable`.\n\u003e\n\u003e For example, to get `myVariable` from C, you would write:\n\u003e ```c\n\u003e int* myVariable = (int*) cyth_get_variable(vm, \"myVariable.int\");\n\u003e ```\n\u003e The address returned from `cyth_get_variable` will be `NULL` if it was not found, or the signature is incorrect.\n\u003e\n\u003e Make sure to only call `cyth_get_variable` after calling `cyth_run`, otherwise global variables will be \n\u003e uninitialized which can lead to issues if you're using types that have special default initializations (like arrays and strings).\n\u003e\n\n## Functions\n\nYou can declare functions like this:\n\n```c\nint myFunction(int a, int b)\n  return a + b\n```\n\nYou can place functions inside other functions:\n\n```c\nint myFunction(int a, int b)\n  int myInnerFunction(int c)\n    return 2 * c\n  \n  return myInnerFunction(a + b)\n```\n\nNested functions are **not** closures, meaning they can't access variables outside their body.\n\nFunctions can appear inside objects making them method functions:\n\n```python\nclass MyClass\n  int a\n  int b\n\n  int myMethodFunction()\n    return this.a + this.b\n```\n\nMethod functions have an implicit `this` parameter which is a pointer to the object itself. This can be `null` if the method is called on a `null` pointer.\n\n```python\nclass MyClass\n  int a\n  int b\n\n  int myMethodFunction()\n    int myInnerMethodFunction()\n      return 2 * (this.a + this.b)\n\n    return myInnerMethodFunction()\n```\n\nNested functions inside method functions are themselves method functions with an implicit `this` parameter. Meaning these nested method functions can access object fields inside them.\n\n\u003e You can access global functions from C using `cyth_get_function`.\n\u003e\n\u003e For example, to get `myFunction` from C, you would write:\n\u003e ```c\n\u003e typedef int (*Func)(int, int);\n\u003e Func my_function = (Func) cyth_get_function(vm, \"myFunction.int(int, int)\");\n\u003e\n\u003e int sum = 0;\n\u003e cyth_try_catch(vm, { \n\u003e   sum = my_function(10, 20); \n\u003e });\n\u003e ```\n\u003e The address returned from `cyth_get_function` will be `NULL` if it was not found, or the signature is incorrect.\n\u003e \n\u003e - Make sure you wrap all calls to Cyth functions with `cyth_try_catch` (see `cyth.h` for details).\n\u003e - Make sure you call `cyth_run` before calling functions obtained from `cyth_get_function`, otherwise global variables will be uninitialized.\n\u003e\n\n## Generics\nYou can declare generic [functions](#functions-1) and [objects](#objects-1). Generics use duck typing and work similarly to [templates](https://en.wikipedia.org/wiki/Template_(C%2B%2B)), where a generic function or object is only created when it is first used, not when it is declared.\n\nAdditionally, generic types must always be explicitly provided. This may change in the future, but the current requirement exists for readability reasons; especially since, in many cases, you may not have access to an LSP when writing Cyth code.\n\n### Functions\n\nYou can declare a generic function like this:\n\n```cpp\nT myGenericFunction\u003cT\u003e(T a, T b)\n  return a + b\n\nint sum = myGenericFunction\u003cint\u003e(10, 20)\n```\n\n### Objects\n\nYou can declare a generic object like this:\n\n```cpp\nclass Object\u003cT\u003e\n  T myField\n\n  void __init__(T value)\n    myField = value\n\nObject\u003cint\u003e myObject = Object\u003cint\u003e(10)\n```\n\n## Overloading\n\nYou can overload functions based on their parameters, like this:\n\n```c++\nint myFunction(int a, int b)\n  return a + b\n\nint myFunction(int a, int b, int c)\n  return a + b + c\n\nmyFunction(10, 20, 30)\nmyFunction(10, 20)\n```\n\nAdditionally, you can overload generic functions, like this:\n\n```c++\nT myFunction\u003cT\u003e(T a, T b)\n  return a + b\n\nT myFunction\u003cT\u003e(T a, T b, T c)\n  return a + b + c\n\nmyFunction\u003cint\u003e(10, 20, 30)\nmyFunction\u003cfloat\u003e(10, 20)\n```\n\n## `if` statement\n\nYou can declare `if` statements, like this:\n\n```python\nbool condition\n\nif condition\n  # true\nelse if not condition\n  # else if\nelse\n  # false\n```\n\n## `while` loop\n\nYou can declare a `while` loop, like this:\n\n```python\nbool condition = true\n\nwhile condition\n  # while loop\n```\n\n## `for` loop\n\nYou can declare a C-style `for` loop, like this:\n\n```python\nfor int i = 0; i \u003c 10; i += 1\n  # for loops\n```\n\nYou can also declare a `for` each loop, like this:\n\n```python\nfor int number in [1, 2, 3]\n  # for each loop\n```\n\nThe index of the element is stored into an implicit `it` variable.\n\n## `break` statement\n\nYou can use `break` to immediately exit a loop:\n\n```python\nfor int i = 0; i \u003c 10; i += 1\n  # Exit when i == 5\n  if i == 5\n    break\n```\n\n## `continue` statement\n\nYou can use `continue` to immediately start the next iteration of a loop:\n\n```python\nfor int i = 0; i \u003c 10; i += 1\n  # Skip iteration when i == 5\n  if i == 5\n    continue\n```\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvldr%2Fcyth","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fvldr%2Fcyth","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvldr%2Fcyth/lists"}