ESP32forth v7 & WebSent π February 27, 2021 What's up with the slides? PRESENTATION FORMAT π€ β’ Takahashi Method β’ Minimalistic presentation style β’ suckless β sent β websent β’ 200 LOC HOW TO USE π€ β’ Small 2-6 line header on html β’ Limited customization (color, font) β’ Unicode text as input β’ Show each paragraph fullscreen β’ @image.png for full page images BUT WHY? π€ β’ Focus on content β’ Cut and paste source code β’ Things fit easily β’ ASCII Art & Emojis = easy trees π²π²π²π² evil πππ β€ spades β₯ hearts β§ clubs β¦ diamonds trees π²π²π²π² evil πππ β€ spades β₯ hearts β§ clubs β¦ diamonds @eforth.png @eforth.png <img src="eforth.png"> @eforth.pngCode π’ Tour ESP32forth v7 Thanks Dr. Ting! New Website: π esp32forth.appspot.com Topics π β’ Vocabularies β’ Block Editor β’ Adding Words β’ Dictionary Pickling β’ Telnet π£οΈ Vocabularies Hybrid Vocabularies π β’ Forth-79 Style Chaining β’ Forth-83+ Style Vocabulary Stack VOCABULARY ( "name" ) Create a vocabulary FORTH ( -- ) The FORTH vocabulary DEFINITIONS ( -- ) Make the context, current VLIST ( -- ) List the vocabulary WORDS ( -- ) List the reachable words TRANSFER ( "name" ) Move a word ALSO ( -- ) Add vocabulary ONLY ( -- ) Reset back to Forth only ( Non-standard ) ORDER ( -- ) Print search order SEALED ( -- ) Make it Forth-83+ 𧱠Block Editor SCR ( -- a ) Pointer to last listed block USE ( "name" -- ) e.g. USE /spiffs/foo FLUSH ( -- ) Save and empty all buffers LIST ( n -- ) List a block LOAD ( n -- ) Evaluate a block EDITOR ( -- ) Enter editor vocabulary WIPE ( -- ) Blank out current block L ( -- ) List the current block D ( n -- ) Delete a line E ( n -- ) Erase a line R ( n "text" -- ) Replace a line A ( n "text" -- ) Add (insert) a line P ( -- ) Move to the previous block N ( -- ) Move to the next block Live π₯ Demo... Adding π¬Words #define OPCODE_LIST \ X("0=", ZEQUAL, tos = !tos ? -1 : 0) \ X("0<", ZLESS, tos = (tos|0) < 0 ? -1 : 0) \ X("+", PLUS, tos += *sp--) \ Y(MY_WORD123, c_function_to_call()) \ X("myword!", MY_WORD_BANG, c_function_to_call()) \ Y(MY_WORD, PUSH calculate_magic_value()) \ n10 n9 n8 n7 n6 n5 n4 n3 n2 n1 n0 - Access stack as cell_t integer values c6 c5 c4 c3 c2 c1 c0 - Access stack as char* values b6 b5 b4 b3 b2 b1 b0 - Access stack as uint8_t* byte values a6 a5 a4 a3 a2 a1 a0 - Access stack as void* values void send_message(const char *message, int code); π X("send-message", SEND_MESSAGE, \ send_message(c1, n0); DROPn(2)) \ Y(DECODE, SET decode_func(n0)) \ Y(MY_WORD, cell_t foo = n0; DROP; \ char *x = c0; DROP; \ PUSH my_func(foo, x)) \ # define ws0 ((WebServer *) a0) # define OPTIONAL_WEBSERVER_SUPPORT \ /* WebServer */ \ X("WebServer.new", WEBSERVER_NEW, PUSH new WebServer(tos)) \ X("WebServer.delete", WEBSERVER_DELETE, delete ws0; DROP) \ X("WebServer.begin", WEBSERVER_BEGIN, ws0->begin(n1); DROPn(2)) \ X("WebServer.stop", WEBSERVER_STOP, ws0->stop(); DROP) \ X("WebServer.on", WEBSERVER_ON, InvokeWebServerOn(ws0, c2, n1); DROPn(3)) \ X("WebServer.hasArg", WEBSERVER_HAS_ARG, n0 = ws0->hasArg(c1); DROP) \ static void InvokeWebServerOn(WebServer *ws, const char *url, cell_t xt) { ws->on(url, [xt]() { cell_t code[2]; code[0] = xt; code[1] = g_sys.YIELD_XT; cell_t stack[16]; cell_t rstack[16]; cell_t *rp = rstack; *++rp = (cell_t) (stack + 1); *++rp = (cell_t) code; forth_run(rp); }); Dictionary Picking π₯ SAVE {filename} RESTORE {filename} SAVE-NAME ( a n -- ) RESTORE-NAME ( a n -- ) 'COLD ( -- a ) address of boot word REMEMBER STARTUP: {word} Telnet π» sockets listen on port 23 DEMO π QUESTIONS? β Thank you!