1 // Loosely based on:
   2 // https://github.com/bytecodealliance/wasmtime/blob/main/docs/WASI-tutorial.md#web-assembly-text-example
   3 #target WASI // This has to be the first directive in an AEC program targeting
   4              // WASI, because declaring anything in WebAssembly is not possible
   5              // until we know whether we are targeting WASI or a browser.
   6 
   7 Structure IOV Consists Of { // The curly braces here are ignored by the
   8                             // tokenizer, they are just here for ClangFormat
   9                             // and text editors optimized for C-like languages.
  10   CharacterPointer iov_base;
  11   Integer32 iov_len;
  12 }
  13 EndStructure;
  14 
  15 Function
  16 fd_write(Integer32 file_descriptor, IOVPointer iovs, Integer32 iovs_len,
  17          Integer32Pointer nwritten) Which Returns Integer32 Is External;
  18 
  19 Function strlen(CharacterPointer str) Which Returns Integer32 Does {
  20   Integer32 size : = 0;
  21   While ValueAt(str + size) Loop { size += 1; }
  22   EndWhile;
  23   Return size;
  24 }
  25 EndFunction;
  26 
  27 Integer32 stdout : = 1;
  28 
  29 Function printString(CharacterPointer string) Which Returns Nothing Does {
  30   InstantiateStructure IOV iov;
  31   iov.iov_base : = string;
  32   iov.iov_len : = strlen(string);
  33   Integer32 tmp : = fd_write(stdout, AddressOf(iov),
  34                              1 /*Because we are printing only 1 string.*/,
  35                              AddressOf(tmp));
  36 }
  37 EndFunction;
  38 
  39 Function main() Which Returns Nothing Does {
  40   printString(
  41       "Hello world, I am writing this from from WASI!\n"); // You need to put
  42                                                            // '\n' in the
  43                                                            // string, or else
  44                                                            // nothing will be
  45                                                            // printed!
  46 }
  47 EndFunction;
  48 
  49 asm("(export \"_start\" (func $main))"); // https://developer.mozilla.org/en-US/docs/WebAssembly/Understanding_the_text_format#calling_the_function
  50 // We could have also renamed "main" to "_start", but thank God I tried this so
  51 // that I found a bug related to inline assembly in global scope in my compiler.