Skip to content

Lambda 代码编辑器

HTML 代码

html
<!doctype html>
<html lang="zh-CN">
  <head>
    <meta charset="UTF-8" />
    <title>Monaco Editor - Lambda Calculus</title>
    <style>
      html,
      body {
        width: 100%;
        height: 100%;
        margin: 0;
        padding: 0;
        overflow: hidden;
        background-color: #1e1e1e;
      }

      #container {
        width: 100%;
        height: 100%;
      }
    </style>
  </head>

  <body>
    <div id="container"></div>

    <!-- 引入 Monaco Editor 的 Loader -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.53.0/min/vs/loader.min.js"></script>

    <script>
      require.config({
        paths: { vs: "https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.45.0/min/vs" },
      });

      require(["vs/editor/editor.main"], function () {
        // 1. 注册自定义语言 ID
        monaco.languages.register({ id: "lambda-calculus" });

        // 2. 定义 Monarch 语法高亮规则
        monaco.languages.setMonarchTokensProvider("lambda-calculus", {
          // 定义起始状态
          tokenizer: {
            root: [
              // 匹配 λ 或 \,并跳转到 'binding' 状态来高亮参数
              [/[\\λ]/, "keyword.lambda", "@binding"],

              // 匹配括号
              [/[()]/, "delimiter.parenthesis"],

              // 匹配普通变量(在 root 状态下即为函数体部分)
              [/[a-z][a-zA-Z0-9_']*/, "variable.reference"],

              // 允许函数体中单独出现的点(虽然标准语法中点应该跟在绑定变量后,但为了容错)
              [/\./, "delimiter"],

              // 空白和注释
              { include: "@whitespace" },
            ],

            // 处理参数绑定状态: \x. 或 λx.
            binding: [
              // 匹配绑定变量(例如 \x 中的 x),样式设为 parameter
              [/[a-z][a-zA-Z0-9_']*/, "variable.parameter"],

              // 遇到点 . 表示绑定结束,返回 root 状态
              [/\./, "delimiter", "@pop"],

              // 空白处理
              { include: "@whitespace" },
            ],

            whitespace: [
              [/\s+/, "white"],
              [/--.*$/, "comment"], // 使用 Haskell 风格的注释
            ],
          },
        });

        // 3. 定义语言配置(括号匹配等)
        monaco.languages.setLanguageConfiguration("lambda-calculus", {
          comments: {
            lineComment: "--",
          },
          brackets: [["(", ")"]],
          autoClosingPairs: [{ open: "(", close: ")" }],
        });

        // 4. 定义专属主题以区分颜色
        monaco.editor.defineTheme("lambda-theme", {
          base: "vs-dark",
          inherit: true,
          rules: [
            // 关键字 λ 和 \ 设为洋红色
            { token: "keyword.lambda", foreground: "C586C0", fontStyle: "bold" },
            // 绑定参数(形参)设为橙色
            { token: "variable.parameter", foreground: "DCDCAA" },
            // 引用变量(实参/体)设为蓝色/浅蓝
            { token: "variable.reference", foreground: "9CDCFE" },
            // 分隔符和括号
            { token: "delimiter", foreground: "D4D4D4" },
            // 注释
            { token: "comment", foreground: "6A9955" },
          ],
          colors: {
            "editor.background": "#1e1e1e",
          },
        });

        // 5. 初始化编辑器
        var editor = monaco.editor.create(document.getElementById("container"), {
          value: [
            "-- Lambda Calculus Example",
            "-- λ represents abstraction, identical to \\",
            "",
            "-- Identity function",
            "λx.x",
            "",
            "-- Using backslash syntax",
            "\\y.y",
            "",
            "-- Church Numerals (2)",
            "λf.λx.f (f x)",
            "",
            "-- Complex example with mixed syntax",
            "(\\x.\\y.x y) (λz.z)",
          ].join("\n"),
          language: "lambda-calculus",
          theme: "lambda-theme",
          fontSize: 16,
          automaticLayout: true,
        });
      });
    </script>
  </body>
</html>