├── .gitignore
├── .travis.yml
├── LICENSE.txt
├── README.md
├── assets
├── index.html
├── main.rkt
├── main.wasm
└── main.wat
├── compiler.rkt
├── info.rkt
├── main.rkt
└── scribblings
└── wracket.scrbl
/.gitignore:
--------------------------------------------------------------------------------
1 | *~
2 | \#*
3 | .\#*
4 | .DS_Store
5 | compiled/
6 | /doc/
7 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: c
2 |
3 | # Based from: https://github.com/greghendershott/travis-racket
4 |
5 | # Optional: Remove to use Travis CI's older infrastructure.
6 | sudo: false
7 |
8 | env:
9 | global:
10 | # Supply a global RACKET_DIR environment variable. This is where
11 | # Racket will be installed. A good idea is to use ~/racket because
12 | # that doesn't require sudo to install and is therefore compatible
13 | # with Travis CI's newer container infrastructure.
14 | - RACKET_DIR=~/racket
15 | matrix:
16 | # Supply at least one RACKET_VERSION environment variable. This is
17 | # used by the install-racket.sh script (run at before_install,
18 | # below) to select the version of Racket to download and install.
19 | #
20 | # Supply more than one RACKET_VERSION (as in the example below) to
21 | # create a Travis-CI build matrix to test against multiple Racket
22 | # versions.
23 | - RACKET_VERSION=6.0
24 | - RACKET_VERSION=6.1
25 | - RACKET_VERSION=6.1.1
26 | - RACKET_VERSION=6.2
27 | - RACKET_VERSION=6.3
28 | - RACKET_VERSION=6.4
29 | - RACKET_VERSION=6.5
30 | - RACKET_VERSION=6.6
31 | - RACKET_VERSION=6.7
32 | - RACKET_VERSION=6.8
33 | - RACKET_VERSION=6.9
34 | - RACKET_VERSION=6.10
35 | - RACKET_VERSION=6.10.1
36 | - RACKET_VERSION=6.11
37 | - RACKET_VERSION=HEAD
38 |
39 | matrix:
40 | allow_failures:
41 | # - env: RACKET_VERSION=HEAD
42 | fast_finish: true
43 |
44 | before_install:
45 | - git clone https://github.com/greghendershott/travis-racket.git ~/travis-racket
46 | - cat ~/travis-racket/install-racket.sh | bash # pipe to bash not sh!
47 | - export PATH="${RACKET_DIR}/bin:${PATH}" #install-racket.sh can't set for us
48 |
49 | install:
50 | - raco pkg install --deps search-auto
51 |
52 | before_script:
53 |
54 | # Here supply steps such as raco make, raco test, etc. You can run
55 | # `raco pkg install --deps search-auto` to install any required
56 | # packages without it getting stuck on a confirmation prompt.
57 | script:
58 | - raco test -x -p wracket
59 |
60 | after_success:
61 | - raco setup --check-pkg-deps --pkgs wracket
62 | - raco pkg install --deps search-auto cover cover-coveralls
63 | - raco cover -b -f coveralls -d $TRAVIS_BUILD_DIR/coverage .
64 |
--------------------------------------------------------------------------------
/LICENSE.txt:
--------------------------------------------------------------------------------
1 | wracket
2 | Copyright (c) 2017 Simon Schauß
3 |
4 | This package is distributed under the GNU Lesser General Public
5 | License (LGPL). This means that you can link wracket into proprietary
6 | applications, provided you follow the rules stated in the LGPL. You
7 | can also modify this package; if you distribute a modified version,
8 | you must distribute it under the terms of the LGPL, which in
9 | particular means that you must release the source code for the
10 | modified software. See http://www.gnu.org/copyleft/lesser.html
11 | for more information.
12 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | wracket
2 | =======
3 | README text here.
4 |
--------------------------------------------------------------------------------
/assets/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | wracket
7 |
8 |
9 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/assets/main.rkt:
--------------------------------------------------------------------------------
1 | (module
2 | (define- (fib n)
3 | (if (<= n 2)
4 | 1
5 | (+ (fib (- n 1)) (fib (- n 2)))))
6 | (define+ (main n) (fib n)))
7 |
--------------------------------------------------------------------------------
/assets/main.wasm:
--------------------------------------------------------------------------------
1 | asm ` main
2 | ' ALA Ak Ak j
--------------------------------------------------------------------------------
/assets/main.wat:
--------------------------------------------------------------------------------
1 | (module (func $fib (param $n i32) (result i32) (return (if (result i32) (i32.le_s (get_local $n) (i32.const 2)) (then (i32.const 1)) (else (i32.add (call $fib (i32.sub (get_local $n) (i32.const 1))) (call $fib (i32.sub (get_local $n) (i32.const 2)))))))) (func $main (param $n i32) (result i32) (return (call $fib (get_local $n)))) (export "main" (func $main)))
--------------------------------------------------------------------------------
/compiler.rkt:
--------------------------------------------------------------------------------
1 | #lang at-exp racket
2 | (provide compile-file)
3 |
4 | (define (compile-file filename)
5 | (let* ([i (open-input-file filename)]
6 | [f (string-replace filename "rkt" "wat")]
7 | [o (open-output-file f #:exists 'replace)])
8 | (let-values ([(c env) (compile (read i) (list))])
9 | (write-string c o))))
10 |
11 | (define (compile d env)
12 | (match d
13 | [`,(? number?) (compile-number d env)]
14 | [`,(? symbol?) (compile-symbol d env)]
15 | [`(+ ,l ,r) (compile-add l r env)]
16 | [`(- ,l ,r) (compile-minus l r env)]
17 | [`(* ,l ,r) (compile-multiply l r env)]
18 | [`(/ ,l ,r) (compile-divide l r env)]
19 | [`(= ,l ,r) (compile-equal l r env)]
20 | [`(!= ,l ,r) (compile-unequal l r env)]
21 | [`(> ,l ,r) (compile-greater l r env)]
22 | [`(>= ,l ,r) (compile-greater-equal l r env)]
23 | [`(< ,l ,r) (compile-less l r env)]
24 | [`(<= ,l ,r) (compile-less-equal l r env)]
25 | [`(define- (,name ,params ...) ,body ...) (compile-define- name params body env)]
26 | [`(define+ (,name ,params ...) ,body ...) (compile-define+ name params body env)]
27 | [`(let [,name ,exp] ,body ...) (compile-let name exp body env)]
28 | [`(if ,cond ,exp1 ,exp2) (compile-if-then-else cond exp1 exp2 env)]
29 | [`(module ,body ...) (compile-module body env)]
30 | [`(,name ,params ...) (compile-call name params env)]))
31 |
32 | (define (compile* exps env)
33 | (letrec ([compile* (lambda (exps env result)
34 | (if (empty? exps)
35 | (values result env)
36 | (let-values ([(exp env) (compile (first exps) env)])
37 | (compile* (rest exps) env (append result (list exp))))))])
38 | (compile* exps env '())))
39 |
40 | (define (compile-number n env)
41 | (values @~a{(i32.const @n)} env))
42 |
43 | (define (compile-symbol s env)
44 | (values @~a{(get_local $@s)} env))
45 |
46 | (define (compile-add l r env)
47 | (let*-values ([(l env) (compile l env)]
48 | [(r env) (compile r env)])
49 | (values @~a{(i32.add @l @r)} env)))
50 |
51 | (define (compile-minus l r env)
52 | (let*-values ([(l env) (compile l env)]
53 | [(r env) (compile r env)])
54 | (values @~a{(i32.sub @l @r)} env)))
55 |
56 | (define (compile-multiply l r env)
57 | (let*-values ([(l env) (compile l env)]
58 | [(r env) (compile r env)])
59 | (values @~a{(i32.mul @l @r)} env)))
60 |
61 | (define (compile-divide l r env)
62 | (let*-values ([(l env) (compile l env)]
63 | [(r env) (compile r env)])
64 | (values @~a{(i32.div @l @r)} env)))
65 |
66 | (define (compile-equal l r env)
67 | (let*-values ([(l env) (compile l env)]
68 | [(r env) (compile r env)])
69 | (values @~a{(i32.eq @l @r)} env)))
70 |
71 | (define (compile-unequal l r env)
72 | (let*-values ([(l env) (compile l env)]
73 | [(r env) (compile r env)])
74 | (values @~a{(i32.ne @l @r)} env)))
75 |
76 | (define (compile-greater l r env)
77 | (let*-values ([(l env) (compile l env)]
78 | [(r env) (compile r env)])
79 | (values @~a{(i32.gt_s @l @r)} env)))
80 |
81 | (define (compile-greater-equal l r env)
82 | (let*-values ([(l env) (compile l env)]
83 | [(r env) (compile r env)])
84 | (values @~a{(i32.ge_s @l @r)}) env))
85 |
86 | (define (compile-less l r env)
87 | (let*-values ([(l env) (compile l env)]
88 | [(r env) (compile r env)])
89 | (values @~a{(i32.lt_s @l @r)} env)))
90 |
91 | (define (compile-less-equal l r env)
92 | (let*-values ([(l env) (compile l env)]
93 | [(r env) (compile r env)])
94 | (values @~a{(i32.le_s @l @r)} env)))
95 |
96 | (define (compile-let name exp body env)
97 | (let*-values ([(exp env) (compile exp env)]
98 | [(body env) (compile* body env)]
99 | [(body) (string-join body)]
100 | [(env) (cons name env)])
101 | (values @~a{(block (result i32) (set_local $@name @exp) @body)} env)))
102 |
103 | (define (compile-define- name params body env)
104 | (let*-values ([(body env) (compile* body env)]
105 | [(body) (string-join body)]
106 | [(params) (string-join (map (lambda (param) @~a{(param $@param i32)}) params))]
107 | [(locals) (string-join (map (lambda (name) @~a{(local $@name i32)}) env))])
108 | (values @~a{(func $@name @params (result i32) @locals (return @body))} env)))
109 |
110 | (define (compile-define+ name params body env)
111 | (let*-values ([(body env) (compile* body env)]
112 | [(body) (string-join body)]
113 | [(params) (string-join (map (lambda (param) @~a{(param $@param i32)}) params))]
114 | [(locals) (string-join (map (lambda (name) @~a{(local $@name i32)}) env))])
115 | (values @~a{(func $@name @params (result i32) @locals (return @body)) (export "@name" (func $@name))} env)))
116 |
117 | (define (compile-if-then-else cond exp1 exp2 env)
118 | (let*-values ([(cond env) (compile cond env)]
119 | [(exp1 env) (compile exp1 env)]
120 | [(exp2 env) (compile exp2 env)])
121 | (values @~a{(if (result i32) @cond (then @exp1) (else @exp2))} env)))
122 |
123 | (define (compile-param name env)
124 | (values @~a{(param $@name i32)} env))
125 |
126 | (define (compile-module body env)
127 | (let*-values ([(body env) (compile* body env)]
128 | [(body) (string-join body)])
129 | (values @~a{(module @body)} env)))
130 |
131 | (define (compile-call name params env)
132 | (let*-values ([(params env) (compile* params env)]
133 | [(params) (string-join params)])
134 | (values @~a{(call $@name @params)} env)))
--------------------------------------------------------------------------------
/info.rkt:
--------------------------------------------------------------------------------
1 | #lang info
2 | (define collection "wracket")
3 | (define deps '("base"))
4 | (define build-deps '("scribble-lib" "racket-doc" "rackunit-lib"))
5 | (define scribblings '(("scribblings/wracket.scrbl" ())))
6 | (define pkg-desc "Lisp-like language to WebAssembly")
7 | (define version "0.0")
8 | (define pkg-authors '(Simon Schauß))
9 |
--------------------------------------------------------------------------------
/main.rkt:
--------------------------------------------------------------------------------
1 | #lang racket/base
2 |
3 | (module+ test
4 | (require rackunit))
5 |
6 | ;; Notice
7 | ;; To install (from within the package directory):
8 | ;; $ raco pkg install
9 | ;; To install (once uploaded to pkgs.racket-lang.org):
10 | ;; $ raco pkg install <>
11 | ;; To uninstall:
12 | ;; $ raco pkg remove <>
13 | ;; To view documentation:
14 | ;; $ raco docs <>
15 | ;;
16 | ;; For your convenience, we have included a LICENSE.txt file, which links to
17 | ;; the GNU Lesser General Public License.
18 | ;; If you would prefer to use a different license, replace LICENSE.txt with the
19 | ;; desired license.
20 | ;;
21 | ;; Some users like to add a `private/` directory, place auxiliary files there,
22 | ;; and require them in `main.rkt`.
23 | ;;
24 | ;; See the current version of the racket style guide here:
25 | ;; http://docs.racket-lang.org/style/index.html
26 |
27 | ;; Code here
28 |
29 | (module+ test
30 | ;; Tests to be run with raco test
31 | )
32 |
33 | (module+ main
34 | ;; Main entry point, executed when run with the `racket` executable or DrRacket.
35 | (require racket/cmdline
36 | wracket/compiler)
37 | (let ([filename (command-line #:args (filename) filename)])
38 | (compile-file filename)))
39 |
--------------------------------------------------------------------------------
/scribblings/wracket.scrbl:
--------------------------------------------------------------------------------
1 | #lang scribble/manual
2 | @require[@for-label[wracket
3 | racket/base]]
4 |
5 | @title{wracket}
6 | @author{Simon Schauß}
7 |
8 | @defmodule[wracket]
9 |
10 | Package Description Here
11 |
--------------------------------------------------------------------------------