1#| -*-Scheme-*- 2 3Copyright (C) 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 4 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 5 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014 Massachusetts 6 Institute of Technology 7 8This file is part of MIT/GNU Scheme. 9 10MIT/GNU Scheme is free software; you can redistribute it and/or modify 11it under the terms of the GNU General Public License as published by 12the Free Software Foundation; either version 2 of the License, or (at 13your option) any later version. 14 15MIT/GNU Scheme is distributed in the hope that it will be useful, but 16WITHOUT ANY WARRANTY; without even the implied warranty of 17MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 18General Public License for more details. 19 20You should have received a copy of the GNU General Public License 21along with MIT/GNU Scheme; if not, write to the Free Software 22Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, 23USA. 24 25|# 26 27;;;; Major Mode for Verilog Programs 28 29(declare (usual-integrations)) 30 31(define-command verilog-mode 32 "Enter Verilog mode." 33 () 34 (lambda () (set-current-major-mode! (ref-mode-object verilog)))) 35 36(define-major-mode verilog fundamental "Verilog" 37 "Major mode specialized for editing Verilog code. 38 39\\{verilog}" 40 (lambda (buffer) 41 (local-set-variable! syntax-table verilog-mode:syntax-table buffer) 42 (local-set-variable! syntax-ignore-comments-backwards #f buffer) 43 (local-set-variable! comment-column 40 buffer) 44 (local-set-variable! comment-locator-hook verilog-comment-locate buffer) 45 (local-set-variable! comment-indent-hook verilog-comment-indentation 46 buffer) 47 (local-set-variable! comment-start "// " buffer) 48 (local-set-variable! comment-end "" buffer) 49 (standard-alternate-paragraph-style! buffer) 50 (local-set-variable! indent-line-procedure 51 (ref-command keyparser-indent-line) 52 buffer) 53 (local-set-variable! definition-start verilog-defun-start-regexp buffer) 54 (local-set-variable! require-final-newline #t buffer) 55 (local-set-variable! keyparser-description verilog-description buffer) 56 (local-set-variable! keyword-table verilog-keyword-table buffer) 57 (local-set-variable! local-abbrev-table 58 (ref-variable verilog-mode-abbrev-table buffer) 59 buffer) 60 (event-distributor/invoke! (ref-variable verilog-mode-hook buffer) 61 buffer))) 62 63(define verilog-mode:syntax-table 64 (let ((syntax-table (make-char-syntax-table))) 65 (for-each (lambda (char) (set-char-syntax! syntax-table char ".")) 66 (string->list "+-=%<>&|")) 67 (set-char-syntax! syntax-table #\' "_") 68 (set-char-syntax! syntax-table #\` ". p") 69 (set-char-syntax! syntax-table #\# ". p") 70 (set-char-syntax! syntax-table #\@ ". p") 71 (set-char-syntax! syntax-table #\/ ". 1456") 72 (set-char-syntax! syntax-table #\* ". 23") 73 (set-char-syntax! syntax-table #\newline ">") 74 syntax-table)) 75 76(define-key 'verilog #\linefeed 'reindent-then-newline-and-indent) 77(define-key 'verilog #\rubout 'backward-delete-char-untabify) 78(define-key 'verilog #\tab 'keyparser-indent-line) 79(define-key 'verilog #\c-m-\\ 'keyparser-indent-region) 80(define-key 'verilog #\) 'lisp-insert-paren) 81(define-key 'verilog #\] 'lisp-insert-paren) 82(define-key 'verilog #\} 'lisp-insert-paren) 83(define-key 'verilog #\m-tab 'complete-keyword) 84 85;;;; Syntax Description 86 87(define (verilog-comment-locate mark) 88 (let ((state (parse-partial-sexp mark (line-end mark 0)))) 89 (and (parse-state-in-comment? state) 90 (verilog-comment-match-start (parse-state-comment-start state)) 91 (cons (re-match-start 0) (re-match-end 0))))) 92 93(define (verilog-comment-match-start mark) 94 (re-match-forward "/\\(/+\\|\\*+\\)[ \t]*" mark)) 95 96(define (verilog-comment-indentation mark) 97 (let ((column 98 (cond ((or (and (line-start? mark) 99 (match-forward "/*" mark)) 100 (match-forward "////" mark)) 101 0) 102 ((match-forward "///" mark) 103 (keyparser-compute-indentation mark #t)) 104 (else 105 (ref-variable comment-column mark))))) 106 (if (within-indentation? mark) 107 column 108 (max (+ (mark-column (horizontal-space-start mark)) 1) 109 column)))) 110 111(define verilog-defun-start-regexp 112 (string-append 113 "^" 114 (regexp-group "module" "macromodule" "primitive" "parameter") 115 (regexp-group "\\s " "$"))) 116 117(define verilog-keyword-table 118 (alist->string-table 119 (map list 120 '("always" "and" "assign" "begin" "buf" "bufif0" "bufif1" 121 "case" "casex" "casez" "cmos" "deassign" "default" 122 "define" "defparam" "disable" "else" "end" 123 "endcase" "endfunction" "endmodule" "endprimitive" 124 "endtable" "endtask" "event" "for" "force" 125 "forever" "fork" "function" "if" "ifdef" "include" 126 "initial" "inout" "input" "integer" "join" "macromodule" 127 "module" "nand" "negedge" "nmos" "nor" "not" 128 "notif0" "notif1" "or" "output" "parameter" "pmos" 129 "posedge" "primitive" "pulldown" "pullup" "rcmos" 130 "real" "reg" "release" "repeat" "rnmos" "rpmos" 131 "rtran" "rtranif0" "rtranif1" "scalared" "supply0" 132 "supply1" "table" "task" "time" "tran" "tranif0" 133 "tranif1" "tri" "tri0" "tri1" "triand" "trior" 134 "trireg" "udp" "vectored" "wait" "wand" "while" 135 "wire" "wor" "xnor" "xor")) 136 #f)) 137 138(define (parse-forward-past-semicolon start end) 139 (let loop ((start start) (state #f)) 140 (let ((semi (char-search-forward #\; start end #f))) 141 (and semi 142 (let ((state (parse-partial-sexp start semi #f #f state))) 143 (if (in-char-syntax-structure? state) 144 (loop semi state) 145 semi)))))) 146 147(define (parse-forward-past-block-tag start end) 148 (if (re-match-forward "[ \t]*:[ \t]*" start end) 149 (forward-one-sexp start end) 150 start)) 151 152(define (parse-forward-noop start end) 153 end 154 start) 155 156(define (continued-header-indent mark) 157 (+ (mark-indentation mark) 158 (ref-variable verilog-continued-header-offset mark))) 159 160(define (continued-statement-indent mark) 161 (+ (mark-indentation mark) 162 (ref-variable verilog-continued-statement-offset mark))) 163 164(define verilog-description 165 (make-keyparser-description 166 'FIND-STATEMENT-END 167 parse-forward-past-semicolon 168 'INDENT-CONTINUED-STATEMENT 169 continued-statement-indent 170 'INDENT-CONTINUED-COMMENT 171 (lambda (mark) 172 (mark-column (or (verilog-comment-match-start mark) mark))))) 173 174(define-keyparser-statement-leader #\# verilog-description 175 (re-compile-char #\# #f) 176 forward-one-sexp) 177 178(define-keyparser-statement-leader #\@ verilog-description 179 (re-compile-char #\@ #f) 180 forward-one-sexp) 181 182(define (define-standard-keyword keyword end parse-header) 183 (define-keyparser-pattern keyword verilog-description 184 (list 185 (make-keyparser-fragment 'KEYWORD 186 keyword 187 'PARSE-HEADER 188 parse-header 189 'INDENT-HEADER 190 continued-header-indent 191 'PARSE-BODY 192 keyparse-forward 193 'INDENT-BODY 194 continued-statement-indent) 195 (and end 196 (make-keyparser-fragment 'KEYWORD 197 end 198 'PARSE-HEADER 199 parse-forward-noop 200 'INDENT-HEADER 201 continued-header-indent 202 'PARSE-BODY 203 #f 204 'INDENT-BODY 205 #f))))) 206 207(define-standard-keyword "always" #f 208 parse-forward-noop) 209 210(define-standard-keyword "begin" "end" 211 parse-forward-past-block-tag) 212 213(define-standard-keyword "case" "endcase" 214 forward-one-sexp) 215 216(define-standard-keyword "casex" "endcase" 217 forward-one-sexp) 218 219(define-standard-keyword "casez" "endcase" 220 forward-one-sexp) 221 222(define-standard-keyword "else" #f 223 parse-forward-noop) 224 225(define-standard-keyword "for" #f 226 forward-one-sexp) 227 228(define-standard-keyword "forever" #f 229 parse-forward-noop) 230 231(define-standard-keyword "fork" "join" 232 parse-forward-past-block-tag) 233 234(define-standard-keyword "function" "endfunction" 235 parse-forward-past-semicolon) 236 237(define-standard-keyword "if" #f 238 forward-one-sexp) 239 240(define-standard-keyword "initial" #f 241 parse-forward-noop) 242 243(define-standard-keyword "macromodule" "endmodule" 244 parse-forward-past-semicolon) 245 246(define-standard-keyword "module" "endmodule" 247 parse-forward-past-semicolon) 248 249(define-standard-keyword "primitive" "endprimitive" 250 parse-forward-past-semicolon) 251 252(define-standard-keyword "repeat" #f 253 forward-one-sexp) 254 255(define-standard-keyword "table" "endtable" 256 parse-forward-noop) 257 258(define-standard-keyword "task" "endtask" 259 parse-forward-past-semicolon) 260 261(define-standard-keyword "while" #f 262 forward-one-sexp)