Show HN: Nimic – 纯Python作为系统语言并支持AOT编译

Hacker News Top 工具

摘要

Nimic是一个纯Python模块,允许使用Python DSL编写可AOT编译的代码,该DSL可转译到Nim,在保持有效Python的同时实现C级性能。

暂无内容
查看原文
查看缓存全文

缓存时间: 2026/06/25 08:09

dima-quant/nimic 源码:https://github.com/dima-quant/nimic # Nimic Nimic 是一个纯 Python 模块,用于帮助用户使用 Python 的子集(领域特定语言)编写 AOT 可编译代码,目标是无需离开 Python 即可获得 C 级别的性能。它基于内置的 ctypes 模块,包含对原生类型、指针及其操作(包括调度、运算符重载和模板)的模拟。Nimic 紧密遵循 Nim 编程语言,nimic 代码可转译为等价的 Nim 代码。

核心原则: nimic 代码是有效的 Python 代码,可原生运行,同时也可转译为等价的 Nim 代码。

模块架构

nimic/  
├── ntypes.py — 公共 API:重新导出类型系统 + Nim 关键字/内置函数 shim  
├── ntypesystem.py — 核心类型系统(Object、NScalar、seq、dispatch、distinct、converter)  
├── transpiler.py — 基于 AST 的 Python → Nim 源码转译器  
├── inliner.py — 模板函数内联(@template、@template_expand)  
├── ncode/ — Nim 定义(pydefs.nim、pystd/)  
├── nimpy/ — 用于生成 Python 库的 API  
├── std/ — Nim stdlib(math、options、os、paths、strformat、...)的 Python shim  
└── system/ — Nim 系统模块(ansi_c)的 Python shim  

ntypesystem.py — 核心类型系统

按层级从底层内存到高层抽象组织:

层级目的
内存Ntype, NTypeRegistry基于 ctypes 的缓冲区,具有值语义
标量NScalarNInteger / NFloat固定宽度类型(int8..int64uint8..uint64float16..float64),支持算术提升
结构体ObjectNim “object” — 通过注解定义字段,底层为 ctypes.Structure
枚举NIntEnumNim 整数枚举,自动注册
变体Object + match kind:Nim “case object” — 判别联合
容器seq[T], UncheckedArray[T]可增长序列和指针索引数组
调度@dispatch, DispDict, NMetaClass通过类型注解实现 Nim 风格的多重调度
修饰符@distinct, @converter类型区分性与简单类型转换
字符串stringstr 的子类,支持 Nim 兼容的 &%isEmpty

ntypes.py — 公共 API 与关键字

重新导出 ntypesystem 的所有内容,并添加 Nim 关键字/内置函数模拟:

  • 编译器提示constletvarblockexportalias(Python 中无操作,Nim 中提供作用域)
  • 引用类型refptrmut@@ 运算符返回身份标识)
  • 枚举工具NStrEnum,支持 succ/pred/ord/nrange/low/high
  • 转换与内存cast[T](x)sizeof(x)addr(x)unsafe_addr(x)
  • 类型别名SomeIntegerSomeFloatuntypedcharu64i64f64
  • 迭代fields(obj)fields(a, b)countdown(a, b)
  • 编译时comptime(x)defined(varname)static
  • 模板@template@template_expand(从 inliner 重新导出)

transpiler.py — Python → Nim 转译器

一个修改过的 CPython ast.py,其中 _Unparser 被扩展以发出 Nim 语法。实现了 30 多条转换规则,涵盖缩进、类型定义、函数签名、运算符、导入和控制流。

inliner.py — 模板内联

@template@template_expand 装饰器在 AST 级别执行函数内联,适用于无类型模板,将参数名称替换为调用参数。

DSL 约定

Nimic 使用具有特定约定的 Python 语法,这些约定具有双重含义——Python 中的运行时行为和 Nim 的转译语义:

约定示例目的
with let/var/const:with let: x = vec3(1,2,3)变量声明作用域限定符
mut @ 注解def f(x: mut @ Vec3):可变参数(Nim 中的 var
{.pragma.} 文档字符串"""{.inline.}"""Nim 编译指示(inline、borrow、noSideEffect)
@dispatch@dispatch def f(x: float64):根据参数类型的多重调度
@distinct@distinct class Color(Vec3):区分类型(无隐式转换)
@template@template def toUV(v):模板(在调用点内联)
@converter@converter def toVec3(uv):隐式类型转换器
<<=dst <<= -src对可变变量进行值赋值
match kind:match kind: case K.a: ...变体类型定义(case object)
comptime(expr)if comptime(cond):编译时求值(Nim 中的 when
fields(obj)for f in fields(obj):遍历对象字段
with export:with export: mod1, mod2重新导出模块

使用 nimic 构建的项目

快速示例

from __future__ import annotations  
from nimic.ntypes import *  

# 结构体定义(Nim object)  
class Vec3(Object):  
    x: float64  
    y: float64  
    z: float64  

    def __add__(self: Vec3, v: Vec3) -> Vec3:  
        """{.inline.}"""  
        result = Vec3()  
        result.x = self.x + v.x  
        result.y = self.y + v.y  
        result.z = self.z + v.z  
        return result  

# 区分类型  
@distinct  
class Point3(Vec3):  
    """{.borrow: `.`.}"""  

# 多重调度  
@dispatch  
def point3(x: float64, y: float64, z: float64) -> Point3:  
    result = Point3(Vec3())  
    result.x = x; result.y = y; result.z = z  
    return result  

# 使用  
with let:  
    a = point3(1.0, 2.0, 3.0)  
    b = point3(4.0, 5.0, 6.0)  
    c = Vec3(a) + Vec3(b)  

相似文章

Show HN: Nibble

Hacker News Top

Nibble 是一种类 C 的系统编程语言,用 3000 行 C 代码实现,无需外部依赖或堆分配即可生成 LLVM IR。它支持 defer、递归、多种类型、结构体、指针,并包含图形演示。

Wren 编程语言的性能表现

Lobsters Hottest

Wren 官网发布微基准测试,称其运行速度超过标准 Python/Ruby/Lua 解释器,同时仍保持简单的字节码虚拟机,得益于 NaN 标记和固定对象布局。

Mojo 1.0 Beta

Hacker News Top

Modular 宣布推出 Mojo 1.0 Beta,这是一种高性能编程语言,将 Python 的易用性与编译型语言的速度相结合,专为 AI 和系统编程设计。