{"id":22624635,"url":"https://github.com/barrettotte/ranger-lang","last_synced_at":"2025-03-29T03:16:49.318Z","repository":{"id":114091130,"uuid":"239174331","full_name":"barrettotte/Ranger-Lang","owner":"barrettotte","description":"A programming language designed while studying compiler design. Compiles RangerLang source to pseudo-assembly language for RangerVM.","archived":false,"fork":false,"pushed_at":"2020-03-26T11:58:47.000Z","size":144,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-02-03T13:13:18.558Z","etag":null,"topics":["compiler","dragon-book","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/barrettotte.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":"2020-02-08T17:33:37.000Z","updated_at":"2021-08-26T20:47:40.000Z","dependencies_parsed_at":"2023-06-12T14:00:36.331Z","dependency_job_id":null,"html_url":"https://github.com/barrettotte/Ranger-Lang","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/barrettotte%2FRanger-Lang","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/barrettotte%2FRanger-Lang/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/barrettotte%2FRanger-Lang/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/barrettotte%2FRanger-Lang/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/barrettotte","download_url":"https://codeload.github.com/barrettotte/Ranger-Lang/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246131335,"owners_count":20728303,"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":["compiler","dragon-book","programming-language"],"created_at":"2024-12-09T00:17:08.327Z","updated_at":"2025-03-29T03:16:49.073Z","avatar_url":"https://github.com/barrettotte.png","language":"C","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Ranger-Lang\nA programming language designed while studying compilers and taking heavy inspiration from RPGLE and C grammars.\nCompiles RangerLang source to a pseudo-assembly language for a simple VM called RangerVM..\n\n\n## About\nThis language was my introduction to the world of compilers. \n\n\nThe goal of writing this was to learn, so there's not a lot of interesting stuff implemented. \nAdditionally, I wimped out and didn't dive into functions. \nSo, I did miss out on a lot of good stuff about activation records, heap management, etc.\nIn the future, I will make a full blown object oriented language to fill in the missing knowledge and more.\n\nI started out making a dumber version of C's grammar, but decided for ease of parsing I would take RPGLE's method of code blocks (if -\u003e endif, dow -\u003e enddo).\nI've been studying RPGLE lately and the simple grammar just makes sense as a good starting point for writing an introductory language.\n\n\n\n\u003cfigure\u003e\n  \u003cp align=\"center\"\u003e\n    \u003cimg src=\"misc/ranger.jpg\" alt=\"Ranger\" width=\"40%\" height=\"40%\"/\u003e\n    \u003cfigcaption\u003e\n      \u003cp align=\"center\"\u003eRangerLang is named after my cat that always hangs out in my room while I code.\u003c/p\u003e\n    \u003c/figcaption\u003e\n  \u003c/p\u003e\n\u003c/figure\u003e\n\n\n## Features\nThe full context free grammar can be found in **RangerLang.ebnf**.\nBut, I will briefly list the sparse features I implemented:\n- [x] Integer variables\n- [x] Base operators - ```+ - / * \u003c \u003e = :=```\n- [x] If/else \n- [x] Do while\n- [x] Read integer from STDIN\n- [x] Write integer to STDOUT\n\n\n## Stretch Features\nEvery side project starts out fun, but later becomes stale; We'll see if I get here.\nIf not, I'm sure the next language I make will have these and more.\n\n- [ ] Additional relational operators - ```!=, \u003e=, \u003c=```\n- [ ] Additional binary operators - ```\u0026\u0026, ||```\n- [ ] Unary operators - ```!, +, -```\n- [ ] Strict type definition - new keywords ```int, float, string```\n- [ ] Additional data types - float, string\n- [ ] Integer arrays\n\n\n## Compilation Example\nExamples can be found in **tests/**.\n\n#### Source program (RangerLang) - **fibonacci.rg**\n```php\n/* Compute fibonacci number using iterative method \n     since my language does not have functions.\n*/\nread n;\nfib := 1;\n\nif(n \u003e 1);\n  temp := 0;\n  prev := 1;\n  i := 2;\n\n  dow(i \u003c (n-1));\n    temp := fib;\n    fib := fib + prev;\n    prev := temp;\n    i := i + 1;\n  enddo;\nendif;\n\nwrite fib;\n```\n\n#### Target program (RangerVM Assembly Language) - **fibonacci.asm**\nPsuedo-assembly meant to mimic how a ROM would work...all opcodes listed in **opcodes.asm**\n\n```assembly\n; RangerLang compilation to RangerVM Assembly\n; File: /home/barrett/Programming/Repos/Ranger-Lang/tests/fibonacci.rg\n;  \n; START PRELUDE:\n  0:     LDM   R6,0[R0] \t\t; load maxaddress from address 0\n  1:     STM   R0,0[R0] \t\t; clear address 0\n; END PRELUDE\n  2:      IN   R0,R0,R0 \t\t; read integer value\n  3:     STM   R0,0[R5] \t\t; read: store value\n  4:     LDI   R0,1[R0] \t\t; load constant\n  5:     STM   R0,1[R5] \t\t; assign: store value\n; IF\n  6:     LDM   R0,0[R5] \t\t; load identifier value\n  7:     STM   R0,0[R6] \t\t; operator: push left\n  8:     LDI   R0,1[R0] \t\t; load constant\n  9:     LDM   R1,0[R6] \t\t; operator: load left\n 10:     SUB   R0,R1,R0 \t\t; operator \u003e\n 11:     JGT   R0,2[R7] \t\t; branch if true\n 12:     LDI   R0,0[R0] \t\t; it was false\n 13:     LDA   R7,1[R7] \t\t; unconditioned jump\n 14:     LDI   R0,1[R0] \t\t; it was true\n 16:     LDI   R0,0[R0] \t\t; load constant\n 17:     STM   R0,2[R5] \t\t; assign: store value\n 18:     LDI   R0,1[R0] \t\t; load constant\n 19:     STM   R0,3[R5] \t\t; assign: store value\n 20:     LDI   R0,2[R0] \t\t; load constant\n 21:     STM   R0,4[R5] \t\t; assign: store value\n; DOW\n 22:     LDM   R0,1[R5] \t\t; load identifier value\n 23:     STM   R0,2[R5] \t\t; assign: store value\n 24:     LDM   R0,1[R5] \t\t; load identifier value\n 25:     STM   R0,0[R6] \t\t; operator: push left\n 26:     LDM   R0,3[R5] \t\t; load identifier value\n 27:     LDM   R1,0[R6] \t\t; operator: load left\n 28:     ADD   R0,R1,R0 \t\t; operator +\n 29:     STM   R0,1[R5] \t\t; assign: store value\n 30:     LDM   R0,2[R5] \t\t; load identifier value\n 31:     STM   R0,3[R5] \t\t; assign: store value\n 32:     LDM   R0,4[R5] \t\t; load identifier value\n 33:     STM   R0,0[R6] \t\t; operator: push left\n 34:     LDI   R0,1[R0] \t\t; load constant\n 35:     LDM   R1,0[R6] \t\t; operator: load left\n 36:     ADD   R0,R1,R0 \t\t; operator +\n 37:     STM   R0,4[R5] \t\t; assign: store value\n 38:     LDM   R0,4[R5] \t\t; load identifier value\n 39:     STM   R0,0[R6] \t\t; operator: push left\n 40:     LDM   R0,0[R5] \t\t; load identifier value\n 41:     STM   R0,-1[R6] \t\t; operator: push left\n 42:     LDI   R0,1[R0] \t\t; load constant\n 43:     LDM   R1,-1[R6] \t\t; operator: load left\n 44:     SUB   R0,R1,R0 \t\t; operator -\n 45:     LDM   R1,0[R6] \t\t; operator: load left\n 46:     SUB   R0,R0,R1 \t\t; operator \u003c\n 47:     JLT   R0,2[R7] \t\t; branch if true\n 48:     LDI   R0,0[R0] \t\t; it was false\n 49:     LDA   R7,1[R7] \t\t; unconditioned jump\n 50:     LDI   R0,1[R0] \t\t; it was true\n 51:     JEQ   R0,-30[R7] \t\t; dow: jump back to start\n; ENDDO\n 15:     JEQ   R0,37[R7] \t\t; if: jump to else\n 52:     LDA   R7,0[R7] \t\t; jump to end\n; ENDIF\n 53:     LDM   R0,1[R5] \t\t; load identifier value\n 54:     OUT   R0,R0,R0 \t\t; write AC\n; END PROGRAM\n 55:    HALT   R0,R0,R0 \t\t; \n\n```\n\n#### Compile Listing - **fibonacci.listing.txt**\nCompile listing with parser debugging turned on (for syntax tree)\n\n```\nRangerLang Compile Listing for \n    /home/barrett/Programming/Repos/Ranger-Lang/tests/fibonacci.rg\n\nSource Program:\n0001: /* Compute fibonacci number using iterative method \n0002:      since my language does not have functions.\n0003: */\n0004: \n0005: read n;\n0006: fib := 1;\n0007: \n0008: if(n \u003e 1);\n0009:   temp := 0;\n0010:   prev := 1;\n0011:   i := 2;\n0012: \n0013:   dow(i \u003c (n-1));\n0014:     temp := fib;\n0015:     fib := fib + prev;\n0016:     prev := temp;\n0017:     i := i + 1;\n0018:   enddo;\n0019: endif;\n0020: \n0021: write fib;\n\nSyntax Tree:\n  Read: n\n  Assignment: fib\n    Literal: 1\n  If\n    Operator: \u003e\n      Identifier: n\n      Literal: 1\n    Assignment: temp\n      Literal: 0\n    Assignment: prev\n      Literal: 1\n    Assignment: i\n      Literal: 2\n    Dow\n      Operator: \u003c\n        Identifier: i\n        Operator: -\n          Identifier: n\n          Literal: 1\n      Assignment: temp\n        Identifier: fib\n      Assignment: fib\n        Operator: +\n          Identifier: fib\n          Identifier: prev\n      Assignment: prev\n        Identifier: temp\n      Assignment: i\n        Operator: +\n          Identifier: i\n          Literal: 1\n  Write\n    Identifier: fib\n\nBuilding symbol table...\n\nSymbol Table:\n\nSymbol         Address     Reference(s)\n-----------    --------    ------------\ntemp           2           0009 0014 0016 \nfib            1           0006 0014 0015 0021 \ni              4           0011 0013 0017\nn              0           0005 0008 0013 \nprev           3           0010 0015 0016 \n\nChecking types...\n\nGenerating code...\n\nDONE.\n```\n\n\n#### Output\nThe output from running ```./rangervm fibonacci.asm```\n```\nRangerVM Started.\nLoading /home/barrett/Programming/Repos/Ranger-Lang/tests/fibonacci.asm into ROM\nIN:  10\nOUT: 55\nExecuted 255 instruction(s)\nPGM HALTED\nRangerVM Ended.\n```\n\n\n## Commands\n* Compile a single RangerLang source file - ```./rangerlang ../tests/fibonacci.rg```\n* Run RangerVM assembly - ```./rangervm ../tests/fibonacci.asm```\n* Build and test compile all example files - ```./test.sh```\n\n\n## References\n* EBNF\n  * https://en.wikipedia.org/wiki/Extended_Backus%E2%80%93Naur_form\n  * https://tomassetti.me/ebnf/\n* Books\n  * Compilers: Principles, Techniques, and Tools (The Dragon Book)\n  * Engineering A Compiler\n  * SubC Compiler - http://www.t3x.org/subc/\n  * Crafting Interpreters - http://craftinginterpreters.com/\n* Misc\n  * Dangling else - https://en.wikipedia.org/wiki/Dangling_else\n  * Pratt Parsing (operator precedence) - https://journal.stuffwithstuff.com/2011/03/19/pratt-parsers-expression-parsing-made-easy/\n  * x86 64-bit assembly reference - https://www.felixcloutier.com/x86/\n\n  \n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbarrettotte%2Franger-lang","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbarrettotte%2Franger-lang","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbarrettotte%2Franger-lang/lists"}