forked from namin/inc
-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This patch probably broke some stuff and made a few things even more terrible, but I couldn't stand Chez Scheme anymore and this took definitely less time than rewriting everything in Haskell. Particularly, 1. racket-mode seems nice, but there is a lot more work required to get comfortable with this. 2. Move files around such that state like pwd is the same for the CLI and repl. This is required to run tests both ways for example. 3. Reload works as long as I use code from just one buffer, but I've no idea how to use definitions from 2 modules at the same time in REPL. 4. Fixed some warts with the Makefile, related to point 2 5. Removed the srfi BS. Racket's stdlib is far richer. 6. Racket's stricter compiler found some issues with arity mismatch in `primitive`, I'm starting to see benefits already. 7. `assert` is gone, should bring it back soon along with typed racket 8. Moved things around to avoid cyclic dependencies. This is an error with Racket unlike Chez. I miss go where everything in a folder is a module and its easier to organize code. 9. Macros are way more painful to than it should ever be. Either I don't get this, or this is vaporware oversold. I'm probably going to replace them with regular functions soon. tldr; I see no reason why I'd write Scheme over Haskell ever again.
- Loading branch information
1 parent
5157d8e
commit a8ab1e6
Showing
20 changed files
with
277 additions
and
1,287 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
#lang racket | ||
|
||
(require "compiler.rkt") | ||
|
||
(provide all-tests add-tests test-all) | ||
|
||
(define file-asm "/tmp/inc.s") | ||
(define file-bin "inc") | ||
(define file-out "/tmp/inc.out") | ||
|
||
;; Collect all tests in a global variable | ||
(define all-tests '()) | ||
|
||
;; Indirect way to get around mutating module level variables. | ||
;; | ||
;; tldr; `set!` is not allowed on module level variables, this function prevents | ||
;; the error `set!: cannot mutate module-required identifier` | ||
;; https://docs.racket-lang.org/guide/module-set.html | ||
(define (mut! val) | ||
(set! all-tests val)) | ||
|
||
(define-syntax add-tests | ||
(syntax-rules (=> >>) | ||
[(_ test-name [input x expectation] ...) | ||
(mut! (cons '(test-name [input x expectation] ...) all-tests))])) | ||
|
||
;; Run the compiler but send the output to a file instead | ||
(define (compile-program expr) | ||
;; Delete previous output file if any; existence of this file fails the test | ||
;; consistently on docker. | ||
(system (format "rm -f ~a ~a" file-out file-bin)) | ||
(let ([p (open-output-file file-asm #:exists 'replace)]) | ||
(parameterize ([compile-port p]) | ||
(emit-program expr)) | ||
(close-output-port p))) | ||
|
||
(define (build) | ||
(unless (system "make -C .. --quiet") | ||
(error 'make "Could not build target"))) | ||
|
||
;; Execute the binary and return the output as a string | ||
(define (execute) | ||
(let ([command (format "../~a > ~a" file-bin file-out)]) | ||
(unless (system command) | ||
(error 'make "Produced program exited abnormally")) | ||
(read (open-input-file file-out)))) | ||
|
||
;; Compile, build, execute and show the result in shell. Great for devel | ||
(define (run expr) | ||
(compile-program expr) | ||
(build) | ||
(execute)) | ||
|
||
(define (test-one test-id test) | ||
(let ([input (car test)] | ||
[type (cadr test)] | ||
[expectation (caddr test)]) | ||
(printf "Test ~s: ~s ..." test-id input) | ||
|
||
(case type | ||
|
||
;; Compile, build, execute and assert output with expectation | ||
['=> (let ([result (run input)]) | ||
(unless (equal? expectation result) | ||
(error 'match-test | ||
(format "~s. expected ~s, got ~s" | ||
test-id expectation result))))] | ||
|
||
;; Run a unit test | ||
['>> (let* (;; Eval + namespace is really ugly and needs to be sorted out. | ||
[ns (module->namespace "compiler.rkt")] | ||
[result (eval input ns)]) | ||
(unless (equal? result (eval expectation ns)) | ||
(error 'unit-test | ||
(format "~s. expected ~s, got ~s" | ||
test-id (eval expectation ns) result))))]) | ||
(printf " ok\n"))) | ||
|
||
(define (test-all) | ||
(let f ([i 0] [ls all-tests]) | ||
(if (null? ls) | ||
(printf "Passed all ~s tests\n" i) | ||
(let ([x (car ls)] [ls (cdr ls)]) | ||
(let* ([test-name (car x)] | ||
[tests (cdr x)] | ||
[n (length tests)]) | ||
(printf "Performing ~a tests ...\n" test-name) | ||
(let g ([i i] [tests tests]) | ||
(cond | ||
[(null? tests) (f i ls)] | ||
[else | ||
(test-one i (car tests)) | ||
(g (add1 i) (cdr tests))]))))))) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
#lang racket | ||
|
||
(require "../tests/01-integers.rkt" | ||
"../tests/02-immediate.rkt" | ||
"../tests/03-unary.rkt" | ||
"../tests/04-binop.rkt" | ||
"../tests/05-if.rkt" | ||
"../tests/06-let.rkt" | ||
"../tests/07-cons.rkt" | ||
"../tests/08-procedures.rkt" | ||
"../tests/09-strings.rkt" | ||
"../tests/10-cc.rkt" | ||
|
||
"compiler.rkt" | ||
"driver.rkt") | ||
|
||
(test-all) |
Oops, something went wrong.