-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.red
88 lines (75 loc) · 2.18 KB
/
main.red
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
Red [
author: "Nędza Darek"
license: "Just point to the gist/github"
version: 0.0.1
subversion: 'alpha
]
do %argument_list.red
memoize: function ['fun][
unless any-function? get fun [
make error! "<fun> is not an <any-function!>"
]
params: get-params :fun
refs: get-refinements :fun
cache-checks: copy [
; cache is indexed by paren! - to make it visually stand out
; e.g. cache: [ (1 2 /foo 3 4) 42]
; cache/(to-paren [1 2 /foo 3 4]) ; 42
; `par` will word holds argument/refinement list
par: to-paren copy []
]
; get normal arguments
foreach param params [
append cache-checks [append par]
append cache-checks param
]
; get refinements + its arguments
foreach [ref args] refs [
; append to `par` only if you call refinement
append cache-checks 'if
append cache-checks to-get-word ref
append/only cache-checks copy []
last-refinement-check: last cache-checks
append last-refinement-check [append par]
append last-refinement-check ref
; refinement's arguments
foreach arg args [
append last-refinement-check [append par]
append last-refinement-check arg
]
]
; makes word `cache` holds... cache
append cache-checks [cache]
; checks if result is in the cache
append cache-checks [
; for debug purpose: print whenever or not result is in the cache
either cache/(par) [
print "In the cache"
; I've changed `return`, so `old-return` is Red's `return`
old-return cache/(par)
][
; new `return` updates the cache from within the code
; so this is for debug purpose
print "NOT in the cache"
]
]
set fun
func
spec-of get fun
bind head
insert
(body-of get fun)
cache-checks
context [
par: none
cache: copy []
old-return: :system/words/return
return: func [val] [
; sadly we cannot set cache/:par: val directly
append/only cache par
append/only cache val
; just normal return here:
old-return val
]
]
]