Son aktivite 3 weeks ago

yumaikas's Avatar yumaikas bu gisti düzenledi 3 weeks ago. Düzenlemeye git

1 file changed, 470 insertions

tinscript.js(dosya oluşturuldu)

@@ -0,0 +1,470 @@
1 +
2 + function copyText(text) {
3 + var tempInput = document.createElement("textarea");
4 + tempInput.style = "position: absolute; left: -1000px; top: -1000px";
5 + tempInput.value = text;
6 +
7 + document.body.appendChild(tempInput);
8 + tempInput.select();
9 +
10 + document.execCommand("copy");
11 + document.body.removeChild(tempInput);
12 + }
13 +
14 +
15 + var app = (function(){
16 + var exported = {};
17 + var stack = [];
18 + var env = {};
19 + var vals = {};
20 +
21 + var codeElem,
22 + inputElem,
23 + runCodeElem,
24 + stackOutput,
25 + errElem;
26 +
27 +
28 + exported.load = function() {
29 + codeElem = elmID("current-code");
30 + inputElem = elmID("repl");
31 + runCodeElem = elmID("run-code");
32 + stackOutput = elmID("stack-output");
33 + errElem = elmID("error-output");
34 + codeElem.value = localStorage.getItem("code") || "";
35 + // Clear loading indicators
36 + codeElem.className = "";
37 + runCodeElem.className = "";
38 + runCodeElem.value = "Run Code";
39 +
40 +
41 + runCodeElem.onclick = function() {
42 + localStorage.setItem("code", codeElem.value);
43 + runCode(codeElem.value);
44 + return false;
45 + };
46 +
47 +
48 + inputElem.onkeypress = function(event) {
49 +
50 + if (event.keyCode != 13 /*Enter*/) {
51 + return;
52 + }
53 +
54 + var code = inputElem.value;
55 + inputElem.value = "Executing code...";
56 + runCode(code);
57 + inputElem.value = "";
58 +
59 + return false;
60 +
61 + };
62 +
63 + }
64 +
65 +
66 + function runCode(code) {
67 + errElem.innerHTML = "";
68 + errElem.className = "hidden";
69 + try {
70 + tin_run(code, stack, env, vals);
71 + } catch(ex) {
72 + errElem.innerHTML = ex.message;
73 + errElem.className = "error";
74 + }
75 + displayStack();
76 + }
77 +
78 +
79 + function cleanStackDisplay(str) {
80 + return str.
81 + replace(/>/g, ">").
82 + replace(/</g, "&lt;").
83 + replace(/\n/g, "<br/>");
84 + }
85 +
86 +
87 + function displayStack() {
88 +
89 + var builtHTML = "";
90 + for (var i = 0; i < stack.length; i++) {
91 + var dropNum = i;
92 + builtHTML +=
93 + "<tr><td class='col'>" + cleanStackDisplay((stack[i] || "falsy").toString()) + "</td>" +
94 + "<td class='col-alt'>&lt;" + typeof(stack[i]) + "&gt;</td>" +
95 + '<td class="col"><a href="javascript:app.removeStackElem(' + dropNum + ')">Remove</a></td>' +
96 + '<td class="col"><a href="javascript:app.copyStackElem('+ dropNum +')">Copy</a></td>'
97 + "</tr>";
98 + }
99 +
100 + stackOutput.innerHTML = builtHTML;
101 + }
102 +
103 + exported.clearStack = function() {
104 + stack = [];
105 + displayStack();
106 + }
107 +
108 + exported.copyStackElem = function(idx) {
109 + var valToCopy = stack[idx].toString();
110 + copyText(valToCopy);
111 + }
112 +
113 + exported.removeStackElem = function(idx) {
114 + stack.splice(idx, 1);
115 + displayStack();
116 + }
117 +
118 + function elmID(id) {
119 + return document.getElementById(id);
120 + }
121 +
122 + return exported;
123 + })();
124 +
125 + window.onload = app.load;
126 + </script>
127 + <script>
128 + function isSpace(char) {
129 + return char === " " || char === "\t" || char === "\r" || char === "\n";
130 + }
131 +
132 + function assert(condition, message) {
133 + if (!condition) {
134 + message = message || "Assertion failed";
135 + if (typeof Error !== "undefined") {
136 + throw new Error(message);
137 + }
138 + throw message;
139 + }
140 + }
141 +
142 + function hasSpaces(str) {
143 + for (var i = 0; i < str.length; i++) {
144 + if (isSpace(str[i])) {
145 + return true;
146 + }
147 + }
148 + return false;
149 + }
150 +
151 + function list_of_string(code) {
152 + var next = tokenize(code);
153 + var list = [];
154 + var tok = next();
155 + while (! tok.message) {
156 + list.push(tok);
157 + tok = next();
158 + }
159 + assert(tok.message === "EOF", tok);
160 + return list;
161 + }
162 +
163 +
164 + function tokenize(code) {
165 + if (Array.isArray(code)) {
166 + var i = 0;
167 +
168 + return function (msg) {
169 + if (i >= code.length) { return { message: msg || "EOF" }; }
170 + var retVal = code[i];
171 + i++;
172 + return retVal;
173 + }
174 + }
175 +
176 + if (code.message) {
177 + throw code;
178 + }
179 +
180 + assert(typeof(code) === "string", "Can only tokenize a string or an array!");
181 +
182 + // Current token
183 + var tok = "";
184 +
185 + // Build up current token until we hit a space, a [ or a "
186 + var idx = 0;
187 + function eatSpace() {
188 + if (idx >= code.length) {
189 + return;
190 + }
191 +
192 + while (isSpace(code[idx])) {
193 + if (idx >= code.length) { return; }
194 + idx++;
195 + }
196 + }
197 +
198 + // next token
199 + return function(msg) {
200 + // Eat spaces
201 + eatSpace();
202 +
203 + if (idx >= code.length) { return { message: msg || "EOF" }; }
204 +
205 + var char = code[idx];
206 +
207 + if (char === "[") {
208 + var seekIdx = idx;
209 + var depth = 1;
210 + while(depth > 0) {
211 + seekIdx++;
212 + if (seekIdx >= code.length) { throw "Unexpected EOF!"; }
213 + if (code[seekIdx] === "[") { depth++; }
214 + if (code[seekIdx] === "]") { depth--; }
215 + if (depth < 0) {
216 + throw "Unexpected ]";
217 + }
218 + }
219 + var retVal = code.slice(idx + 1, seekIdx);
220 + idx = seekIdx + 1;
221 + return retVal;
222 + }
223 +
224 + if (char === "\"") {
225 +
226 + var seekIdx = idx + 1;
227 + while(code[seekIdx] != "\"") {
228 + seekIdx++;
229 + if (seekIdx >= code.length) {
230 + throw "Unterminated string!";
231 + }
232 + }
233 +
234 + var retVal = code.slice(idx + 1, seekIdx);
235 + idx = seekIdx + 1;
236 + return retVal;
237 + }
238 +
239 + var seekIdx = idx + 1;
240 +
241 + while(!isSpace(code[seekIdx])) {
242 + seekIdx++;
243 + if (seekIdx >= code.length) {
244 + var retVal = code.slice(idx, seekIdx);
245 + idx = seekIdx;
246 + return retVal;
247 + }
248 + }
249 +
250 + var retVal = code.slice(idx, seekIdx);
251 + idx = seekIdx + 1;
252 + return retVal;
253 + }
254 + }
255 +
256 +
257 + function pop(stack) {
258 + if (stack.length === 0) { throw { message: "Data underflow" } }
259 + return stack.pop();
260 + }
261 +
262 + function eval_or_push(tok, env, stack, next, vals) {
263 + if (typeof(env[tok]) === "function") { env[tok](next, vals); }
264 + else { stack.push(tok); }
265 + }
266 +
267 +
268 + function tin_run(code, stack, env, vals) {
269 + var env = env || {};
270 + var next = tokenize(code);
271 + var stack = stack || [];
272 + var vals = vals || {};
273 +
274 + function num_op(fn) {
275 + var a = pop(stack);
276 + var b = pop(stack);
277 + stack.push(fn(Number(b), Number(a)));
278 + }
279 +
280 +
281 + env["+"] = env["+"] || function() {
282 + num_op(function(a,b) {return a + b});
283 + };
284 +
285 + env["*"] = env["*"] || function() {
286 + num_op(function(a,b) {return a * b});
287 + };
288 +
289 + env["/"] = env["/"] || function() {
290 + num_op(function(a,b) {return a / b});
291 + };
292 +
293 + env["-"] = env["-"] || function() {
294 + num_op(function(a,b) { return a - b});
295 + };
296 +
297 + env["concat"] = env["concat"] || function() {
298 + var b = pop(stack).toString();
299 + var a = pop(stack).toString();
300 +
301 + stack.push(a + b);
302 + }
303 +
304 + env["rand"] = env["rand"] || function() {
305 + var max = Number(pop(stack));
306 + // Based on https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/random
307 + stack.push(Math.floor(Math.random() * Math.floor(max)));
308 + };
309 +
310 + env["str:"] = env["str:"] || function(next, vals) {
311 + var str = next("str: expected a string literal");
312 + stack.push(str);
313 + };
314 +
315 + env["split"] = env["split"] || function(next, vals) {
316 + var sep = pop(stack);
317 + var str = pop(stack);
318 + stack.push(str.toString().split(sep));
319 + };
320 +
321 + env["eval"] = env["eval"] || function(next, vals) {
322 + var fragment = pop(stack);
323 + tin_exec(tokenize(fragment), stack, env, vals);
324 + };
325 +
326 + env["dup"] = env["dup"] || function() { stack.push(stack[stack.length - 1]); };
327 +
328 + env["swap"] = env["swap"] || function() {
329 + var b = pop(stack);
330 + var a = pop(stack);
331 +
332 + stack.push(b);
333 + stack.push(a);
334 + }
335 +
336 + env["drop"] = env["drop"] || function() { pop(stack); };
337 + env["print"] = env["print"] || function() { console.log(pop(stack)); };
338 + env["vec"] = env["vec"] || function(next, vals) {
339 + var literal = pop(stack);
340 + assert(literal, "No data on stack");
341 + stack.push(tin_exec(tokenize(literal), [], env, vals));
342 +
343 + };
344 +
345 + env["set"] = function() {
346 + var name = pop(stack).toString();
347 + var value = pop(stack);
348 + vals[name] = value;
349 + };
350 +
351 + env["get"] = function() {
352 + var name = pop(stack).toString();
353 + stack.push(vals[name]);
354 + }
355 +
356 + env["t"] = function() { stack.push(true); };
357 + env["f"] = function() { stack.push(false); };
358 +
359 + env["and"] = function() {
360 + var b = pop(stack);
361 + var a = pop(stack);
362 + stack.push(a && b);
363 + }
364 +
365 + env["or"] = function() {
366 + var b = pop(stack);
367 + var a = pop(stack);
368 + stack.push(a || b);
369 + }
370 +
371 + function timeFromString(time_str) {
372 + var parser = /(\d+):(\d+)(a|p|am|pm)/i;
373 + var parts = parser.exec(time_str);
374 + var hour = Number.parseFloat(parts[1], 10);
375 + var minutes = Number.parseFloat(parts[2], 10);
376 +
377 + if (hour < 12 && (parts[3] === "p" || parts[3] === "pm")) {
378 + hour += 12;
379 + }
380 +
381 + return new Date(2019,1,1, hour, minutes);
382 + }
383 +
384 + env["duration"] = function() {
385 +
386 + var b = pop(stack);
387 + var a = pop(stack);
388 + var a_time = timeFromString(a);
389 + var b_time = timeFromString(b);
390 +
391 + stack.push((b_time.getHours() + (b_time.getMinutes() / 60) ) - (a_time.getHours() + a_time.getMinutes() / 60));
392 +
393 + }
394 +
395 + env["not"] = function() { stack.push(!pop(stack)); }
396 +
397 + env["when:"] = function(next, vals) {
398 + var cond = pop(stack);
399 + if (cond) {
400 + tin_exec(tokenize(next("when: expected a string")), stack, env, vals);
401 +
402 + }
403 +
404 + };
405 +
406 + env["if:"] = function(next, vals) {
407 + var cond = pop(stack);
408 + var t_branch = list_of_string(next("if: expected a true branch"));
409 + var f_branch = list_of_string(next("if: expected a false branch"));
410 +
411 + if (cond) {
412 + tin_exec(tokenize(t_branch), stack, env, vals);
413 + } else {
414 + tin_exec(tokenize(f_branch), stack, env, vals);
415 + }
416 + };
417 +
418 + /*
419 + env["while-do"] = env["while-do"] || function(next, vals) {
420 + var cond = list_of_string(pop(stack));
421 + var body = list_of_string(next("while-do: expects a body"));
422 + var toCheck = tin_exec(tokenize(cond), stack, env, vals);
423 + while(toCheck[0]) {
424 + tin_exec(tokenize(body), stack, env, vals);
425 + toCheck = tin_exec(tokenize(cond), stack, env, vals);
426 + }
427 + }*/
428 +
429 + env["times:"] = env["times:"] || function(next, vals) {
430 + // debugger;
431 + var num_times = Number(pop(stack));
432 + var body = list_of_string(next("times: expects an expression to repeat"));
433 + for (var i = 0; i < num_times; i++) {
434 + tin_exec(tokenize(body), stack, env, vals);
435 + }
436 + }
437 +
438 + env["def:"] = env["def:"] || function(next, vals) {
439 +
440 + // A spec is a name and a list of arguments
441 + var spec = list_of_string(next("def: expects a function specification"));
442 + assert(spec.length > 0, "The spec for a function *must* have a name!");
443 + var name = spec[0];
444 +
445 + var def = list_of_string(next("def: expects a function body"));
446 + env[name] = function(next, vals) {
447 + var old_vals = vals;
448 + vals = {};
449 + tin_exec(tokenize(def), stack, env, vals);
450 + vals = old_vals;
451 + }
452 + };
453 + tin_exec(next, stack, env, vals);
454 +
455 + }
456 +
457 +
458 +
459 + function tin_exec(next, stack, env, vals) {
460 + stack = stack || [];
461 + vals = vals || {};
462 +
463 + var tok = next();
464 +
465 + while (!tok.message) {
466 + eval_or_push(tok, env, stack, next, vals);
467 + tok = next();
468 + }
469 + return stack;
470 + }
Daha yeni Daha eski