-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsurface.rkt
81 lines (64 loc) · 2.3 KB
/
surface.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
75
76
77
78
79
80
81
#lang racket/base
#|
Syntax for specifying variant configurations.
There can be variation in feature sets, target platforms, or
toolchains, for example.
The variant specifications should strive to be fairly high-level, so
that only the actual variable choices can be made there. A
specification should pretty much be just a set of key/value pairs,
which we call attributes.
To avoid duplication in specifications, inheritance is supported, by
allowing multiple inheritance of base configurations, specified in
decreasing priority order.
|#
(require "ir.rkt" "util.rkt"
racket/stxparam
(for-syntax racket/base racket/syntax syntax/parse))
(define-syntax-parameter* self
(syntax-rules ()))
(define-syntax-rule* ($ name)
(get-attr! self 'name))
(define-syntax* (define-field stx)
(syntax-parse stx
[(_ name:id v:expr ...+)
#'(begin
(define-id-syntax name (get-attr! self 'name))
(hash-set! (VarObj-attrs self) 'name (field-thunk v ...)))]))
(define-syntax* (define-attribute stx)
(syntax-parse stx
[(_ name:id v:expr ...+)
#'(begin
(define-id-syntax name (get-attr! self 'name))
(hash-set! (VarObj-attrs self) 'name (lambda () v ...)))]))
(define-syntax* (define-axiom stx)
(syntax-parse stx
[(_ name:id v:expr ...+)
#'(hash-set! (VarObj-axioms self) 'name (lambda () v ...))]))
(define-syntax* (variant-class stx)
(syntax-parse stx
[(_ name:id (base:expr ...) body ...+)
(define/with-syntax obj (generate-temporary 'this))
#'(VarCls 'name (list base ...)
(lambda (obj)
(syntax-parameterize ([self (make-rename-transformer #'obj)])
body ...)))]))
(define-syntax-rule*
(define-variant name (base ...) body ...)
(define name
(variant-class name (base ...) body ...)))
(define-syntax-rule*
(define-variant* name (base ...) body ...)
(begin
(define-variant name (base ...) body ...)
(provide name)))
(define-syntax* (define-variant** stx)
(syntax-parse stx
[(_ name (base ...) body ...)
(define/with-syntax main-name (datum->syntax stx 'klass%))
#'(begin
(define-variant name (base ...) body ...)
(provide name (rename-out [name main-name])))]))
(define* (class-all-attrs cls)
(define obj
(make-VarObj cls))
(get-all-attrs! obj))