From: Chris Hanson Date: Fri, 7 Mar 1997 23:34:54 +0000 (+0000) Subject: Implement VHDL mode. Generalize the keyword parser used by Verilog X-Git-Tag: 20090517-FFI~5241 X-Git-Url: https://birchwood-abbey.net/git?a=commitdiff_plain;h=86261cd8689eae59f9c05babf36d1bf48d8fd722;p=mit-scheme.git Implement VHDL mode. Generalize the keyword parser used by Verilog mode so that it is powerful enough to parse both languages. Implement a high-level extensible pattern matcher to allow the VHDL indenter to recognize keyword contexts in cases where it is necessary. --- diff --git a/v7/src/edwin/decls.scm b/v7/src/edwin/decls.scm index e0509a67b..80fdd4324 100644 --- a/v7/src/edwin/decls.scm +++ b/v7/src/edwin/decls.scm @@ -1,8 +1,8 @@ #| -*-Scheme-*- -$Id: decls.scm,v 1.58 1996/12/07 22:24:13 cph Exp $ +$Id: decls.scm,v 1.59 1997/03/07 23:34:40 cph Exp $ -Copyright (c) 1989-96 Massachusetts Institute of Technology +Copyright (c) 1989-97 Massachusetts Institute of Technology This material was developed by the Scheme project at the Massachusetts Institute of Technology, Department of Electrical Engineering and @@ -85,6 +85,7 @@ MIT in each case. |# "class" "clscon" "clsmac" + "comatch" "display" "key-w32" "key-x11" @@ -164,6 +165,7 @@ MIT in each case. |# "intmod" "iserch" "keymap" + "keyparse" "kilcom" "kmacro" "lincom" @@ -219,6 +221,7 @@ MIT in each case. |# "unix" "vc" "verilog" + "vhdl" "wincom" "winout" "xcom" diff --git a/v7/src/edwin/ed-ffi.scm b/v7/src/edwin/ed-ffi.scm index 8c46570b7..59dc69b1b 100644 --- a/v7/src/edwin/ed-ffi.scm +++ b/v7/src/edwin/ed-ffi.scm @@ -1,8 +1,8 @@ #| -*-Scheme-*- -$Id: ed-ffi.scm,v 1.41 1996/12/07 22:24:20 cph Exp $ +$Id: ed-ffi.scm,v 1.42 1997/03/07 23:34:42 cph Exp $ -Copyright (c) 1990-96 Massachusetts Institute of Technology +Copyright (c) 1990-97 Massachusetts Institute of Technology This material was developed by the Scheme project at the Massachusetts Institute of Technology, Department of Electrical Engineering and @@ -95,6 +95,8 @@ of that license should have been included along with this file. edwin-syntax-table) ("comint" (edwin) edwin-syntax-table) + ("comatch" (edwin) + syntax-table/system-internal) ("comman" (edwin) edwin-syntax-table) ("compile" (edwin) @@ -171,6 +173,8 @@ of that license should have been included along with this file. edwin-syntax-table) ("keymap" (edwin command-summary) edwin-syntax-table) + ("keyparse" (edwin keyparser) + edwin-syntax-table) ("kilcom" (edwin) edwin-syntax-table) ("kmacro" (edwin) @@ -319,6 +323,8 @@ of that license should have been included along with this file. edwin-syntax-table) ("verilog" (edwin verilog) edwin-syntax-table) + ("vhdl" (edwin vhdl) + edwin-syntax-table) ("win32" (edwin screen win32) edwin-syntax-table) ("win32com" (edwin win-commands) diff --git a/v7/src/edwin/edwin.ldr b/v7/src/edwin/edwin.ldr index bb78d9f28..419c9ae86 100644 --- a/v7/src/edwin/edwin.ldr +++ b/v7/src/edwin/edwin.ldr @@ -1,8 +1,8 @@ #| -*-Scheme-*- -$Id: edwin.ldr,v 1.58 1996/12/07 22:24:04 cph Exp $ +$Id: edwin.ldr,v 1.59 1997/03/07 23:34:45 cph Exp $ -Copyright (c) 1989-96 Massachusetts Institute of Technology +Copyright (c) 1989-97 Massachusetts Institute of Technology This material was developed by the Scheme project at the Massachusetts Institute of Technology, Department of Electrical Engineering and @@ -150,6 +150,8 @@ MIT in each case. |# (load "syntax" environment) (load "regexp" (->environment '(EDWIN REGULAR-EXPRESSION))) (load "rgxcmp" (->environment '(EDWIN REGULAR-EXPRESSION-COMPILER))) + (load "comatch" environment) + (load "keyparse" (->environment '(EDWIN KEYPARSER))) (load "linden" (->environment '(EDWIN LISP-INDENTATION))) (case (lookup 'OS-TYPE) diff --git a/v7/src/edwin/edwin.pkg b/v7/src/edwin/edwin.pkg index 6b691ad53..38ebb0f75 100644 --- a/v7/src/edwin/edwin.pkg +++ b/v7/src/edwin/edwin.pkg @@ -1,6 +1,6 @@ #| -*-Scheme-*- -$Id: edwin.pkg,v 1.207 1997/03/04 06:49:05 cph Exp $ +$Id: edwin.pkg,v 1.208 1997/03/07 23:34:48 cph Exp $ Copyright (c) 1989-97 Massachusetts Institute of Technology @@ -45,17 +45,18 @@ MIT in each case. |# "class" "paths" - "struct" - "regops" - "motion" - "search" - "image" - "comman" - "docstr" - "modes" - "buffer" - "bufset" - "winren" ; window system rename targets + "struct" ; low-level data structures + "regops" ; low-level editing operations + "motion" ; low-level mark movement + "search" ; search/match chars and strings + "comatch" ; combinatoric matcher + "image" ; character-display imaging + "comman" ; editor command/variable abstractions + "docstr" ; out-of-core documentation support + "modes" ; editor mode abstraction + "buffer" ; buffer abstraction + "bufset" ; buffer-set abstraction + "winren" ; window-system rename targets "edtstr" ; editor abstraction "editor" ; editor top level @@ -76,13 +77,14 @@ MIT in each case. |# "dabbrev" ; M-x dabbrev-expand "evlcom" ; evaluation commands "filcom" ; file commands - "fill" ; text fill commands + "fill" ; text-fill commands "hlpcom" ; help commands "kilcom" ; kill commands "kmacro" ; keyboard macros "lincom" ; line commands "lspcom" ; lisp commands "motcom" ; motion commands + "mousecom" ; mouse commands "replaz" ; replace commands "schmod" ; scheme mode "scrcom" ; frame commands @@ -92,27 +94,14 @@ MIT in each case. |# "modefs" ; fundamental mode - "loadef" - "c-mode" - "midas" - "pasmod" - "tximod" - "notify" ; mode line notifications + "loadef" ; auto-load definitions + "c-mode" ; C mode + "midas" ; MIDAS mode + "pasmod" ; Pascal mode + "tximod" ; Texinfo mode + "notify" ; mode-line notifications "outline" ; outline minor mode - "sort" - - "mousecom" ; mouse commands - - ;; These are only available under Unix/X - - "comint" ; command interpreter process stuff - "compile" ; compilation subprocess - "shell" ; shell subprocess commands - "techinfo" ; techinfo commands - "telnet" ; telnet subprocess commands - "xmodef" ; x bindings for fundamental mode - "manual" ; man page display - "print" ; printer output + "sort" ; sorting commands ) (parent ()) @@ -992,7 +981,16 @@ MIT in each case. |# (os-type-case ((unix) (extend-package (edwin) - (files "unix")) + (files "unix" + "comint" ; command interpreter process stuff + "compile" ; compilation subprocess + "shell" ; shell subprocess commands + "techinfo" ; techinfo commands + "telnet" ; telnet subprocess commands + "xmodef" ; x bindings for fundamental mode + "manual" ; man page display + "print" ; printer output + )) (extend-package (edwin dired) (files "dirunx") @@ -1246,7 +1244,13 @@ MIT in each case. |# ((os/2) (extend-package (edwin) - (files "os2" "dosfile") + (files "os2" + "dosfile" + "comint" ; command interpreter process stuff + "compile" ; compilation subprocess + "shell" ; shell subprocess commands + "telnet" ; telnet subprocess commands + ) (import (runtime os2-window-primitives) os2-clipboard-read-text os2-clipboard-write-text)) @@ -1816,13 +1820,33 @@ MIT in each case. |# set-nntp-connection:reader-hook! token->number)) +(define-package (edwin keyparser) + (files "keyparse") + (parent (edwin)) + (export (edwin) + edwin-command$complete-keyword + edwin-command$keyparser-indent-line + edwin-command$keyparser-indent-region + edwin-variable$keyparser-description + edwin-variable$keyword-table + keyparse-forward + keyparse-initial + keyparse-partial + keyparser-compute-indentation + keyparser-compute-indentation-1 + make-keyparser-description + make-keyparser-fragment)) + (define-package (edwin verilog) (files "verilog") (parent (edwin)) (export (edwin) - edwin-command$verilog-indent-line - edwin-command$verilog-indent-region edwin-command$verilog-mode - edwin-mode$verilog - edwin-variable$verilog-continued-statement-offset - edwin-variable$verilog-mode-hook)) \ No newline at end of file + edwin-mode$verilog)) + +(define-package (edwin vhdl) + (files "vhdl") + (parent (edwin)) + (export (edwin) + edwin-command$vhdl-mode + edwin-mode$vhdl)) \ No newline at end of file diff --git a/v7/src/edwin/loadef.scm b/v7/src/edwin/loadef.scm index a1bbb6813..bf108a41c 100644 --- a/v7/src/edwin/loadef.scm +++ b/v7/src/edwin/loadef.scm @@ -1,8 +1,8 @@ ;;; -*-Scheme-*- ;;; -;;; $Id: loadef.scm,v 1.29 1996/04/23 22:39:30 cph Exp $ +;;; $Id: loadef.scm,v 1.30 1997/03/07 23:34:51 cph Exp $ ;;; -;;; Copyright (c) 1986, 1989-96 Massachusetts Institute of Technology +;;; Copyright (c) 1986, 1989-97 Massachusetts Institute of Technology ;;; ;;; This material was developed by the Scheme project at the ;;; Massachusetts Institute of Technology, Department of @@ -236,7 +236,7 @@ Normally uses the server specified by the variable news-server, but with a prefix arg prompts for the server name. Only one News reader may be open per server; if a previous News reader is open the that server, its buffer is selected.") - + (define-library 'VERILOG-MODE '("verilog" (EDWIN VERILOG))) @@ -254,6 +254,34 @@ is open the that server, its buffer is selected.") "Extra indent for lines not starting new statements." 2 exact-nonnegative-integer?) + +(define-variable verilog-continued-header-offset + "Extra indent for continuation lines of structure headers." + 4 + exact-nonnegative-integer?) + +(define-library 'VHDL-MODE + '("vhdl" (EDWIN VHDL))) + +(define-autoload-major-mode 'vhdl 'fundamental "VHDL" 'VHDL-MODE + "Major mode specialized for editing VHDL code.") + +(define-autoload-command 'vhdl-mode 'VHDL-MODE + "Enter VHDL mode.") + +(define-variable vhdl-mode-hook + "An event distributor that is invoked when entering VHDL mode." + (make-event-distributor)) + +(define-variable vhdl-continued-header-offset + "Extra indent for continuation lines of structure headers." + 4 + exact-nonnegative-integer?) + +(define-variable vhdl-continued-statement-offset + "Extra indent for lines not starting new statements." + 2 + exact-nonnegative-integer?) ;;;; DOS-specific commands diff --git a/v7/src/edwin/verilog.scm b/v7/src/edwin/verilog.scm index 3c5f40434..818b3f6d9 100644 --- a/v7/src/edwin/verilog.scm +++ b/v7/src/edwin/verilog.scm @@ -1,6 +1,6 @@ ;;; -*-Scheme-*- ;;; -;;; $Id: verilog.scm,v 1.2 1997/03/04 06:43:51 cph Exp $ +;;; $Id: verilog.scm,v 1.3 1997/03/07 23:34:54 cph Exp $ ;;; ;;; Copyright (c) 1996-97 Massachusetts Institute of Technology ;;; @@ -67,9 +67,14 @@ (local-set-variable! paragraph-start paragraph-start buffer) (local-set-variable! paragraph-separate paragraph-start buffer)) (local-set-variable! indent-line-procedure - (ref-command verilog-indent-line) + (ref-command keyparser-indent-line) buffer) + (local-set-variable! definition-start verilog-defun-start-regexp buffer) (local-set-variable! require-final-newline #t buffer) + (local-set-variable! keyparser-description + verilog-keyparser-description + buffer) + (local-set-variable! keyword-table verilog-keyword-table buffer) (event-distributor/invoke! (ref-variable verilog-mode-hook buffer) buffer))) @@ -86,15 +91,25 @@ (modify-syntax-entry! syntax-table #\newline ">") syntax-table)) +(define-key 'verilog #\linefeed 'reindent-then-newline-and-indent) +(define-key 'verilog #\rubout 'backward-delete-char-untabify) +(define-key 'verilog #\tab 'keyparser-indent-line) +(define-key 'verilog #\c-m-\\ 'keyparser-indent-region) +(define-key 'verilog #\) 'lisp-insert-paren) +(define-key 'verilog #\] 'lisp-insert-paren) +(define-key 'verilog #\} 'lisp-insert-paren) +(define-key 'verilog #\m-tab 'complete-keyword) + +;;;; Syntax Description + (define (verilog-comment-locate mark) (let ((state (parse-partial-sexp mark (line-end mark 0)))) (and (parse-state-in-comment? state) - (and (verilog-comment-match-start state) - (cons (re-match-start 0) (re-match-end 0)))))) + (verilog-comment-match-start (parse-state-comment-start state)) + (cons (re-match-start 0) (re-match-end 0))))) -(define (verilog-comment-match-start state) - (re-match-forward "/\\(/+\\|\\*+\\)[ \t]*" - (parse-state-comment-start state))) +(define (verilog-comment-match-start mark) + (re-match-forward "/\\(/+\\|\\*+\\)[ \t]*" mark)) (define (verilog-comment-indentation mark) (let ((column @@ -103,7 +118,7 @@ (match-forward "////" mark)) 0) ((match-forward "///" mark) - (verilog-compute-indentation mark)) + (keyparser-compute-indentation mark)) (else (ref-variable comment-column mark))))) (if (within-indentation? mark) @@ -111,306 +126,11 @@ (max (+ (mark-column (horizontal-space-start mark)) 1) column)))) -(define-key 'verilog #\linefeed 'reindent-then-newline-and-indent) -(define-key 'verilog #\rubout 'backward-delete-char-untabify) -(define-key 'verilog #\tab 'verilog-indent-line) -(define-key 'verilog #\) 'lisp-insert-paren) -(define-key 'verilog #\] 'lisp-insert-paren) -(define-key 'verilog #\} 'lisp-insert-paren) -(define-key 'verilog #\m-tab 'verilog-complete-keyword) - -;;;; Indentation - -(define-command verilog-indent-line - "Indent current line as Verilog code." - "d" - (lambda (#!optional mark) - (let* ((mark (if (default-object? mark) (current-point) mark)) - (point? (mark= (line-start mark 0) (line-start (current-point) 0)))) - (verilog-indent-line mark (verilog-compute-indentation mark)) - (if point? - (let ((point (current-point))) - (if (within-indentation? point) - (set-current-point! (indentation-end point)))))))) - -(define-command verilog-indent-region - "Indent current region as Verilog code." - "r" - (lambda (region) - (let ((start - (mark-left-inserting-copy (line-start (region-start region) 0))) - (end (mark-left-inserting-copy (line-start (region-end region) 0)))) - (let ((dstart (or (find-verilog-defun-start start) (group-start start)))) - (let loop ((state (verilog-parse-initial dstart start))) - ;; The temporary marks in STATE are to the left of START, and - ;; thus are unaffected by insertion at START. - (if (not (line-blank? start)) - (verilog-indent-line start - (verilog-compute-indentation-1 dstart - start - state))) - (let ((start* (line-start start 1 'LIMIT))) - (if (mark<= start* end) - (let ((state (verilog-parse-partial start start* state))) - (move-mark-to! start start*) - (loop state)))))) - (mark-temporary! start) - (mark-temporary! end)))) - -(define (verilog-indent-line mark indentation) - (let ((indent-point (indentation-end mark))) - (if (not (= indentation (mark-column indent-point))) - (change-indentation indentation indent-point)))) - -(define (verilog-parse-initial dstart mark) - (let ((mark (line-start mark 0)) - (state (initial-verilog-parse-state))) - (if (mark= dstart mark) - state - (verilog-parse-partial dstart mark state)))) - -(define (find-verilog-defun-start mark) - (let ((start (line-start mark 0)) - (regexp verilog-defun-start-regexp)) - (if (re-match-forward regexp start (group-end mark) #f) - start - (re-search-backward regexp start (group-start mark) #f)))) - -(define (verilog-compute-indentation mark) - (let ((dstart (or (find-verilog-defun-start mark) (group-start mark))) - (end (line-start mark 0))) - (verilog-compute-indentation-1 dstart - end - (verilog-parse-initial dstart end)))) - -(define (verilog-compute-indentation-1 dstart lstart state) - (let ((indent-point (indentation-end lstart)) - (sexp-state (verilog-parse-state/sexp-state state)) - (statement-state (verilog-parse-state/statement-state state))) - (cond ((and sexp-state (in-char-syntax-structure? sexp-state)) - (cond ((parse-state-in-comment? sexp-state) - (mark-column (if (verilog-comment-match-start sexp-state) - (re-match-end 0) - (parse-state-comment-start sexp-state)))) - ((> (parse-state-depth sexp-state) 0) - (+ (mark-column - (or (parse-state-containing-sexp sexp-state) - (parse-state-containing-sexp - (parse-partial-sexp dstart lstart)))) - 1)) - (else 0))) - ((verilog-parse-state/restart-point state) - => continued-statement-indent) - ((match-statement-ending indent-point statement-state) - (mark-indentation (caar statement-state))) - ((pair? statement-state) - (continued-statement-indent (caar statement-state))) - (else 0)))) - -(define (continued-statement-indent mark) - (+ (mark-indentation mark) - (ref-variable verilog-continued-statement-offset mark))) - -(define-structure (verilog-parse-state (conc-name verilog-parse-state/)) - (sexp-state #f read-only #t) - (statement-state #f read-only #t) - (restart-point #f read-only #t)) - -(define (initial-verilog-parse-state) - (make-verilog-parse-state #f '() #f)) - -(define (verilog-parse-partial start end state) - (let ((ss - (parse-partial-sexp start end #f #f - (verilog-parse-state/sexp-state state)))) - (if (in-char-syntax-structure? ss) - (make-verilog-parse-state - ss - (verilog-parse-state/statement-state state) - (or (verilog-parse-state/restart-point state) start)) - (call-with-values - (lambda () - (parse-forward (or (verilog-parse-state/restart-point state) - start) - end - (verilog-parse-state/statement-state state))) - (lambda (statement-state restart-point) - (make-verilog-parse-state ss statement-state restart-point)))))) - -(define (parse-forward start end nesting) - (let ((start (parse-forward-to-statement start end))) - (cond ((not start) - (values nesting #f)) - ((match-statement-ending start nesting) - (parse-keyword-statement-end start end nesting)) - ((match-statement-keyword start) - => (lambda (record) - (parse-keyword-statement start end record nesting))) - (else - (let ((semi (parse-forward-past-semicolon start end))) - (if semi - (finish-parsing-statement semi end nesting) - (values nesting start))))))) - -(define (parse-keyword-statement start end record nesting) - (let ((keyword (keyword-record/name record))) - (let ((mark (skip-keyword start keyword))) - (if (mark<= mark end) - (let ((mark (skip-keyword-noise mark end keyword)) - (nesting (cons (cons start record) nesting))) - (if mark - (parse-forward mark end nesting) - (values nesting #f))) - ;; This can't happen if END is at a line start. - (values nesting start))))) - -(define (parse-keyword-statement-end start end nesting) - (let ((mark (skip-keyword start (keyword-record/ending (cdar nesting))))) - (if (mark<= mark end) - (finish-parsing-statement mark end (cdr nesting)) - ;; This can't happen if END is at a line start. - (values nesting start)))) - -(define (finish-parsing-statement start end nesting) - (parse-forward start - end - (let loop ((nesting nesting)) - (if (and (pair? nesting) - (not (keyword-record/ending (cdar nesting)))) - (loop (cdr nesting)) - nesting)))) - -(define (parse-forward-to-statement start end) - (let ((mark (forward-to-sexp-start start end))) - (cond ((mark= mark end) #f) - ((and (mark< start mark) - (memv (mark-left-char mark) '(#\# #\@))) - (let ((m (forward-one-sexp mark end))) - (and m - (parse-forward-to-statement m end)))) - (else mark)))) - -(define (match-statement-keyword start) - (let loop ((records verilog-statement-keywords)) - (and (not (null? records)) - (if (re-match-forward (keyword-record/pattern (car records)) start) - (car records) - (loop (cdr records)))))) - -(define (match-statement-ending mark nesting) - (let ((record (and (pair? nesting) (cdar nesting)))) - (and record - (keyword-record/ending-pattern record) - (re-match-forward (keyword-record/ending-pattern record) mark)))) - -(define (parse-forward-past-semicolon start end) - (let loop ((start start) (state #f)) - (let ((semi (char-search-forward #\; start end #f))) - (and semi - (let ((state (parse-partial-sexp start semi #f #f state))) - (if (in-char-syntax-structure? state) - (loop semi state) - semi)))))) - -(define (skip-keyword start keyword) - (mark+ start (string-length keyword))) - -(define (skip-keyword-noise start end keyword) - (cond ((member keyword verilog-keywords:semicolon-delimited-header) - (parse-forward-past-semicolon start end)) - ((or (member keyword verilog-keywords:paren-delimited-header) - (and (member keyword verilog-keywords:optional-block-tag) - (re-match-forward "[ \t]*:[ \t]*" start end #f))) - (forward-one-sexp start end)) - (else start))) - -(define (in-char-syntax-structure? state) - (or (parse-state-in-comment? state) - (parse-state-in-string? state) - (parse-state-quoted? state) - (not (= (parse-state-depth state) 0)))) - (define verilog-defun-start-regexp - "^\\(module\\|macromodule\\|primitive\\|parameter\\)\\(\\s \\|$\\)") - -(define verilog-keywords:semicolon-delimited-header - '("function" "macromodule" "module" "primitive" "task")) - -(define verilog-keywords:paren-delimited-header - '("case" "casex" "casez" "for" "if" "repeat" "while")) - -(define verilog-keywords:optional-block-tag - '("begin" "fork")) - -(define-structure (keyword-record (constructor make-keyword-record - (name ending)) - (conc-name keyword-record/) - (print-procedure - (standard-unparser-method 'KEYWORD-RECORD - (lambda (record port) - (write-char #\space port) - (write-string - (keyword-record/name record) - port))))) - (name #f read-only #t) - (pattern (keyword->pattern name) read-only #t) - (ending #f read-only #t) - (ending-pattern (and ending (keyword->pattern ending)) read-only #t)) - -(define (keyword->pattern keyword) - (re-compile-pattern - (string-append keyword - (if (member keyword verilog-keywords:optional-block-tag) - "\\(\\s \\|$\\|:\\)" - "\\(\\s \\|$\\)")) - #f)) - -(define verilog-statement-keywords - (map (lambda (entry) (make-keyword-record (car entry) (cadr entry))) - '(("always" #f) - ("begin" "end") - ("case" "endcase") - ("casex" "endcase") - ("casez" "endcase") - ("else" #f) - ("for" #f) - ("forever" #f) - ("fork" "join") - ("function" "endfunction") - ("if" #f) - ("initial" #f) - ("macromodule" "endmodule") - ("module" "endmodule") - ("primitive" "endprimitive") - ("repeat" #f) - ("table" "endtable") - ("task" "endtask") - ("while" #f)))) - -;;;; Keyword Completion - -(define-command verilog-complete-keyword - "Perform completion on Verilog keyword preceding point." - () - (lambda () - (let ((end - (let ((point (current-point))) - (let ((end (group-end point))) - (or (re-match-forward "\\sw+" point end #f) - (and (mark< (group-start point) point) - (re-match-forward "\\sw+" (mark-1+ point) end #f)) - (editor-error "No keyword preceding point")))))) - (let ((start (backward-word end 1 'LIMIT))) - (standard-completion (extract-string start end) - (lambda (prefix if-unique if-not-unique if-not-found) - (string-table-complete verilog-keyword-table - prefix - if-unique - if-not-unique - if-not-found)) - (lambda (completion) - (delete-string start end) - (insert-string completion start))))))) + (string-append + "^" + (regexp-group "module" "macromodule" "primitive" "parameter") + (regexp-group "\\s " "$"))) (define verilog-keyword-table (alist->string-table @@ -431,4 +151,91 @@ "tranif1" "tri" "tri0" "tri1" "triand" "trior" "trireg" "udp" "vectored" "wait" "wand" "while" "wire" "wor" "xnor" "xor")) - #f)) \ No newline at end of file + #f)) + +(define (parse-forward-past-semicolon start end) + (let loop ((start start) (state #f)) + (let ((semi (char-search-forward #\; start end #f))) + (and semi + (let ((state (parse-partial-sexp start semi #f #f state))) + (if (in-char-syntax-structure? state) + (loop semi state) + semi)))))) + +(define (parse-forward-past-block-tag start end) + (if (re-match-forward "[ \t]*:[ \t]*" start end) + (forward-one-sexp start end) + start)) + +(define (parse-forward-noop start end) + end + start) + +(define (continued-header-indent mark) + (+ (mark-indentation mark) + (ref-variable verilog-continued-header-offset mark))) + +(define (continued-statement-indent mark) + (+ (mark-indentation mark) + (ref-variable verilog-continued-statement-offset mark))) + +(define verilog-keyparser-description + (make-keyparser-description + 'PATTERNS + (map (lambda (entry) + (list + (make-keyparser-fragment 'KEYWORD + (car entry) + 'PARSE-HEADER + (caddr entry) + 'INDENT-HEADER + continued-header-indent + 'PARSE-BODY + keyparse-forward + 'INDENT-BODY + continued-statement-indent) + (and (cadr entry) + (make-keyparser-fragment 'KEYWORD + (cadr entry) + 'PARSE-HEADER + parse-forward-noop + 'INDENT-HEADER + continued-header-indent + 'PARSE-BODY + #f + 'INDENT-BODY + #f)))) + `(("always" #f ,parse-forward-noop) + ("begin" "end" ,parse-forward-past-block-tag) + ("case" "endcase" ,forward-one-sexp) + ("casex" "endcase" ,forward-one-sexp) + ("casez" "endcase" ,forward-one-sexp) + ("else" #f ,parse-forward-noop) + ("for" #f ,forward-one-sexp) + ("forever" #f ,parse-forward-noop) + ("fork" "join" ,parse-forward-past-block-tag) + ("function" "endfunction" ,parse-forward-past-semicolon) + ("if" #f ,forward-one-sexp) + ("initial" #f ,parse-forward-noop) + ("macromodule" "endmodule" ,parse-forward-past-semicolon) + ("module" "endmodule" ,parse-forward-past-semicolon) + ("primitive" "endprimitive" ,parse-forward-past-semicolon) + ("repeat" #f ,forward-one-sexp) + ("table" "endtable" ,parse-forward-noop) + ("task" "endtask" ,parse-forward-past-semicolon) + ("while" #f ,forward-one-sexp))) + + 'STATEMENT-LEADERS + `((,(re-compile-char #\# #f) . ,forward-one-sexp) + (,(re-compile-char #\@ #f) . ,forward-one-sexp)) + + 'FIND-STATEMENT-END + parse-forward-past-semicolon + + 'INDENT-CONTINUED-STATEMENT + continued-statement-indent + + 'INDENT-CONTINUED-COMMENT + (lambda (mark) + (mark-column (or (verilog-comment-match-start mark) mark))) + )) \ No newline at end of file