wat-mode
wat-mode copied to clipboard
An Emacs major mode for WebAssembly's text format
#+TITLE: wat-mode #+SUBTITLE: An Emacs major mode for WebAssembly's text format #+AUTHOR: Devon Sparks #+STARTUP: showeverything
-
Summary /wat-mode/ is an Emacs major mode for [[https://webassembly.github.io/spec/core/bikeshed/index.html#text-format%E2%91%A0][WebAssembly's text format]] based on /lisp-mode/. It currently supports:
- syntax highlighting for all core WebAssembly keywords including .wast, SIMD, and threading extensions
- s-expression indentation (from /lisp-mode/)
- an experimental macro assembler
/wat-mode/ can be helpful to those writing WebAssembly by hand. It pairs well with the [[https://github.com/WebAssembly/wabt][WebAssembly Binary Toolkit]].
-
Installation Put the contents of this directory somewhere on your load-path, i.e.,: #+begin_src: emacs-lisp (add-to-list 'load-path "
/ / /") ... (require 'wat-mode) #+end_src The intent is to distribute /wat-mode/ via MELPA after a bit more testing.
-
Usage To use /wat-mode/, visit any file with a .wat or .wast file extension.
** Indentation /wat-mode/ inherits the default indentation behavior of /lisp-mode/. If you'd like to change it, you can ~set-variable RET wat-mode-indent-offset RET value RET~. ~wat-mode-indent-offset~ is bound to ~lisp-indent-offset~ under the hood and its behavior is identical. See [[https://www.gnu.org/software/emacs/manual/html_node/emacs/Lisp-Indent.html][Customizing Lisp Indentation]] of the Emacs Manual for details.
** Syntax Highlighting /wat-mode/ supports syntax highlighting for all core WebAssembly keywords. Highlighting support comes in four levels with increasing coverage:
- wat-mode-font-lock-keywords-1: Only top-level keyords (e.g., /module/, /table/, /func/, etc).
- wat-mode-font-lock-keywords-2: level (1) plus support for all data types and instructions excluding memory and numerical instructions.
- wat-mode-font-lock-keywords-3: level (2) plus support for identifiers and both memory and numerical instructions. This includes support for the SIMD and threading extensions.
- wat-mode-font-lock-keywords-4: level (3) plus support for .wast keywords.
The active highlighting level is bound to ~wat-mode-font-lock-keywords~. ~wat-mode-font-lock-keywords-4~ is used by default.
** Experimental Macro Assembler /wat-mode/ introduces a single new keyword to WebAssembly syntax: ~@~ (pronounced "w-at"). ~@~ allows the definition of macros by leveraging the elisp runtime.
Say you're writing an emulator for a particular register machine. You'd like to have shorthand for defining and operating on the virtual machine registers. In /wat-mode/, you might make a register constructor like
#+begin_src: emacs-lisp (@ define-register (name initial-value) (global ,name (mut i32) (i32.const ,initial-value))) #+end_src
and then define register operations:
#+begin_src: emacs-lisp (@ op-reg (reg value op) (set_global ,reg (,op (get_global ,reg) ,value)))
(@ reg.add (reg value) (op-reg ,reg ,value i32.add))
(@ reg.sub (reg value) (op-reg ,reg ,value i32.sub)) #+end_src
You could define these macros interactively using ~eval-last-sexp~ (~C-x C-e~) or define them in a separate file to be loaded with before your .wat files.
Once defined and loaded, macros can be used like folded instructions in standard .wat files.
#+begin_src: emacs-lisp (define-register $W 0)
...
(func $do-add (reg.add $W 2)) #+end_src
You can evaluate a macro interactively by placing /point/ at the start of the macro form and invoking ~wat-mode-macro-expand~ (~C-c 1~).
The expanded definition includes annotating information on the macro that produced it -- a primitive aid to debugging until something better is written. Undoing the operation (~C-x u~) will return the macro to its unevaluated form.
[[./doc/wat-mode-macro.gif]]
Macro expansion is useful during program development. It can also be run in batch:
~emacs -batch -L . -l ~/.emacs -l $(ROOT)/demo/regm.el $(ROOT)/demo/reg.wat -f wat-mode-macro-expand -f save-buffer~
The expanded macro will be saved back to =$(ROOT)/demo/reg.wat= with the original module saved to =$(ROOT)/demo/reg.wat~=.
*** A Word of Caution Expect macro support to evolve or be removed entirely if it turns out to be a Bad Idea.
-
Contributing I made /wat-mode/ for my own use. There's loads or room for improvement. Have ideas to make it better? ~M-x make-pull-request~!
-
License /wat-mode/ is licensed under GPLv3. See LICENSE.