Web Embeddable Common Lisp

Check-in [fa96ed9db6]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:"code buffer integration"
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: fa96ed9db68411ceb35a4151a275f51a7ba23970e5c68bab2aaa86326a1f5e58
User & Date: jack 2024-05-30 19:28:29
Context
2024-05-30
20:14
js_text: use innerText to preserve newlines check-in: d443e61bc8 user: jack tags: trunk
19:28
"code buffer integration" check-in: fa96ed9db6 user: jack tags: trunk
13:09
tiles: add tiling support check-in: 8ed9d55502 user: jack tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to Code/main.js.

30
31
32
33
34
35
36

37
38
39
40
41
42
43
    term = new Terminal({
        theme: theme,
        fontSize: 14,
    });
    term.loadAddon(fito);
    term.open(node);
    fito.fit();

    return term;
}

const ostr_nl = '\r\n';
const ostr_style_non = '\x1B[0m';
const ostr_style_err = '\x1B[1;3;31m';








>







30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
    term = new Terminal({
        theme: theme,
        fontSize: 14,
    });
    term.loadAddon(fito);
    term.open(node);
    fito.fit();
    
    return term;
}

const ostr_nl = '\r\n';
const ostr_style_non = '\x1B[0m';
const ostr_style_err = '\x1B[1;3;31m';

Changes to Code/wecl.c.

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
#include <stdio.h>
#include <emscripten.h>
#include <ecl/ecl.h>

/* EM_ASYNC_JS(void, js_test, (), { */
/*     tick = document.getElementById('tick'); */
/*     return new Promise(resolve => tick.onclick = () => resolve()); */
/*   }); */

/* EM_ASYNC_JS(char *, js_test, (), { */
/*     return new Promise(resolve => read_promise = */
/*                        function(cmd) { */
/*                          c_cmd = stringToNewUTF8(cmd); */
/*                          read_promise = null; */
/*                          return resolve(c_cmd); */
/*                        }); */

/*   }); */

EM_ASYNC_JS(char *, js_read_inner, (), {
    return new Promise(resolve => read_promise =
                       function(cmd) {
                         c_cmd = stringToNewUTF8(cmd);
                         read_promise = null;
                         read_promise_var = null;
                         return resolve(c_cmd);
                       });
  });

cl_object js_read() {
  char *result = js_read_inner();
  return ecl_cstring_to_base_string_or_nil(result);
}














cl_object js_eval(cl_object js_str) {
  const char *str = ecl_base_string_pointer_safe
    (ecl_null_terminated_base_string(js_str));
  emscripten_run_script(str);
  return ECL_NIL;
}




<
<
<
<
<
<
<
<
<
<
<
<
<
<
<














>
>
>
>
>
>
>
>
>
>
>
>
>







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
#include <stdio.h>
#include <emscripten.h>
#include <ecl/ecl.h>
















EM_ASYNC_JS(char *, js_read_inner, (), {
    return new Promise(resolve => read_promise =
                       function(cmd) {
                         c_cmd = stringToNewUTF8(cmd);
                         read_promise = null;
                         read_promise_var = null;
                         return resolve(c_cmd);
                       });
  });

cl_object js_read() {
  char *result = js_read_inner();
  return ecl_cstring_to_base_string_or_nil(result);
}

EM_JS(char *, js_text_inner, (const char *element_id), {
    id = Module.UTF8ToString(element_id);
    result = document.getElementById(id).textContent;
    return stringToNewUTF8(result);
  });

cl_object js_text(cl_object id) {
  const char * elt_id= ecl_base_string_pointer_safe
    (ecl_null_terminated_base_string(id));
  char *result = js_text_inner(elt_id);
  return ecl_cstring_to_base_string_or_nil(result);
}

cl_object js_eval(cl_object js_str) {
  const char *str = ecl_base_string_pointer_safe
    (ecl_null_terminated_base_string(js_str));
  emscripten_run_script(str);
  return ECL_NIL;
}
52
53
54
55
56
57
58



59
60
61
62
63
64
65
  ecl_def_c_function(aux, js_yield, 0);

  aux = ecl_make_symbol("JS-EVAL", "CL-USER");
  ecl_def_c_function(aux, js_eval, 1);

  aux = ecl_make_symbol("JS-READ", "CL-USER");
  ecl_def_c_function(aux, js_read, 0);



}

void wecl_exit() {
  cl_shutdown();
}

void wecl_test() {







>
>
>







50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
  ecl_def_c_function(aux, js_yield, 0);

  aux = ecl_make_symbol("JS-EVAL", "CL-USER");
  ecl_def_c_function(aux, js_eval, 1);

  aux = ecl_make_symbol("JS-READ", "CL-USER");
  ecl_def_c_function(aux, js_read, 0);

  aux = ecl_make_symbol("JS-TEXT", "CL-USER");
  ecl_def_c_function(aux, js_text, 1);
}

void wecl_exit() {
  cl_shutdown();
}

void wecl_test() {

Changes to Code/wecl.lisp.

29
30
31
32
33
34
35

















36
37
38
39
40
41
42
  (case ch
    (#\newline "\\n")
    (#\'       "\\'")
    (#\`       "\\`")
    (#\\       "\\\\")
    (otherwise (string ch))))


















(defun read-file-to-js-string (file)
  (with-output-to-string (output)
    (with-open-file (input file)
      (loop for line = (read-line input nil)
            while line do
              (loop for ch across line do
                (write-string (sanitize ch) output))







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







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
  (case ch
    (#\newline "\\n")
    (#\'       "\\'")
    (#\`       "\\`")
    (#\\       "\\\\")
    (otherwise (string ch))))

(defun print-file (file)
  (with-open-file (input file)
    (format t "-- ~a~%" file)
    (loop for idx from 0
          for line = (read-line input nil)
          while line do
            (format t "~4,'0d: ~a~%" idx line)
            (js-yield))
    (format t "++ ~a~%" file)))

(defun read-file-to-string (file)
  (with-output-to-string (output)
    (with-open-file (input file)
      (loop for line = (read-line input nil)
            while line do
              (write-string line output)))))

(defun read-file-to-js-string (file)
  (with-output-to-string (output)
    (with-open-file (input file)
      (loop for line = (read-line input nil)
            while line do
              (loop for ch across line do
                (write-string (sanitize ch) output))
392
393
394
395
396
397
398
399
400



401
402
403
404
405
406
407
    (if (probe-file file)
        (prog1 t
          (let ((string (read-file-to-js-string file)))
            (js-eval* "shadow_dom.get('code').textContent=`~a`;" string)))
        (prog1 t
          (js-eval* "fetch_file(`~a`);" file)))))

(defun compile-and-load-from-code-buffer ()
  )




#+(or) ;; not yet (static build? ship fasl? c.f dlopen)
(progn
  (require "ASDF")
  (print (asdf:asdf-version)))









|
<
>
>
>







409
410
411
412
413
414
415
416

417
418
419
420
421
422
423
424
425
426
    (if (probe-file file)
        (prog1 t
          (let ((string (read-file-to-js-string file)))
            (js-eval* "shadow_dom.get('code').textContent=`~a`;" string)))
        (prog1 t
          (js-eval* "fetch_file(`~a`);" file)))))

(defun invoke-code-buffer (&optional (buffer-id "code"))

  (with-open-file (stream "code-buffer.lisp" :direction :output)
    (write-string (js-text buffer-id) stream))
  (compile-file "code-buffer.lisp" :load t))

#+(or) ;; not yet (static build? ship fasl? c.f dlopen)
(progn
  (require "ASDF")
  (print (asdf:asdf-version)))


592
593
594
595
596
597
598


599
600
601
602
603
604
605
606
607
608
609
610
611
612
613



(defun create-world ()
  (let ((graft (import-sheet "body" "body" "graft"))
        (stdo (import-sheet "div" "" "ostr"))
        (repl (import-sheet "div" "" "repl"))
        (code (open-buffer "code"))
        (draw (open-canvas "draw")))))



(defun js-init ()
  (setf *standard-output* *ostr-stream*
        *standard-input*  *ostr-stream*
        *error-output*    *ostr-stream*
        *query-io*        *repl-stream*
        *debug-io*        *repl-stream*
        *terminal-io*     *repl-stream*)
  (ext:install-bytecodes-compiler)
  (pushnew #'update-code-buffer ext:*ed-functions*)
  (clear-output *repl-stream*)
  (create-world)
  ;; go!
  (repl))

#+wasm32(js-init)










>
>














|
>
>
>
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
(defun create-world ()
  (let ((graft (import-sheet "body" "body" "graft"))
        (stdo (import-sheet "div" "" "ostr"))
        (repl (import-sheet "div" "" "repl"))
        (code (open-buffer "code"))
        (draw (open-canvas "draw")))))

(defvar *js-initialized-p* nil)

(defun js-init ()
  (setf *standard-output* *ostr-stream*
        *standard-input*  *ostr-stream*
        *error-output*    *ostr-stream*
        *query-io*        *repl-stream*
        *debug-io*        *repl-stream*
        *terminal-io*     *repl-stream*)
  (ext:install-bytecodes-compiler)
  (pushnew #'update-code-buffer ext:*ed-functions*)
  (clear-output *repl-stream*)
  (create-world)
  ;; go!
  (repl))

#+wasm32
(unless *js-initialized-p*
  (setf *js-initialized-p* t)
  (js-init))

Changes to make.sh.

14
15
16
17
18
19
20

21
22
23
24
25
26
27
28
29
    echo "Building..."
    cp wecl.c wecl.lisp wasm-ecl/
    pushd wasm-ecl
    emcc -O2 \
         -sASYNCIFY -sASYNCIFY_STACK_SIZE=1048576 \
         -sASYNCIFY_IMPORTS=[cl_eval,js_test,js_read] \
         -sSTACK_SIZE=1048576 \

         -sERROR_ON_UNDEFINED_SYMBOLS=0 \
         -sEXPORTED_RUNTIME_METHODS=ccall,cwrap,stringToNewUTF8 \
         -sEXPORTED_FUNCTIONS=_wecl_brrt \
         --embed-file "wecl.lisp" \
         libecl{,gc,gmp}.a wecl.c -I./ -o wecl.js
    popd
    cp wasm-ecl/libecl{,gc,gmp}.a wasm-ecl/wecl.js wasm-ecl/wecl.wasm .
}








>

|







14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
    echo "Building..."
    cp wecl.c wecl.lisp wasm-ecl/
    pushd wasm-ecl
    emcc -O2 \
         -sASYNCIFY -sASYNCIFY_STACK_SIZE=1048576 \
         -sASYNCIFY_IMPORTS=[cl_eval,js_test,js_read] \
         -sSTACK_SIZE=1048576 \
         -sINITIAL_MEMORY=67108864 \
         -sERROR_ON_UNDEFINED_SYMBOLS=0 \
         -sEXPORTED_RUNTIME_METHODS=ccall,cwrap,stringToNewUTF8,UTF8ToString \
         -sEXPORTED_FUNCTIONS=_wecl_brrt \
         --embed-file "wecl.lisp" \
         libecl{,gc,gmp}.a wecl.c -I./ -o wecl.js
    popd
    cp wasm-ecl/libecl{,gc,gmp}.a wasm-ecl/wecl.js wasm-ecl/wecl.wasm .
}