-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathexecute.rkt
74 lines (66 loc) · 1.92 KB
/
execute.rkt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
#lang racket
(require "print/css.rkt")
(provide execute-script script->js)
(define (execute-script lines)
(define environment (make-hash))
(define effects '())
(for ([line (in-list lines)])
(match line
[`(let ,var ,expr)
(define val (evaluate-expr expr environment))
(hash-set! environment var val)]
[`(set ,var ,field ,expr)
(void)]
[`(append-child ,elt ,child)
(define elt* (evaluate-expr elt environment))
(define child* (evaluate-expr child environment))
(define box (elt->box child*))
(set! effects (cons (list 'append-child elt* child* box) effects))]))
(reverse effects))
(define (evaluate-expr expr env)
(match expr
[(? symbol?)
(hash-ref env expr)]
[`(select ,sel)
sel]
[`(create ,tree)
tree]))
(define (elt->box tree)
'[BLOCK])
(define (script->js lines name)
(define js-lines '())
(set! js-lines (cons (format "function ~a(e) {" name) js-lines))
(for ([line (in-list lines)])
(define str
(match line
[`(let ,var ,expr)
(format "var ~a = ~a;" var (expr->js expr))]
[`(set ,var ,field ,expr)
(format "~a.~a = ~a;" var (field->js field) (expr->js expr))]
[`(append-child ,elt ,child)
(format "~a.appendChild(~a);" (expr->js elt) (expr->js child))]))
(set! js-lines (cons str js-lines)))
(set! js-lines (cons "}" js-lines))
(string-join (reverse js-lines) "\n"))
(define (field->js field)
(match field
[`(quote ,elt)
(match elt
[':id
"id"]
[':text
"innerText"]
[else
(raise (format "~a not supported" elt))])]))
(define (expr->js expr)
(match expr
[`(select ,sel)
(format "document.querySelector(\"~a\")" (selector->string sel))]
[`(create ,elt)
(match elt
[(list element)
(format "document.createElement('~a')" element)]
[else
(raise "Bad input for create")])]
[else
expr]))