找回密码
 立即注册
搜索
查看: 339|回复: 6

zlang v0.12.2.0 发布,支持中文编程、支持Web开发/桌面应用开发的国产全自研编程语言

[复制链接]

主题

0

回帖

0

积分

积分
0
发表于 2026-8-26 13:02:39 | 显示全部楼层 |阅读模式
目录

一、zlang简介

二、更新日志

三、技术专栏

3.1. 《zlang不需要getter、setter八股文》

3.2. 《构造和解析二进制数据包》

--------------------------------

zlang是一门完全国产自研的、追求干净观感的、基于对象克隆支持中文编程的编程语言:


完全从底层开始编写,语言引擎(词法 / 语法分析等)、对象库等均未基于 / 采用任何已有语言进行改造、包装或扩展,保证了代码和权利的干净、清晰与自主可控。


定位:简洁、高效、易上手、全栈能力,兼顾开发效率与运行性能。


设计理念:解决主流语言痛点(如 C 语言字符串处理繁琐、Java 冗余的 Getter/Setter),融合优势并加入创新设计。


对标语言:Python。


LOGO:中华狸花猫,象征独立、坚韧、不畏挑战。


一、Hello world

  1. import stdtypes stdio ;

  2. function int main( array args )
  3. {
  4.         stdout.Println( "Hello world" );

  5.         return 0;
  6. }
复制代码
二、核心亮点(5 大特色)
1. 完全从底层自研,自主可控,国产编程语言


不基于任何其它语言/框架/引擎的改造或扩展,核心技术100%自研,真正自主可控;


产品起源于中国,完全中国制造,填补了国内原创编程语言领域的空白,和世界一起推动编程语言发展;


2. 原生中文编程,降低门槛


原生支持中文关键字和标识符,提供对中文编程的良好支持,打破英文编程的传统壁垒,适配国人的文字习惯,降低编程入门门槛,助力编程教育普及,让软件技术更贴合本土场景;


3. 创新语法设计,简洁高效


源于C/C++/Java又发展创新:C/Java的语法已经设计的相当完美了,新语言根本没必要完全设计一套新的语法,zlang语法继承自C/C++/Java,能让最广大同学们快速学习掌握;


极简哲学,万物皆对象:摒弃class,进化面向对象思想,声明变量即复制对象,简化和统一对象体系;


语义直观,减少冗余注解:支持带空格、符号、汉字等的标识符命名;在Web开发中,允许以HTTP 方法与 URL来定义函数名(如 function GET /api/user(){ ... }),无需额外注解,减少命名工作,让代码语义一目了然,大幅降低开发量;


以后不用写Getter/Setter繁琐代码了:没必要为了将来1%的扩展性导致99%都遵循繁琐的写法,zlang`提供了属性拦截器解决扩展性问题;


对异常处理体系的重新思考和实践


吸取了很多语言的优秀精华:比如atomic、defer等;


4. 完整生态,开箱即用


官方标准库内置微整型、短整型、整形、长整型、浮点型、双浮点型、布尔型、字符串型、函数指针型等基础对象;


官方标准库内置数组、链表、映射、队列、栈、有序堆、树、缓冲区等数据容器;


官方标准库内置大数运算、日期时间、文件、输入输出、随机数、编码、缓存、JSON、XML、MSOffice、线程、日志等对象库;


官方标准库内置了加解密对象库,支持常用MD5、SHA1、SHA256、SHA512、DES、3DES、AES、RSA、SM2、SM3、SM4等算法,以及秘钥管理;


官方标准库内置了互斥量、读写锁、条件变量、内存屏障等线程同步机制;


官方标准库内置数据库对象库支持MySQL、PostgreSQL、Sqlite数据库;


官方标准库内置网络对象ip、netaddress、tcp、udp、http、httpclient、httpserver、htmlsection,自带高性能HTTP服务+网页模板引擎套装,支持Web应用开发;


官方还提供了跨平台图形界面库开源项目gtk-zlang,支持Windows、Linux桌面应用开发;


5. 高性能 + 跨平台


语言内核+对象库用C实现,耗时极低,压测验证性能稳定,静态网页 TPS 达 25000(5 并发),动态网页 RT 5~30ms(单个网页后端含 5 条结果集查询 SQL、23 条单记录查询 SQL、1 条插入 SQL)。


支持 Windows、Linux (glibc>=2.17) 跨平台编译与运行。


三、快速开始

1.
源码仓库地址:https://gitee.com/calvinwilliams/zlang (仓库内含整套源代码、测试用例与详细介绍)

2.
环境要求:Windows、Linux (glibc>=2.17)


四、关于作者

zlang由独立开发者calvinwilliams从零研发,历时多年打造。
zlang文档传送门
zlang技术专栏传送门

--------------------------------

0.12.2.0 2026-08-13 calvin

* 调整调试宏架构

* 对象zruntime新增函数PrintObjectBase(object)、PrintObjectFunctions(object)、PrintObjectProperties(object)

* 解决对象内的属性集合实体的循环引用的缺陷

0.12.1.0 2026-08-09 calvin

* 对象poller新增支持定时器

* 修复了原子机制的一个问题

0.12.0.0 2026-08-07 calvin

* 对象eventfd新增函数SetFd、IsValid、GetFd

* 对象thread、queue新增函数BindEventFd(eventfd)、GetFd;多路复用适用对象扩充到线程和消息队列了

* zlang启动参数新增"--child-*-level"

0.11.13.2 2026-08-05 calvin

* 性能优化

0.11.13.1 2026-08-03 calvin

* 内部做了小调整

* 回归测试脚本输出带颜色了

0.11.13.0 2026-07-31 calvin

* 同步了network文档中的返回值和异常说明

* 新增对象eventfd

* 现在子线程返回如果带致命错误会传递给主线程了

0.11.12.0 2026-07-30 calvin

* ip对象新增函数CreateFromDefaultGateway、CreateFromViaConnectingGateway、SetFromDefaultGateway、SetFromViaConnectingGateway

0.11.11.0 2026-07-28 calvin

* netaddress对象新增函数GetIpInteger、Create(uint,ushort)、Set(uint,ushort)

* 对象-缓冲区转换函数支持跟踪当前偏移量了

* 修复了启动线程时未把当前对象和函数传入环境上下文的问题

* 调整了一批全局API名字

* 根对象新增函数GetDirectPropertySize、GetPropertiesDirectPropertySize

0.11.10.0 2026-07-27 calvin

* 所有数值类对象都增加ToTiny~ToULong~ToDouble系列函数

* 各网络对象明确了超时类型、端口类型、数据长度类型,以及更新相关函数原型

* buffer对象新增函数ResizeElementCount、GetSize

0.11.9.1 2026-07-25 calvin

* 重构了zexception对象,一劳永逸的解决了zexception和string加载优先级悖论

* 补充thread对象,如果是非守护线程,子线程结束后会把致命错误和异常传回主线程

0.11.9.0 2026-07-24 calvin

* 新增pipe对象

* 对象poller支持pipe对象

0.11.8.0 2026-07-23 calvin

* TEST_RUNTIME_LEVEL对内性能优化

* string对象增加内置小缓存区以减少内存块分配次数,整个string对象代码做了调整

* ZlangRuntime一些成员移到ZlangGlobalEnvironment,真正把ZlangGlobalEnvironment用起来

0.11.7.0 2026-07-22 calvin

* 新增zlang命令行参数--builtin-parameters或-B用于显示所有内部缺省参数

* 修正了基础类型升级的问题

0.11.6.0 2026-07-21 calvin

* 解开了一些类型检查硬性约束,更有适配性和灵活度

* 输出格式化增加内嵌非基础变量自动调用ToString

* 重整C开发zlang对象库模板zlang_c_object而调整一些地方,完善文档

--------------------------------
《zlang不需要getter、setter八股文》
getter、setter八股文

目前很多编程语言都有getter、setter八股文,本人很是反感,这也是创造zlang的主要原因之一。

getter、setter的作用是解耦 调用者代码 和 被调对象字段代码,其实现在IDE已经很智能了,换名字就是一键的事情。

Java

  1. class MyClass
  2. {
  3.         private int                age ;
  4.         public MyClass() {
  5.     }
  6.         public int getAge()
  7.         {
  8.                 return age;
  9.         }
  10.         public void setAge( int age )
  11.         {
  12.                 this.age = age ;
  13.         }
  14. }
  15. public class Main {
  16.     public static void main(String[] args) {
  17.         MyClass o = new MyClass();
  18.         o.setAge(25);
  19.         System.out.println(o.getAge());
  20.     }
  21. }
复制代码
zlang不需要getter、setter八股文

zlang设计成不需要getter、setter八股文,代码理解直观,代码量大幅减少,产出提效。

zlang

  1. object MyObject
  2. {
  3.         int                age ;
  4. }
  5. function int main( array args )
  6. {
  7.         MyObject        o ;
  8.         o.age = 25 ;
  9.         stdout.FormatPrintln( o.age );
  10. }
复制代码
getter、setter允许“存取字段值时可以做一些转换”

还有人解释getter、setter允许“存取字段值时可以做一些转换”,你评估一下真实项目中有多少需要转换的需求,为了所谓的将来莫须有的扩展性,造成所有代码中都无谓充斥着大量getter、setter是一种愚蠢和低效。

Java

  1. class MyClass
  2. {
  3.         private int                age ;
  4.         public MyClass() {
  5.     }
  6.         public int getAge()
  7.         {
  8.                 return age;
  9.         }
  10.         public void setAge( int age )
  11.         {
  12.                 if (age < 0 || age > 300) {
  13.                         throw new IllegalArgumentException( "age invalid" );
  14.                 this.age = age ;
  15.         }
  16. }
  17. public class Main {
  18.     public static void main(String&#91;&#93; args) {
  19.             try {
  20.                         MyClass o = new MyClass();
  21.                         o.setAge(25);
  22.                         System.out.println(o.getAge());
  23.                 } catch (IllegalArgumentException e) {
  24.                         System.out.println("EXCEPTION:" + e.getMessage());
  25.         }
  26.     }
  27. }
复制代码
`zlang有属性拦截器

你会问,那么将来有字段存取过程需要转换怎么办?zlang的回答是:用属性拦截器。1%的字段需要转换,就写1%的字段属性拦截器,而不是写100%的getter、setter,不多写一个字符,干净利落。

zlang

  1. import stdtypes stdio ;
  2. object MyObject
  3. {
  4.         int                age ;
  5.         intercept set age( object age )
  6.         {
  7.                 if( age < 0 || age > 300 )
  8.                 {
  9.                         zexception.SetException(-1,"age invalid");
  10.                         return;
  11.                 }
  12.                 this.age = age ;
  13.                 return;
  14.         }
  15. }
  16. function int main( array args )
  17. {
  18.         try
  19.         {
  20.                 MyObject        o ;
  21.                 o.age = -1 ;
  22.                 stdout.FormatPrintln( o.age );
  23.                 catch
  24.                 {
  25.                         stdout.Println( zexception.GetExceptionDesc() );
  26.                 }
  27.         }
  28. }
复制代码
执行效果

  1. $ zlang zlang_dont_need_getter_setter.z
  2. age invalid
复制代码

--------------------------------
《构造和解析二进制数据包》

zlang的缓冲区对象buffer特别适合构造和解析二进制数据包,下面以IP数据包为例,介绍zlang如何编写代码来构造和解析二进制数据包。

之所以选择IP数据包并不是鼓励用zlang处理网络协议栈,而是觉得IP数据包是典型的二进制数据包的研究案例。
构造总体思路


定义一个数据包对象,按顺序定义各字段(注意字段的字长;如果只取字段的几个比特,在字段名后面加上位域:(bit_fields);如果多个字段的位段映射到目标缓冲区中的一个字节,写对位域即可);


用缓冲区对象函数ResizeElementCount调整好缓冲区对象内部缓冲区大小;


为不影响父级对象,克隆子对象;填充子对象各字段的值;子对象缺省继承根对象zobject,调用根对象函数DumpBuffer倾倒到缓冲区对象缓冲区中;


IP数据包头还有附带区域,可以在倾倒缓冲区后附加倾倒一个字符串;


倾倒后调用标准输出对象函数HexPrintln按十六进制打印输出缓冲区;(可选)


编写构造具体代码段

定义IP数据包对象:

  1. object ip_package
  2. {
  3.         utiny        version:4 ;
  4.         utiny        ihl:4 ;
  5.         utiny        tos ;
  6.         ushort        total_length ;
  7.         ushort        identification ;
  8.         utiny        flags:3 ;
  9.         ushort        fragment_offset:13 ;
  10.         utiny        ttl ;
  11.         utiny        protocol ;
  12.         ushort        header_checksum ;
  13.         uint        source_ip ;
  14.         uint        dest_ip ;
  15. }
复制代码

调整好缓冲区对象内部缓冲区大小:

  1.                 ip_packet_head_size = ip_package.GetPropertiesDirectPropertySize() ;
  2.                 ip_packet_payload_size = (payload.Length()+4)/5*5 ;
  3.                 ip_packet_size = ip_packet_head_size + ip_packet_payload_size ;
  4.                 stdout.FormatPrintln( "ip_packet_head_size&#91;%d&#93;B + ip_packet_payload_size&#91;%d&#93;B = ip_packet_size&#91;%d&#93;B" , ip_packet_head_size , ip_packet_payload_size , ip_packet_size );
  5.                 buf.ResizeElementCount( ip_packet_size );
复制代码

填充子对象各字段的值:

  1.                 ipp1..;
  2.                         ..version = 4b0100UT ;
  3.                         ..ihl = 5UT ;
  4.                         ..tos = 8b00000000UT ;
  5.                         ..total_length = ip_packet_size.ToUShort() ;
  6.                         ..identification = 0x1234US ;
  7.                         ..flags = 3b010UT ;
  8.                         ..fragment_offset = 4098US ;
  9.                         ..ttl = 64UT ;
  10.                         ..protocol = 6UT ;
  11.                         ..header_checksum = 0US ;
  12.                         ..source_ip = ip.CreateFromString("192.168.0.1").ToIntegerInHostOrder();
  13.                         ..dest_ip = ip.CreateFromString("192.168.0.2").ToIntegerInHostOrder();
复制代码

倾倒各字段以及附带区域到缓冲区:

  1.                 offset = 0 ;
  2.                 ipp1.DumpBuffer( buf , offset );
  3.                 buf.CopyIntoAsVString( offset , payload );
复制代码

按十六进制打印输出缓冲区:

  1.                 stdout.HexPrintln( buf );
复制代码
解析总体思路


已经定义好了数据包对象;拿到构造好的缓冲区对象;


设置解析偏移量为0,调用缓冲区对象函数ToEntityObject解析到数据包对象中各字段;偏移量自动前进;


IP数据包头还有附带区域,计算出附带区域大小,调用缓冲区对象函数CopyOutAsVString解析到字符串中;


编写解析具体代码段

解析缓冲区对象到数据包对象中各字段:

  1.                 offset = 0 ;
  2.                 buf.ToEntityObject( <object>ipp2 , offset );
复制代码

解析附带区域:

  1.                 buf.CopyOutAsVString( offset , payload2 , buf.GetSize()-ip_package.GetPropertiesDirectPropertySize() );
复制代码
构造和解析的完整源代码

源文件名:tech-notes/binary-packet.z

  1. import stdtypes stdio network ;

  2. object ip_package
  3. {
  4.         utiny        version:4 ;
  5.         utiny        ihl:4 ;
  6.         utiny        tos ;
  7.         ushort        total_length ;
  8.         ushort        identification ;
  9.         utiny        flags:3 ;
  10.         ushort        fragment_offset:13 ;
  11.         utiny        ttl ;
  12.         utiny        protocol ;
  13.         ushort        header_checksum ;
  14.         uint        source_ip ;
  15.         uint        dest_ip ;
  16. }

  17. function void PrintlnIpPackage( ip_package ipp , string payload )
  18. {
  19.         stdout.FormatPrintln( "ipp.version&#91;%{ipp.version}&#93;" );
  20.         stdout.FormatPrintln( "ipp.ihl&#91;%{ipp.ihl}&#93;" );
  21.         stdout.FormatPrintln( "ipp.tos&#91;%{ipp.tos}&#93;" );
  22.         stdout.FormatPrintln( "ipp.total_length&#91;%{ipp.total_length}&#93;" );
  23.         stdout.FormatPrintln( "ipp.identification&#91;0x%04x&#93;" , ipp.identification );
  24.         stdout.FormatPrintln( "ipp.flags&#91;%{ipp.flags}&#93;" );
  25.         stdout.FormatPrintln( "ipp.fragment_offset&#91;%{ipp.fragment_offset}&#93;" );
  26.         stdout.FormatPrintln( "ipp.ttl&#91;%{ipp.ttl}&#93;" );
  27.         stdout.FormatPrintln( "ipp.protocol&#91;%{ipp.protocol}&#93;" );
  28.         stdout.FormatPrintln( "ipp.header_checksum&#91;%{ipp.header_checksum}&#93;" );
  29.         stdout.FormatPrintln( "ipp.source_ip&#91;%s&#93;" , ip.CreateFromIntegerInHostOrder(ipp.source_ip).ToString() );
  30.         stdout.FormatPrintln( "ipp.dest_ip&#91;%s&#93;" , ip.CreateFromIntegerInHostOrder(ipp.dest_ip).ToString() );
  31.         stdout.FormatPrintln( "ipp.payload&#91;%s&#93;" , payload );
  32.        
  33.         return;
  34. }

  35. function int main( array args )
  36. {
  37.         try
  38.         {
  39.                 ip_package        ipp1 , ipp2 ;
  40.                 string                payload = "helo" ;
  41.                 string                payload2 ;
  42.                 int                ip_packet_head_size ;
  43.                 int                ip_packet_payload_size ;
  44.                 int                ip_packet_size ;
  45.                 buffer<char>        buf ;
  46.                 int                offset ;
  47.                
  48.                 ip_packet_head_size = ip_package.GetPropertiesDirectPropertySize() ;
  49.                 ip_packet_payload_size = (payload.Length()+4)/5*5 ;
  50.                 ip_packet_size = ip_packet_head_size + ip_packet_payload_size ;
  51.                 stdout.FormatPrintln( "ip_packet_head_size&#91;%d&#93;B + ip_packet_payload_size&#91;%d&#93;B = ip_packet_size&#91;%d&#93;B" , ip_packet_head_size , ip_packet_payload_size , ip_packet_size );
  52.                 buf.ResizeElementCount( ip_packet_size );
  53.                
  54.                 ipp1..;
  55.                         ..version = 4b0100UT ;
  56.                         ..ihl = 5UT ;
  57.                         ..tos = 8b00000000UT ;
  58.                         ..total_length = ip_packet_size.ToUShort() ;
  59.                         ..identification = 0x1234US ;
  60.                         ..flags = 3b010UT ;
  61.                         ..fragment_offset = 4098US ;
  62.                         ..ttl = 64UT ;
  63.                         ..protocol = 6UT ;
  64.                         ..header_checksum = 0US ;
  65.                         ..source_ip = ip.CreateFromString("192.168.0.1").ToIntegerInHostOrder();
  66.                         ..dest_ip = ip.CreateFromString("192.168.0.2").ToIntegerInHostOrder();
  67.                 stdout.Println( "--- ipp1 ---");
  68.                 PrintlnIpPackage( ipp1 , payload );
  69.                
  70.                 offset = 0 ;
  71.                 ipp1.DumpBuffer( buf , offset );
  72.                 buf.CopyIntoAsVString( offset , payload );
  73.                 stdout.HexPrintln( buf );
  74.                
  75.                 offset = 0 ;
  76.                 buf.ToEntityObject( <object>ipp2 , offset );
  77.                 buf.CopyOutAsVString( offset , payload2 , buf.GetSize()-ip_package.GetPropertiesDirectPropertySize() );
  78.                 stdout.FormatPrintln( "offset&#91;%d&#93;B" , offset );
  79.                 stdout.Println( "--- ipp2 ---");
  80.                 PrintlnIpPackage( ipp2 , payload2 );
  81.                
  82.                 catch
  83.                 {
  84.                         stdout.Println( zexception.GetExceptionDesc() );
  85.                 }
  86.         }
  87.        
  88.         return 0;
  89. }
复制代码
执行效果

  1. $ zlang binary-packet.z
  2. ip_packet_head_size&#91;20&#93;B + ip_packet_payload_size&#91;5&#93;B = ip_packet_size&#91;25&#93;B
  3. --- ipp1 ---
  4. ipp.version&#91;4&#93;
  5. ipp.ihl&#91;5&#93;
  6. ipp.tos&#91;0&#93;
  7. ipp.total_length&#91;25&#93;
  8. ipp.identification&#91;0x1234&#93;
  9. ipp.flags&#91;2&#93;
  10. ipp.fragment_offset&#91;4098&#93;
  11. ipp.ttl&#91;64&#93;
  12. ipp.protocol&#91;6&#93;
  13. ipp.header_checksum&#91;0&#93;
  14. ipp.source_ip&#91;192.168.0.1&#93;
  15. ipp.dest_ip&#91;192.168.0.2&#93;
  16. ipp.payload&#91;helo&#93;
  17.            | 0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F  | 0123456789ABCDEF
  18. -----------+-------------------------------------------------+-----------------
  19. 0x00000000 | 45 00 00 19 12 34 50 02 40 06 00 00 C0 A8 00 01 | E....4P.@.......
  20. 0x00000010 | C0 A8 00 02 68 65 6C 6F 00                      | ....helo.
  21. offset&#91;25&#93;B
  22. --- ipp2 ---
  23. ipp.version&#91;4&#93;
  24. ipp.ihl&#91;5&#93;
  25. ipp.tos&#91;0&#93;
  26. ipp.total_length&#91;25&#93;
  27. ipp.identification&#91;0x1234&#93;
  28. ipp.flags&#91;2&#93;
  29. ipp.fragment_offset&#91;4098&#93;
  30. ipp.ttl&#91;64&#93;
  31. ipp.protocol&#91;6&#93;
  32. ipp.header_checksum&#91;0&#93;
  33. ipp.source_ip&#91;192.168.0.1&#93;
  34. ipp.dest_ip&#91;192.168.0.2&#93;
  35. ipp.payload&#91;helo&#93;
复制代码

原文链接

打赏作者

当前余额:0 Token,打赏后立即到账

主题

0

回帖

0

积分

积分
0
发表于 2026-8-26 13:03:39 | 显示全部楼层
这篇干货浓度很高,支持中文编程和zlang两个点都讲到位了。

主题

0

回帖

0

积分

积分
0
发表于 2026-8-26 13:03:39 | 显示全部楼层
坐等更新,zlang系列要是能写下去就更好了。

主题

0

回帖

0

积分

积分
0
发表于 2026-8-26 13:50:42 | 显示全部楼层
这种认真写长文的楼主不多了,必须支持。

主题

0

回帖

0

积分

积分
0
发表于 2026-8-26 13:43:14 | 显示全部楼层
有一说一,现在肯把zlang讲这么细的人不多了。

主题

0

回帖

0

积分

积分
0
发表于 2026-8-26 13:59:31 | 显示全部楼层
写得不错,zlang那部分说到点子上了,顶一个。

主题

0

回帖

0

积分

积分
0
发表于 2026-8-26 14:11:20 | 显示全部楼层
支持中文编程和zlang结合起来讲的思路很好,这种对比很少见。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

{ template common/footer}