-
Notifications
You must be signed in to change notification settings - Fork 0
/
algebra.rkt
56 lines (47 loc) · 1.59 KB
/
algebra.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
#lang racket
(require (for-syntax syntax/parse))
(provide #%module-begin
(rename-out [number-datum #%datum]
[plus +]
[subb -]
[allops ~]
[elsethen if]
[complain-app #%app]))
(define-syntax (number-datum stx)
(syntax-parse stx
[(_ . v:number) #'(#%datum . v)]
[(_ . v:boolean) #'(#%datum . v)]
[(_ . other) (raise-syntax-error #f "not allowed" #'other)]))
(define-syntax (elsethen stx)
(syntax-parse stx #:datum-literals(then else)
[(_ e0 then e1 else e2) #'(if e0 e1 e2)]
[(_ e0 then e1) #'(if (e0) e1)]
[(_ . other) (raise-syntax-error #f "bad syntax" #'other)]))
(define-syntax (plus stx)
(syntax-parse stx
[(_ n1 n2) #'(+ n1 n2)]))
(define-syntax (subb stx)
(syntax-parse stx
[(_ n1 n2) #'(- n1 n2)]))
;; helper function macro for all operations
(define-syntax (allops stx)
(syntax-parse stx
[(_ n1 n2) #'(~ n1 n2)]))
(define-syntax (complain-app stx)
(define (complain msg src-stx)
(raise-syntax-error 'parentheses msg src-stx))
(define without-app-stx
(syntax-parse stx [(_ e ...) (syntax/loc stx (e ...))]))
(syntax-parse stx
[(_)
(complain "empty parentheses are not allowed" without-app-stx)]
[(_ n:number)
(complain "extra parentheses are not allowed around numbers" #'n)]
[(_ x:id _ ...)
(complain "unknown operator" #'x)]
[_
(complain "something is wrong here" without-app-stx)]))
(define-syntax (complain-top stx)
(syntax-parse stx
[(_ . x:id)
(raise-syntax-error 'variable "unknown" #'x)]))