Download Jar. Libraryless. Click here for Pure Java version (10722L/79K).
1 | !7 |
2 | |
3 | // TODO: use JavaXHyperlinker |
4 | |
5 | static Set<S> tooComplicatedSnippets = lithashset(#1006654); |
6 | |
7 | // only a single token allowed on LHS |
8 | static SS shortFor = litmap( |
9 | "LS", "List<String>", |
10 | "sclass", "static class", |
11 | "asclass", "abstract static class", |
12 | "svoid", "static void", |
13 | "SS", "Map<String, String>", |
14 | "S", "String", |
15 | "ret", "return", |
16 | "L", "List", |
17 | "Cl", "Collection", |
18 | "O", "Object", |
19 | "sO", "static Object", |
20 | "sS", "static String", |
21 | "fO", "final Object", |
22 | "fS", "final String", |
23 | "sS", "static String", |
24 | "sbool", "static boolean", |
25 | "fbool", "final boolean", |
26 | "bool", "boolean", |
27 | "Int", "Integer", |
28 | "cast", "casting to the type required on the left-hand side", |
29 | "°", "()", |
30 | "ItIt", "IterableIterator", |
31 | "ES", "Ext<S> (string plus extended information)", |
32 | "CloseableItIt", "CloseableIterableIterator", |
33 | "LPairS", "List<Pair<String>>", |
34 | "ISegmenter", "IF1<BufferedImage, L<Rect>>", |
35 | ); |
36 | |
37 | sS explFunc = "anonymous function declaration (similar to Java 8 lambdas)"; |
38 | sS explPNoconsole = "Main program including Substance L&F, started in non-AWT thread, hiding the console"; |
39 | |
40 | // any number of tokens allowed on LHS |
41 | static SS tokenExplanations = litmap( |
42 | "p-exp {", "main program with automatic upgrade", |
43 | "mapLike", "a function that takes a global function name as first argument and can be called like this: <mapLikeFunction> <otherFunction>(...)", |
44 | "mapMethodLike", "a function that takes a method or field name as first argument and can be called like this: <mapMethodLikeFunction> <methodOrFieldName>(...)", |
45 | "func(", explFunc, "func{", explFunc, |
46 | //"f(", explFunc, "f{", explFunc, |
47 | "voidfunc", "anonymous function declaration without return value (similar to Java 8 lambdas)", |
48 | "ctex", "ctex rethrows exceptions as RuntimeExceptions so you don't have to declare them", |
49 | "p {", "short for: public static void main(String[] args)", |
50 | "p-experiment {", "Main program with a nice big console & auto-restart", |
51 | "p-substance {", "Main program including Substance L&F, started in AWT thread", |
52 | "p-subst {", "Main program including Substance L&F, started in non-AWT thread", |
53 | "p-noconsole {", explPNoconsole, |
54 | "pn {", explPNoconsole, |
55 | "answer {", "Answer function - static S answer(S s) { new Matches m; ...; null; }", |
56 | "time {", "Run the code block and print how long it took", |
57 | "cprint {", "A module with default class name derived from DynPrintLog", |
58 | "semiauto {", "In a semiauto block, JavaX automatically adds a ; to (almost) every line", |
59 | "autosemi {", "In an autosemi block, JavaX automatically adds a ; to (almost) every line", |
60 | "Clusters", "Clusters<A> is short for Map<A, Collection<A>>", |
61 | "temp", "temp is like try (...) extending to the end of the current block", |
62 | "pcall {", "protected call - try { ... } catch { print exception }", |
63 | "r {", "r { ... } is short for: new Runnable() { public void run() { ... } }", |
64 | "runnable {", "runnable { ... } is short for: new Runnable() { public void run() { ... } }", |
65 | "pcall-short {", "protected call, shorter output - try { ... } catch { printShortException }", |
66 | "LPair<", "LPair<...> is short for: L<Pair<...>>", |
67 | "visualize {", "Visualisation method for an OS module; returns a Swing component", |
68 | "visualize as", "define a visualization for the module", |
69 | "enhanceFrame {", "Method that changes properties of an OS module's frame", |
70 | "run {", "short for: public void run()", |
71 | "start {", "Method that is run when an OS module is loaded", |
72 | "enter {", "Methods in a module should be marked 'enter' for bookkeeping", |
73 | "vf<", "reference to function as voidfunc", |
74 | "compact module", "try to save memory by reusing code between modules", |
75 | "cmodule", "cmodule = compact module for Stefan's OS. compact = try to save memory by reusing code between modules", |
76 | "cmodule2", "cmodule2 = compact module for Stefan's OS (newer version). compact = try to save memory by reusing code between modules", |
77 | "rThread {", "Runnable in a new thread", |
78 | "shit(", "short for: return with print", |
79 | "shit:", "short for: return with print", |
80 | ":=", [[the := operator translates to a simple comma, but converts an identifier on its left-hand side into a string]], |
81 | "noeq", "don't auto-generate equals+hashCode methods", |
82 | "for single (", "for single is for ping + singletonUnlessNull", |
83 | "selfType", "selfType is replaced with the enclosing class's name", |
84 | "runnable class", "short for: class X implementing Runnable { run { ... }}", |
85 | ); |
86 | |
87 | static SS sc, sf; |
88 | static StringTree2<S> tokenExplanationsTree; |
89 | |
90 | p { |
91 | clearCaches(); |
92 | serveHttp(7777); |
93 | tokenExplanationsTree = stringTree2_javaTok(tokenExplanations); |
94 | printStruct(tokenExplanationsTree); |
95 | } |
96 | |
97 | html { |
98 | try { |
99 | ret html2(uri, params); |
100 | } catch print e { |
101 | ret stackTraceToString(e); |
102 | } |
103 | } |
104 | |
105 | sS html2(S uri, SS params) { |
106 | uri = dropPrefix("/", uri); |
107 | bool real = uri.startsWith("real/"); |
108 | if (real) uri = dropPrefix("real/", uri); |
109 | S snippetID = #1007528; |
110 | if (isSnippetID(uri)) snippetID = fsI(uri); |
111 | |
112 | if (contains(tooComplicatedSnippets, snippetID)) ret ""; //fail("too complicated"); |
113 | |
114 | S code = loadSnippet(snippetID); |
115 | L<S> tok = javaTok(code); |
116 | |
117 | new Map<Int, S> links; // token index -> sf snippet ID |
118 | new Map<Int, S> explanations; // token index -> explanation text |
119 | |
120 | putMultipleKeys(explanations, allPlus(4, jfindAll(tok, "void <id> q {")), |
121 | "Function will execute in module's queue"); |
122 | |
123 | new Matches m; |
124 | for (int i = 1; i < l(tok); i += 2) { |
125 | S t = tok.get(i); |
126 | S prev = get(tok, i-2), prevPrev = get(tok, i-4); |
127 | S next = get(tok, i+2); |
128 | S sfID = sf.get(t); |
129 | |
130 | if (startsWith(t, "lambda", m) && isInteger(m.rest()) && isIdentifier(next)) |
131 | explanations.put(i, "lambda reference to a \*m.rest()*/-argument function"); |
132 | |
133 | if (eq(t, "methodLambda0") && isIdentifier(next)) |
134 | explanations.put(i, "short for: x -> x.\*next*/() (with a fresh variable instead of x)"); |
135 | |
136 | if (eq(t, "swappable") && isIdentifier(next)) |
137 | explanations.put(i, "swappable functions can be exchanged per object instance"); |
138 | |
139 | if (eq(t, "autoDispose") && isIdentifier(next)) |
140 | explanations.put(i, [[autoDispose adds a cleanMeUp method that properly disposes of this variable]]); |
141 | |
142 | if (eq(t, "virtual") && isIdentifier(next)) |
143 | explanations.put(i, [["virtual" represents a type that is not visible in this realm, so it is transpiled to just Object]]); |
144 | |
145 | if (eq(t, "concept") && isIdentifier(next)) |
146 | explanations.put(i, "A concept is like a Java class, but persistable"); |
147 | |
148 | if (eq(t, "flexeq") && isIdentifier(next)) |
149 | explanations.put(i, "flexeq is a fix for records inside parameterized classes"); |
150 | |
151 | if (eq(t, "switchable") && isIdentifier(next)) |
152 | explanations.put(i, "A field that can be changed through the module's popup menu"); |
153 | |
154 | if (eq(t, "embedded") && isIdentifier(next)) |
155 | explanations.put(i, [["embedded" allows you to put a function where they would not normally be allowed]]); |
156 | |
157 | if (eq(t, "visual") && isIdentifier(next)) |
158 | explanations.put(i, "short definition of the visualize() function"); |
159 | |
160 | if (eq(t, "dm_q") && isIdentifier(next)) |
161 | explanations.put(i, "Function reference delegating to module queue"); |
162 | |
163 | if (eq(t, "!") && isIdentifier(prev) && neq(next, "=")) |
164 | explanations.put(i, "! is short for .get()"); |
165 | |
166 | /*if (eq(t, "!") && containsNewLine(get(tok, i-1)) && isInteger(next)) |
167 | explanations.put(i, "Translator invocation");*/ |
168 | |
169 | if (eq(t, "#") && isIdentifier(next)) |
170 | explanations.put(i, "#<name> makes an identifier local to the scope"); |
171 | |
172 | if (eq(t, "f") && isIdentifier(next)) |
173 | explanations.put(i, "f <name> references a static function in the main class"); |
174 | |
175 | if (eq(t, "r") && isIdentifier(next)) |
176 | explanations.put(i, "short for: r { " + next + "() }"); |
177 | |
178 | if (eqOneOf(t, "rThread", "rThreadEnter") && isIdentifier(next)) |
179 | explanations.put(i, "short for: " + t + " { " + next + "() }"); |
180 | |
181 | if (eq(t, "dispose") && isIdentifier(next)) |
182 | explanations.put(i, "short for: cleanUp(" + next + "); " + next + " = null;"); |
183 | |
184 | if (eq(t, "*") && eq(next, "(")) |
185 | explanations.put(i, "Short syntax for a constructor declaration"); |
186 | |
187 | if (eq(t, "thread") && eq(next, "{")) |
188 | explanations.put(i, "Start a new thread with the following code"); |
189 | |
190 | if (eq(t, "module") && isIdentifier(next)) |
191 | explanations.put(i, "A module is a class that can be loaded in Stefan's OS"); |
192 | |
193 | if (eq(t, "record") && isIdentifier(next)) |
194 | explanations.put(i, "A record is a value-based class"); |
195 | |
196 | if (eq(t, "srecord") && isIdentifier(next)) |
197 | explanations.put(i, "An srecord is a static value-based class"); |
198 | |
199 | if (eqOneOf(t, "cached", "simplyCached") && isIdentifier(next)) |
200 | explanations.put(i, "A function that caches its return value"); |
201 | |
202 | if (eq(t, "thread") && isQuoted(next)) |
203 | explanations.put(i, "Start a new thread with the following name & code"); |
204 | |
205 | if (eq(t, "html") && eq(next, "{")) |
206 | explanations.put(i, "short for: static Object html(String uri, final Map<String, String> params) ctex {"); |
207 | |
208 | if (eq(t, 'try) && eq(next, 'answer)) |
209 | doublePut(explanations, i, i+2, "\"try answer\" returns the expression if it isn't null or empty"); |
210 | |
211 | if (isSingleQuoteIdentifier(t)) |
212 | explanations.put(i, "string constant, " + quote(fromSingleQuoteIdentifier(t))); |
213 | |
214 | if (eqOneOf(t, 'null, 'false, 'true, 'this) |
215 | && eq(next, ";") |
216 | && tok_tokenBeforeLonelyReturnValue(tok, i-2)) |
217 | doublePut(explanations, i, i+2, "short for: return " + t + ";"); |
218 | |
219 | S e = shortFor.get(t); |
220 | if (e != null) |
221 | mapPut(explanations, i, "short for: " + e); |
222 | |
223 | // link to standard function |
224 | if (!explanations.containsKey(i) && sfID != null) { |
225 | if (eqOneOf(prev, "f", "r", "rThread") |
226 | || startsWith(prev, "lambda") |
227 | || isIdentifier(next) && eqGet(tok, i+4, "(") |
228 | || eqOneOf(next, "(", "°") |
229 | && (neq(prev, ".") || eq(prevPrev, "main") && neq(get(tok, i-6), ".")) |
230 | || eq(prev, "{") && eq(next, "}") && eq(prevPrev, "postProcess") |
231 | || eq(prev, ":") && eq(prevPrev, ":")) |
232 | links.put(i, sfID); |
233 | } |
234 | |
235 | L<S> fewTokens = codeTokens(subList(tok, i-1, i+2*5)); |
236 | Pair<S, Int> p = stringTreeLeafValue2(tokenExplanationsTree, fewTokens); |
237 | if (p != null) { |
238 | //print(struct(p)); |
239 | int lastCodeToken = i+p.b*2-2; |
240 | if (eq(get(tok, lastCodeToken), "{")) lastCodeToken -= 2; |
241 | mapPutInRange(explanations, i, lastCodeToken+1, p.a); |
242 | } |
243 | |
244 | if (isQuoted(t) && eq(prev, "(") && isIdentifier(prevPrev) |
245 | && isMechFunction(prevPrev)) |
246 | mapPut(links, i, neatMechListURL(unquote(t))); |
247 | |
248 | //mapPut(explanations, i, tokenExplanations.get(t)); |
249 | |
250 | S id = sc.get(t); |
251 | if (id != null) |
252 | links.put(i, id); |
253 | } |
254 | new StringBuilder out; |
255 | SS titles = getSnippetTitles(filter isSnippetID(values(links))); |
256 | for i over tok: { |
257 | S t = tok.get(i), id = links.get(i), ex = explanations.get(i); |
258 | if (empty(t)) continue; |
259 | if (t.startsWith("[[") && t.endsWith("]]")) { |
260 | S explanation = "[[...]] denotes a multi-line string constant (as in Lua)"; |
261 | out.append(dottedSpan("[[", explanation); |
262 | S inner = htmlencode(dropPrefix("[[", dropSuffix("]]", t))); |
263 | out.append(span(inner, style := "background-color: #77FF77")); |
264 | out.append(dottedSpan("]]", explanation); |
265 | continue; |
266 | } |
267 | if (t.startsWith("[=[") && t.endsWith("]=]")) { |
268 | S explanation = "[=[...]=] denotes a multi-line string constant (as in Lua)"; |
269 | out.append(dottedSpan("[=[", explanation); |
270 | S inner = htmlencode(dropPrefix("[=[", dropSuffix("]=]", t))); |
271 | out.append(span(inner, style := "background-color: #77FF77")); |
272 | out.append(dottedSpan("]=]", explanation); |
273 | continue; |
274 | } |
275 | S enc = htmlencode(t); |
276 | out.append(id != null |
277 | ? ahref(makeLink(real, id), enc, |
278 | title := isSnippetID(id) ? titles.get(fsI(id)) : ex, style := "text-decoration: none; color: black; border-bottom: dotted 1px") |
279 | : ex != null ? dottedSpan(enc, ex) |
280 | : enc); |
281 | } |
282 | S html = str(out); |
283 | html = dynamize_noEncode(html); |
284 | if (real) ret html; |
285 | ret h3_title("Snippet " + snippetID) + hpre(html); |
286 | } |
287 | |
288 | // id can be a URL |
289 | sS makeLink(bool real, S id) { |
290 | if (isURL(id)) ret id; |
291 | if (real) |
292 | ret longSnippetLink(id); |
293 | ret "/" + psI(id); |
294 | } |
295 | |
296 | svoid clearCaches { |
297 | stdFunctions_clearCache(); |
298 | sc = standardClassesMap(); |
299 | sf = stdFunctions_cached(); |
300 | sf.putAll(tok_findStandardFunctionDefinitions(javaTokSnippet(#1022367))); |
301 | } |
302 | |
303 | sbool isMechFunction(S s) { |
304 | ret startsWithOneOf(s, "mech", "mL"); |
305 | } |
Began life as a copy of #1008705
download show line numbers debug dex old transpilations
Travelled to 4 computer(s): bhatertpkbcr, mqqgnosmbjvj, pyentgdyhuwx, vouqrxazstgt
No comments. add comment
Snippet ID: | #1030133 |
Snippet name: | Hyperlink+explain standard functions etc. in JavaX source [backup] |
Eternal ID of this version: | #1030133/1 |
Text MD5: | a890cdc9514117220caed6cadce41a9e |
Transpilation MD5: | f5a8ea6de7da1ef46578478d14be81bf |
Author: | stefan |
Category: | javax |
Type: | JavaX source code (desktop) |
Public (visible to everyone): | Yes |
Archived (hidden from active list): | No |
Created/modified: | 2020-11-11 10:01:42 |
Source code size: | 13013 bytes / 305 lines |
Pitched / IR pitched: | No / No |
Views / Downloads: | 328 / 903 |
Referenced in: | [show references] |