-
Notifications
You must be signed in to change notification settings - Fork 1
/
formula-op.ss
86 lines (70 loc) · 2.73 KB
/
formula-op.ss
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
#lang scheme/base
(require scheme/contract
(only-in (planet dherman/javascript:9:2/ast)
prefix-operators
postfix-operators
infix-operators
assignment-operators
prefix-operator?
postfix-operator?
infix-operator?
assignment-operator?))
; Operator symbols -------------------------------
; (listof symbol)
(define operator-names null)
; (hasheqof symbol string)
(define operator-lookup (make-hasheq))
; (hasheqof symbol (U natural #f))
(define arity-lookup (make-hasheq))
; (hasheqof symbol (U 'infix 'prefix 'postfix 'function))
(define type-lookup (make-hasheq))
; symbol (U natural #f) [(U 'infix 'prefix 'function)] [string] -> void
(define (register-operator! scheme arity [type 'infix] [excel (symbol->string scheme)])
(set! operator-names `(,@operator-names ,scheme))
(hash-set! operator-lookup scheme excel)
(hash-set! type-lookup scheme type)
(hash-set! arity-lookup scheme arity))
(register-operator! '+ #f)
(register-operator! '- #f)
(register-operator! '* #f)
(register-operator! '/ 2)
(register-operator! '& #f)
(register-operator! 'exp 2 'infix "^")
;(register-operator! 'or #f 'function)
;(register-operator! 'and #f 'function)
;(register-operator! 'not 1 'function)
(register-operator! '= 2)
(register-operator! '> 2)
(register-operator! '< 2)
(register-operator! '>= 2)
(register-operator! '<= 2)
(register-operator! '<> 2)
(register-operator! '% 1 'postfix)
(register-operator! ': 2)
(register-operator! '!range-or #f 'infix ",")
(register-operator! '!range-and #f 'infix " ")
; Predicates -------------------------------------
; symbol -> boolean
(define (operator-name? op)
(and (memq op operator-names) #t))
; symbol -> string
(define (operator->string op)
(hash-ref operator-lookup op))
; symbol -> (U natural #f)
(define (operator-arity op)
(hash-ref arity-lookup op))
; symbol -> (U 'infix 'prefix 'postfix 'function)
(define (operator-type op)
(hash-ref type-lookup op))
; symbol (listof any) -> boolean
(define (operator-arity-okay? op arity)
(let ([op-arity (operator-arity op)])
(or (not op-arity) (= arity op-arity))))
; Provide statements -----------------------------
(provide/contract
[operator-names (listof symbol?)]
[operator-name? (-> symbol? boolean?)]
[operator->string (-> symbol? string?)]
[operator-arity (-> symbol? (or/c natural-number/c #f))]
[operator-type (-> symbol? (or/c 'infix 'prefix 'postfix 'function))]
[operator-arity-okay? (-> symbol? natural-number/c boolean?)])