nondescript:一款简单的嵌入式编程语言
摘要
Nondescript 是一种全新的单文件、可嵌入 C 项目的脚本语言,采用 AppleScript 风格语法,支持列表推导、可扩展语法等特性。
<p><a href="https://lobste.rs/s/ivj2o8/nondescript_simple_embedded">评论</a></p>
查看缓存全文
缓存时间: 2026/04/22 21:06
deadpixi/nondescript 源码:https://github.com/deadpixi/nondescript
Nondescript
一款可嵌入 C 应用的极简脚本语言。Nondescript 的定位与 Lua 类似:体积小巧、单文件实现,可零依赖地编译进任何 C 项目。
特性
- 单文件实现 —— 一个
.c和一个.h,仅依赖 C 标准库 - 兼容 C11(实为 C99 +
_Alignof) - AppleScript 风格语法 —— 受自然语言启发,大小写不敏感
- 可扩展语法 —— 用自定义关键字模式注册宿主命令
- Chunk 访问器 ——
word 1 of myString、item 3 of myList等,可在运行时注册自己的 chunk 类型 given代码块 —— 向函数传入一段代码- 列表推导 ——
set nonSpaces to every character of myString where it != ' ' - 可插拔分配器 —— 内置池分配器与限额分配器
编译
Nondescript 设计为直接编译进你的工程:
#include "nondescript.h"
cc -o myapp myapp.c nondescript.c -lm
快速上手
#include <stdio.h>
#include "nondescript.h"
int main(int argc, char **argv) {
if (argc < 2) {
fprintf(stderr, "usage: nds <script.nds>\n");
return 1;
}
NDSConfig config = {0};
NDSContext *ctx = NDSContext_new(&config);
NDSStatus status = NDSContext_evaluateFile(ctx, argv[1]);
if (status != NDSStatus_OK)
fprintf(stderr, "%s\n", NDSContext_getError(ctx));
NDSContext_free(ctx);
return status == NDSStatus_OK ? 0 : 1;
}
-- 函数
function greet(name)
println("hello, ", name, "!")
end function
greet("world")
-- Chunk 与 set 表达式
set firstItem to item 1 of ["foo", "bar", "baz"]
println("firstItem:", firstItem)
-- 列表推导
set nonSpaces to every character of "foo bar baz" where it != ' '
println("nonSpaces:", nonSpaces)
-- 代码块
function map(input)
my result is []
for each item i in input do
append given(i) to result
end for
return result
end function
set plus2 to map([1, 2, 3]) given (i)
return i + 2
end given
println("plus2:", plus2)
-- 块作用域。Set 会设置最近一层的绑定。
-- 使用 "my" 显式声明内部绑定。所有结构都会引入新作用域。
function functionScope()
my outer is "outer"
if true then
my outer
set outer to "inner now!"
println("inside if block:", outer)
end if
println("outside if block:", outer)
end function
functionScope()
-- 错误处理按函数划分
function errorFunction()
my NaN is 1 / 0
on error myError
println("errored:", myError)
end function
errorFunction()
-- 错误会向上冒泡
function innerError()
raise nothing message "foo"
end function
function outerError()
innerError()
on error myError
println("got error with message", message of myError)
end function
outerError()
示例
见 examples/ 目录:
- calc —— 在脚本里定义函数,通过
NDSContext_callFunction从 C 调用 - turtle —— 注册自然语言宿主命令(
move forward 100、turn right 90),运行脚本并输出 SVG
编译示例:
cd examples
c11 -o turtle turtle.c ../nondescript.c
./turtle
许可证
Apache 2.0
TODO
- 字节/字符的分裂很奇怪……应该拆成独立类型。
- 大量小修小补。NDSValue/NDSObject 的拆分也很丑……
相似文章
Show HN: Nibble
Nibble 是一种类 C 的系统编程语言,用 3000 行 C 代码实现,无需外部依赖或堆分配即可生成 LLVM IR。它支持 defer、递归、多种类型、结构体、指针,并包含图形演示。
Nanopass Framework: 简洁编译器构建语言
Nanopass Framework 是一种嵌入在 Scheme 中的领域特定语言,用于通过小的遍历和中间表示来创建编译器,减少样板代码并提高可维护性。
7行代码,3分钟:实现一种编程语言(2010)
本文介绍了一种基于 Lambda 演算的图灵完备函数式语言的极简 7 行解释器,展示了 eval/apply 设计模式。
自己造一门编程语言比你想象的简单(但也更难)
作者分享了为游戏模组系统构建自定义编程语言的经验,讨论了设计动机和技术挑战。这篇文章反思了在个人项目中实现一门非玩具级编程语言的可行性与复杂度。
新推出的面向代理的Markdown对象语言MOL
MOL(Markdown对象语言)是一种新的正式规范,用于解析基于markdown的配置和数据文件,其设计比JSON更适合人类和LLM使用。