| <!doctype html> |
| <html lang="zh-CN"> |
| <head> |
| <meta charset="utf-8"> |
| <meta name="viewport" content="width=device-width, initial-scale=1"> |
| <title>Mini Lang - 功能展示</title> |
| <style> |
| * { |
| box-sizing: border-box; |
| } |
| body { |
| margin: 0; |
| padding: 0; |
| font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; |
| background-color: #0f172a; |
| color: #e5e7eb; |
| line-height: 1.6; |
| } |
| main { |
| max-width: 960px; |
| margin: 0 auto; |
| padding: 32px 20px 48px; |
| } |
| header { |
| margin-bottom: 32px; |
| text-align: left; |
| } |
| h1 { |
| margin: 0 0 8px; |
| font-size: 32px; |
| color: #f9fafb; |
| } |
| h2 { |
| margin-top: 32px; |
| margin-bottom: 12px; |
| font-size: 22px; |
| color: #e5e7eb; |
| } |
| p { |
| margin: 4px 0 12px; |
| color: #cbd5f5; |
| } |
| .tagline { |
| color: #9ca3af; |
| font-size: 14px; |
| } |
| .section-card { |
| border-radius: 12px; |
| border: 1px solid rgba(148, 163, 184, 0.35); |
| background: radial-gradient(circle at top left, rgba(59, 130, 246, 0.18), transparent 55%), |
| radial-gradient(circle at bottom right, rgba(236, 72, 153, 0.18), transparent 55%), |
| rgba(15, 23, 42, 0.9); |
| padding: 18px 16px 16px; |
| margin-bottom: 18px; |
| } |
| .badge { |
| display: inline-flex; |
| align-items: center; |
| gap: 8px; |
| padding: 4px 10px; |
| border-radius: 999px; |
| border: 1px solid rgba(148, 163, 184, 0.4); |
| background-color: rgba(15, 23, 42, 0.8); |
| color: #e5e7eb; |
| font-size: 12px; |
| margin-top: 8px; |
| } |
| .badge span { |
| display: inline-block; |
| width: 6px; |
| height: 6px; |
| border-radius: 999px; |
| background: radial-gradient(circle at 30% 30%, #22c55e, #16a34a); |
| } |
| ul { |
| padding-left: 20px; |
| margin: 6px 0 0; |
| color: #d1d5db; |
| } |
| code { |
| font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; |
| background-color: rgba(15, 23, 42, 0.9); |
| padding: 1px 4px; |
| border-radius: 4px; |
| font-size: 13px; |
| } |
| pre { |
| margin: 8px 0 0; |
| padding: 10px 12px; |
| border-radius: 10px; |
| background-color: #020617; |
| color: #e5e7eb; |
| overflow-x: auto; |
| font-size: 13px; |
| border: 1px solid rgba(30, 64, 175, 0.7); |
| } |
| pre code { |
| background: none; |
| padding: 0; |
| } |
| .pill-label { |
| display: inline-block; |
| font-size: 12px; |
| color: #a5b4fc; |
| margin-bottom: 4px; |
| text-transform: uppercase; |
| letter-spacing: 0.08em; |
| } |
| .grid { |
| display: grid; |
| grid-template-columns: minmax(0, 1.1fr) minmax(0, 0.9fr); |
| gap: 16px; |
| align-items: flex-start; |
| } |
| .grid-item { |
| min-width: 0; |
| } |
| .output-line { |
| display: inline-flex; |
| align-items: center; |
| gap: 8px; |
| padding: 3px 8px; |
| border-radius: 999px; |
| background: rgba(15, 23, 42, 0.85); |
| font-size: 12px; |
| color: #e5e7eb; |
| } |
| .output-line span { |
| display: inline-block; |
| width: 6px; |
| height: 6px; |
| border-radius: 999px; |
| background: radial-gradient(circle at 30% 30%, #22c55e, #16a34a); |
| } |
| .footer { |
| margin-top: 28px; |
| font-size: 12px; |
| color: #6b7280; |
| text-align: right; |
| } |
| @media (max-width: 720px) { |
| main { |
| padding: 20px 16px 32px; |
| } |
| h1 { |
| font-size: 26px; |
| } |
| .grid { |
| grid-template-columns: minmax(0, 1fr); |
| } |
| } |
| </style> |
| </head> |
| <body> |
| <main> |
| <header> |
| <h1>Mini Lang 自定义语言</h1> |
| <p class="tagline">一个用 JavaScript 实现的微型脚本语言,支持变量、表达式与打印输出。</p> |
| <div class="badge"> |
| <span></span> |
| <div>命令行运行 · Hugging Face Spaces 静态展示</div> |
| </div> |
| </header> |
|
|
| <section class="section-card"> |
| <div class="pill-label">语言特性概览</div> |
| <h2>支持的语法</h2> |
| <p>Mini Lang 目前专注于表达式计算与简单的脚本结构:</p> |
| <ul> |
| <li>数字字面量,例如 <code>1</code>、<code>3.14</code></li> |
| <li>变量声明:<code>let x = 表达式;</code></li> |
| <li>四则运算:<code>+</code>、<code>-</code>、<code>*</code>、<code>/</code>,支持括号改变优先级</li> |
| <li>打印语句:<code>print 表达式;</code> 会在控制台输出值</li> |
| <li>语句之间用分号结尾:<code>;</code></li> |
| </ul> |
| </section> |
|
|
| <section class="section-card"> |
| <div class="pill-label">在线体验</div> |
| <h2>在线运行 Mini Lang</h2> |
| <p>在下方输入框编写 Mini Lang 代码,点击运行查看结果:</p> |
| <div class="grid"> |
| <div class="grid-item"> |
| <textarea id="code-input" style="width: 100%; height: 200px; background: #020617; color: #e5e7eb; border: 1px solid rgba(30, 64, 175, 0.7); border-radius: 8px; padding: 12px; font-family: monospace;">let x = 10; |
| let y = 20; |
| print x + y; |
| print x * y; |
| </textarea> |
| <button onclick="runCode()" style="margin-top: 10px; padding: 8px 16px; background: #3b82f6; color: white; border: none; border-radius: 6px; cursor: pointer;">运行代码</button> |
| </div> |
| <div class="grid-item"> |
| <pre id="output-area" style="height: 200px; overflow-y: auto;">Waiting for output...</pre> |
| </div> |
| </div> |
| <script src="mini_lang.js"></script> |
| <script> |
| function runCode() { |
| const source = document.getElementById('code-input').value; |
| const outputArea = document.getElementById('output-area'); |
| outputArea.innerText = ''; |
| |
| try { |
| |
| if (window.MiniLang) { |
| window.MiniLang.run(source, (val) => { |
| outputArea.innerText += val + '\n'; |
| }); |
| } else { |
| outputArea.innerText = 'Error: MiniLang engine not loaded.'; |
| } |
| } catch (e) { |
| outputArea.innerText += 'Error: ' + e.message; |
| } |
| } |
| </script> |
| </section> |
|
|
| <section class="section-card"> |
| <div class="pill-label">最小可运行示例</div> |
| <h2>示例程序与运行效果</h2> |
| <div class="grid"> |
| <div class="grid-item"> |
| <p>示例源文件 <code>example.mini</code>:</p> |
| <pre><code>let x = 1 + 2 * 3; |
| let y = (x - 2) / 2; |
| print x; |
| print y; |
| print x + y * 10;</code></pre> |
| </div> |
| <div class="grid-item"> |
| <p>在命令行运行后输出:</p> |
| <pre><code>7 |
| 2.5 |
| 32</code></pre> |
| <p> |
| 其中: |
| </p> |
| <ul> |
| <li><code>x = 1 + 2 * 3 = 7</code></li> |
| <li><code>y = (x - 2) / 2 = 2.5</code></li> |
| <li>最后一行输出 <code>7 + 2.5 * 10 = 32</code></li> |
| </ul> |
| </div> |
| </div> |
| </section> |
|
|
| <section class="section-card"> |
| <div class="pill-label">本地命令行使用方式</div> |
| <h2>如何在本地运行 Mini Lang</h2> |
| <p>本项目使用 Node.js 作为运行时,只依赖内置模块 <code>fs</code> 与 <code>path</code>:</p> |
| <pre><code># 进入项目目录 |
| cd mini-lang |
|
|
| # 使用默认示例程序运行 |
| node main.js |
|
|
| # 或者指定自己的脚本文件 |
| node main.js your_program.mini</code></pre> |
| <p>在入口文件 <code>main.js</code> 中,会读取传入的脚本文件内容,并调用解释器执行。</p> |
| </section> |
|
|
| <section class="section-card"> |
| <div class="pill-label">部署到 Hugging Face Spaces</div> |
| <h2>在 Spaces 上展示</h2> |
| <p> |
| 将本项目作为 <strong>Static</strong> 类型的 Space 使用时,只需要把整个 |
| <code>mini-lang</code> 文件夹推送到 |
| <code>hf026:spaces/duqing026/mini-lang</code> 对应的仓库即可。 |
| </p> |
| <p>此页面 <code>index.html</code> 会作为默认展示入口,用于说明 Mini Lang 的语法与示例。</p> |
| <pre><code># 在 mini-lang 目录下(本地已经配置好 huggingface 的 ssh 别名 hf026) |
| git init |
| git add . |
| git commit -m "chore: add mini-lang demo page" |
| git push hf026:spaces/duqing026/mini-lang main</code></pre> |
| <p>推送成功后,在浏览器访问对应的 Hugging Face Space,即可看到本页面。</p> |
| </section> |
|
|
| <div class="footer"> |
| Mini Lang · 仅用于教学与功能演示 |
| </div> |
| </main> |
| </body> |
| </html> |
|
|