{"id":15477091,"url":"https://github.com/ichard26/masml","last_synced_at":"2025-07-14T23:08:38.989Z","repository":{"id":115374170,"uuid":"518225326","full_name":"ichard26/masml","owner":"ichard26","description":"Richard's silly ASM-like(-ish) language.","archived":false,"fork":false,"pushed_at":"2024-08-08T20:07:15.000Z","size":75,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-07-04T23:13:57.056Z","etag":null,"topics":["c","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":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ichard26.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"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":"2022-07-26T21:43:46.000Z","updated_at":"2024-08-08T20:07:18.000Z","dependencies_parsed_at":"2024-11-26T08:45:56.731Z","dependency_job_id":null,"html_url":"https://github.com/ichard26/masml","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/ichard26/masml","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ichard26%2Fmasml","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ichard26%2Fmasml/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ichard26%2Fmasml/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ichard26%2Fmasml/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ichard26","download_url":"https://codeload.github.com/ichard26/masml/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ichard26%2Fmasml/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":265365697,"owners_count":23753379,"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":["c","programming-language"],"created_at":"2024-10-02T03:43:45.248Z","updated_at":"2025-07-14T23:08:38.964Z","avatar_url":"https://github.com/ichard26.png","language":"C","funding_links":[],"categories":[],"sub_categories":[],"readme":"# masml\n\n\u003e My ASM Language\n\nRichard's silly ASM-like(-ish) language. This little project was meant both as a better\nimplementation over my original Python one *and* as a way to get better at C. This is my\nsecond major piece of software written in C. 🎉\n\n## Usage\n\nTo get a debug build (note it has ASAN), simply run `make` from the root of your checkout.\nOtherwise, run `make build-release` for an optimized build. Afterwards, you'll have a\n`masal` executable with which you can pass a MASML program to.\n\n\u003e The preferred file extension for MASML programs is `.masml`.\n\nFor example, you can run the `examples/factor-finder.masml` program I wrote to test the\nparser and VM. You should see the following output:\n\n```console\n$ ./masml examples/factor-finder.masml\n[OUTPUT] 1.000000\n[OUTPUT] 27.000000\n[OUTPUT] 3.000000\n[OUTPUT] 9.000000\n[OUTPUT] 9.000000\n[OUTPUT] 3.000000\n[OUTPUT] 27.000000\n[OUTPUT] 1.000000\n```\n\nThere are three flags available: `--show-result`, `--debug-parser`, and `--debug-vm`. The\nfirst simply shows the value of the first VM register on termination. The other two enable\ndebug output for the parser and VM respectively.\n\nFor the parser, they show you the parsed instructions, what registers they're using and if\nthey have an argument (and if so, whether it's a variable or a constant). For the VM, they\nlog each instruction executed along with some details about the VM's internal state before\nthe instruction is executed.\n\nHere's an example rerun with some flags. (`--debug-vm` is *very* noisy so it isn't\nincluded here)\n\n```console\n$ ./masml examples/factor-finder.masml --show-result --debug-parser\n[LINE 1  ] #0   SET-REGISTER  $1      27\n[LINE 2  ] #1   STORE         $1      \u0026product -\u003e ram[0]\n[LINE 5  ] #2   ADD           $1      1\n[LINE 6  ] #3   STORE         $1      \u0026loop_until -\u003e ram[1]\n[LINE 7  ] #4   SET-REGISTER  $2      1\n[LINE 12 ] #5   LOAD          $1      \u0026product -\u003e ram[0]\n[LINE 13 ] #6   MODULO        $1      (null)\n[LINE 14 ] #7   GOTO-IF-NOT   $1      13\n[LINE 17 ] #8   LOAD          $1      \u0026loop_until -\u003e ram[1]\n[LINE 18 ] #9   ADD           $2      1\n[LINE 19 ] #10  EQUAL         $1      (null)\n[LINE 20 ] #11  GOTO-IF-NOT   $1      5\n[LINE 22 ] #12  EXIT          (null)  (null)\n[LINE 25 ] #13  LOAD          $1      \u0026product -\u003e ram[0]\n[LINE 26 ] #14  DIVIDE        $1      (null)\n[LINE 27 ] #15  PRINT         $2      (null)\n[LINE 28 ] #16  PRINT         $1      (null)\n[LINE 29 ] #17  GOTO          (null)  8\n[OUTPUT] 1.000000\n[OUTPUT] 27.000000\n[OUTPUT] 3.000000\n[OUTPUT] 9.000000\n[OUTPUT] 9.000000\n[OUTPUT] 3.000000\n[OUTPUT] 27.000000\n[OUTPUT] 1.000000\n[RESULT] 1.000000\n```\n\n### Platform compatibility\n\n`masal.c` targets C11 without using any POSIX specific features as far as I know, but I've\nonly built and tested this code on my Ubuntu 20.04.04 x86-64 machine. It *should* work on\nother platforms, but I can't make any guarantees. And no, I'm not providing a VS build\nconfiguration, sorry Windows folks.\n\nAnyway, I'm still pretty awful at C. Expecting me to write portable C first try is a bit\nmuch :)\n\n### Language syntax\n\nEach line in a program is an instruction. Each instruction can read registers and/or an\nnumerical constant (as an argument) and write to a register if it produces a result (eg.\n`EQUAL`). There are two registers: `$1` and `$2`. Arguments come in two types: variables\n(eg. `\u0026daylily`) and numerical constants (eg. `27`).\n\nOnly `LOAD` and `STORE` can read and write a variable respectively. Actually, `PRINT` can\nalso read a variable. All other instructions only interact with the two VM registers\n(which are simply double-precision float stack variables in the VM).\n\nEach instruction can have a register and/or an argument specified. How the register and\nargument are used is instruction-dependant. If a register specifier doesn't start with a\ndollarsign (`$`), it will be instead treated as an argument.\n\nHere are the available instructions and their semantics:\n\n**LOAD**\n\nRead a variable and store it in the target register.\n\n**STORE**\n\nRead the target register and set a variable.\n\n**SET-REGISTER**\n\nWrite a numerical constant to the target register.\n\n**SWAP**\n\nReplace the value stored in register A with what's in register B and vice versa.\n\n**ADD** / **SUBTRACT** / **MULTIPLY** / **DIVIDE** / **MODULO**\n\nPerform X mathematical operation with register A as the left operand and register B as the\nright operand if no numerical constant is specified. Otherwise, the left operand is the\ntarget register and the right operand is the constant.\n\nIn either case, the result is written to the target register.\n\n**EQUAL**\n\nCompare the specified numerical constant against the target register. If a numerical\nconstant is not given, compare the two registers instead.\n\n`1.0` will be written to the target register if the two operands are equal, otherwise\n`0.0` is written.\n\n**NOT**\n\nRead the target register and write back `0.0` if it's non-zero, otherwise `1.0`.\n\n**GOTO**\n\nUnconditional jump to instruction X. Remember that instruction indexes start at zero!\n\n**GOTO-IF** / **GOTO-IF-NOT**\n\nIf the target register is non-zero (or zero with `GOTO-IF-NOT`), jump to instruction X.\nRemember that instruction indexes start at zero!\n\n**PRINT**\n\nIf a variable is specified, print its value, otherwise print the target register's value.\n\n**EXIT**\n\nStop execution.\n\n______________________________________________________________________\n\nTo include a comment, prefix the line with `#`. Comments and empty lines are ignored in\nthe parser (lines with only whitespace probably break the parser right now though).\n\n## Tooling\n\n### Vim syntax highlighting\n\nA Vim syntax file can be found at `tools/masml.vim`. To install it and set up syntax\nhighlighting:\n\n1. Create these files and directories if they don't exist:\n\n   ```php\n   $HOME/.vim/ftdetect/masml.vim\n   $HOME/.vim/syntax/masml.vim\n   ```\n\n1. Put the following in `$HOME/.vim/ftdetect/masml.vim`:\n\n   ```vim\n   autocmd BufRead,BufNewFile *.masml set filetype=masml\n   ```\n\n1. Copy and paste the contents of `tools/masml.vim` into `$HOME/.vim/syntax/masml.vim`\n\n## Possible improvements\n\n- Implement goto labels since specifying instruction indexes is error-prone\n- Support `GOTO 0` (or a label pointing to the first instruction) properly (it may or may\n  not crash currently ¯\\\\\\_(ツ)\\_/¯)\n- Support an (practically) unlimited amount of variables (currently RAM is implemented\n  simply as `double ram[1000] = {0}`)\n- Support programs with lines of (practically) unlimited length (limit is 64 characters\n  right now)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fichard26%2Fmasml","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fichard26%2Fmasml","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fichard26%2Fmasml/lists"}