CodeMirror.defineMode("prism", function (config, parserConfig) {
  return {
    startState: function () {
      return {};
    },
    token: function (stream, state) {
      // Skip whitespace
      if (stream.eatSpace()) {
        return null;
      }

      // Single-line comments
      if (stream.match(/\/\/.*/)) {
        return "comment";
      }

      // Check for module keyword and the identifier after it
      if (state.afterModule && stream.match(/^[a-zA-Z_][a-zA-Z0-9_]*/)) {
        state.afterModule = false;
        return "variable"; // Return token type for module names
      }

      // Check for module keyword and set state to look for identifier
      if (stream.match(/\bmodule\b/)) {
        state.afterModule = true;
        return "keyword"; // Return token type for keywords
      }

      // Keywords
      if (
        stream.match(
          /\b(?:smg|mdp|dtmc|ctmc|pta|module|endmodule|player|endplayer|system|endsystem|invariant|endrewards|rewards|const|init|min|max|floor|ceil|round|pow|mod|log)\b/
        )
      ) {
        return "keyword";
      }

      // Constants
      if (stream.match(/\b(?:true|false)\b/)) {
        return "atom";
      }

      // Variable types
      if (stream.match(/\b(?:bool|double|int)\b/)) {
        return "keyword";
      }

      // Variable definitions
      if (stream.match(/^[a-zA-Z_][a-zA-Z0-9_]*\s*(?=[:=!'`])/)) {
        return "variable";
      }
      // Strings
      if (stream.match(/"([^"\\]|\\.)*"/)) {
        return "string";
      }

      // Operators
      if (stream.match(/[+\-*/|&<>!=]/)) {
        return "operator";
      }

      // Numbers
      if (stream.match(/\b\d+(\.\d+)?\b/)) {
        return "number";
      }

      // Handle other characters
      stream.next();
      return null;
    },
    startState: function () {
      return {
        afterModule: false, // Track whether we are looking for an identifier after a module keyword
      };
    },
  };
});

// Register the mode with a MIME type
CodeMirror.defineMIME("text-x/myLanguage", "prism");