add minimal repl for IO debugging purpose

This commit is contained in:
pmp-p 2019-07-07 18:31:31 +02:00
parent 0838e1fd8c
commit 455fbb5791
5 changed files with 311 additions and 165 deletions

View File

@ -0,0 +1,165 @@
// ============================== FILE I/O (sync => bad) =================================
window.urls = {"name":"webcache","id":-1, "index": "/index.html"}
function awfull_get(url) {
function updateProgress (oEvent) {
if (oEvent.lengthComputable) {
var percentComplete = oEvent.loaded / oEvent.total;
} else {
// Unable to compute progress information since the total size is unknown
// on binary XHR
}
}
function transferFailed(evt) {
console.log("callfs: An error occurred while transferring the file '"+window.currentTransfer+"'");
}
function transferCanceled(evt) {
console.log("callfs: transfer '"+window.currentTransfer+"' has been canceled by the user.");
}
var oReq = new XMLHttpRequest();
function transferComplete(evt) {
if (oReq.status==404){
console.log("callfs: File not found : "+ url );
window.currentTransferSize = -1 ;
} else {
window.currentTransferSize = oReq.response.length;
console.log("callfs: Transfer is complete saving : "+window.currentTransferSize);
}
}
oReq.overrideMimeType("text/plain; charset=x-user-defined");
oReq.addEventListener("progress", updateProgress);
oReq.addEventListener("load", transferComplete);
oReq.addEventListener("error", transferFailed);
oReq.addEventListener("abort", transferCanceled);
oReq.open("GET",url ,false);
oReq.send();
return oReq.response
}
function wasm_file_open(url, cachefile){
var dirpath = ""
if ( url == cachefile ) {
//we need to build the target path, it could be a module import.
//transform to relative path to /
while (cachefile.startswith("/"))
cachefile = cachefile.substring(1)
while (url.startswith("/"))
url = url.substring(1)
// is it still a path with at least a one char folder ?
if (cachefile.indexOf('/')>0) {
var path = cachefile.split('/')
// last elem is the filename
while (path.length>1) {
var current_folder = path.shift()
try {
FS.createFolder(dirpath, current_folder, true, true)
//FS.createPath('/', dirname, true, true)
} catch (err) {
if (err.code !== 'EEXIST') throw err
}
dirpath = dirpath + "/" + current_folder
}
console.log("+dir: "+dirpath+" +file: " + path.shift())
} else {
// this is a root folder, abort
if (url.indexOf(".") <1 )
return -1
}
cachefile = "/" + url
console.log("in / +" + cachefile)
}
try {
if (url[0]==":")
url = url.substr(1)
else {
// [TODO:do some tests there for your CORS integration]
if (url.includes('/wyz.fr/'))
url = CORS_BROKER + url
}
var ab = awfull_get(url)
var ret = ab.length
window.urls.id += 1
if (!cachefile){
cachefile = "cache_"+window.urls.id
ret = window.urls.id
}
FS.createDataFile("/", cachefile, ab, true, true);
return ret
} catch (x) {
console.log("wasm_file_open :"+x)
return -1
}
}
function wasm_file_exists(url, need_dot) {
// need_dot reminds we can't check for directory on webserver
// but we can check for a know file (probaby with a dot) under it
// -1 not found , 1 is a file on server , 2 is a directory
function url_exists(url,code) {
var xhr = new XMLHttpRequest()
xhr.open('HEAD', url, false)
xhr.send()
if (xhr.status == 200 )
return code
return -1
}
// we know those are all MEMFS local files.
// and yes it's the same folder name as in another OS apps
if (url.startswith('assets/'))
return -1
if (url.endswith('.mpy'))
return -1
// are we possibly doing folder checking ?
if (need_dot) {
// .mpy is blacklisted for now
// so if it's not .py then it's a folder check.
if (!url.endswith('.py')) {
var found = -1
// package search
found = url_exists( url + '/__init__.py' , 2 )
//console.log("wasm_([dir]/file)_exists ? :"+url+ ' --> ' + '/__init__.py => '+found)
if (found>0) return found
//namespace search
found = url_exists( url + window.urls.index , 2 )
//console.log("wasm_([dir]/file)_exists ? :"+url+ ' --> ' + window.urls.index + " => "+found)
if (found>0) return found
}
// if name has no dot then it was a folder check
//console.log("wasm_(dir/[file])_exists ? :"+url)
need_dot = url.split('.').pop()
if (need_dot==url) {
console.log("wasm_file_exists not-a-file :"+url)
return -1
}
}
// default is a file search
return url_exists(url, 1)
}

View File

@ -30,169 +30,8 @@ given some restrictions.
You will need to provide two functions in your js loader.
These are provided as examples and only cover some usefull cases.
window.urls = {}
window.urls.index = 0
function awfull_get(url) {
function updateProgress (oEvent) {
if (oEvent.lengthComputable) {
var percentComplete = oEvent.loaded / oEvent.total;
} else {
// Unable to compute progress information since the total size is unknown
// on binary XHR
}
}
function transferFailed(evt) {
console.log("callfs: An error occurred while transferring the file '"+window.currentTransfer+"'");
}
function transferCanceled(evt) {
console.log("callfs: transfer '"+window.currentTransfer+"' has been canceled by the user.");
}
var oReq = new XMLHttpRequest();
function transferComplete(evt) {
if (oReq.status==404){
console.log("callfs: File not found : "+ url );
window.currentTransferSize = -1 ;
} else {
window.currentTransferSize = oReq.response.length;
console.log("callfs: Transfer is complete saving : "+window.currentTransferSize);
}
}
oReq.overrideMimeType("text/plain; charset=x-user-defined");
oReq.addEventListener("progress", updateProgress);
oReq.addEventListener("load", transferComplete);
oReq.addEventListener("error", transferFailed);
oReq.addEventListener("abort", transferCanceled);
oReq.open("GET",url ,false);
oReq.send();
return oReq.response
}
function wasm_file_open(url, cachefile){
var dirpath = ""
if ( url == cachefile ) {
//we need to build the target path, it could be a module import.
//transform to relative path to /
while (cachefile.startswith("/"))
cachefile = cachefile.substring(1)
while (url.startswith("/"))
url = url.substring(1)
// is it still a path with at least a one char folder ?
if (cachefile.indexOf('/')>0) {
var path = cachefile.split('/')
// last elem is the filename
while (path.length>1) {
var current_folder = path.shift()
try {
FS.createFolder(dirpath, current_folder, true, true)
//FS.createPath('/', dirname, true, true)
} catch (err) {
if (err.code !== 'EEXIST') throw err
}
dirpath = dirpath + "/" + current_folder
}
console.log("+dir: "+dirpath+" +file: " + path.shift())
} else {
// this is a root folder, abort
if (url.indexOf(".") <1 )
return -1
}
cachefile = "/" + url
console.log("in / +" + cachefile)
}
try {
if (url[0]==":")
url = url.substr(1)
else {
// [TODO:do some tests there for your CORS integration]
}
var ab = awfull_get(url)
var ret = ab.length
window.urls.index += 1
if (!cachefile){
cachefile = "cache_"+window.urls.index
ret = window.urls.index
}
FS.createDataFile("/", cachefile, ab, true, true);
return ret
} catch (x) {
console.log("wasm_file_open :"+x)
return -1
}
}
window.USE_DIR_INDEX = "/index.html"
function wasm_file_exists(url, need_dot) {
// need_dot reminds we can't check for directory on webserver
// but we can check for a know file (probaby with a dot) under it
// -1 not found , 1 is a file on server , 2 is a directory
function url_exists(url,code) {
var xhr = new XMLHttpRequest()
xhr.open('HEAD', url, false)
xhr.send()
if (xhr.status == 200 )
return code
return -1
}
// we know those are all MEMFS local files.
// and yes it's the same folder name as in another OS apps
if (url.startswith('assets/'))
return -1
if (url.endswith('.mpy'))
return -1
// are we possibly doing folder checking ?
if (need_dot) {
// .mpy is blacklisted for now
// so if it's not .py then it's a folder check.
if (!url.endswith('.py')) {
var found = -1
// package search
found = url_exists( url + '/__init__.py' , 2 )
console.log("wasm_([dir]/file)_exists ? :"+url+ ' --> ' + '/__init__.py => '+found)
if (found>0) return found
//namespace search
found = url_exists( url + USE_DIR_INDEX , 2 )
console.log("wasm_([dir]/file)_exists ? :"+url+ ' --> ' + USE_DIR_INDEX+" => "+found)
if (found>0) return found
}
// if name has no dot then it was a folder check
console.log("wasm_(dir/[file])_exists ? :"+url)
need_dot = url.split('.').pop()
if (need_dot==url) {
console.log("wasm_file_exists not-a-file :"+url)
return -1
}
}
// default is a file search
return url_exists(url, 1)
}
see docs/wasm_file_api.js for a dumb implementation using MEMFS as a cache.

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@ -132,7 +132,7 @@ STATIC int execute_from_lexer(int source_kind, const void *source, mp_parse_inpu
MP_STATE_VM(mp_pending_exception) = MP_OBJ_NULL;
nlr_raise(obj);
}
nlr_pop();
return 0;
@ -212,7 +212,7 @@ void mp_js_init(int heap_size) {
#endif
mp_init();
mp_obj_list_init(mp_sys_path, 0);
mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR_));
mp_obj_list_init(mp_sys_argv, 0);
@ -251,7 +251,7 @@ MP_DEFINE_CONST_FUN_OBJ_KW(mp_builtin_open_obj, 1, mp_builtin_open);
#endif
#else
#pragma message "file.c will require external WASM_FILE_API functions"
#pragma message "see wasm_file_api.txt"
#pragma message "see docs/wasm_file_api.txt"
#endif
void nlr_jump_fail(void *val) {

142
ports/javascript/repl.html Normal file
View File

@ -0,0 +1,142 @@
<html>
<head>
<meta charset="utf-8">
<meta name=viewport content='width=device-width,initial-scale=1'>
<style>
body {
width: 100%;
box-sizing: border-box;
padding: 0;
margin: 0;
text-align: center;
}
a { white-space: nowrap; }
#vt100,#mp_js_stdout {
display: inline-block;
vertical-align: middle;
}
#canvas {
border: 4px black solid;
border-radius: 4px;
</style>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/xterm/3.14.4/xterm.min.css" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/xterm/3.14.4/xterm.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/xterm/3.14.4/addons/fit/fit.min.js"></script>
<script src="lvgl_mp.js"></script>
<script src="docs/wasm_file_api.js"></script>
</head>
<body>
<h1>MicroPython javascript port + lvgl</h1>
<pre id="url"></pre>
<pre id="test"></pre>
<pre id="log"></pre>
<div id='mp_js_stdout'></div>
<canvas id="canvas" width="240" height="320" oncontextmenu="event.preventDefault()" tabindex="-1"></canvas>
<p>
<script type="text/µpython">
if 1:
print("hello World")
</script>
<script defer>
window.vt100 = mp_js_stdout
Module.canvas = canvas
// Ctrl+L is mandatory ! need xterm.js 3.14+
function xterm_helper(term, key) {
function ESC(data) {
return String.fromCharCode(27)+data
}
if ( key.charCodeAt(0)==12 ) {
var cy = 0+term.buffer.cursorY
if ( cy > 0) {
if (cy <= term.rows) {
term.write( ESC("[B") )
term.write( ESC("[J") )
term.write( ESC("[A") )
}
term.write( ESC("[A") )
term.write( ESC("[K") )
term.write( ESC("[1J"))
for (var i=1;i<cy;i++) {
term.write( ESC("[A") )
term.write( ESC("[M") )
}
term.write( ESC("[M") )
}
return false
}
return true
}
Terminal.applyAddon(fit);
var term = new Terminal({
cols : 132,
rows : 33,
tabStopWidth : 8,
cursorBlink : true,
cursorStyle : 'block',
applicationCursor : true,
});
term.open(vt100)
vt100.addEventListener('print', function(e) {
text = e.data;
term.write(text);
}, false);
mp_js_init(512 * 1024);
mp_js_init_repl()
window.stdin = ""
term.on('data', function(key, e) {
if ( xterm_helper(term, key) ) {
const kc = key.charCodeAt(0)
if (kc <=27)
console.log("KBD : "+kc+ " len= "+key.length)
if (0) {
// canonical term - bug
term.write(key)
if (kc==13) {
mp_js_do_str(window.stdin + "\r\n")
window.stdin =""
} else window.stdin += key
} else {
// raw
for (var i = 0; i < key.length; i++) {
mp_js_process_char(key.charCodeAt(i));
}
}
}
});
</script>
</body>
</html>