{"id":22731336,"url":"https://github.com/sno2/apscript","last_synced_at":"2025-10-07T19:47:11.087Z","repository":{"id":112568884,"uuid":"582386457","full_name":"sno2/apscript","owner":"sno2","description":"An interpreter for the AP CS Principles Pseudocode Language","archived":false,"fork":false,"pushed_at":"2022-12-29T03:50:27.000Z","size":273,"stargazers_count":6,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-06-15T14:39:03.711Z","etag":null,"topics":["rust"],"latest_commit_sha":null,"homepage":"https://pseudocode.vercel.app","language":"Rust","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/sno2.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","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":"2022-12-26T17:00:12.000Z","updated_at":"2024-07-13T14:58:56.000Z","dependencies_parsed_at":"2023-05-16T08:30:20.772Z","dependency_job_id":null,"html_url":"https://github.com/sno2/apscript","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/sno2/apscript","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sno2%2Fapscript","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sno2%2Fapscript/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sno2%2Fapscript/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sno2%2Fapscript/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sno2","download_url":"https://codeload.github.com/sno2/apscript/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sno2%2Fapscript/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":278837522,"owners_count":26054719,"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-10-07T02:00:06.786Z","response_time":59,"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":["rust"],"created_at":"2024-12-10T19:21:35.567Z","updated_at":"2025-10-07T19:47:11.056Z","avatar_url":"https://github.com/sno2.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# APScript (aps)\n\nA speedy interpreter for the AP Computer Science Principles pseudocode language built in Rust.\n\n## Features\n\n- Robust garbage collector (using `gc`)\n- Great Specification conformity\n- Beautiful error logging for parsing and runtime errors (using\n  `codespan-reporting`)\n- Hackable virtual machine design\n\n## Usage\n\nThe interpreter is patched along with [a web playground](https://pseudocode.vercel.app) using Monaco, the\ntext editor that powers VS Code, and term.js, an emulated terminal for the web.\nThe interpreter supports live parse checking and runtime error diagnostics\nintegrated into both the terminal and editor. Furthermore, the playground\nsupports browsing example programs and sharing your programs with anyone in the\nworld!\n\n## Language Guide\n\nA brief introductory guide to the language. If you get lost, please file an\nissue because it is _our_ fault for not explaining it better and others will\nbe confused if you are.\n\n#### Table of Contents\n\n1. [Comments](#comments)\n2. [Variables](#variables)\n3. [Lists](#lists)\n4. [Conditionals](#conditionals)\n5. [Loops](#loops)\n6. [I/O](#io)\n\n### Comments\n\nComments allow other programmers and yourself to understand code better by\nincluding annotations along with the logic. AP's specification did not include\na syntax for comments so I implemented Python-style comments which start with\na hashtag.\n\n```\n# This is a comment.\n# This is another comment.\n# Comments do not do anything at runtime.\n```\n\n\u003e **Tip**: Although comments may seem useless, they are extremely important in\n\u003e real-world codebases because it can be nearly impossible to understand what a\n\u003e 100+ line function is doing without any explanation. Even just adding a\n\u003e short explanation above a function will go a long ways towards maintaining an\n\u003e approachable codebase.\n\n### Variables\n\nVariables allow you to store data into named locations and can be created using\nthe syntax `name \u003c- value`.\n\n```\nage \u003c- 20\n```\n\nVariables can be complex expressions like math and follow the order of\noperations.\n\n```\nage \u003c- 20 + 5 * 2\n```\n\nWe will represent the state of the program using tables like this. For example,\nrunning the above script will result in a state table with the following data:\n\n| Variable | Value |\n| -------- | ----- |\n| age      | `30`  |\n\nYou can also use other variables when assigning to variables.\n\n```\nage \u003c- 20\nage \u003c- age + 5\n```\n\n| State         | Value |\n| ------------- | ----- |\n| age (initial) | `20`  |\n| age (final)   | `25`  |\n\nText can be assigned to variables as well in the form of strings. Although, the\nonly useful operations you can do with text mostly relate to input/output which\nwill be [explained later in the guide](#io).\n\nAnyways, strings start with a double quote and continue until another double\nquote. Do not include new lines in your strings. All of the text in-between is\nconsidered part of the string.\n\n```\nmessage \u003c- \"Hello, world!\"\n```\n\n| Variable | Value             |\n| -------- | ----------------- |\n| message  | `\"Hello, world!\"` |\n\n### Lists\n\nLists allow you to store multiple values in the same data type. You can create\nlists by inserting comma-separated value expressions between brackets.\n\n```\nages1 \u003c- [] # creates an empty list\nages2 \u003c- [2, 3, 4]\n```\n\nYou can get the number of items in an array by using the `LENGTH` function:\n\n```\nages \u003c- [2, 3, 4]\nagesLength \u003c- LENGTH(ages)\n```\n\n| Variable   | Value       |\n| ---------- | ----------- |\n| ages       | `[2, 3, 4]` |\n| agesLength | `3`         |\n\nIn order to get values at specified indexes (positions) in an array, you can use\ninclude brackets after an array name. Note that the index of the first value is\n1, in contrast to many other programming languages.\n\n```\nages \u003c- [40, 24, 36]\n\nages1 \u003c- ages[1]\nages2 \u003c- ages[2]\nages3 \u003c- ages[3]\n```\n\n| Variable | Value          |\n| -------- | -------------- |\n| ages     | `[40, 24, 36]` |\n| ages1    | `40`           |\n| ages2    | `24`           |\n| ages3    | `36`           |\n\nAlso, it is possible to dynamically add items to a list using the `APPEND`\nfunction.\n\n```\nages \u003c- [60]\nAPPEND(ages, 5)\nAPPEND(ages, 10)\nAPPEND(ages, 8)\nAPPEND(ages, 16)\n```\n\n| State          | Value                |\n| -------------- | -------------------- |\n| ages (initial) | `[60]`               |\n| ages (final)   | `[60, 5, 10, 8, 16]` |\n\nSee the [Standard Library reference](#standard-library) for information on all\nof the functions for manipulating lists.\n\n### Conditionals\n\nThe `IF` statement can be used to conditionally run a block of statements based\non if an expression is true or false.\n\n```\nIF (TRUE) {\n  # this code will run because the expression is true\n}\n# code after here will still run\n```\n\n```\nIF (FALSE) {\n  # this code will not run because the expression is false\n}\n# code after here will still run\n```\n\n```\nage \u003c- 16\nIF (age \u003e= 18) {\n  #  this code will not run because the expression is false\n}\n# code after here will still run\n```\n\n`IF` statements can be combined with a trailing `ELSE` statement which will only\nrun if the `IF` statement's expression was false.\n\n```\nage \u003c- 16\n\nIF (age \u003e= 18) {\n\t# this code will not run\n} ELSE {\n\t# this code will run - the first condition was false\n}\n```\n\nFurthermore, `ELSE IF` statements can be tagged after an `IF` statement to add\nextra checks that only take place if the initial `IF` statement's condition\nwas false.\n\n```\nage \u003c- 16\n\nIF (age \u003e= 18) {\n\t# this code will not run\n} ELSE IF (age \u003e= 13) {\n\t# this code will run - 1st condition false, 2nd true\n} ELSE {\n\t# this code will not run\n}\n```\n\n### Loops\n\nThe pseudocode includes three different kinds of loops. The most basic loop is\nthe `REPEAT n` loop which will run the block `n` times.\n\n```\nfoo \u003c- []\nREPEAT 5 TIMES {\n  APPEND(foo, 1)\n}\n```\n\n| State         | Value             |\n| ------------- | ----------------- |\n| foo (initial) | `[]`              |\n| foo (final)   | `[1, 1, 1, 1, 1]` |\n\nAnother form of loop is the `REPEAT UNTIL` loop which will run the associated\nblock until the condition is true. This can be especially useful when you are\nvalidating input from a user.\n\n```\n# Build a list of five 10's\nlist \u003c- []\nREPEAT UNTIL (LENGTH(list) = 5) {\n\tAPPEND(list, 10)\n}\n```\n\n| State          | Value                  |\n| -------------- | ---------------------- |\n| list (initial) | `[]`                   |\n| list (final)   | `[10, 10, 10, 10, 10]` |\n\nThe most niche loop availabe is the `FOR EACH` loop. This allows you to easily\niterate through the items of a list. For example, let's create a list of ages\nand output the predicted age in a year.\n\n```\nages \u003c- [15, 20, 23]\npredictedAges \u003c- []\n\nFOR EACH age IN ages {\n\tAPPEND(predictedAges, age + 1)\n}\n```\n\n| Variable      | Value          |\n| ------------- | -------------- |\n| predictedAges | `[16, 21, 24]` |\n\n### I/O\n\nI/O stands for input/output, or methods that the outside parts can interact with\nyour program. You can interact with your program using the console.\n\nThe `DISPLAY` function is used to log out to the console.\n\n```\nDISPLAY(5)\n```\n\n```\n5\n```\n\nYou can also pass in string arguments and it will log them out with spaces in\nbetween.\n\n```\nDISPLAY(6, 8)\n```\n\n```\n6 8\n```\n\nFurthermore, strings can be used to log text to the console.\n\n```\nDISPLAY(\"Hello user!\")\nDISPLAY(\"How are you?\")\n```\n\n```\nHello user!\nHow are you?\n```\n\nThe `INPUT` function can be used to get input from the user. The same sort of\narguments can be passed to the function and logged before the input is asked\nfor. Also, the program will pause until the user enters input.\n\n```\nINPUT(\"What is your name?\")\n```\n\n```\nWhat is your name? [waits for input]\n```\n\n`INPUT` will return a string that you can use in other `INPUT` and `DISPLAY`\ncalls later.\n\n```\nfavColor \u003c- INPUT(\"What is your favorite color?\")\nDISPLAY(\"Woah! My favorite color is\", favColor, \"too!\")\n```\n\n```\n\nWhat is your favorite color? blue\nWoah! My favorite color is blue too!\n\n```\n\n`INPUT` will return a number if the user entered in a valid number.\n\n```\nage \u003c- INPUT(\"What is your age?\")\nDISPLAY(\"Well, you will be\", age + 1, \"next year!\")\n```\n\n```\nWhat is your age? 15\nWell, you will be 16 next year!\n```\n\n## Standard Library\n\nThe standard library as specified by the [AP Computer Science Principles Pseudocode Exam Reference Sheet](https://apcentral.collegeboard.org/media/pdf/ap-computer-science-principles-exam-reference-sheet.pdf).\n\n### `LENGTH(list)`\n\nReturns the number of items in `list`.\n\n```\nages \u003c- [16, 24, 3]\nagesLength \u003c- LENGTH(ages)\n```\n\n| Variable   | Value         |\n| ---------- | ------------- |\n| ages       | `[16, 24, 3]` |\n| agesLength | `3`           |\n\n### `INSERT(list, i, value)`\n\nAny values in `list` at indices greater than or equal to `i` are shifted to the\nright. The length of `list` is increased by 1, and `value` is placed at index\n`i` in `list`.\n\n```\nages \u003c- [100, 200, 300]\nINSERT(ages, 1, 6)\n```\n\n| Variable       | Value                |\n| -------------- | -------------------- |\n| ages (initial) | `[100, 200, 300]`    |\n| ages (final)   | `[100, 6, 200, 300]` |\n\n### `APPEND(list, value)`\n\nThe length of `list` is increased by 1, and `value` is placed at the end of\n`list`.\n\n### `REMOVE(list, i)`\n\nRemoves the item at index `i` in `list` and shifts to the left any values at\nindices greater than `i`. The length of list is decreased by `1`.\n\n### `DISPLAY(value1, ...)`\n\nWrites all of the given arguments to the console separated by spaces.\n\n### `INPUT(hint1, ...)`\n\nWrites all of the given arguments to the console separated by spaces in the same\nformat of `DISPLAY`. After that, it waits for input and returns the parsed\ninput. If the returned input is a number, then it parses the number and returns\nit. Otherwise, it returns the input as a string.\n\n```sql\nfav \u003c- INPUT(\"What's your favorite color?\")\nDISPLAY(\"Cool! My favorite color is\", fav, \"too!\")\n```\n\n```\n$ aps run [myfile.aps]\n  What's your favorite color? [input: blue]\n  Cool! My favorite color is blue too!\n```\n\n\u003e Note: All of the builtins are standalone function pointers wrapped as values\n\u003e in the interpreter. You can view the source of any of them in `src/stdlib.rs`\n\u003e and add your own builtins by appending them to the scope of `VM`.\n\n## Notes\n\n- `FOR EACH _ IN _` only goes through indices that were present at the start of\n  the block. It does not, for example, go on forever if you were to append items\n  to the list in the middle of the loop because it uses a cached length of the\n  array. If the array had a few items removed while iterating, then the loop\n  will simply terminate silently.\n\n## License\n\naps is licensed under the MIT License.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsno2%2Fapscript","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsno2%2Fapscript","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsno2%2Fapscript/lists"}