A mostly AI coded js-maker, supervised by me.

This commit is contained in:
2026-05-26 09:42:35 +02:00
parent 8e8afc321b
commit 2cf831c180
23 changed files with 4143 additions and 1 deletions
+152
View File
@@ -0,0 +1,152 @@
// exercise01
{
let p = document.querySelector("p");
p.innerHTML = ((__rkt_body) => {
const __rkt_to_regexp = (__pat, __global) => {
const __flags = (__pat instanceof RegExp)
? Array.from(new Set((__pat.flags.replace(/g/g, '') + (__global ? 'g' : '')).split(''))).join('')
: (__global ? 'g' : '');
return (__pat instanceof RegExp) ? new RegExp(__pat.source, __flags) : new RegExp(String(__pat), __flags);
};
const __rkt_match_array = (__m) => (__m === null ? false : Array.from(__m, (__x) => __x === undefined ? false : __x));
const __rkt_replacement = (__s) => {
if (typeof __s !== 'string') return __s;
let __out = '';
for (let __i = 0; __i < __s.length; __i++) {
const __ch = __s[__i];
if (__ch === '$') { __out += '$$'; continue; }
if (__ch === '\\' && __i + 1 < __s.length) {
const __n = __s[++__i];
if (__n >= '0' && __n <= '9') __out += (__n === '0' ? '$&' : ('$' + __n));
else __out += __n;
} else __out += __ch;
}
return __out;
};
return __rkt_body(__rkt_to_regexp, __rkt_match_array, __rkt_replacement);
})((__rkt_to_regexp, __rkt_match_array, __rkt_replacement) => String(p.innerHTML).replace(__rkt_to_regexp(new RegExp("\\b\\w{9,}\\b"), true), __rkt_replacement(function(word) {
return ("<span style=\"background: yellow\">" + word + "</span>");
})));
}
// exercise02
{
let p = document.querySelector("p");
p.insertAdjacentHTML("afterend", "<a href=\"https://forcemipsum.com/\">Source: ForceM Ipsum</a>");
}
// exercise03
{
let p = document.querySelector("p");
p.innerHTML = ((__rkt_body) => {
const __rkt_to_regexp = (__pat, __global) => {
const __flags = (__pat instanceof RegExp)
? Array.from(new Set((__pat.flags.replace(/g/g, '') + (__global ? 'g' : '')).split(''))).join('')
: (__global ? 'g' : '');
return (__pat instanceof RegExp) ? new RegExp(__pat.source, __flags) : new RegExp(String(__pat), __flags);
};
const __rkt_match_array = (__m) => (__m === null ? false : Array.from(__m, (__x) => __x === undefined ? false : __x));
const __rkt_replacement = (__s) => {
if (typeof __s !== 'string') return __s;
let __out = '';
for (let __i = 0; __i < __s.length; __i++) {
const __ch = __s[__i];
if (__ch === '$') { __out += '$$'; continue; }
if (__ch === '\\' && __i + 1 < __s.length) {
const __n = __s[++__i];
if (__n >= '0' && __n <= '9') __out += (__n === '0' ? '$&' : ('$' + __n));
else __out += __n;
} else __out += __ch;
}
return __out;
};
return __rkt_body(__rkt_to_regexp, __rkt_match_array, __rkt_replacement);
})((__rkt_to_regexp, __rkt_match_array, __rkt_replacement) => String(p.textContent).replace(__rkt_to_regexp(new RegExp("\\.\\s*"), true), __rkt_replacement(".<br>")));
}
// exercise04
{
let heading = document.querySelector("h1");
let p = document.querySelector("p");
let words = ((__rkt_body) => {
const __rkt_to_regexp = (__pat, __global) => {
const __flags = (__pat instanceof RegExp)
? Array.from(new Set((__pat.flags.replace(/g/g, '') + (__global ? 'g' : '')).split(''))).join('')
: (__global ? 'g' : '');
return (__pat instanceof RegExp) ? new RegExp(__pat.source, __flags) : new RegExp(String(__pat), __flags);
};
const __rkt_match_array = (__m) => (__m === null ? false : Array.from(__m, (__x) => __x === undefined ? false : __x));
const __rkt_replacement = (__s) => {
if (typeof __s !== 'string') return __s;
let __out = '';
for (let __i = 0; __i < __s.length; __i++) {
const __ch = __s[__i];
if (__ch === '$') { __out += '$$'; continue; }
if (__ch === '\\' && __i + 1 < __s.length) {
const __n = __s[++__i];
if (__n >= '0' && __n <= '9') __out += (__n === '0' ? '$&' : ('$' + __n));
else __out += __n;
} else __out += __ch;
}
return __out;
};
return __rkt_body(__rkt_to_regexp, __rkt_match_array, __rkt_replacement);
})((__rkt_to_regexp, __rkt_match_array, __rkt_replacement) => String(p.textContent).split(__rkt_to_regexp(new RegExp(" "), true)));
let count = (words).length;
heading.insertAdjacentHTML("afterend", ("<p>" + String(count) + " words</p>"));
}
// exercise05
{
let p = document.querySelector("p");
let step = ((__rkt_body) => {
const __rkt_to_regexp = (__pat, __global) => {
const __flags = (__pat instanceof RegExp)
? Array.from(new Set((__pat.flags.replace(/g/g, '') + (__global ? 'g' : '')).split(''))).join('')
: (__global ? 'g' : '');
return (__pat instanceof RegExp) ? new RegExp(__pat.source, __flags) : new RegExp(String(__pat), __flags);
};
const __rkt_match_array = (__m) => (__m === null ? false : Array.from(__m, (__x) => __x === undefined ? false : __x));
const __rkt_replacement = (__s) => {
if (typeof __s !== 'string') return __s;
let __out = '';
for (let __i = 0; __i < __s.length; __i++) {
const __ch = __s[__i];
if (__ch === '$') { __out += '$$'; continue; }
if (__ch === '\\' && __i + 1 < __s.length) {
const __n = __s[++__i];
if (__n >= '0' && __n <= '9') __out += (__n === '0' ? '$&' : ('$' + __n));
else __out += __n;
} else __out += __ch;
}
return __out;
};
return __rkt_body(__rkt_to_regexp, __rkt_match_array, __rkt_replacement);
})((__rkt_to_regexp, __rkt_match_array, __rkt_replacement) => String(p.innerHTML).replace(__rkt_to_regexp(new RegExp("\\?"), true), __rkt_replacement("🤔")));
let out = ((__rkt_body) => {
const __rkt_to_regexp = (__pat, __global) => {
const __flags = (__pat instanceof RegExp)
? Array.from(new Set((__pat.flags.replace(/g/g, '') + (__global ? 'g' : '')).split(''))).join('')
: (__global ? 'g' : '');
return (__pat instanceof RegExp) ? new RegExp(__pat.source, __flags) : new RegExp(String(__pat), __flags);
};
const __rkt_match_array = (__m) => (__m === null ? false : Array.from(__m, (__x) => __x === undefined ? false : __x));
const __rkt_replacement = (__s) => {
if (typeof __s !== 'string') return __s;
let __out = '';
for (let __i = 0; __i < __s.length; __i++) {
const __ch = __s[__i];
if (__ch === '$') { __out += '$$'; continue; }
if (__ch === '\\' && __i + 1 < __s.length) {
const __n = __s[++__i];
if (__n >= '0' && __n <= '9') __out += (__n === '0' ? '$&' : ('$' + __n));
else __out += __n;
} else __out += __ch;
}
return __out;
};
return __rkt_body(__rkt_to_regexp, __rkt_match_array, __rkt_replacement);
})((__rkt_to_regexp, __rkt_match_array, __rkt_replacement) => String(step).replace(__rkt_to_regexp(new RegExp("!"), true), __rkt_replacement("😲")));
p.innerHTML = out;
}
+83
View File
@@ -0,0 +1,83 @@
#lang racket/base
(require "../main.rkt")
(provide exercise01
exercise02
exercise03
exercise04
exercise05
all-dom-exercises
show-dom-exercises)
;; JavaScript DOM Exercises 01 Tutorial: https://youtu.be/EHF7xBUAmrQ
;; Exercise 01
;; Highlight all words over 8 characters long in the paragraph text.
(define exercise01
(js
(let* ([p (send document querySelector "p")])
(set! p.innerHTML
(regexp-replace* #px"\\b\\w{9,}\\b"
p.innerHTML
(λ (word)
(string-append "<span style=\"background: yellow\">"
word
"</span>")))))))
;; Exercise 02
;; Add a link back to the source of the text after the paragraph tag.
(define exercise02
(js
(let* ([p (send document querySelector "p")])
(send p insertAdjacentHTML
"afterend"
"<a href=\"https://forcemipsum.com/\">Source: ForceM Ipsum</a>"))))
;; Exercise 03
;; Split each new sentence on to a separate line in the paragraph text.
;; A sentence is assumed to be terminated with a period.
(define exercise03
(js
(let* ([p (send document querySelector "p")])
(set! p.innerHTML
(regexp-replace* #rx"\\.\\s*" p.textContent ".<br>")))))
;; Exercise 04
;; Count the number of words in the paragraph tag and display the count
;; after the heading. Words are separated by one singular whitespace.
(define exercise04
(js
(let* ([heading (send document querySelector "h1")]
[p (send document querySelector "p")]
[words (regexp-split #rx" " p.textContent)]
[count (length words)])
(send heading insertAdjacentHTML
"afterend"
(string-append "<p>" (number->string count) " words</p>")))))
;; Exercise 05
;; Replace question marks with thinking faces and exclamation marks with
;; astonished faces.
(define exercise05
(js
(let* ([p (send document querySelector "p")]
[step (regexp-replace* #rx"\\?" p.innerHTML "🤔")]
[out (regexp-replace* #rx"!" step "😲")])
(set! p.innerHTML out))))
(define all-dom-exercises
`((exercise01 . ,exercise01)
(exercise02 . ,exercise02)
(exercise03 . ,exercise03)
(exercise04 . ,exercise04)
(exercise05 . ,exercise05)))
(define (show-dom-exercises)
(for ([entry (in-list all-dom-exercises)])
(displayln (format "// ~a" (car entry)))
(displayln (cdr entry))
(newline)))
(module+ main
(show-dom-exercises))
+312
View File
@@ -0,0 +1,312 @@
// Generated by demo/js-usecases.rkt
// Each use case is wrapped in a function so snippets with return are valid.
// random-number
function run_random_number() {
function randomBetween1And5() {
return (Math.floor((Math.random() * 5)) + 1);
}
}
// unique-values
function run_unique_values() {
function uniqueValues(xs) {
return Array.from(new Set(xs));
}
}
// falsey-values
function run_falsey_values() {
function falseyValues() {
return [false, 0, "", null, undefined, NaN];
}
}
// currying
function run_currying() {
function add(x) {
return function(y) {
return (x + y);
};
}
}
// object-destructuring
function run_object_destructuring() {
function describePerson(person) {
return (() => {
const { name: name, age: age = 0 } = person;
return (name + ":" + String(age));
})();
}
}
// timer-interval
function run_timer_interval() {
function startTimer() {
{
let ticks = 0;
let intervalId = false;
intervalId = setInterval(function() {
ticks = (ticks + 1);
if ((ticks === 3)) {
clearInterval(intervalId);
}
return undefined;
}, 10);
return {id: intervalId, getTicks: function() {
return ticks;
}};
}
}
}
// object-props
function run_object_props() {
function objectProps() {
{
let obj = {a: 1};
let a1 = obj.a;
let a2 = obj["a"];
return (() => {
const { a: a3 } = obj;
obj.b = 2;
obj["c"] = 3;
delete obj["a"];
return [a1, a2, a3, obj.b, obj["c"], Object.hasOwn(obj, "a")];
})();
}
}
}
// string-concat-order
function run_string_concat_order() {
function concatOrder() {
return [(1 + 2 + "3"), ("1" + 2 + 3)];
}
}
// freeze-vs-seal
function run_freeze_vs_seal() {
function freezeVsSeal() {
{
let frozen = Object.freeze({a: 1});
let sealed = Object.seal({a: 1});
frozen.a = 9;
sealed.a = 9;
delete sealed["a"];
return [frozen.a, sealed.a, Object.isFrozen(frozen), Object.isSealed(sealed), Object.hasOwn(sealed, "a")];
}
}
}
// switch
function run_switch() {
function switchExample(n) {
return (() => {
{
const __case_value = n;
switch (__case_value) {
case 1:
return "one";
break;
case 2:
case 3:
return "two-or-three";
break;
default:
return "other";
}
}
})();
}
}
// class-constructor
function run_class_constructor() {
class Greeter {
constructor(name = "world") {
this.name = name;
}
greet() {
return ("Hello " + this.name);
}
}
function classExample() {
{
let a = new Greeter();
let b = new Greeter("Ada");
return [a.greet(), b.greet()];
}
}
}
// sort-objects-by-property
function run_sort_objects_by_property() {
function sortByProperty(xs, prop) {
return xs.slice().sort(function(a, b) {
return (a[prop] - b[prop]);
});
}
}
// delete-array-elements
function run_delete_array_elements() {
function deleteArrayWays(xs) {
{
let a1 = xs.slice();
let a2 = xs.slice();
let a3 = xs.slice();
let a4 = xs.slice();
a1.splice(1, 1);
a2 = a2.filter(function(x, i) {
return ((i === 1) === false);
});
a3 = a3.slice(0, 1).concat(a3.slice(2));
delete a4[1];
return [a1, a2, a3, [Object.hasOwn(a4, "1"), (a4).length]];
}
}
}
// bubble-sort
function run_bubble_sort() {
function bubbleSort(xs) {
{
let a = xs.slice();
let n = (a).length;
while (n > 1) {
{
let i = 1;
while (i < n) {
if ((() => {
const __cmp_1 = (a)[(i - 1)];
const __cmp_2 = (a)[i];
return (__cmp_1 > __cmp_2);
})()) {
{
let tmp = (a)[(i - 1)];
a[(i - 1)] = (a)[i];
a[i] = tmp;
}
}
i = (i + 1);
}
}
n = (n - 1);
}
return a;
}
}
}
// binary-search
function run_binary_search() {
function binarySearch(xs, target, low, high) {
if (low > high) {
return -1;
} else {
{
let mid = Math.floor((() => {
const __div_3 = (low + high);
const __div_4 = 2;
if (__div_4 === 0) throw new Error("division by zero");
return (__div_3 / __div_4);
})());
let value = (xs)[mid];
const __cond_value_5 = (value === target);
if (__cond_value_5 !== false) {
return mid;
} else {
const __cond_value_6 = (value < target);
if (__cond_value_6 !== false) {
return binarySearch(xs, target, (mid + 1), high);
} else {
return binarySearch(xs, target, low, (mid - 1));
}
}
}
}
}
}
// map-count-occurrences
function run_map_count_occurrences() {
function countOccurrences(xs) {
{
let counts = new Map();
for (const x of xs) {
if ((counts.has(x) !== false)) {
counts.set(x, (counts.get(x) + 1));
} else {
counts.set(x, 1);
}
}
return Array.from(counts.entries());
}
}
}
// get-html-three-ways
function run_get_html_three_ways() {
function getHtmlThreeWays() {
return [document.body.innerHTML, document.querySelector("body").innerHTML, document.getElementById("root")["innerHTML"]];
}
}
// anagram
function run_anagram() {
function sortChars(s) {
return s.split("").sort().join("");
}
function canArrange(stringA, stringB) {
return (() => {
const __cmp_8 = sortChars(stringA);
const __cmp_9 = sortChars(stringB);
return (__cmp_8 === __cmp_9);
})();
}
}
// pairs-equal-target
function run_pairs_equal_target() {
function pairsEqualTarget(xs, target) {
{
let seen = new Set();
let used = new Set();
let out = [];
for (const x of xs) {
{
let y = (target - x);
if (((() => {
let __and_value_11 = seen.has(y);
if (__and_value_11 === false) return false;
__and_value_11 = (used.has(x) === false);
if (__and_value_11 === false) return false;
return (used.has(y) === false);
})() !== false)) {
out.push([y, x]);
used.add(x);
used.add(y);
} else {
seen.add(x);
}
}
}
return out;
}
}
}
// fetch-api
function run_fetch_api() {
function loadTitle(url) {
return fetch(url).then(function(response) {
return response.json();
}).then(function(data) {
return {ok: true, title: data.title};
}).catch(function(err) {
return {ok: false, message: err.message};
});
}
}
+304
View File
@@ -0,0 +1,304 @@
#lang racket/base
(require racket/list
"../main.rkt")
(provide usecase-random-number
usecase-unique-values
usecase-falsey-values
usecase-currying
usecase-object-destructuring
usecase-timer-interval
usecase-object-props
usecase-string-concat-order
usecase-freeze-vs-seal
usecase-switch
usecase-class-constructor
usecase-sort-objects-by-property
usecase-delete-array-elements
usecase-bubble-sort
usecase-binary-search
usecase-map-count-occurrences
usecase-get-html-three-ways
usecase-anagram
usecase-pairs-equal-target
usecase-fetch-api
all-js-usecases
show-js-usecases
write-js-usecases-file)
;; Use case 01: generate a random integer between 1 and 5.
(define usecase-random-number
(js
(define (randomBetween1And5)
(return (+ (send Math floor (* (send Math random) 5)) 1)))))
;; Use case 02: get unique values from an array with duplicates using Set.
(define usecase-unique-values
(js
(define (uniqueValues xs)
(return (send Array from (new Set xs))))))
;; Use case 03: the six JavaScript falsey values.
(define usecase-falsey-values
(js
(define (falseyValues)
(return (array #f 0 "" js-null js-undefined js-NaN)))))
;; Use case 04: currying, simple example.
(define usecase-currying
(js
(define (add x)
(return (lambda (y)
(return (+ x y)))))))
;; Use case 05: object destructuring.
(define usecase-object-destructuring
(js
(define (describePerson person)
(let-object ([name 'name]
[age 'age 0])
person
(return (string-append name ":" (number->string age)))))))
;; Use case 06: get out of a timer interval with setInterval/clearInterval.
(define usecase-timer-interval
(js
(define (startTimer)
(let* ([ticks 0]
[intervalId #f])
(set! intervalId
(setInterval (lambda ()
(set! ticks (+ ticks 1))
(when (= ticks 3)
(clearInterval intervalId)))
10))
(return (object 'id intervalId
'getTicks (lambda () (return ticks))))))))
;; Use case 07: get/set/delete object properties. The value of a is read via
;; dot access, bracket access, and destructuring.
(define usecase-object-props
(js
(define (objectProps)
(let* ([obj (object 'a 1)]
[a1 obj.a]
[a2 (js-ref obj "a")])
(let-object ([a3 'a]) obj
(set! obj.b 2)
(set-prop! obj "c" 3)
(delete-prop! obj "a")
(return (array a1 a2 a3 obj.b (js-ref obj "c")
(send Object hasOwn obj "a"))))))))
;; Use case 08: string concatenation; order matters with JavaScript +.
(define usecase-string-concat-order
(js
(define (concatOrder)
(return (array (+ 1 2 "3")
(+ "1" 2 3))))))
;; Use case 09: Object.freeze() vs Object.seal().
(define usecase-freeze-vs-seal
(js
(define (freezeVsSeal)
(let* ([frozen (send Object freeze (object 'a 1))]
[sealed (send Object seal (object 'a 1))])
(set! frozen.a 9)
(set! sealed.a 9)
(delete-prop! sealed "a")
(return (array frozen.a
sealed.a
(send Object isFrozen frozen)
(send Object isSealed sealed)
(send Object hasOwn sealed "a")))))))
;; Use case 10: switch example. The Racket surface form is case.
(define usecase-switch
(js
(define (switchExample n)
(case n
[(1) (return "one")]
[(2 3) (return "two-or-three")]
[else (return "other")]))))
;; Use case 11: class constructor with a default value.
(define usecase-class-constructor
(js
(define-class Greeter
(constructor ([name "world"])
(set! this.name name))
(method greet ()
(return (string-append "Hello " this.name))))
(define (classExample)
(let* ([a (new Greeter)]
[b (new Greeter "Ada")])
(return (array (send a greet) (send b greet)))))))
;; Use case 12: sort an array of objects by a given property.
(define usecase-sort-objects-by-property
(js
(define (sortByProperty xs prop)
(return (send (send xs slice)
sort
(lambda (a b)
(return (- (js-ref a prop) (js-ref b prop)))))))))
;; Use case 13: four ways to delete/remove an element from an array.
(define usecase-delete-array-elements
(js
(define (deleteArrayWays xs)
(let* ([a1 (send xs slice)]
[a2 (send xs slice)]
[a3 (send xs slice)]
[a4 (send xs slice)])
;; 1. Mutating removal with splice.
(send a1 splice 1 1)
;; 2. Functional removal with filter.
(set! a2 (send a2 filter (lambda (x i) (return (not (= i 1))))))
;; 3. Rebuild with slice + concat.
(set! a3 (send (send a3 slice 0 1) concat (send a3 slice 2)))
;; 4. delete leaves a hole and preserves length.
(delete-prop! a4 1)
(return (array a1 a2 a3 (array (send Object hasOwn a4 "1") (length a4))))))))
;; Use case 14: Bubble Sort.
(define usecase-bubble-sort
(js
(define (bubbleSort xs)
(let* ([a (send xs slice)]
[n (length a)])
(while (> n 1)
(let* ([i 1])
(while (< i n)
(when (> (list-ref a (- i 1)) (list-ref a i))
(let* ([tmp (list-ref a (- i 1))])
(vector-set! a (- i 1) (list-ref a i))
(vector-set! a i tmp)))
(set! i (+ i 1))))
(set! n (- n 1)))
(return a)))))
;; Use case 15: Binary Search using recursion.
(define usecase-binary-search
(js
(define (binarySearch xs target low high)
(if (> low high)
(return -1)
(let* ([mid (send Math floor (/ (+ low high) 2))]
[value (list-ref xs mid)])
(cond
[(= value target) (return mid)]
[(< value target) (return (binarySearch xs target (+ mid 1) high))]
[else (return (binarySearch xs target low (- mid 1)))]))))))
;; Use case 16: use Map to count how often each element occurs in an array.
(define usecase-map-count-occurrences
(js
(define (countOccurrences xs)
(let* ([counts (new Map)])
(for ([x (in-list xs)])
(if (send counts has x)
(send counts set x (+ (send counts get x) 1))
(send counts set x 1)))
(return (send Array from (send counts entries)))))))
;; Use case 17: get HTML in three different ways via the DOM.
(define usecase-get-html-three-ways
(js
(define (getHtmlThreeWays)
(return (array document.body.innerHTML
(js-dot (send document querySelector "body") innerHTML)
(js-ref (send document getElementById "root") "innerHTML"))))))
;; Use case 18: determine if stringA can be arranged into stringB.
(define usecase-anagram
(js
(define (sortChars s)
(return (send (send (send s split "") sort) join "")))
(define (canArrange stringA stringB)
(return (string=? (sortChars stringA) (sortChars stringB))))))
;; Use case 19: determine what pairs in an array equal a given value, with no
;; repeated numbers in the result pairs.
(define usecase-pairs-equal-target
(js
(define (pairsEqualTarget xs target)
(let* ([seen (new Set)]
[used (new Set)]
[out (array)])
(for ([x (in-list xs)])
(let* ([y (- target x)])
(if (and (send seen has y)
(not (send used has x))
(not (send used has y)))
(begin
(send out push (array y x))
(send used add x)
(send used add y))
(send seen add x))))
(return out)))))
;; Use case 20: fetch API, handling results and errors. The function returns a
;; Promise, which the test framework awaits.
(define usecase-fetch-api
(js
(define (loadTitle url)
(return
(send
(send
(send (fetch url)
then
(lambda (response)
(return (send response json))))
then
(lambda (data)
(return (object 'ok #t 'title data.title))))
catch
(lambda (err)
(return (object 'ok #f 'message err.message))))))))
(define all-js-usecases
`((random-number . ,usecase-random-number)
(unique-values . ,usecase-unique-values)
(falsey-values . ,usecase-falsey-values)
(currying . ,usecase-currying)
(object-destructuring . ,usecase-object-destructuring)
(timer-interval . ,usecase-timer-interval)
(object-props . ,usecase-object-props)
(string-concat-order . ,usecase-string-concat-order)
(freeze-vs-seal . ,usecase-freeze-vs-seal)
(switch . ,usecase-switch)
(class-constructor . ,usecase-class-constructor)
(sort-objects-by-property . ,usecase-sort-objects-by-property)
(delete-array-elements . ,usecase-delete-array-elements)
(bubble-sort . ,usecase-bubble-sort)
(binary-search . ,usecase-binary-search)
(map-count-occurrences . ,usecase-map-count-occurrences)
(get-html-three-ways . ,usecase-get-html-three-ways)
(anagram . ,usecase-anagram)
(pairs-equal-target . ,usecase-pairs-equal-target)
(fetch-api . ,usecase-fetch-api)))
(define (show-js-usecases)
(for ([entry (in-list all-js-usecases)])
(displayln (format "// ~a" (car entry)))
(displayln (cdr entry))
(newline)))
(define (write-js-usecases-file path)
(call-with-output-file path
#:exists 'replace
(lambda (out)
(displayln "// Generated by demo/js-usecases.rkt" out)
(displayln "// Each use case is wrapped in a function so snippets with return are valid." out)
(for ([entry (in-list all-js-usecases)])
(fprintf out "\n// ~a\n" (car entry))
(fprintf out "function run_~a() {\n~a\n}\n"
(regexp-replace* #rx"[^A-Za-z0-9_$]" (symbol->string (car entry)) "_")
(cdr entry))))))
(module+ main
(show-js-usecases))
+32
View File
@@ -0,0 +1,32 @@
#lang racket/base
(require "../main.rkt")
(define examples
(list
(cons 'expression
(js/expression
(let loop ([i 0] [acc 0])
(if (< i 5)
(loop (+ i 1) (+ acc i))
acc))))
(cons 'program-t1
(js
(set! window.myfunc
(λ (x)
(let* ((el (send document getElementById 'hi))
(y (* x x)))
(send el setAttribute "x" (+ y "")))
(send console log "dit set attribute x on element hi")))))
(cons 'program-t2
(js
(define (f x)
(if (and (> x 10) (< x 15))
(begin (console.log x)
(return x))
(return (* x x))))))
(cons 'regexp
(js/expression
(regexp-match #px"([a-z]+)-([0-9]+)" "abc-123")))))
(for ([e (in-list examples)])
(printf "===== ~a =====\n~a\n\n" (car e) (cdr e)))
+16
View File
@@ -0,0 +1,16 @@
#lang racket/base
(require "../main.rkt")
(displayln "--- and ---")
(displayln (js/expression (and (> x 10) (< x 15))))
(displayln "--- t2 ---")
(displayln (js (define (f x)
(if (and (> x 10) (< x 15))
(begin (console.log x)
(return x))
(return (* x x))))))
(displayln "--- let* ---")
(displayln (js (let* ((x 10)
(y (+ x x)))
(return y))))
(displayln "--- let* tdz ---")
(displayln (js/expression (let ([x 4]) (let* ([x x] [y x]) (+ x y)))))