undar-mode/undar-mode.el

102 lines
4.0 KiB
EmacsLisp
Executable File

;;; undar-mode.el --- Major mode for editing Undar code -*- lexical-binding: t; -*-
;; Copyright (C) 2025 zongor
;;
;; This program is free software: you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation, either version 3 of the License, or
;; (at your option) any later version.
;;
;; This program is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;;
;; You should have received a copy of the GNU General Public License
;; along with this program. If not, see <https://www.gnu.org/licenses/>.
;;;
(defvar undar-keywords
'("function" "to" "in" "is" "as" "use" "if" "else" "default"
"for" "try" "catch" "while" "do" "exit" "switch" "continue"
"return" "const" "type" "this" "yield" "case" "loop" "plex"
"assert" "break" "mod" "not" "and" "or" "print" "ref" "interface"
"implements" "impls" "band" "bor" "bxor" "srl" "sll")
"Keywords in Undar.")
(defvar undar-types
'("byte" "str" "real" "bool"
"int" "nat" "f32" "void"
"u8" "u16" "u32"
"i8" "i16" "i32")
"Types in Undar.")
(defvar undar-constants
'("true" "false" "nil")
"Constants in Undar.")
(defvar undar-font-lock-keywords
`(
;; Keywords
(,(regexp-opt undar-keywords 'words) . font-lock-keyword-face)
;; Types
(,(regexp-opt undar-types 'words) . font-lock-type-face)
;; Constants
(,(regexp-opt undar-constants 'words) . font-lock-constant-face)
;; Structs: CamelCase identifiers
("\\b[A-Z][a-zA-Z0-9_]*\\b" . font-lock-type-face)
;; Function definitions: "function name(...)"
("\\_<function\\>\\s-+\\([\\w+\\)(" (1 font-lock-function-name-face))
;; Numbers (Integers and Floats)
("\\b-?[0-9]+\\(?:\\.[0-9]+\\)?\\(?:[eE][+-]?[0-9]+\\)?\\b" . font-lock-constant-face)
;; Strings with double quotes
("\"[^\"\n]*\"" . font-lock-string-face)
;; Strings with backticks
("`[^`\n]*`" . font-lock-string-face))
"Font lock keywords for Undar mode.")
(defvar undar-mode-syntax-table
(let ((st (make-syntax-table)))
;; C-style comments: // and /* */
;; Clear potential existing syntax for / and * if needed (though default is usually fine initially)
;; Clearing standard C++/C comment syntax if it was somehow set beforehand is generally not needed
;; unless explicitly overridden elsewhere, so we rely on the default being clean.
;; The crucial setup for both // and /* */ comments together:
;; / is punctuation and starts both // (1, 2) and /* (4) comments
(modify-syntax-entry ?\/ ". 124" st)
;; * is punctuation and part of /* */ (2, 3) and also part of // (b) comments (this is key for //)
(modify-syntax-entry ?* ". 23b" st)
;; Newline ends comments (>) and is part of // comments (b) - essential for // to end correctly
(modify-syntax-entry ?\n ">" st)
;; Strings
(modify-syntax-entry ?\" "\"" st)
(modify-syntax-entry ?` "\"" st)
st)
"Syntax table for Undar mode, using C-style comments (// and /* */).")
(define-derived-mode undar-mode prog-mode "Undâr"
"Major mode for editing Undar code."
:syntax-table undar-mode-syntax-table
(setq-local font-lock-defaults '(undar-font-lock-keywords))
;; Set comment syntax for commands like M-; (comment-dwim)
(setq-local comment-start "// ")
(setq-local comment-end "")
(setq-local comment-start-skip "\\(//+\\|/\\*+\\)\\s *")
;; Ensure comments are ignored during parsing (e.g., for indentation)
(setq-local parse-sexp-ignore-comments t)
;; Use C-style indentation function
(setq-local indent-line-function 'c-indent-line))
;;;###autoload
(add-to-list 'auto-mode-alist '("\\.ul\\'" . undar-mode))
(provide 'undar-mode)
;;; undar-mode.el ends here