Resuming nand2tetris with a touch of emacs
So I have been following the nand2tetris course in Coursera, but I find it could have a better integration with emacs. So here I am declaring that I'll do a major mode for nand2tetris. You can follow my progress here. And I'll keep updating you on improvements.
So First things I did was to copy python-mode
because I kinda feel more
comfortable with it, even though I don't understand much of it.
We first assume people are gonna get the nand2tetris source dir, so we can do
(defvar nand2tetris-source-dir nil "Source directory where nadn2tetris has been downloaded")
Now we define the major mode:
(define-derived-mode nand2tetris-mode prog-mode "nand2tetris" "Major mode for editing HDL files for the course Nand2Tetris. \\{nand2tetris-mode-map}")
This will use nand2tetris-mode-syntax-table by default, so let's also define that:
(defconst nand2tetris-mode-syntax-table (let ((table (make-syntax-table))) (c-populate-syntax-table table) table))
We inherit the C syntax table because it will do the //
and /* ... */
comments for free. and now our mode has syntax highlighting for comments and
stuff. Now we only need font-locking.
So far I've seen these keywords CHIP, IN, OUT, PARTS
, so let's see how it looks:
(defvar nand2tetris-font-lock-keywords ;;Keywords `(,(rx symbol-start (or "CHIP" "IN" "OUT" "PARTS") symbol-end) ;; CHIP <ChipName> (,(rx symbol-start "CHIP" (1+ space) (group (1+ (or word ?_)))) (1 font-lock-type-face)) ;; <ChipName> (in=in, out=out); (,(rx symbol-start (group (1+ (or word ?_))) (? space) (seq "(" (0+ not-newline) ")")) (1 font-lock-variable-name-face))))
Lets add it to the major-mode:
(define-derived-mode nand2tetris-mode prog-mode "nand2tetris" "Major mode for editing HDL files for the course Nand2Tetris. \\{nand2tetris-mode-map}" (set (make-local-variable 'font-lock-defaults) '(nand2tetris-font-lock-keywords nil nil nil nil)))
Now, the hard part will be to bind the hdl files. As I know hdl
is a very
common extension (maybe? correct me if I'm wrong plz) I will just limit this
major mode to bind to all .hdl
files inside the nand2tetris-source-dir
.
(add-to-list 'auto-mode-alist `(,(concat (expand-file-name nand2tetris-source-dir) "\.*\\.hdl") . nand2tetris-mode))
And that's been it for today. it all looks like this:
;;; nand2tetris.el --- Major Mode for HDL files in the Nand2Tetris Course ;;; https://www.coursera.org/course/nand2tetris1 ;; Copyright (C) 2015 Diego Berrocal ;; Author: Diego Berrocal <cestdiego@gmail.com> ;; Created: 10 August 2015 ;; Keywords: nand2tetris, hdl ;; Homepage: http://www.github.com/CestDiego/nand2tetris.el/ ;; Version: 0.0.1 ;; This file is not part of GNU Emacs. ;;; License: GPLv3 ;;; Commentary: ;; Useful functions to make following the coursera course easier. ;;; Code: (defvar nand2tetris-source-dir nil "Source directory where nadn2tetris has been downloaded") (defconst nand2tetris-mode-syntax-table (let ((table (make-syntax-table))) (c-populate-syntax-table table) table)) (defvar nand2tetris-font-lock-keywords ;;Keywords `(,(rx symbol-start (or "CHIP" "IN" "OUT" "PARTS") symbol-end) ;; CHIP <ChipName> (,(rx symbol-start "CHIP" (1+ space) (group (1+ (or word ?_)))) (1 font-lock-type-face)) ;; <ChipName> (in=in, out=out); (,(rx symbol-start (group (1+ (or word ?_))) (? space) (seq "(" (0+ not-newline) ")")) (1 font-lock-variable-name-face)))) (define-derived-mode nand2tetris-mode prog-mode "nand2tetris" "Major mode for editing HDL files for the course Nand2Tetris. \\{nand2tetris-mode-map}" (set (make-local-variable 'font-lock-defaults) '(nand2tetris-font-lock-keywords nil nil nil nil))) (add-to-list 'auto-mode-alist `(,(concat (expand-file-name nand2tetris-source-dir) "\.*\\.hdl") . nand2tetris-mode)) (provide 'nand2tetris)
Next things is to actually use the scripts that nand2tetris gives us.