{"id":31103605,"url":"https://github.com/acerx-amj/cll_interpreter","last_synced_at":"2025-09-17T02:10:04.156Z","repository":{"id":310039391,"uuid":"1038162554","full_name":"Acerx-AMJ/CLL_Interpreter","owner":"Acerx-AMJ","description":"Interpreter for CLL inspired by C++ and Python.","archived":false,"fork":false,"pushed_at":"2025-08-24T17:56:47.000Z","size":186,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-08-24T22:04:04.304Z","etag":null,"topics":["cpp17","interpreted-programming-language","interpreter","programming-language"],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Acerx-AMJ.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}},"created_at":"2025-08-14T18:10:01.000Z","updated_at":"2025-08-24T17:56:50.000Z","dependencies_parsed_at":"2025-08-16T12:21:07.755Z","dependency_job_id":null,"html_url":"https://github.com/Acerx-AMJ/CLL_Interpreter","commit_stats":null,"previous_names":["acerx-amj/cll_interpreter"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/Acerx-AMJ/CLL_Interpreter","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Acerx-AMJ%2FCLL_Interpreter","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Acerx-AMJ%2FCLL_Interpreter/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Acerx-AMJ%2FCLL_Interpreter/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Acerx-AMJ%2FCLL_Interpreter/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Acerx-AMJ","download_url":"https://codeload.github.com/Acerx-AMJ/CLL_Interpreter/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Acerx-AMJ%2FCLL_Interpreter/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":275521497,"owners_count":25479612,"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","status":"online","status_checked_at":"2025-09-17T02:00:09.119Z","response_time":84,"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":["cpp17","interpreted-programming-language","interpreter","programming-language"],"created_at":"2025-09-17T02:10:01.997Z","updated_at":"2025-09-17T02:10:04.144Z","avatar_url":"https://github.com/Acerx-AMJ.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"# CLL\nCLL is a high-level interpreted language inspired by Python and C++ made to be comfortable and easy to use.\n### ToC\n- [Compiling](#compiling)\n- - [CMake](#build-with-cmake)\n- - [Clang](#build-with-clang)\n- - [GCC](#build-with-gcc)\n- [Usage](#usage)\n- [Features](#features)\n- - [Comments](#comments)\n- - [Numbers](#numbers)\n- - [Strings](#strings)\n- - [Characters](#characters)\n- - [Booleans](#booleans)\n- - [Null](#null)\n- - [Operators](#supported-operators)\n- - [Operator Precedence](#operator-precedence)\n- - [Standard Functions](#built-in-functions)\n- - [Calling Functions](#calling-functions)\n- - [Variables](#variable-declaration)\n- - [Constants](#constant-declaration)\n- - [Shadowing](#variable-shadowing)\n- - [Assignment](#assignment)\n- - [Scope](#scopes)\n- - [Delete Statements](#delete-statements)\n- - [Exists Statements](#exists-statements)\n- - [Do Statements](#do-statements)\n- - [If Statements](#if-statements)\n- - [While Loop](#while-loop)\n- - [For Loop](#for-loop)\n- - [Break, Continue \u0026 Return](#break-continue--return)\n- - [Unless Statement](#unless)\n- - [Escape Codes](#escape-codes)\n## Compiling\nCLL uses no dependencies and is easy to build.\n#### Build with CMake\n```bash\nmkdir build  # Create the build directory\ncmake -B build  # Create build files\ncmake --build build  # Build CLL interpreter. Executable 'cll' can be found in the build folder\n```\n#### Build with Clang\n```bash\nclang++ -Iinclude src/*.cpp -o cll\n```\n#### Build with GCC\n```bash\ng++ -Iinclude src/*.cpp -o cll\n```\n## Usage\nCLL interpreter expects a single argument. It currently has no help support.\n```bash\ncll [CODE]\n```\nTo run code directly:\n```bash\ncll 'println(\"Hello, World!\")'\n```\nTo read a file and run the contents:\n```bash\ncll file.cll\n```\n## Features\n#### Comments\nCLL uses C-style comments:\n```cxx\n// This is a single-line comment\n/*\n   This is a\n   multi-line\n   comment\n*/\n```\n#### Numbers\nNumber type includes any number, both integral and floating:\n```cxx\nlet x, y, z = 29, 6.12, -2.29\n```\nCLL supports scientific notation:\n```cxx\nlet s1, s2 = 1.125e3, 188E-4\n```\n#### Strings\nStrings can be defined with `\"` quotes:\n```cxx\nlet name = \"John\"\n```\nSome [escape codes](#escape-codes) are supported:\n```cxx\nprint(\"This is \\\"CLL\\\".\\n\")\n// Outputs:\n// This is \"CLL\".\n```\n#### Characters\nCharacters can be defined with `'` quotes. A character must be one character or one escape code large:\n```cxx\nlet c1, c2 = 'a', '\\n'\n```\nJust like strings, characters support [escape codes](#escape-codes).\n#### Booleans\nBooleans are either true or false. Use `true` constant to represent a true boolean and `false` to represent a false boolean:\n```cxx\nlet x, y = true, false\n```\n#### Null\nNull values do not represent a value. Statements like variable declaration, delete statements, etc. always return a null value. Values operating with null will turn to null. Null values can be defined using `null` constant:\n```cxx\nlet x = null\n```\n#### Supported operators\nUnary:\n- `-a` - negate `a`.\n- `+a` - do nothing.\n- `a--` - decrement `a` (only right side).\n- `a++` - increment `a` (only right side).\n- `!a` - if `a` is true, return false, else true. Same as `not` operator.\n\nBinary:\n- `a + b` - add `a` to `b`. If one or both of the values is a string, concatenate it and return string.\n- `a - b` - subtract `a` by `b`.\n- `a * b` - multiply `a` by `b`. If one value is a number (this includes characters and booleans) and other a string, then return a string that is repeated n amount of times.\n- `a / b` - divide `a` by `b`.\n- `a % b` - divide `a` by `b` and return remainder (works with real numbers: `2.50 % 2 -\u003e 0.50`).\n- `a ** b` - exponentiate `a` to the power of `b`.\n- `a \u0026\u0026 b` - if `a` and `b` are true, return true, else false. Skips evaluating `b` if `a` is false. Same as `and` operator.\n- `a || b` - if either `a` or `b` is true, return true, else false. Skips evaluating `b` is `a` is true. Same as `or` operator.\n- `a %% b` - if `a` is divisible by `b`, return true, else false.\n- `a ?? b` - if `a` is true, return `b`, else null.\n- `a == b` - if `a` is equal to `b`, return true, else false.\n- `a === b` - if `a` is equal to `b` and is the same type, return true, else false.\n- `a != b` - if `a` is not equal to `b`, return true, else false.\n- `a !== b` - if `a` is not equal to `b` or is not the same type, return true, else false.\n- `a \u003e b` - if `a` is greater than `b`, return true, else false.\n- `a \u003e= b` - if `a` is greater than or equal to `b`, return true, else false.\n- `a \u003c b` - if `a` is smaller than `b`, return true, else false.\n- `a \u003c= b` - if `a` is smaller than or equal to `b`, return true, else false.\n\nTernary:\n- `a ? b : c` - if a is true, return b, else c\n\nAssignment:\n- `a = b` - assign `b` to `a`.\n- `a += b` - add `a` to `b` and assign the result.\n- `a -= b` - subtract `a` by `b` and assign the result.\n- `a *= b` - multiply `a` by `b` and assign the result.\n- `a /= b` - divide `a` by `b` and assign the result.\n- `a %= b` - divide `a` by `b` and assign the remainder.\n- `a **= b` - exponentiate `a` to the power of `b` and assign the result.\n\nParentheses (`()`) can change operator precedence as follows:\n```cxx\n(2 + 2) * 3  // -\u003e 12\n2 + 2 * 3  // -\u003e 8 \n```\n#### Operator precedence\nThe following table lists precedence and associativity of operators and expressions.\n|Precedence|Expression|Description|Associativity|\n|-|-|-|-|\n|1|`identifier`, `number`, `character`, `string`, `()`, `{}`, `variable declaration`, `delete statement`|Primary expressions, parentheses, scopes, statements.|Single|\n|2|`a, b, c`|Argument list expression.|Single|\n|3|`a(b, c)`|Call expression.|Single|\n|4|`a--`, `a++`|Increment, decrement.|Single|\n|5|`-a`, `+a`, `!a`|Unary minus and plus, logical not.|Right-to-left|\n|6|`a ** b`|Exponentiation.|Right-to-left|\n|7|`a * b`, `a / b`, `a % b`|Multiplication, division, remainder.|Left-to-right|\n|8|`a + b`, `a - b`|Addition, subtraction.|Left-to-right|\n|9|`a \u003e b`, `a \u003e= b`, `a \u003c b`, `a \u003c= b`|Relation operators.|Left-to-right|\n|10|`a == b`, `a === b`, `a != b`, `a !== b`, `a %% b`|Equality operators and divisible operator.|Left-to-right|\n|11|`a \u0026\u0026 b`|Logical and.|Left-to-right|\n|12|`a \\|\\| b`|Logical or.|Left-to-right|\n|13|`a = b`, `a += b`, `a -= b`, `a *= b`, `a /= b`, `a %= b`, `a **= b`|Assignment and compound assignment.|Left-to-right|\n|14|`a ?? b`|Binary condition.|Right-to-left|\n|15|`a ? b : c`|Ternary condition.|Right-to-left|\n\nLeft-to-right and right-to-left associativity shows in which direction expressions get parsed. Single means that expressions cannot be chained.\n#### Built-in functions\nThe following table lists all built-in functions and their expected arguments and return values.\n|Function|Arguments|Return|Description|\n|-|-|-|-|\n|`print`|(...)|`Null`|Print all arguments separated by a space.|\n|`println`|(...)|`Null`|Print all arguments separated by a space and print a newline at the end.|\n|`printf`|(`String`, ...)|`Null`|Format the string using other arguments and print it (e.g. `print(\"Hello, {}!\", \"World\")` -\u003e `Hello, World!`).|\n|`printfln`|(`String`, ...)|`Null`|Format the string using other arguments and print it, and print a newline.|\n|`format`|(`String`, ...)|`String`|Format the string using other arguments and return the result.|\n|`raise`|(`String`, ...)|`No Return`|Format the string using other arguments and raise an error at the line of the call.|\n|`assert`|(`Boolean`, `String`)|`Null`|If boolean is true, throw an error at the line of the call with the given error.|\n|`throw`|(`String`, `Number`)|`No Return`|Both arguments are optional. Throw an error at no line with the given exit code.|\n|`exit`|(`Number`)|`No Return`|Argument is optional. Exit the program with the given exit code.|\n|`input`|(`Any`)|`String`|Print argument (if any) and return user's input as string.|\n|`inputnum`|(`Any`)|`Number`|Print argument (if any) and return user's input as number.|\n|`inputch`|(`Any`)|`Character`|Print argument (if any) and return user's input as a single character.|\n|`string`|(`Any`)|`String`|Convert argument to string, or return empty string if no arguments.|\n|`number`|(`Any`)|`Number`|Convert argument to number, or return 0 if no arguments.|\n|`char`|(`Any`)|`Character`|Convert argument to character, or return 0 if no arguments.|\n|`bool`|(`Any`)|`Boolean`|Convert argument to boolean, or return false if no arguments.|\n#### Calling functions\nFunctions can be called using `()` operators like so:\n```cxx\nprintln()  // Print a newline\nprintln(35)  // Print '35'\nprintfln(\"Hello, {} {}!\", \"John\", \"Doe\")  // Print 'Hello, John Doe!'\n```\n#### Variable declaration\nAs could be seen before, variables can be declared in two ways. For a single variable:\n```cxx\nlet x = 1\nlet y = false\nlet x = \"Hello!\"\n```\nFor multiple variables at once:\n```cxx\nlet x, y, z = 1, false, \"Hello!\"\n```\nFor multiple variable declaration, it is important that identifier count is smaller than value count. Here's what happens with different counts:\n```cxx\nlet x = 1  // x is 1\nlet x, y = 1  // Both x and y are 1\nlet x, y = 1, 2  // x is 1 and y is 2\nlet x, y, z = 1, 2  // x is 1, y is 2 and z is null\nlet x, y, z  // All 3 values are null\n\nlet x, y = 1, 2, 3 // ERROR! Identifier count is smaller than value count\n```\n#### Constant declaration\nConstants can be declared the same way as variables, except constants cannot implicitly be defined null, here's the same example as before, using constants:\n```cxx\n// Do note that constants cannot be shadowed unlike variables, let's ignore that in this example\ncon x = 1  // x is 1\ncon x, y = 1  // Both x and y are 1\ncon x, y = 1, 2  // x is 1 and y is 2\ncon x, y, z = 1, 2  // ERROR: z would be null\ncon x, y, z  // ERROR: All 3 values would be null\ncon x, y, z = 1, 2, null  // x is 1, y is 2 and z is null. Explicit null constants are okay\n\ncon x, y = 1, 2, 3 // ERROR! Identifier count is smaller than value count\n```\n#### Variable shadowing\nVariables can be shadowed, whereas constants cannot:\n```cxx\nlet x = \"String\"\nprintln(x)  // -\u003e String\nlet x = 24\nprintln(x)  // -\u003e 24\n\ncon x = true  // We shadow x once again\nprintln(x)  // -\u003e true\ncon x = null  // ERROR: Cannot shadow constant\n```\n#### Assignment\nVariables can be assigned new values without the need for shadowing. Constants, again, cannot be assigned a new value:\n```cxx\nlet x = 23\nprintln(x)  // -\u003e 23\nprintln(x = 9)  // -\u003e 9\nprintln(x += 2)  // -\u003e 11\nprintln(x++)  // -\u003e 12\n\ncon y = 2\nprintln(y)  // -\u003e 2\ny = 3  // ERROR: Cannot assign to a constant\n```\nVariables can be incremented using `++` and decremented using `--`:\n```cxx\nlet x = 0\nprintln(x++)  // -\u003e 1\nprintln(x--)  // -\u003e 0\n```\nUnlike other binary and unary operators, `++` and `--` operators cannot be chained (e.g. `x-- --`), for that, there are the `+=` and `-=` operators.\n#### Scopes\nScopes can be defined using `{}` like so:\n```cxx\nlet x = 1\n{\n   let x = 2\n   println(x)  // -\u003e 2\n   // Global scope: x = 1, local scope: x = 2, local takes precedence\n}\nprintln(x)  // -\u003e 1\n// Global scope: x = 1, no local scopes, using global\n```\nScopes return last value or null, if it's a statement:\n```cxx\nlet z = {\n   let x, y = 1, 2\n   x + y\n}\n// x and y are no longer defined here\nprintln(z)  // -\u003e 3\n```\n#### Delete statements\nVariables can be deleted early using `delete` keyword. Constants cannot be deleted.\n```cxx\nlet x, y, z = 1, 2, x + y\ndelete x, y\n// x and y do not exist anymore, while z is fine to use\nprintln(z)\n```\n#### Exists statements\nIt is possible to check if a variable exists using `exists` keyword. It returns true if the given variable exists, false otherwise.\n```cxx\nlet x\nprintln(exists x, exists y)  // -\u003e true false\ndelete x\n\nlet y\n{\n   let z\n}\nprintln(exists x, exists y, exists z)  // -\u003e false true false\n```\nNote that the following code is valid and may be more readable to some:\n```cxx\nprintln(exists(x), exists(y))\n```\n#### Do statements\nDo statements simply execute a single statement after them. They might seem useless, but are really useful in `unless`, `if`, `while`, etc. statements that are covered later on.\n```cxx\nlet x = 10\ndo x = 20\nprintln(x)  // -\u003e 20\n\ndo {\n   let y = 20\n   x += y\n}\nprintln(x)  // -\u003e 40\n```\nDo note that even if a new scope is not defined, `do` statements create a new scope:\n```cxx\ndo let x = 20\nprintln(exists x)  // -\u003e false\n```\nAlso note that `do` statements that do not execute a scope can only execute a single statement:\n```cxx\ndo let y = 0 println(y)  // ERROR: Y is not defined in the give scope \n```\n#### If statements\nIf statements use the following syntax:\n```cxx\nif condition {\n   statements\n} elif condition {\n   statements\n} elif condition {\n   statements\n} else {\n   statements\n}\n```\nAn if statement can have a single if clause, infinite optional elif clauses and a single optional else clause. If statements cannot start with elif clauses or else clauses. If condition is false, program will check the next clause until a condition is true, or until it checks everything. In the case that every condition is false and an else clause is present, it will be executed.\n\nThis is where `do` statements come in handy:\n```cxx\nlet x, y = true, false\nif x \u0026\u0026 y do\n   println(\"Both X and Y are true!\")\nelif x do\n   println(\"Only X is true!\")\nelif y do\n   println(\"Only Y is true!\")\nelse do\n   println(\"None are true!\")\n```\nDo not that the following code is valid:\n```cxx\nif true do {\n   println(\"True!\")\n}\n```\nAnd that the following is not valid:\n```cxx\nif true do\n   println(\"True!\")\n   println(\"True!\")\n```\n#### While loop\nWhile loop statement follows this syntax:\n```cxx\nwhile condition {\n\n}\n```\nWhile loop will keep executing statements until condition is false. Just like in if statements, `do` keyword can be used here:\n```cxx\nlet i = 10\nwhile i-- \u003e 0 do\n   println(i)\n```\nTo create an infinite loop, the condition can be left out:\n```cxx\nwhile {\n\n}\n```\n#### For loop\nFor loops use the following syntax:\n```cxx\nfor stmt; condition; stmt {\n\n}\n```\nFirst statement will be executed on loop creation, condition is checked at the beginning of the loop and the second statement is executed at the end of the loop. The following code prints numbers 1-10 including:\n```cxx\nfor let i = 1; i \u003c= 10; i++ do\n   println(i)\n```\nThe three statements inside the for loop declaration and the scope after the for loop use the same scope.\n\nStatements and the condition can be left out, but the semicolons must stay, so the program knows which statement is which.\n```cxx\nlet i = 1\nfor ; i \u003c= 10; do\n   println(i++)\n```\nInfinite loop can be created like so:\n```cxx\nfor ;; {\n\n}\n// Semicolons are fine to ommit in this case\nfor {\n\n}\n```\n#### Break, continue \u0026 return\nIt is possible to break out of a loop using `break` keyword:\n```cxx\nwhile {\n   // Get user input\n   let ch = inputch()\n\n   if ch == 'y' do\n      break\n}\nprintln(\"Broke!\")\n```\nBreak statements, of course, only break out of the current loop they are in:\n```cxx\nfor let i = 0;; i++ {\n   for let j = 0;; j++ {\n      print(i, j, ' ')\n      if j == 5 do\n         break\n   }\n\n   println()\n   if i == 5 do\n      break\n}\n```\nA single iteration of a loop can be skipped using the `continue` keyword:\n```cxx\nfor let i = 0; i \u003c 100; i++ {\n   if i %% 2 do\n      continue\n   println(i)\n}\n```\nContinue statements also only target the most recent loop. Both statements ignore any other scopes than loops.\n\nValues can be returned early from scopes using the `return` keyword:\n```cxx\nlet x = {\n   return 10\n   println(\"This will not print!\")\n}\nprintfln(\"X is {}.\", x)\n```\nCurrently, return statements only return to the latest scope, so they don't work under if statements. For that, there is the `unless` statement.\n\nReturn statements must return something, if no value should be returned, null must be used:\n```cxx\nreturn null\n```\n#### Unless\nDo, break, continue, return, delete, for, while and if statements can be ignored based on a condition with the `unless` keyword:\n```cxx\ndo statement unless condition\nbreak unless condition\ncontinue unless condition\nreturn value unless condition\ndelete identifier unless condition\n\nfor stmt1; condition; stmt2 {\n\n} unless condition\n\nwhile condition {\n\n} unless condition\n\nif condition {\n\n} elif condition {\n\n} else condition {\n\n} unless condition\n```\nIn the case that condition is false, the whole statement is skipped. Try running this and then changing x to false:\n```cxx\nlet y = inputnum()\nlet x = true\n\nif y == 0 do\n   println(\"y is zero\")\nelif y \u003e 0 do\n   println(\"y is positive\")\nelse do\n   println(\"y is negative\")\nunless x\n```\n#### Escape codes\nSupported escape codes:\n- `\\a` - Terminal bell.\n- `\\b` - Backspace.\n- `\\t` - Horizontal tab.\n- `\\n` - Newline.\n- `\\v` - Vertical tab.\n- `\\f` - Formfeed.\n- `\\r` - Carriage return.\n- `\\e` - Escape.\n- `\\\\` - Escape backslash.\n- `\\'` - Escape single quote.\n- `\\\"` - Escape double quotes.\n\nColors can be added by using the `Escape` escape code as follows (note that Windows may not support this):\n- `\\e[30m` - Black color. \n- `\\e[31m` - Red color.\n- `\\e[32m` - Green color.\n- `\\e[33m` - Yellow color.\n- `\\e[34m` - Blue color.\n- `\\e[35m` - Magenta color.\n- `\\e[36m` - Cyan color.\n- `\\e[37m` - White color.\n- `\\e[39m` - Default color (reset only the color).\n- `\\e[0m` - Reset (reset all color and text effects).\n\nExample:\n```cxx\nprintln(\"\\e[31m This is red text! \\e[0m\")\nprintln(\"\\e[32m This is green text! \\e[0m\")\nprintln(\"\\e[34m This is blue text! \\e[0m\")\n```\nThere's a lot more that can be done using the `Escape` escape code. [This](https://gist.github.com/ConnerWill/d4b6c776b509add763e17f9f113fd25b) is a good reference on escape codes.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Facerx-amj%2Fcll_interpreter","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Facerx-amj%2Fcll_interpreter","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Facerx-amj%2Fcll_interpreter/lists"}