202 lines
7.3 KiB
Scheme
202 lines
7.3 KiB
Scheme
(define (get-function-names wat)
|
|
(filter-map
|
|
(lambda (item)
|
|
(if (and (equal? (car item) 'export) (assq 'func item))
|
|
(cons (cadr (assq 'func item)) (string->symbol (cadr item)))
|
|
#f))
|
|
(cdr wat)))
|
|
|
|
(define (get-global-export-names wat)
|
|
(filter-map
|
|
(lambda (item)
|
|
(if (and (equal? (car item) 'export) (assq 'global item))
|
|
(cons (cadr (assq 'global item)) (string->symbol (cadr item)))
|
|
#f))
|
|
(cdr wat)))
|
|
|
|
(define (get-globals wat)
|
|
(filter-map
|
|
(lambda (item)
|
|
(cond
|
|
((equal? (car item) 'global)
|
|
`(define ,(list-ref item 1) ,(cadr (car (reverse item)))))
|
|
((and (equal? (car item) 'export) (assq 'global item))
|
|
`(define ,(string->symbol (cadr item)) ,(cadr (car (reverse item)))))
|
|
(else #f)))
|
|
(cdr wat)))
|
|
|
|
#;(define (get-memory-export-names wat)
|
|
(filter-map
|
|
(lambda (item)
|
|
(if (and (equal? (car item) 'export) (assq 'memory item))
|
|
(string->symbol
|
|
(string-append "memory-"
|
|
(symbol->string (cadr (assq 'memory item)))))
|
|
#f))
|
|
(cdr wat)))
|
|
|
|
(define (get-memories wat)
|
|
(filter-map
|
|
(lambda (item)
|
|
(cond
|
|
((equal? (car item) 'memory)
|
|
(let* ((sizes (list-tail item 2))
|
|
(size (cond ((= (length sizes) 1)
|
|
(list-ref sizes 0))
|
|
(else (list-ref sizes 1)))))
|
|
`(vector-set! memory-index
|
|
,(string->number
|
|
(string-copy (symbol->string (list-ref item 1))
|
|
1))
|
|
(make-vector ,size 0))))
|
|
(else #f)))
|
|
(cdr wat)))
|
|
|
|
(define (symbol-append sym1 sym2)
|
|
(string->symbol (string-append (symbol->string sym1) (symbol->string sym2))))
|
|
|
|
(define (char-index str c)
|
|
(letrec*
|
|
((looper
|
|
(lambda (index)
|
|
(cond ((>= index (string-length str)) -1)
|
|
((char=? c (string-ref str index)) index)
|
|
(else (looper (+ index 1)))))))
|
|
(looper 0)))
|
|
|
|
(define (offset=N->N sym)
|
|
(string->number
|
|
(string-copy
|
|
(symbol->string sym)
|
|
(+ (char-index (symbol->string sym) #\=) 1))))
|
|
|
|
(define (symbol-starts-with? sym str)
|
|
(if (not (symbol? sym))
|
|
#f
|
|
(let ((sym-str (symbol->string sym)))
|
|
(and (>= (string-length sym-str) (string-length str))
|
|
(string=? (string-copy sym-str 0 (string-length str)) str)))))
|
|
|
|
(define (body-item->sexp item)
|
|
(cond ((not (list? item)) item)
|
|
((equal? (car item) 'local)
|
|
`(define ,(list-ref item 1) 0))
|
|
((equal? (car item) 'global.get)
|
|
(list-ref item 1))
|
|
((equal? (car item) 'global.set)
|
|
`(set! ,(list-ref item 1) ,@(map body-item->sexp (list-tail item 2))))
|
|
((equal? (car item) 'global.tee)
|
|
`(set! ,(list-ref item 1) ,@(map body-item->sexp (list-tail item 2))))
|
|
((equal? (car item) 'local.get)
|
|
(list-ref item 1))
|
|
((equal? (car item) 'local.set)
|
|
`(set! ,(list-ref item 1) ,@(map body-item->sexp (list-tail item 2))))
|
|
((equal? (car item) 'local.tee)
|
|
`(set! ,(list-ref item 1) ,@(map body-item->sexp (list-tail item 2))))
|
|
((equal? (car item) 'result)
|
|
#f)
|
|
((equal? (car item) 'i32.const)
|
|
(list-ref item 1))
|
|
((equal? (car item) 'i32.and)
|
|
`(bitwise-and ,@(map body-item->sexp (cdr item))))
|
|
((equal? (car item) 'i32.add)
|
|
`(+ ,@(map body-item->sexp (cdr item))))
|
|
((equal? (car item) 'i32.sub)
|
|
`(- ,@(map body-item->sexp (cdr item))))
|
|
((equal? (car item) 'i32.store)
|
|
`(vector-set!
|
|
(vector-ref memory-index
|
|
,(if (list? (list-ref item 2))
|
|
(body-item->sexp (list-ref item 2))
|
|
(list-ref item 2)))
|
|
,(offset=N->N (body-item->sexp (list-ref item 1)))
|
|
,(body-item->sexp (list-ref item 3))))
|
|
((equal? (car item) 'i32.load)
|
|
`(vector-ref
|
|
(vector-ref memory-index
|
|
,(if (symbol-starts-with? (list-ref item 1) "offset=")
|
|
(offset=N->N (list-ref item 1))
|
|
0))
|
|
,(if (symbol-starts-with? (list-ref item 1) "offset=")
|
|
(if (list? (list-ref item 2))
|
|
(body-item->sexp (list-ref item 2))
|
|
(body-item->sexp (list-ref item 2)))
|
|
(if (list? (list-ref item 1))
|
|
(body-item->sexp (list-ref item 1))
|
|
(body-item->sexp (list-ref item 1))))))
|
|
((equal? (car item) 'call)
|
|
`(,@(map body-item->sexp (cdr item))))
|
|
#;((equal? (car item) 'block)
|
|
(display "HERE: block ")
|
|
(write (list-tail item 2))
|
|
(newline)
|
|
`(call-with-current-continuation
|
|
(lambda (,(list-ref item 1))
|
|
,@(map body-item->sexp (list-tail item 2)))))
|
|
#;((or (equal? (car item) 'i32.eqz))
|
|
`(= ,@(map body-item->sexp (cdr item))))
|
|
#;((equal? (car item) 'br_if)
|
|
`(when (= 1 ,@(map body-item->sexp (list-tail item 2))) (,(list-ref item 1))))
|
|
(else (map body-item->sexp item)))
|
|
)
|
|
|
|
(define (get-functions function-names wat)
|
|
(filter-map
|
|
(lambda (item)
|
|
(if (equal? (car item) 'func)
|
|
(let ((name (if (assq (list-ref item 1) function-names)
|
|
(cdr (assq (list-ref item 1) function-names))
|
|
(list-ref item 1)))
|
|
(params (filter-map
|
|
(lambda (item)
|
|
(if (and (list? item) (equal? (car item) 'param))
|
|
(list-ref item 1)
|
|
#f))
|
|
(cdr item)))
|
|
(return (filter-map
|
|
(lambda (item)
|
|
(if (and (list? item)
|
|
(equal? (car item) 'return))
|
|
item
|
|
#f))
|
|
(cdr item)))
|
|
(body (filter-map
|
|
(lambda (item)
|
|
(if (and (list? item)
|
|
(equal? (car item) 'param))
|
|
#f
|
|
(body-item->sexp item)))
|
|
(cdr item))))
|
|
(list-set! item 0 'define)
|
|
(list-set! item 1 name)
|
|
`(define ,name
|
|
(lambda ,params
|
|
(call-with-current-continuation
|
|
(lambda (return)
|
|
,@(cdr body))))))
|
|
#f))
|
|
(cdr wat)))
|
|
|
|
(define (wat-module->r7rs-library library-name port)
|
|
(let* ((wat (read port))
|
|
(global-export-names (get-global-export-names wat))
|
|
(globals (get-globals wat))
|
|
;(memory-export-names (get-memory-export-names wat))
|
|
(memories (get-memories wat))
|
|
(function-names (get-function-names wat))
|
|
(exports (append (map cdr function-names)
|
|
(map cdr global-export-names)
|
|
;memory-export-names
|
|
))
|
|
(functions (get-functions function-names wat)))
|
|
`(define-library
|
|
,library-name
|
|
(import (scheme base)
|
|
(srfi 60))
|
|
(export ,@exports)
|
|
(begin
|
|
(define memory-index (make-vector 8))
|
|
,@memories
|
|
,@globals
|
|
,@functions))))
|