This repository has been archived by the owner on Aug 17, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1
/
sort.rkt
124 lines (113 loc) · 2.28 KB
/
sort.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
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
#lang racket
(require "etc.rkt"
"read.rkt")
(provide sort-module)
(define-syntax for/sublists
(syntax-rules ()
((_ ((x x1)) b ...)
(let loop ((x x1))
(if (atom? x)
x
(begin
(set! x
(for/list ((y x))
(loop y)))
b ...))))))
(define (fragments pred lst)
(cond
((null? lst)
lst)
((pred (car lst))
(receive (a b)
(splitf-at lst pred)
(cons a (fragments pred b))))
(else
(receive (a b)
(splitf-at lst (negate pred))
(cons a (fragments pred b))))))
(define (list<? lst1 lst2)
(cond
((eq? lst1 lst2)
#f)
((null? lst1)
#t)
((value<? (car lst1) (car lst2))
#t)
((value<? (car lst2) (car lst1))
#f)
(else
(list<? (cdr lst1) (cdr lst2)))))
(define (name x)
(match x
((list def (list id args ...) b ...)
id)
((list def id b ...)
id)))
(define (quoted-symbol? v)
(match v
((list (== quote-symbol) w)
(symbol? w))
(_ #f)))
(define (sort-case v)
(match v
((list (list c ...) b ...)
(cons (sort c value<?) b))
(_ v)))
(define (sort-cases lst)
(set! lst (map sort-case lst))
(sort lst value<?))
(define (sort-module m)
(for/sublists ((x m))
(begin
(set! x
(match x
((list 'case a b ...)
`(case ,a
,@(sort-cases b)))
((list 'or b ...)
#:when
(andmap quoted-symbol? b)
`(or ,@(sort b value<?)))
((list 'provide b ...)
`(provide ,@(sort b value<?)))
((list 'require b ...)
`(require ,@(sort b value<?)))
(_ x)))
(append* (for/list ((fragment (fragments decl? x)))
(if (decl? (car fragment))
(sort fragment
(lambda (v w)
(symbol<? (name v) (name w))))
fragment))))))
(define (typeof v)
(cond
((boolean? v)
'boolean)
((char? v)
'char)
((null? v)
'null)
((number? v)
'number)
((pair? v)
'pair)
((string? v)
'string)
((symbol? v)
'symbol)
((vector? v)
'vector)))
(define (value<? v w)
(if (eq? (typeof v) (typeof w))
(cond
((char? v)
(char<? v w))
((number? v)
(< v w))
((pair? v)
(list<? v w))
((string? v)
(string<? v w))
((symbol? v)
(symbol<? v w)))
(symbol<? (typeof v) (typeof w))))