-
Notifications
You must be signed in to change notification settings - Fork 12
/
Copy pathnsource.red
162 lines (153 loc) · 4.07 KB
/
nsource.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
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
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
Red [
Title: "Nsource - native source"
Purpose: "Print source for native functions"
Author: "Boleslav Březovský"
Date: "9-2-2018"
]
indent: func [
"(Un)indent text by tab"
string [string!] "Text to (un)indent"
value [integer!] "Positive vales indent, negative unindent"
/space "Use spaces instead of tabs (default is 4)"
/size "Tab size in spaces"
sz [integer!]
; NOTE: Unindent automaticaly detects tabs/spaces, but for different size than 4,
; /size refinement must be used (TODO: autodetect space size?)
;
; Zero value does automatic unindentation based on first line
] [
out: make string! length? string
indent?: positive? value ; indent or unindent?
ending?: equal? newline back tail string ; is there newline on end?
unless size [sz: 4]
tab: either any [space not positive? value] [append/dup copy "" #" " sz] [#"^-"]
if zero? value [
parse string [
; NOTE: The rule will accept comination of tabs and spaces.
; Probably not a good thing, maybe it can be detected somehow.
some [
tab (value: value - 1)
| #"^-" (value: value - 1)
| break
]
to end
]
]
data: split string newline
foreach line data [
loop absolute value [
case [
; indent
indent? [insert line tab]
; unindent
all [not indent? equal? first line #"^-"] [remove line]
all [not indent? equal? copy/part line sz tab] [remove/part line sz]
]
]
; process output
append out line
append out newline
]
unless ending? [remove back tail out] ; there wasn't newline on end, remove current
out
]
entab: function [
"Replace spaces at line start with tabs (default size is 4)"
string [string!]
/size "Number of spaces per tab"
sz [integer!]
] [
sz: max 1 any [sz 4]
spaces: append/dup clear "" #" " sz
sz: sz - 1
parse string [some [some [not spaces change 1 sz space "" | change spaces tab] thru newline]]
string
]
detab: function [
"Replace tabs at line start with spaces (default size is 4)"
string [string!]
/size "Number of spaces per tab"
sz [integer!]
] [
sz: max 1 any [sz 4]
spaces: append/dup clear "" #" " sz
sz: sz - 1
parse string [some [some [spaces | change [0 sz space tab] spaces] thru newline]]
string
]
match-bracket: function [
string [string!]
] [
mark: none
level: 0
slevel: 0
subrule: [fail]
string-char: complement charset [#"^""]
mstring-char: complement charset [#"{" #"}"]
string-rule: [
#"^""
some [
{^^"}
| [#"^"" break]
| string-char
]
]
mstring-rule: [ ; multiline string
#"{" (slevel: slevel + 1)
some [
#"{" (slevel: slevel + 1)
| [#"}" (slevel: slevel - 1 subrule: either zero? slevel [[break]] [[fail]]) subrule]
| mstring-char
]
]
parse string [
some [
{#"["} ; ignore char!
| {#"]"} ; ignore char!
| #"[" (level: level + 1)
| #"]" (level: level - 1 subrule: either zero? level [[break]] [[fail]]) subrule
| string-rule
| mstring-rule
| skip
]
mark:
]
mark
]
nsource: func [
'word
] [
if native? get word [
runtime-link: https://raw.githubusercontent.com/red/red/master/runtime/natives.reds
env-link: https://raw.githubusercontent.com/red/red/master/environment/natives.red
; Red/System source
sources: read runtime-link
run-word: append form word #"*"
src: next find/reverse find sources run-word newline ; find source and go back to line start
spec: match-bracket find src #"[" ; skip spec
end: match-bracket find spec #"[" ; skip body
src: copy/part src end ; copy func source
; Red header
headers: read env-link
hdr: find headers head append form word #":"
end: back match-bracket spec: next find hdr #"[" ; get spec
spec: copy/part next spec end ; copy func source
if equal? newline spec/1 [remove spec]
; output
print [
uppercase form word "is native! so source is not available." newline
newline
"Here is latest version of Red/System source code" newline
"which may or may not be same version as you are using" newline
newline
"Native specs:" newline
newline
indent spec 0
newline
"Native Red/System source:" newline
newline
indent src 0
newline
]
]
]