{"id":16724273,"url":"https://github.com/badboy/ruby-hackvm","last_synced_at":"2025-03-15T14:40:51.484Z","repository":{"id":450389,"uuid":"73543","full_name":"badboy/ruby-hackvm","owner":"badboy","description":"a virtual machine for hackers","archived":false,"fork":false,"pushed_at":"2009-01-17T16:31:27.000Z","size":96,"stargazers_count":2,"open_issues_count":0,"forks_count":1,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-03-14T19:52:09.678Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Ruby","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/badboy.png","metadata":{"files":{"readme":"README.textile","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}},"created_at":"2008-11-09T16:54:23.000Z","updated_at":"2019-08-13T13:41:40.000Z","dependencies_parsed_at":"2022-07-07T14:41:49.816Z","dependency_job_id":null,"html_url":"https://github.com/badboy/ruby-hackvm","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/badboy%2Fruby-hackvm","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/badboy%2Fruby-hackvm/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/badboy%2Fruby-hackvm/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/badboy%2Fruby-hackvm/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/badboy","download_url":"https://codeload.github.com/badboy/ruby-hackvm/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243639489,"owners_count":20323507,"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-10-12T22:44:35.491Z","updated_at":"2025-03-15T14:40:51.465Z","avatar_url":"https://github.com/badboy.png","language":"Ruby","funding_links":[],"categories":[],"sub_categories":[],"readme":"h1. Ruby Hack VM\n\nh2. Information\n\nh3. The Hack VM is a tiny, trivial, virtual machine.\n\nIts purpose is to be used as a simple execution engine that can run very simple programs.\n\nmore Information on \u003ca href=\"http://www.hacker.org/hvm/\"\u003ehttp://www.hacker.org/hvm/\u003c/a\u003e\n\nThe virtual machine executes a single program and terminates, either by reaching the end of the code, an '!' instruction, or because an exception was thrown during execution.\nA program is represented by a string of single-character instructions.\nThe virtual machine starts with the first instruction, executes it, and moves on to the next instruction, etc... \n\nThe index of the current instruction is called the program counter.\nThe execution model is simple: the virtual machine has an operand stack, a memory buffer, and a call stack.\n\nEach item on the operand stack or in memory is a cell that can hold a signed integer. \nFor implementation reasons, those integers are currently limited to 32 bits, but do not count on it, they could be large in future implementations. \nThe call stack is used to push the value of the program counter when jumping to a routine from which we want to return.\n\nh2. Instructions\n\n\u003cpre\u003e\nInstruction\t\tDescription\n' '\t\tDo Nothing \n'p'\t\tPrint S0 interpreted as an integer \n'P'\t\tPrint S0 interpreted as an ASCII character (only the least significant 7 bits of the value are used) \n'0'\t\tPush the value 0 on the stack \n'1'\t\tPush the value 1 on the stack \n'2'\t\tPush the value 2 on the stack \n'3'\t\tPush the value 3 on the stack \n'4'\t\tPush the value 4 on the stack \n'5'\t\tPush the value 5 on the stack \n'6'\t\tPush the value 6 on the stack \n'7'\t\tPush the value 7 on the stack \n'8'\t\tPush the value 8 on the stack \n'9'\t\tPush the value 9 on the stack \n'+'\t\tPush S1+S0 \n'-'\t\tPush S1-S0 \n'*'\t\tPush S1*S0 \n'/'\t\tPush S1/S0 \n':'\t\tPush -1 if S1\u003cS0, 0 if S1=S0, or 1 S1\u003eS0\n'g'\t\tAdd S0 to the program counter \n'?'\t\tAdd S0 to the program counter if S1 is 0 \n'c'\t\tPush the program counter on the call stack and set the program counter to S0 \n'$'\t\tSet the program counter to the value pop'ed from the call stack \n'\u003c'\t\tPush the value of memory cell S0 \n'\u003e'\t\tStore S1 into memory cell S0 \n'^'\t\tPush a copy of S\u003cS0+1\u003e (ex: 0^ duplicates S0) \n'v'\t\tRemove S\u003cS0+1\u003e from the stack and push it on top (ex: 1v swaps S0 and S1) \n'd'\t\tDrop S0 \n'!'\t\tTerminate the program \n\u003c/pre\u003e\n\n\nh2. Examples\n\nInput: \"78*p\" Output: 56\n\nInput: \"123451^2v5:4?9p2g8pppppp\" Output: 945321\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbadboy%2Fruby-hackvm","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbadboy%2Fruby-hackvm","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbadboy%2Fruby-hackvm/lists"}