{"id":21187018,"url":"https://github.com/thunderstruct/planck-lang","last_synced_at":"2025-03-14T20:19:33.142Z","repository":{"id":257021031,"uuid":"855316867","full_name":"ThunderStruct/planck-lang","owner":"ThunderStruct","description":"An esoteric, minimal programming language","archived":false,"fork":false,"pushed_at":"2024-09-13T19:22:31.000Z","size":41,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-01-21T13:07:24.181Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ThunderStruct.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}},"created_at":"2024-09-10T17:10:01.000Z","updated_at":"2024-09-13T19:23:43.000Z","dependencies_parsed_at":"2024-09-14T11:29:18.338Z","dependency_job_id":null,"html_url":"https://github.com/ThunderStruct/planck-lang","commit_stats":null,"previous_names":["thunderstruct/planck-lang"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ThunderStruct%2Fplanck-lang","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ThunderStruct%2Fplanck-lang/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ThunderStruct%2Fplanck-lang/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ThunderStruct%2Fplanck-lang/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ThunderStruct","download_url":"https://codeload.github.com/ThunderStruct/planck-lang/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243639558,"owners_count":20323511,"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":[],"created_at":"2024-11-20T18:27:46.035Z","updated_at":"2025-03-14T20:19:33.112Z","avatar_url":"https://github.com/ThunderStruct.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"\n\u003cimg src=\"https://i.imgur.com/iXfjUbP.png\" alt=\"Planck Logo\" width=\"250\"\u003e\n\n# Planck Language\n\n**Planck** is an esoteric, minimal language created as a hobby project as part of my _Compiler Design_ course during my undergrad. Recently branded and open-sourced just for fun!\n\n\n## The Extended Backus-Naur Form Grammar for Planck\n\n```ebnf\n\u003cprogram\u003e ::= \u003cstatement_list\u003e\n\n\u003cstatement_list\u003e ::= \u003cstatement\u003e { \u003cstatement\u003e }\n\n\u003cstatement\u003e ::= \u003coutput\u003e \n              | \u003cloop\u003e \n              | \u003cconditional\u003e \n              | \u003cmethod_call\u003e \n              | \u003cassignment\u003e\n\n\u003coutput\u003e ::= \"%\" \u003cidentifier\u003e\n\n\u003cloop\u003e ::= \"**\" \u003cexpression\u003e \"-\u003e\" \u003cstatement\u003e \"$\"\n\n\u003cconditional\u003e ::= \u003cexpression\u003e \"?\" \u003cstatement\u003e\n\n\u003cmethod_call\u003e ::= \"get\" \u003cidentifier\u003e \"(\" \u003cidentifier\u003e \")\"\n\n\u003cassignment\u003e ::= \u003cidentifier\u003e \"=\" \u003cexpression\u003e\n\n\u003cexpression\u003e ::= \u003cadditive_expression\u003e { \u003crelop\u003e \u003cadditive_expression\u003e }\n\n\u003cadditive_expression\u003e ::= \u003cterm\u003e { \u003caddop\u003e \u003cterm\u003e }\n\n\u003cterm\u003e ::= \u003cfactor\u003e { \u003cmulop\u003e \u003cfactor\u003e }\n\n\u003cfactor\u003e ::= \"(\" \u003cexpression\u003e \")\" \n           | \u003cidentifier\u003e \n           | \u003cnumber\u003e\n\n\u003crelop\u003e ::= \"\u003c=\" | \"\u003c\" | \"\u003e\" | \"\u003e=\" | \"==\" | \"!=\"\n\n\u003caddop\u003e ::= \"+\" | \"-\"\n\n\u003cmulop\u003e ::= \"*\" | \"/\"\n\n\u003cidentifier\u003e ::= [a-zA-Z_][a-zA-Z0-9_]*\n\n\u003cnumber\u003e ::= [0-9]+ (\".\" [0-9]+)?\n```\n\n## Tokens\n\nThe tokens recognized by the Planck language are:\n\n- **Identifiers**: Any variable name starting with a letter or underscore, followed by alphanumeric characters, underscores, periods, or special characters like `\\#`, `$`, and `_`.\n- **Numbers**: Numeric literals, including integers and floating-point numbers, written as `123` or `12.34`.\n- **Operators**: Arithmetic and relational operators like `+`, `-`, `*`, `/`, `\u003c`, `\u003c=`, `\u003e`, `\u003e=`, `==`, and `!=`.\n- **Assignment**: The assignment operator `=`.\n- **Method Call**: The keyword `get`, used to call a method with syntax like `get x(y)`.\n- **Output**: The `%` symbol, used to output the value of a variable.\n- **Loops**: Denoted with the `**` symbol followed by an expression, then `-\u003e`, a statement, and ending with `$`.\n- **Conditionals**: Denoted with a `?` after an expression and followed by a statement.\n- **Delimiters**: Characters like parentheses `()`, braces `{}`, and brackets `[]`.\n\n## Examples\n\n1. **Assignment and Output**:\n\n```\nx = 10\n% x\n```\n\n**Output**:\n\n```\n10\n```\n\n\n2. **Loop**:\n\n```\n** 5 -\u003e % x $\n```\n\n**Explanation**:\nThis defines a loop that runs 5 times and outputs the value of `x`.\n\n3. **Conditional**:\n\n```\nx = 5 ? % x\n```\n\n**Output**:\n\n```\n5\n```\n\n4. **Method Call**:\n\n```\nget x(y)\n```\n\n**Explanation**:\nCalls the method `x` with the argument `y`.\n\n## Planck Interpreter\n\nThe Planck interpreter is built purely using C++, and is split into 3 fundamental components: a custom lexer (Flex configuration is also implemented), a parser to evaluate expressions, and a symbol table to manage and track identifiers.\n\n### Lexer\n\nWe use Flex to tokenize the input into various tokens like identifiers, numbers, operators, etc. The lexer handles both numeric and identifier-based inputs, as well as arithmetic and comparison operators.\n\n### Parser\n\nThe parser uses _recursive descent_ techniques to break down the tokenized input according to Planck's EBNF grammar. It evaluates statements like assignments, loops, conditionals, and expressions, constructing an abstract syntax tree (AST) and managing control flow. It checks for syntax and semantic errors, ensuring valid execution.\n\n### Symbol Table\n\nThe symbol table in Planck is implemented using a hash table. After implementing both the symbol and symbolTable classes, it was important to integrate the new data structure with the parser.\n\nThe symbol table insertion starts in `parser::expression_stmt`, where assignments are matched. When a variable is assigned, its name, line number, and value are stored as a symbol object and inserted into the table.\n\nTo check for variable declarations before usage, a simple `lookup()` call in the expression production rule ensures that variables exist before they are used. If not found, an error is raised.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthunderstruct%2Fplanck-lang","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fthunderstruct%2Fplanck-lang","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthunderstruct%2Fplanck-lang/lists"}