{"id":17769472,"url":"https://github.com/pagliacii/sicp-reg-machine","last_synced_at":"2025-11-11T11:16:02.451Z","repository":{"id":108252333,"uuid":"383199683","full_name":"Pagliacii/sicp-reg-machine","owner":"Pagliacii","description":"Register machine in SICP Chapter 5. Solve exercise 5.51.","archived":false,"fork":false,"pushed_at":"2021-07-24T08:25:14.000Z","size":362,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-02-07T09:11:27.727Z","etag":null,"topics":["compiler","nom","rust","sicp"],"latest_commit_sha":null,"homepage":"","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/Pagliacii.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":"2021-07-05T16:17:25.000Z","updated_at":"2023-08-16T01:47:40.000Z","dependencies_parsed_at":"2023-03-29T13:03:18.748Z","dependency_job_id":null,"html_url":"https://github.com/Pagliacii/sicp-reg-machine","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/Pagliacii%2Fsicp-reg-machine","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Pagliacii%2Fsicp-reg-machine/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Pagliacii%2Fsicp-reg-machine/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Pagliacii%2Fsicp-reg-machine/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Pagliacii","download_url":"https://codeload.github.com/Pagliacii/sicp-reg-machine/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246652098,"owners_count":20812086,"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","nom","rust","sicp"],"created_at":"2024-10-26T21:12:23.634Z","updated_at":"2025-11-11T11:16:02.402Z","avatar_url":"https://github.com/Pagliacii.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Register Machine\n\nThe machine details could be found in the SICP chapter 5. See [here](https://sarabander.github.io/sicp/html/5_002e1.xhtml#g_t5_002e1).\n\n## Instruction Summary\n\n```scheme\n; access the register contents\n(reg \u003cregister-name\u003e)\n; a constant value\n(const \u003cconstant-value\u003e)\n; a control label\n(label \u003clabel-name\u003e)\n; test a condition and jump to the control label\n(test (op \u003coperation-name\u003e) \u003cinput_1\u003e ... \u003cinput_n\u003e)\n(branch (label \u003clabel-name\u003e)) ; only jump if the preceded test passes\n; go to label immediately\n(goto (label \u003clabel-name\u003e))\n; or go to label holds in the register\n(goto (reg \u003cregister-name\u003e))\n; perform an operation\n(perform (op \u003coperation-name\u003e) \u003cinput_1\u003e .. \u003cinput_n\u003e)\n; assignment\n(assign \u003cregister-name\u003e (reg \u003cregister-name\u003e))\n(assign \u003cregister-name\u003e (const \u003cconstant-value\u003e))\n(assign \u003cregister-name\u003e (op \u003coperation-name\u003e) \u003cinput_1\u003e .. \u003cinput_n\u003e)\n(assign \u003cregister-name\u003e (label \u003clabel-name\u003e))\n; instructions to use the stack\n(save \u003cregister-name\u003e)\n(restore \u003cregister-name\u003e)\n```\n\nValid kinds of constant value:\n\n- `(const 123)` is the number `123`,\n- `(const 1.23)` is the float point number `1.23`,\n- `(const \"abc\")` is the string `\"abc\"`,\n- `(const abc)` is the symbol `abc`,\n- `(const (a b c))` is the list `(a b c)`,\n- and `(const ())` is the empty list.\n\n## Machines\n\n| Machine                        | Details                                                                                                                                                                              | Code                                                      |\n| ------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | --------------------------------------------------------- |\n| Fibonacci                      | See [Section 5.1.4](https://sarabander.github.io/sicp/html/5_002e1.xhtml#g_t5_002e1_002e4) and [Figure 5.12](https://sarabander.github.io/sicp/html/5_002e1.xhtml#Figure-5_002e12)   | [fibonacci.rs](examples/fibonacci.rs)                     |\n| GCD V1                         | See [Section 5.1.1](https://sarabander.github.io/sicp/html/5_002e1.xhtml#g_t5_002e1_002e1)                                                                                           | [gcd.rs](examples/gcd.rs)                                 |\n| GCD V2                         | See [Figure 5.4](https://sarabander.github.io/sicp/html/5_002e1.xhtml#Figure-5_002e4)                                                                                                | [gcd_v2.rs](examples/gcd_v2.rs)                           |\n| GCD V3                         | See [Figure 5.5](https://sarabander.github.io/sicp/html/5_002e1.xhtml#Figure-5_002e5) and [Figure 5.6](https://sarabander.github.io/sicp/html/5_002e1.xhtml#Figure-5_002e6)          | [gcd_v3.rs](examples/gcd_v3.rs)                           |\n| Factorial                      | See [Exercise 5.1](https://sarabander.github.io/sicp/html/5_002e1.xhtml#Exercise-5_002e1) and [Exercise 5.2](https://sarabander.github.io/sicp/html/5_002e1.xhtml#Exercise-5_002e2)  | [factorial.rs](examples/factorial.rs)                     |\n| Recursive Factorial            | See [Section 5.1.4](https://sarabander.github.io/sicp/html/5_002e1.xhtml#g_t5_002e1_002e4) and [Figure 5.11](https://sarabander.github.io/sicp/html/5_002e1.xhtml#Figure-5_002e11)   | [recursive_factorial.rs](examples/recursive_factorial.rs) |\n| Newton V1                      | See [Exercise 5.3](https://sarabander.github.io/sicp/html/5_002e1.xhtml#Exercise-5_002e3) and [Section 1.1.7](https://sarabander.github.io/sicp/html/1_002e1.xhtml#g_t1_002e1_002e7) | [newton.rs](examples/newton.rs)                           |\n| Newton V2                      | See [Exercise 5.3](https://sarabander.github.io/sicp/html/5_002e1.xhtml#Exercise-5_002e3) and [Section 1.1.7](https://sarabander.github.io/sicp/html/1_002e1.xhtml#g_t1_002e1_002e7) | [newton_v2.rs](examples/newton_v2.rs)                     |\n| Iterative Exponentiation       | See [Exercise 5.4](https://sarabander.github.io/sicp/html/5_002e1.xhtml#Exercise-5_002e4)                                                                                            | [iterative_exp.rs](examples/iterative_exp.rs)             |\n| Recursive Exponentiation       | See [Exercise 5.4](https://sarabander.github.io/sicp/html/5_002e1.xhtml#Exercise-5_002e4)                                                                                            | [recursive_exp.rs](examples/recursive_exp.rs)             |\n| The Explicit-Control Evaluator | See [Section 5.4](https://sarabander.github.io/sicp/html/5_002e4.xhtml#g_t5_002e4) and [controller.scm](examples/ec_evaluator/controller.scm)                                        | [main.rs](examples/ec_evaluator/main.rs)                  |\n\n### Running\n\n```shell\n$ git clone https://github.com/Pagliacii/sicp-reg-machine\n$ cd sicp-reg-machine\n# List all machines\n$ ls examples\n# Running machine\n$ cargo run --example \u003cmachine-name\u003e\n```\n\n## Exercise 5.51\n\n\u003e Develop a rudimentary implementation of Scheme in C (or some other low-level language of your choice) by translating the explicit-control evaluator of [Section 5.4](https://sarabander.github.io/sicp/html/5_002e4.xhtml#g_t5_002e4) into C. In order to run this code you will need to also provide appropriate storage-allocation routines and other run-time support.\n\n### The Explicit-Control Evaluator\n\nSee [5.4 The Explicit-Control Evaluator](https://sarabander.github.io/sicp/html/5_002e4.xhtml#g_t5_002e4) for more details.\n\n#### Play with it\n\n```scheme\n$ cargo run --example ec_evaluator\n    Finished dev [unoptimized + debuginfo] target(s) in 0.06s\n     Running `target/debug/examples/ec_evaluator`\n\n;;; EC-Eval input:\n(define (factorial n)\n  (if (= n 1) 1 (* (factorial (- n 1)) n)))\n\n;;; EC-Eval value:\nok\n\n;;; EC-Eval input:\n(factorial 5)\n\n;;; EC-Eval value:\n120\n\n;;; EC-Eval input:\n(define (factorial n)\n  (define (iter product counter)\n    (if (\u003e counter n)\n        product\n        (iter (* product counter) (+ counter 1))))\n  (iter 1 1))\n\n;;; EC-Eval value:\nok\n\n;;; EC-Eval input:\n(factorial 5)\n\n;;; EC-Eval value:\n120\n\n;;; EC-Eval input:\n(define (append x y)\n  (if (null? x) y (cons (car x) (append (cdr x) y))))\n\n;;; EC-Eval value:\nok\n\n;;; EC-Eval input:\n(append '(a b c) '(d e f))\n\n;;; EC-Eval value:\n(a b c d e f)\n\n;;; EC-Eval input:\n(define (fib n)\n  (if (\u003c n 2)\n      n\n      (+ (fib (- n 1)) (fib (- n 2)))))\n\n;;; EC-Eval value:\nok\n\n;;; EC-Eval input:\n(fib 5)\n\n;;; EC-Eval value:\n5\n\n;;; EC-Eval input:\n(fib 6)\n\n;;; EC-Eval value:\n8\n\n;;; EC-Eval input:\n(exit)\n```\n\n#### Enable debug logging\n\n```shell\n# output to stderr\n$ RUST_LOG=debug cargo run --example ec_evaluator\n# redirect to a file. *Note*: direct writes to a file can become a bottleneck due to IO operation times.\n$ RUST_LOG=debug cargo run --example ec_evaluator 2\u003e /path/to/log/file\n```\n\n#### Currently supports syntax\n\n```scheme\n; number\n1\n1.2\n; boolean\ntrue\nfalse\n;; or\n#t\n#f\n; string\n\"hello\"\n\"hi\"\n\"123\"\n; symbol\n'hello\n'hi\n; list\n(list 1 2 3 4)\n'(1 2 3 4)\n'(a b c)\n'()\n; manipulate pair\n(define p (cons 1 2))\n(car p) ; =\u003e 1\n(cdr p) ; =\u003e 2\n; primitive procedures*\n(+ 1 1)\n(- 1 1)\n(* 2 1.5)\n(/ 1 2)\n; definition\n;; define a variable\n(define a 1)\n;; define a procedure\n(define (inc x) (+ x 1))\n; access and assignment\na\n(set! a 2)\na\n; if statement\n(if (\u003e a 1) (display \"fizz\") (display \"buzz\"))\n;; or without else branch\n(if (\u003c a 1) (display \"without else\"))\n; lambda statement\n(lambda (a b) (if (\u003e a b) (display \"a\")))\n; sequence statements\n(begin (define a 1)\n       (set! a 2)\n       (if (\u003e a 1) (display \"hello\")))\n; call a procedure\n(+ 1 1)\n(inc 2)\n((lambda (a b) (if (\u003e a b) (display \"a\"))) 2 1)\n; `cond` statement\n(cond ((= a 1) (display \"Apple\")  (newline))\n      ((= a 2) (display \"Banana\") (newline))\n      ((= a 3) (display \"Cherry\") (newline))\n      (else    (display \"Oops\")   (newline)))\n;; `cond` in procedure definition\n(define (abs x)\n  (cond ((\u003c x 0) (- x))\n        ((= x 0) 0)\n        (else (+ x))))\n; logical composition operations\n(and #t #t #t)    ;; zero or more arbitrary arguments\n(or #f #f #f #f)  ;; zero or more arbitrary arguments\n(not #f)          ;; requires exactly 1 argument\n; `let` statement, a syntactic sugar\n(let ((a 1) (b 2) (c 3))\n  (display (+ a b c)))\n; `let*` statement, a syntactic sugar\n(let* ((x 3) (y (+ x 2)) (z (+ x y 5)))\n  (* x z))\n; \"Named `let`\" statement: `(let \u003cvar\u003e \u003cbindings\u003e \u003cbody\u003e)`\n(define (fib n)\n  (let fib-iter ((a 1)\n                 (b 0)\n                 (count n))\n    (if (= count 0)\n        b\n        (fib-iter (+ a b) a (- count 1)))))\n(fib 50) ; =\u003e 12586269025\n```\n\n**Note:**\n\n1. See [primitive.rs](examples/ec_evaluator/supports/primitive.rs) for more primitive procedures.\n\n2. `cond` Statement Details:\n\n![cond-statement-flow](examples/ec_evaluator/img/cond-statement-flow.svg)\n\n## License\n\nThis project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.\n\n## Acknowledgments\n\n- Sam Scott - [Building a runtime reflection system for Rust 🦀️](https://www.osohq.com/post/rust-reflection-pt-1)\n- Michael-F-Bryan - [How could I implement a more accurate comparison?](https://users.rust-lang.org/t/how-could-i-implement-a-more-accurate-comparison/61698/6)\n- H2CO3 - [How to use a HashMap to store a struct method?](https://users.rust-lang.org/t/how-to-use-a-hashmap-to-store-a-struct-method/61726/2)\n- Geoffroy Couprie - [Geal/nom](https://github.com/Geal/nom)\n- code and bitters - [Learning Rust: Let's Build a Parser!](https://codeandbitters.com/lets-build-a-parser/)\n- 2e71828 - [How to import a trait defined at another file inside a macro?](https://users.rust-lang.org/t/how-to-import-a-trait-defined-at-another-file-inside-a-macro/62697)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpagliacii%2Fsicp-reg-machine","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpagliacii%2Fsicp-reg-machine","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpagliacii%2Fsicp-reg-machine/lists"}