{"id":21719655,"url":"https://github.com/laputanmachines/simple-script","last_synced_at":"2025-04-12T20:35:16.308Z","repository":{"id":45750232,"uuid":"248614821","full_name":"LaputanMachines/simple-script","owner":"LaputanMachines","description":"An interpreted, BASIC-like programming language. The language is built with Python. Project was built as a proof-of-concept language but has since been used for data processing at home.","archived":false,"fork":false,"pushed_at":"2022-07-15T18:52:35.000Z","size":119,"stargazers_count":6,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-03-26T14:55:42.278Z","etag":null,"topics":["basic-programming","interpreted-programming-language","interpreter","lexer-parser","lexical-analysis","programming-language"],"latest_commit_sha":null,"homepage":"https://simplescript.bassi.li","language":"Python","has_issues":false,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/LaputanMachines.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null},"funding":{"github":null,"patreon":null,"open_collective":null,"ko_fi":"michaelbassili","tidelift":null,"community_bridge":null,"liberapay":null,"issuehunt":null,"otechie":null,"lfx_crowdfunding":null,"custom":null}},"created_at":"2020-03-19T22:09:48.000Z","updated_at":"2025-02-12T09:49:16.000Z","dependencies_parsed_at":"2022-08-31T07:00:38.908Z","dependency_job_id":null,"html_url":"https://github.com/LaputanMachines/simple-script","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LaputanMachines%2Fsimple-script","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LaputanMachines%2Fsimple-script/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LaputanMachines%2Fsimple-script/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LaputanMachines%2Fsimple-script/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/LaputanMachines","download_url":"https://codeload.github.com/LaputanMachines/simple-script/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248631208,"owners_count":21136549,"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":["basic-programming","interpreted-programming-language","interpreter","lexer-parser","lexical-analysis","programming-language"],"created_at":"2024-11-26T01:39:13.687Z","updated_at":"2025-04-12T20:35:16.285Z","avatar_url":"https://github.com/LaputanMachines.png","language":"Python","readme":"# Documentation\n\nSimpleScript is an interpreted, BACIC-like programming language built with Python. It is small, clean, and powerful. \nThe language itself is straightforward and allows for cleaner-looking mathematical operations and data processing.\nThe SimpleScript language can he used in two ways: through direct commands in the interactive shell, and by executing complete programs. You can read more about both execution methods below. \n\n## Installation\n\nEnsure Python 3 is installed on your system. SimpleScript does not use any external libraries.\nThis makes it entirely portable since it does not require the installation of any third-party libraries. **TL;DR: all you need is Python 3 installed on your system.** Nothing else is needed to write and execute SimpleScript programs.\n\n## How To Use\n\nYou can use Python to launch the interactive shell. This will allow you to play with the SimpleSCript language in your terminal. You can use the shell to test expressions. \nIn your BASH terminal, run the `shell.py` script using Python. \n\n```BASH\n$ python shell.py \n```\n\nYou can run programs using the `RUN` builtin function in the interactive shell. \n**There is no file extension defined for SimpleScript.** Feel free to name your file anything.\nThe interpreter will attempt to run _all_ files executed, regardless of extension. \n\n```BASH\n$ python shell.py\n$ RUN (\"my_program.simple\") \n```\n\nBy default, error messages are not displayed. To toggle the visibility of error messages, use the `debug` command.\nThis will allow all error messages to be printed after any interpretation. This is handy for improving the language itself. It's also handy to see smaller syntax and execution errors that the interpreter may have encountered.\nThe reason it's not enabled by default is that one of the principles of SimpleScript is to rarely stop you dead in your tracks. Error handling measures have been built to inform-if-needed, otherwise it will attempt to sally forth.\n\n```BASIC\n$ DEBUG\n```\n\nTo exit the interactive shell, simply use the `exit` keyword. This will terminate your program and perform garbage collection.\nYou'll be dumped back into the BASH terminal you launched from. \n\n```BASIC\n$ EXIT\n```\n\nMore specifically, garbage collection of the variables and functions you created and used will occur. All system variables and functions will return to their original state.\nThis means that if you overrode the system variable `FALSE` to the value `10`, for example, that it would be restored back to its default value of `0`.\n\n## Example Program\n\nHere is a small example program written in SimpleScript. It uses some of the language's features including loops, functions, and variables.\nSimpleScript is Turing-complete; the language is simple to use yet robust enough to handle whatever you throw at it.\n\n```BASIC\n############################################\n# Sample SimpleScript Program\t\t   #\n# [bash]$ python3 shell.py\t\t   #\n# [SimpleScript]$ RUN(\"my_program.simple\") #\n############################################\n\n# Function to prepends a prefix to the word\nFUNC function(prefix) -\u003e prefix + \"SimpleScript\"\n\n# Join function for elements\nFUNC join(elements, separator)\n\tVAR result = \"\"\n\tVAR len = LEN(elements)\n\tFOR i = 0 TO len THEN\n\t\tVAR result = result + elements/i\n\t\tIF i != len - 1 THEN VAR result = result + separator\n\tEND\n\tRETURN result\nEND\n\n# Maps elements to a function\nFUNC map(elements, func)\n\tVAR new_elements = []\n\tFOR i = 0 TO LEN(elements) THEN\n\t\tAPPEND(new_elements, func(elements/i))\n\tEND\n\tRETURN new_elements\nEND\n\n# Print using builtin function\nPRINT(\"Greetings universe!\")\n\n# Loop example snippet\nFOR i = 0 TO 5 THEN\n\tPRINT(join(map([\"l\", \"sp\"], function), \", \"))\nEND\n```\n\nFor more detailed documentation, you can continue below. Every feature of SimpleScript is outlined in the documentation.\nIf you encounter any issues, or feel like the language is missing something, you can [contribute to the project on GitHub](https://github.com/FlatlanderWoman/SimpleScript).\nHappy coding!\n\n---\n\n## Special Variables\n\nThe following special variables have set values in the language. However, they _can_ be remapped in your program. This is by design and allows your program to define its own basic terms and concepts.\n\n| Variable | SimpleScript Variable | Value | Use |\n| --- | --- | --- | --- |\n| Null/NaN | `NULL` | 0 | Represents an empty value |\n| Logical True | `TRUE` | 1 | Represents a True Boolean | \n| Logical False | `FALSE` | 0 | Represents a False Boolean | \n\nNote that since these values are stored in a symbol table, you can also define `true` as your own version of `TRUE`; the values of `TRUE` and `true` can be different if you want. SimpleScript will never tell you that you shouldn't reassign these special variables. Configure your program as you'd like.\n\n## Builtin Functions\n\nThere are many builtin functions in SimpleScript. You can, of course, write your own. \nBut these can be quite useful. You can chain together many functions into much larger compound functions that include both user-defined and builtin functions.\nYou can also redefine builtin functions on a per-program basis; your changes will not be saved to the interpreter. \n\n| Function Name | SimpleScript Command | Description | Example |\n| --- | --- | --- | --- |\n| Run | `RUN` | Runs a program | `RUN(\"my_program.simple\")` |\n| Print | `PRINT` | Prints strings of text | `PRINT(\"This is a string\")` |\n| Print Return | `PRINT_RET` | Returns a String instance of the input value | `PRINT_RET(123)` |\n| Input | `INPUT` |Accepts input from the stream | `INPUT()` |\n| Input Int | `INPUT_INT` | Accepts integer input from the stream | `INPUT_INT()` |\n| Clear | `CLEAR`, `CLS` | Clears the terminal screen | `CLEAR()`, `CLS()` |\n| Is Number | `IS_NUM` | Return `TRUE` if argument is a number | `IS_NUM(123)` |\n| Is String | `IS_STR` | Returns `TRUE` if argument is a string | `IS_STR(\"This is a string\")` |\n| Is List | `IS_LIST` | Returns `TRUE` if argument is a list | `IS_LIST([1, 2, 3])` |\n| Is Function | `IS_FUNC` | Returns `TRUE` if argument is a function | `IS_FUNC(PRINT)` |\n| Append | `APPEND` | Append value to a list | `APPEND(list, 5)` |\n| Pop | `POP` | Remove an element from a list by index | `POP(list, 3)` |\n| Extend | `EXTEND` | Concatenate two lists together | `EXTEND(list_a, list_b)` | \n\nE.g. if you set `PRINT` to add two numbers instead of printing strings, that change will only take effect in your current program. \nThe next time you run a SimpleScript program, `PRINT` will default back to printing strings.\n\n## Supported Math Operators\n\nHere is a table including all supported mathematical operations in SimpleScript. Most are similar to Python or BASIC's implementations, but I've made some small changes which hopefully improve the look and feel of larger mathematical expressions.\n\n| Operation | SimpleScript Command | Description | Notes |\n|---|---|---|---|\n| Addition | `+` | Performs addition |  |\n| Subtraction | `-` | Performs subtraction |  |\n| Multiplication | `*` | Performs multiplication |  |\n| Division | `/` | Performs typical floating division | Cannot divide by 0 |\n| Integer Division | `\\|` | Performs division using integers | Cannot divide by 0 |\n| Power | `^` | Raises expression to a power | Supports negative powers |\n| Modulo | `%` | Returns remainder of division |  |\n\nAll these operations can be performed on both numeric values and sub-expressions, including variables. Variables are executed before any other numeric operation, so you can actually assign variables _while performing numeric operations_ on other values. \n\n## Examples Of Math Operations\n\nBasic arithmetic operations can be performed directly on numbers, variables, and other values. Mathematical operations all return their associated value. Anytime a floating point operation is introduced, the data type returned will be a float. \n\n```BASIC\n$ (2 + 1) | (4 - 1)\n1\n```\n\n```BASIC\n$ 10 % 5\n 0\n```\n\n```BASIC\n$ 1 + 2 - 3 * 4 / 5\n0.6000000000000001\n```\n\n```BASIC\n$ ((1 + 2) * 3 ^ 2) / 2\n13.5\n```\n\n```BASIC\n$ 10 | 2 + (8 ^ 2) - 6\n63\n```\n\nAs you'd expect, division by zero is not allowed. If you try, the interpreter will inform you that the operation you're trying to execute is invalid. It will even highlight the error in your file. Negative powers are valid operations that will evaluate to the same result as would a similar BASIC operation.\n\n```BASIC\n$ 12345 / 0\n\nTraceback (most recent call last):\nFile \u003cstdin\u003e, line 1, in \u003cprogram\u003e\nFile \u003cstdin\u003e, on line 1\n12345 / 0\n        ^\n```\n\n```BASIC\n$ 98765 / (4 - 5 + 1)\n\nTraceback (most recent call last):\nFile \u003cstdin\u003e, line 1, in \u003cprogram\u003e\nFile \u003cstdin\u003e, on line 1\n98765 / (4 - 5 + 1)\n         ^^^^^^^^^\n```\n\nOperations that eventually evaluate into zero are also not allowed, as seen in the above example. In this case, the entire sub-expression is highlighted by the interpreter. This hopefully provides enough tracing and error information to fix the issue in your program. The stack trace will always be displayed in error messages.e,\" there is a great deal that can be improved upon. I, for one, am less-than-satisfied with much of the variable and function mechanisms of SimpleScript.\n\n## Variables\n\nVariables can be declared by using the `VAR` keyword. Variable names can include letters and underscores in their name. Variables can be re-assigned without restriction. Variables are stored in a symbol table, so they can be mutated and altered throughout execution.\n\n```BASIC\n$ VAR my_variable = 12345\n12345\n$ my_variable\n12345\n```\n\n```BASIC\n$ VAR my_other_variable = 67890\n67890\n$ my_other_variable\n67890\n```\n\n```BASIC\n$ VAR addition = my_variable + my_other_variable\n80235\n$ addition\n80235\n```\n\nAlso, variables can be assigned _in the middle of expressions_ which may seem odd to those used to assigning variables before use. However, this can allow one to spawn helper variables in context to one statement instead of having to add to the parent's scope.\n\n```BASIC\n$ VAR x = 10 + (VAR y = 5)   \n15\n$ y\n5\n```\n\nThis kind of inline assignment is thanks to the interpretation of the abstract syntax tree (AST). Instead of searching line-by-line for variables to be assigned, SimpleScript simply treats the `VAR` keyword like a token that triggers the parsing of its sub-tree. In short, SimpleScript considers `VAR` definitions a higher priority than brackets in the BEDMAS order of operations.\n\n## Lists\n\nSimpleScript allows for lists to be defined. They are immutable, unlike Python lists. \nYou can define a list, add elements to a list, remove elements from a list, and join two lists together.\nSince lists are immutable, you'll need to leverage list joins and value extraction to obtain your resulting list. \n\n```BASIC\n$ VAR list = [1, 2, 3, 4, 5]\n[1, 2, 3, 4, 5]\n```\n\n```BASIC \n$ VAR list = [1, 2, 3]\n[1, 2, 3]\nlist + [4, 5]\n[1, 2, 3, 4, 5]\n```\n\n```BASIC\n$ VAR list = [1, 2, 3, 4, 5]\n[1, 2, 3, 4, 5]\n$ VAR other_list = [6, 7, 8, 9, 0]\n[6, 7, 8, 9, 0]\n$ list * other_list\n[1, 2, 3, 4, 5, 6, 7, 8, 9, 0]\n```\n\n```BASIC\n$ VAR list = [1, 2, 3, 4, 5]\n[1, 2, 3, 4, 5]\n$ list - 1\n[1, 3, 4, 5]\n$ list - 0\n[3, 4, 5]\n$ list - (-1)\n[3, 4]\n```\n\nYou can get elements by-index in lists using the `/` operator. You can also use negative index values to fetch values from the ends of arrays. \nAs always, you can chain expressions together. For example, you can evaluate an expression that results in an index for the list. \n\n```BASIC\n$ [1, 2, 3, 4, 5] / 0\n1\n```\n\n```BASIC\n$ VAR list = [1, 2, 3, 4, 5]\n[1, 2, 3, 4, 5]\n$ list / -1\n5\n```\n\nLists are useful in performing computations on data. For example, images can be expressed as arrays of integers. \nUsing SimpleScript, you can use this list representation to perform computations on the image by interacting with its respective list.\n\n## Strings\n\nStrings are essentially just lists of individual characters. In SimpleScript, you can define and operate on strings the same way you would in BASIC. \nYou can concatenate two or more strings together, and you can repeat strings by multiplying it with a number.\n\n```BASIC\n$ \"This is a string!\"\nThis is a string!\n```\n\n```BASIC\n$ \"I can start here, \" + \"and end here!\"\nI can start here, and end here!\n```\n\n```BASIC\n$ \"Echo! \" * 5\nEcho! Echo! Echo! Echo! Echo! \n```\n\n```BASIC\n$ FUNC welcome (name, repeat) -\u003e \"Welcome, \" * repeat + name\n\u003cfunction welcome\u003e\n$ welcome (\"Michael\", 5)\nWelcome, Welcome, Welcome, Welcome, Welcome, Michael\n```\n\nYou can set variables to equal strings and you can also write anonymous functions which perform actions on strings.\n\n## Supported Comparison Operators\n\nThe following comparison operators are supported in SimpleScript. They can be used in addition to variable assignment and function executions. This is due to how the interpreter understands the ASTs being generated. The result is that you can chain together long and complex comparisons without needing to stop to define anything.\n\n| Operator | SimpleScript Command | Description |\n| --- | --- | --- |\n| Exactly Equals | `==` | Evaluates to TRUE if both sides are equal |\n| Not Equals | `!=` | Evaluates to TRUE if both sides are not equal |\n| Less Than | `\u003c` | Evaluates to TRUE if the left side is smaller than the right side |\n| Greater Than | `\u003e` | Evaluates to TRUE if the left side is larger than the right side |\n| Less Than Or Equals To | `\u003c=` | Evaluates to TRUE if the left side is smaller or equal to the right side |\n| Greater Than Or Equals To | `\u003e=` | Evaluates to TRUE if the left side is larger or equal to the right side |\n\nThese operators are the same as BASIC or Python's operators, so their syntax should hopefully be familiar to some. Comparisons between 1 and 0 can be interpreted as comparisons between TRUE and FALSE respectively.\n\n## Supported Logical Operators\n\nNo language would be complete without logical operators. These operate the same way as logic gates do. All of AND, OR, and NOT operate in the same way they do in regular BASIC and Python.\n\n| Operator | SimpleScript Command | Description | Notes |\n| --- | --- | --- | --- | \n| Logical AND | `AND` | Evaluates to TRUE if both sizes are TRUE |  |\n| Logical OR | `OR` | Evaluates to TRUE if at least one side is TRUE |  |\n| Negation | `NOT` | Evaluates to the opposite Boolean value of the expression | TRUE becomes FALSE, and vice-versa |\n\nThese can be chained into variable definitions and other assignments and function declarations to evaluate the truth values of abstract statements. The underlying ASTs of these operations are built in such a way to be able to handle applications on abstract entities; you can apply these logical operators to any expression.\n\n## Supported Control Flow Operators\n\nSimpleScript allows you to add break, continue, return, and end commands in your loops and functions.\nThey all work the same way they do in BASIC and Python. Here is a table describing each control flow operator.\n\n| Statement | SimpleScript Command | Description |\n| --- | --- | --- |\n| Return | `RETURN` | Tells the function to return something |\n| Break | `BREAK` | Breaks out of loops |\n| Continue | `CONTINUE` | Continues (skips) to next iteration in loop |\n| END | `END` | Delimit the end of a function or loop |\n\nYou can add these control flow statements into your loops and functions the same way you would in BASIC or Python.\nPlease read the relevant documentation section for examples.\n\n## If-Statements\n\nYou can make if-statements by using the `IF`, `ELSE`, and `ELIF` keywords. Pairing this with logical or comparison operators can allow for dynamic variable assignment.\n\n```BASIC\n$ IF TRUE THEN 123\n123\n```\n\n```BASIC\n$ IF (1 + 2) \u003c= (3 + 4) THEN TRUE\n1\n```\n\n```BASIC\n$ IF 1 != 1 THEN 100 \n$ IF 1 != 1 THEN 100 ELSE 999\n999\n```\n\n```BASIC\n$ IF TRUE == 0 THEN (VAR x = 9) ELIF TRUE == 1 THEN (VAR x = 5) ELSE (VAR x = 0)\n5\n```\n\n```BASIC\n$ IF (10 - 5) == 5 THEN (VAR x = TRUE) ELSE (VAR x = FALSE)\n1\n$ x\n1\n```\n\nThese control flow operations also allow for the inline assignment of variables, as seen above. In the case that no value is assigned (e.g. `IF 0 THEN 123`), then no value is outputted.\n\n## For-Loops\n\nFor-loops are control flows that execute a set number of times before terminating. For-loops are great for iteration and compounding operations.\nSimpleScript follows the BASIC model of for-loops, where a loop condition are defined and a body expression is grouped up and executed. More simply, SimpleScript for-loops are formatted like for-loops in C.\n\n```BASIC\n$ FOR i = 1 TO 10 THEN 2 ^ i\n[2, 4, 8, 16, 32, 64, 128, 256, 512]\n```\n\n```BASIC\n$ VAR x = 1\n1\n$ FOR i = 1 TO 5 THEN VAR x = x + i\n[2, 4, 7, 11]\n$ x\n11\n```\n\n```BASIC\n$ VAR y = 100\n100\n$ FOR i = 100 TO 0 STEP -1 THEN VAR y = y - i\n[0, -99, ... -4949, -4950]\n$ y\n-4950\n```\n\n```BASIC\n$ VAR z = 1  \n1\n$ IF 10 == (20 - 10) THEN FOR i = 0 TO 10 THEN VAR z = z + i\n[1, 2, 4, 7, 11, 16, 22, 29, 37, 46]\n$ z\n46\n```\n\nYou can take advantage of `BREAK` and `CONTINUE` commands to control the flow of your loops.\nAs you can see from the following example, we can chain together multi-line for-loops that execute different control flow commands on certain values of `i`.\n\n```BASIC\n$ VAR a = []\n[]\n$ FOR i = 0 TO 10 THEN; IF i == 4 THEN CONTINUE ELIF i == 8 THEN BREAK; VAR a = a + i; END\n[0]\n$ a\n[0, 1, 2, 3, 5, 6, 7]\n```\n\nSimpleScript allows you to assign variables inline with your for-loop. This opens up the possibility for dynamic variable assignment depending on predefined contexts.\nThe greatest benefit, however, is that because SimpleScript allows for mutations of variables, you can initialize a variable beforehand and then use it to perform meta-computations in the for-loop itself. \n\n## While-Loops\n\nLike for-loops, while-loops take some condition and execute an expression. The difference here is that the provided expression will keep executing until the provided condition proves false. \nThis allows us to repeat programs and expressions until we reach some desired goal. \n\n```BASIC\n$ VAR x = 1\n1\n$ WHILE x \u003c 10 THEN VAR x = x + 1\n[2, 3, 4, 5, 6, 7, 8, 9, 10]\n$ x\n10\n```\n\n```BASIC\n$ VAR y = 10\n10\n$ WHILE y \u003e 0 AND (TRUE == 1) THEN VAR y = y - 2\n[8, 6, 4, 2, 0]\n$ y\n0\n```\n\nJust like for-loops, control flow statements like `BREAK` and `CONTINUE` can be used to augment your while-loops.\nHere is the same example found in the previous section. Instead of using for-loops, we're going to get the same resulting list using while-loops.\n\n```BASIC\n$ VAR a = []; VAR i = 0\n[, 0]\n$ WHILE i \u003c 10 THEN; VAR i = i + 1; IF i == 4 THEN CONTINUE; IF i == 8 THEN BREAK; VAR a = a + i; END\n[0]\n$ a\n[1, 2, 3, 5, 6, 7]\n\n```\n\nVariables and sub-expressions can be chained together to form large compound conditions for your while-loop. The body of the loop can be similarly built. \nThese larger compound control flow programs can chain into function calls and other sub-routines, making them very powerful.\n\n## Functions\n\nYou can use the `FUNC` keyword to create functions in SimpleScript. Like Python, you can assign functions to variables for future use. Function names can be made up of letters and underscores. \n\n```BASIC\n$ FUNC my_math (a, b, c) -\u003e a + b - c\n\u003cfunction my_math\u003e\n$ my_math (1, 2, 3)    \n0\n```\n\n```BASIC\n$ VAR my_func = FUNC my_math (a, b, c) -\u003e a + b - c\n\u003cfunction my_math\u003e\n$ my_func\n\u003cfunction my_math\u003e\n$ my_func (1, 2, 3)  \n0\n$ my_math (1, 2, 3)    \n0\n```\n\n```BASIC\n$ debug\n$ FUNC bad_func (a, b) -\u003e a | b ^ 2\n\u003cfunction bad_func\u003e\n$ bad_func ()\n\nTraceback (most recent call last):\nFile \u003cstdin\u003e, line 1, in \u003cprogram\u003e\nbad_func ()\n^^^^^^^^\n```\n\n```BASIC\n$ debug\n$ FUNC bad_func (a, b) -\u003e a | b\n\u003cfunction bad_func\u003e\n$ bad_func (1, 2, 3, 4)\n\nTraceback (most recent call last):\nFile \u003cstdin\u003e, line 1, in \u003cprogram\u003e\nbad_func (1, 2, 3, 4)\n^^^^^^^^^^^^^^^^^^^^\n```\n\n```BASIC\n$ FUNC test(); VAR foo = 5; RETURN foo; END\n[\u003cfunction test\u003e]\n$ test()\n[5]\n```\n\nIf `debug` is enabled, the interpreter will complain if you add too many or too few function parameters. You can also create anonymous functions (e.g. lambda functions in Python) using similar syntax.\n\n```BASIC\n$ FUNC (a, b) -\u003e a ^ 2 + b ^ 2\n\u003cfunction \u003canonymous\u003e\u003e\n$ VAR anon_func = FUNC (a, b) -\u003e a ^ 2 + b ^ 2\n\u003cfunction \u003canonymous\u003e\u003e\n$ anon_func (2, 3)  \n13\n```\n\nLike variables and flow control loops, you can chain together large compound function calls inside smaller anonymous function declarations. \nThe interpreter's backend has been built to handle abstract layers of expressions and nesting; there is no restriction to the number of nested compound functions you can use.\n\n## Multi-line Statements\n\nYou can chain multiple statements together using multiple lines. Not only does this clean up your program, but it allows you to execute more than one operation in loops. \nSemi-colons are used to delimit newlines in your program. You can also write multi-line expressions in the interactive shell by using semi-colons.\n\n```BASIC\n$ VAR result = IF 5 == 5 THEN \"Math is working well\" ELSE \"Not working\"\n[Math is working well]\n$ result\n[Math is working well]\n```\n\n```BASIC\n$ IF 5 == (3 + 2) THEN; PRINT(\"Math is cool\");PRINT(\"Working well\") ELSE PRINT(\"Not working\")\nMath is cool\nWorking well\n[0]\n```\n\nThis same rule applies to all other loops and control flow operations. Same goes for functions. \nYou write longer, more complex programs by chaining together multiple operations in loops and function bodies.\n\n## Comments\n\nComments are simply anything to the right of a `#` character. There are no multi-line comments in SimpleScript.\n\n```BASIC\n$ # This is a comment! \n$ # I will not be executed!\n``` \n\nComments are for personal use. The interpreter will simply skip over them. \nIt is a personal preference when and where to use comments. There is no standard way of using them, as the underlying language itself doesn't care about them.\nDo whatever brings you joy.\n\n---\n\n## Language Grammars\n\nThe SimpleScript language is built around the grammar of BASIC. The grammar was used in the creation of the Lexer and the Parser. It served to inform the design and development of the creation of the abstract syntax trees and their tokens.\n\n```text\nstatements  : NEWLINE* statement (NEWLINE+ statement)* NEWLINE*\n\nstatement\t\t: KEYWORD:RETURN expr?\n\t\t\t\t\t\t: KEYWORD:CONTINUE\n\t\t\t\t\t\t: KEYWORD:BREAK\n\t\t\t\t\t\t: expr\n\nexpr        : KEYWORD:VAR IDENTIFIER EQ expr\n            : comp-expr ((KEYWORD:AND|KEYWORD:OR) comp-expr)*\n\ncomp-expr   : NOT comp-expr\n            : arith-expr ((EE|LT|GT|LTE|GTE) arith-expr)*\n\narith-expr  :\tterm ((PLUS|MINUS) term)*\n\nterm        : factor ((MUL|DIV) factor)*\n\nfactor      : (PLUS|MINUS) factor\n            : power\n\npower       : call (POW factor)*\n\ncall        : atom (LPAREN (expr (COMMA expr)*)? RPAREN)?\n\natom        : INT|FLOAT|STRING|IDENTIFIER\n            : LPAREN expr RPAREN\n            : list-expr\n            : if-expr\n            : for-expr\n            : while-expr\n            : func-def\n\nlist-expr   : LSQUARE (expr (COMMA expr)*)? RSQUARE\n\nif-expr     : KEYWORD:IF expr KEYWORD:THEN\n              (statement if-expr-b|if-expr-c?)\n            | (NEWLINE statements KEYWORD:END|if-expr-b|if-expr-c)\n\nif-expr-b   : KEYWORD:ELIF expr KEYWORD:THEN\n              (statement if-expr-b|if-expr-c?)\n            | (NEWLINE statements KEYWORD:END|if-expr-b|if-expr-c)\n\nif-expr-c   : KEYWORD:ELSE\n              statement\n            | (NEWLINE statements KEYWORD:END)\n\nfor-expr    : KEYWORD:FOR IDENTIFIER EQ expr KEYWORD:TO expr \n              (KEYWORD:STEP expr)? KEYWORD:THEN\n              statement\n            | (NEWLINE statements KEYWORD:END)\n\nwhile-expr  : KEYWORD:WHILE expr KEYWORD:THEN\n              statement\n            | (NEWLINE statements KEYWORD:END)\n\nfunc-def    : KEYWORD:FUN IDENTIFIER?\n              LPAREN (IDENTIFIER (COMMA IDENTIFIER)*)? RPAREN\n              (ARROW expr)\n            | (NEWLINE statements KEYWORD:END)\n```\n\nThis grammar was lifted from [davidcallanan/py-myopl-code](https://github.com/davidcallanan/py-myopl-code/blob/master/ep14/grammar.txt) as they already had the most accurate and feature-rich BASIC grammar I could find online. This grammar is completely barebones; all BASIC implementations would be identical. This was lifted to save me the hastle of drafting the initial grammar myself, a task reserved for POWs and grammar enthusiasts.\n\n## Backend Architecture\n\nThe process of building and interpreting a programming language from scratch can be split into three main components. Each component produces their own deliverable that is used as an input for the following process.\n\n- Lexing: Turns text strings into a list of tokens\n- Parsing: Turns the list of tokens into an abstract syntax tree (AST)\n- Interpreting: Evaluates every node of the AST to return a result\n\nThe three components are named accordingly in the `bin/` directory. They are: `lexer.py`, `parser.py`, and `interpreter.py`. These three components are the backbone of (most) programming languages.\n\n## Related Readings\n\nHere are some of the best physical and digital resources I could find on the subject of creating an interpreter for a programming language from scratch:\n\n* [Language Implementation Patterns: Create Your Own Domain-Specific and General Programming Languages (Pragmatic Programmers)](https://www.amazon.ca/gp/product/193435645X/ref=as_li_tl?ie=UTF8\u0026camp=1789\u0026creative=9325\u0026creativeASIN=193435645X\u0026linkCode=as2\u0026tag=russblo0b-20\u0026linkId=MP4DCXDV6DJMEJBL)\n* [Writing Compilers and Interpreters: A Software Engineering Approach](https://www.amazon.ca/gp/product/0470177071/ref=as_li_tl?ie=UTF8\u0026camp=1789\u0026creative=9325\u0026creativeASIN=0470177071\u0026linkCode=as2\u0026tag=russblo0b-20\u0026linkId=UCLGQTPIYSWYKRRM)\n* [Modern Compiler Implementation in Java](https://www.amazon.ca/gp/product/052182060X/ref=as_li_tl?ie=UTF8\u0026camp=1789\u0026creative=9325\u0026creativeASIN=052182060X\u0026linkCode=as2\u0026tag=russblo0b-20\u0026linkId=ZSKKZMV7YWR22NMW)\n* [Modern Compiler Design](https://www.amazon.com/gp/product/1461446988/ref=as_li_tl?ie=UTF8\u0026camp=1789\u0026creative=9325\u0026creativeASIN=1461446988\u0026linkCode=as2\u0026tag=russblo0b-20\u0026linkId=PAXWJP5WCPZ7RKRD)\n* [Compilers: Principles, Techniques, and Tools (2nd Edition)](https://www.amazon.ca/gp/product/0321486811/ref=as_li_tl?ie=UTF8\u0026camp=1789\u0026creative=9325\u0026creativeASIN=0321486811\u0026linkCode=as2\u0026tag=russblo0b-20\u0026linkId=GOEGDQG4HIHU56FQ)\n* [The \"Let’s Build A Simple Interpreter\" Blog Series](https://ruslanspivak.com/lsbasi-part1/)\n* [The \"Make YOUR OWN Programming Language\" Video Series](https://www.youtube.com/playlist?list=PLZQftyCk7_SdoVexSmwy_tBgs7P0b97yD)\n* [Introduction to Programming Languages/Interpreted Programs](https://en.wikibooks.org/wiki/Introduction_to_Programming_Languages/Interpreted_Programs)\n* [Clean Architecture: A Craftsman's Guide to Software Structure and Design (Robert C. Martin Series)](https://www.amazon.ca/dp/B075LRM681?ref_=cm_sw_r_kb_dp_zbbTDb7E1P022\u0026tag=davidcallanan-20\u0026linkCode=kpe)\n\nHopefully these help inform similar projects in the future. While SimpleScript is \"complete,\" there is a great deal that can be improved upon. I, for one, am less-than-satisfied with much of the variable and function mechanisms of SimpleScript.\n","funding_links":["https://ko-fi.com/michaelbassili"],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flaputanmachines%2Fsimple-script","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flaputanmachines%2Fsimple-script","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flaputanmachines%2Fsimple-script/lists"}