{"id":18645478,"url":"https://github.com/cscott/rusty-turtle","last_synced_at":"2025-09-14T05:13:45.359Z","repository":{"id":66063582,"uuid":"10137816","full_name":"cscott/rusty-turtle","owner":"cscott","description":"A TurtleScript interpreter written in Rust.","archived":false,"fork":false,"pushed_at":"2013-10-03T06:10:56.000Z","size":1040,"stargazers_count":18,"open_issues_count":1,"forks_count":1,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-03-25T13:51:10.131Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/cscott.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"COPYING","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2013-05-18T07:01:25.000Z","updated_at":"2024-02-15T10:02:37.000Z","dependencies_parsed_at":"2023-02-19T22:00:52.312Z","dependency_job_id":null,"html_url":"https://github.com/cscott/rusty-turtle","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/cscott%2Frusty-turtle","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cscott%2Frusty-turtle/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cscott%2Frusty-turtle/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cscott%2Frusty-turtle/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/cscott","download_url":"https://codeload.github.com/cscott/rusty-turtle/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248401955,"owners_count":21097328,"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-07T06:16:04.246Z","updated_at":"2025-04-11T12:31:21.874Z","avatar_url":"https://github.com/cscott.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# rusty-turtle\n\n`rusty-turtle` is an implementation of\n[TurtleScript](https://github.com/cscott/turtlescript) in\n[Rust](http://www.rust-lang.org/).  TurtleScript is a syntactic\n(but not semantic) subset of JavaScript, originally created for\nthe One Laptop per Child project.\n\n## Build, Install, and Run\n\nNot hard... just start by building the latest (28-May-2013) version of rust.\nNo problem, right?  After that,\n```\n$ make\n```\nwill create an executable named `main`.  To run a TurtleScript\n[REPL](http://en.wikipedia.org/wiki/Read%E2%80%93eval%E2%80%93print_loop):\n```\n$ ./main\n\u003e 2+3\n5\n\u003e var fact = function(x) { return (x\u003c2) ? x : (x * fact(x-1)) ; };\nundefined\n\u003e fact(42)\n1405006117752880268066222604204040608686664282428002\n\u003e\n```\nUse Control-D (or Control-C) to exit the REPL.  You can also evaluate entire\nTurtleScript scripts by passing the name on the command line:\n```\n$ ./main foo.js\n```\n\n## Testing\nThere are quite a few unit tests built into `rusty-turtle` (although never\nenough!).  You can build and run them with `make test`.  See the end of\n`interp.rs` for a set of script-based tests, which you could manually\nreproduce in the REPL (if you were so inclined).\n\n## Design\n`rusty-turtle` is a simple interpreter for the bytecode emitted by\n`bcompile.js` from the TurtleScript project.  It is heavily based on\n`binterp.js` from that project, which is a TurtleScript interpreter written\nin TurtleScript.  The `startup.rs` file contains the bytecode for the\nTurtleScript standard library implementation (from `binterp.js`) as\nwell as the tokenizer, parser, and bytecode compiler itself (emitted\nby `write-rust-bytecode.js` in the TurtleScript project).  This allows\nthe `rusty-turtle` REPL to parse and compile the expressions you type\nat it into modules which it can interpret.\n\nThe interpreter is not particularly fast, however it could become so.\nThe object model used associates an object map with every object; this\nmap gives the position of all fields in the object.  One of the ideas\nbehind `rusty-turtle` was to explore the JavaScript/Rust interaction\nmodel; I wanted to see if one could use \"native rust\" data structures\nfrom JavaScript by simply providing an appropriate object map, and\nvice-versa.  In fact, the vice-versa case was more interesting;\nsince I'm one of the maintainers of\n[Domino](https://github.com/fgnass/domino), which is a fork of\nMozilla's [dom.js](https://github.com/andreasgal/dom.js) project,\nI was interested in exploring whether the native javascript\ndata structure used by domino/dom.js could in fact be accessed\ndirectly by rust (since [Servo](https://github.com/mozilla/servo)\nuses hand-coded JS bindings to a native Rust data structure instead).\n\nFor a fast(er) interpreter, the field lookup in the object map would\nhappen only the first time a method was executed/interpreted; future\nuses would use a direct dereference of the appropriate field in the\nobject (so long as the object map for the value remained the same).\n\n## Other research ideas\n\nI've already described dom.js/servo as an interesting experiment.  Other\nresearch ideas which could be pursued with `rusty-turtle`:\n\n1. Concurrency/parallelism exploration.  The most obvious map to Rust's\ncurrent concurrency mechanisms would be a web workers-style message-passing\ninterface.  Each TurtleScript \"worker\" would have its own Rust task and\n@-heap, and use (wrapped) Rust message pipes to communicate.\n\n    But a more interesting exploration would use data sharing and fork/join\nparallelism.  This could be pursued along with the experimental\nfork/join support in Rust, or it could be emulated using remote objects.\n\n    Alternatively, speculative/transactional execution could be explored.\nA typical web page begins with a handful of `\u003cscript\u003e` tags, often\nloading independent libraries.  One could imagine executing all those\nscripts in parallel, pausing or aborting execution only if a sequential\ndependency was violated.\n\n2. Export Rust's llvm interface to TurtleScript code, then write a TurtleScript\nJIT in TurtleScript, using the Rust data structure for objects in memory.\n\n3. Tweak TurtleScript/`rusty-turtle` to parse/interpret\n[asm.js](http://asmjs.org/); then write a bytecode-to-asm.js compiler\nfor TurtleScript.  The object map, layout and field lookup/access code\nwould probably be moved into TurtleScript, such that the heap is\naccessed via a Typed Array.\n\n4. Optimization via partial evaluation.  The interpreter still needs\nto do a significant amount of type matching and virtual dispatch.\nMuch of this could be simplified via partial evaluation.  That is,\nthe first time a method is executed, various constants and near-constants\n(such as the object map corresponding to the method arguments) would\nbe tracked and a specialized version of the method compiled which\npropagates all the constants through the method, including field offsets\nand method dispatch targets.\n\n## License\n\nTurtleScript and `rusty-turtle` are (c) 2010-2013 C. Scott Ananian and\nlicensed under the terms of the GNU GPL v2.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcscott%2Frusty-turtle","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcscott%2Frusty-turtle","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcscott%2Frusty-turtle/lists"}