Skip to content

Latest commit

 

History

10 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

TzdTools

TzdTools 是一个自定义编程语言 TzdLang 的开发工具链,包含语言解释器、VSCode 扩展支持和丰富的标准库。

项目概述

TzdLang 是一门面向对象的编程语言,具有现代语言特性,包括:

  • 类继承和多态
  • 异常处理机制
  • 线程支持
  • 动态类型系统
  • JIT 编译支持

项目结构

TzdTools/
├── README.md                    # 项目说明文档
├── bench.py                     # Python 性能基准测试
├── bench.tzd                   # TzdLang 性能基准测试
├── TzdLang_Reference.pdf       # 语言参考手册
├── TzdTools/                   # C++ 源代码和构建产物
│   ├── stdlib/                 # 标准库
│   │   ├── core/               # 核心功能库
│   │   └── thread/             # 线程支持库
│   └── x64/                    # 构建输出目录
│       ├── Release/            # 发布版本
│       └── Debug/              # 调试版本
├── vscodePlugin/               # VSCode 扩展
│   └── tzdlang/                # TzdLang VSCode 扩展
├── examples/                   # 示例代码
├── test_*.tzd                  # 测试文件
└── Generated/                 # ANTLR 生成的代码

快速开始

构建项目

项目使用 C++ 开发,需要 Visual Studio 2019 或更高版本:

# 使用 Visual Studio 打开解决方案
# 或在命令行中构建
msbuild TzdTools.sln /p:Configuration=Release /p:Platform=x64

VSCode 扩展安装

项目包含完整的 VSCode 扩展支持:

  1. 安装扩展 (直接使用 .vsix 文件或开发模式)
  2. 配置 TzdTools.exe 路径
  3. 享受语法高亮、代码补全和调试功能

语言特性

基本语法

// 变量声明
var int x = 10;
var string name = "TzdLang";

// 函数定义
fun greet(name) {
    print("Hello, " + name + "!");
}

// 类定义
class Person {
    var string name;
    
    Person(name) {
        this.name = name;
    }
    
    fun introduce() {
        print("I am " + this.name);
    }
}

控制流

注意:for 循环的第一个表达式不能指定类型,包括 var

正确的 for 循环语法:

// 正确的语法
for (i = 0; i < 5; i = i + 1) {
    print(i);
}

// 正确的语法
for (j = 0; j < 10; j++) {
    if (j == 3) break;
    print(j);
}

// 错误的语法(不支持)
for (var i = 0; i < 5; i++) {
    // 这种写法会报错
}

while 循环和 break 语句

// while 循环
var i = 0;
while (i < 5) {
    print("i = " + i);
    i = i + 1;
}

// 使用 break 退出循环
for (j = 0; j < 10; j++) {
    if (j == 3) break;
    print(j);
}

继承和多态

class Animal {
    var string name;
    Animal(name) { this.name = name; }
    fun speak() { print(this.name + " says ..."); }
}

class Dog extends Animal {
    Dog(name) : super(name) {}
    fun speak() { print(this.name + " barks! woof!"); }
}

fun testOop() {
    var d = new Dog("Buddy");
    d.speak();  // 输出: Buddy barks! woof!
}

异常处理

import "core/Error.tzd";

fun runDemo() {
    try {
        throw new Error("test error", "TEST");
    } catch (err) {
        print("caught: " + err.code + " " + err.message);
    }
}

线程支持

import "thread/Thread.tzd";

fun worker() {
    for (i = 0; i < 5; i++) {
        print("Thread: " + i);
        sleep(1000);
    }
}

var t = new Thread(worker);
t.start();
t.join();

调试功能

调试命令

TzdLang 支持完整的调试功能,包括:

断点管理

  • 设置断点:通过调试器界面或命令行
  • 清除断点:支持按文件和行号删除
  • 条件断点:支持基于条件的断点触发

调试控制

  • continue - 继续执行到下一个断点
  • step into - 进入当前函数调用
  • step over - 跳过当前函数调用
  • step out - 退出当前函数调用
  • pause - 暂停执行

状态检查

  • 堆栈跟踪:显示函数调用堆栈
  • 变量查看:检查当前作用域的变量值
  • 表达式求值:实时计算表达式值

调试示例

fun greet(name) {
    print("Greeting started...");
    msg = "Hello " + name;
    print(msg);
    print("Greeting ended.");
}

print("Main script started.");
greet("TzdLang");
print("Main script ended.");

性能监控

fun testPerformance() {
    var start = clock();
    var i = 0;
    while (i < 50000) {
        if (i == 10000) { print("进度: 20%"); }
        if (i == 20000) { print("进度: 40%"); }
        if (i == 30000) { print("进度: 60%"); }
        if (i == 40000) { print("进度: 80%"); }
        i = i + 1;
    }
    var end = clock();
    print("完成,耗时: " + ((end - start) / 1000.0) + " s");
}

异常处理调试

fun testException() {
    var i = 0;
    while (i < 100000) {
        if (i == 10) {
            throw "测试异常";
        }
        i = i + 1;
    }
}

testException();

VSCode 扩展功能

支持的命令

  • TzdLang: 运行当前脚本 (F5) - 运行当前打开的 .tzd 文件
  • TzdLang: 重新设置 TzdTools 路径 - 配置解释器路径
  • TzdLang: Hello World - 显示问候信息

调试功能

完整的集成调试支持,包括:

调试控制

  • 启动调试:F5 或运行按钮
  • 暂停/继续:暂停执行和继续运行
  • 单步执行:
    • Step Into (F11) - 进入函数
    • Step Over (F10) - 跳过函数
    • Step Out (Shift+F11) - 退出函数
  • 断点管理:
    • 点击行号设置断点
    • 右键菜单管理断点
    • 条件断点支持

调试信息显示

  • 变量监视:实时查看变量值
  • 调用堆栈:显示函数调用层次
  • 输出控制台:显示程序输出和调试信息
  • 错误提示:语法和运行时错误提示

配置选项

{
    "tzdlang.toolsPath": "C:/path/to/TzdTools.exe"
}

语言支持

  • 语法高亮
  • 代码自动补全
  • 错误检查
  • 完整的调试支持
  • 一键运行
  • 断点管理
  • 堆栈跟踪
  • 变量监视

使用示例

基本调试

  1. 打开 .tzd 文件
  2. 设置断点(点击行号)
  3. 按 F5 启动调试
  4. 使用调试控制按钮控制执行
  5. 查看变量值和堆栈信息

调试配置

{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "TzdLang Debug",
            "type": "tzdlang",
            "request": "launch",
            "program": "${file}",
            "stopOnEntry": true,
            "console": "integratedTerminal"
        }
    ]
}

测试项目

项目包含丰富的测试用例,涵盖语言的各个方面:

基本功能测试

  • test_loop.tzd - while 循环语法测试
  • test_bool.tzd - 布尔值和条件表达式测试
  • test_func_loop.tzd - 函数和循环组合测试
  • test_break.tzd - break 语句测试
  • test_1k_loop.tzd - 基础循环性能测试

高级特性测试

  • test_script.tzd - 脚本功能测试(继承、多态、异常处理)
  • test_error_demo.tzd - 错误处理演示
  • test_feat.tzd - 语言功能特性测试
  • test_debug.tzd - 调试功能演示
  • test_throw_while.tzd - 循环中的异常处理

控制流测试

  • test_progress_while.tzd - 大型循环进度监控
  • test_100k_while.tzd - 大型循环性能测试
  • test_100k_exit_no_semicolon.tzd - 退出语句测试
  • test_no_loop.tzd - 无循环代码测试

面向对象测试

  • examples/test.tzd - 基础面向对象功能演示
  • test_script.tzd - 类继承和方法重写

性能基准测试

  • bench.tzd - 基本性能基准测试
  • bench_func.tzd - 函数调用性能测试
  • math_loop.tzd - 数学计算性能测试

运行测试

# 运行所有测试
TzdTools.exe --runMainTzd=test_all.tzd

# 运行单个测试
TzdTools.exe --runMainTzd=test_loop.tzd

# 运行性能测试
TzdTools.exe --runMainTzd=bench.tzd

开发工具

性能基准测试

项目包含 Python 和 TzdLang 的对比基准测试:

# Python 版本
python bench.py

# TzdLang 版本
TzdTools.exe --runMainTzd=bench.tzd

# 函数调用性能测试
TzdTools.exe --runMainTzd=bench_func.tzd

# 数学计算性能测试
TzdTools.exe --runMainTzd=math_loop.tzd

构建和编译

项目使用 Visual Studio 2019 或更高版本构建:

# 构建发布版本
msbuild TzdTools.sln /p:Configuration=Release /p:Platform=x64

# 构建调试版本
msbuild TzdTools.sln /p:Configuration=Debug /p:Platform=x64

# 清理构建文件
msbuild TzdTools.sln /p:Clean=true

代码生成

使用 ANTLR4 生成的解析器:

# 生成词法分析器和语法分析器
antlr4 -Dlanguage=Cpp -no-listener -visitor TzdLang.g4

# 生成访问者模式的代码
antlr4 -Dlanguage=Cpp -visitor TzdLang.g4

# 生成监听器模式的代码
antlr4 -Dlanguage=Cpp -listener TzdLang.g4

调试工具

命令行调试

# 启动调试模式
TzdTools.exe --debug --runMainTzd=script.tzd

# 连接调试客户端
TzdTools.exe --debug-server --port=8080

# 堆栈跟踪
TzdTools.exe --stack-trace --runMainTzd=script.tzd

调试命令系统

  • break <file>:<line> - 设置断点
  • clear <file>:<line> - 清除断点
  • continue - 继续执行
  • step - 单步执行
  • next - 下一步
  • finish - 完成当前函数
  • where - 显示堆栈
  • print <expr> - 打印表达式值

开发环境配置

VSCode 扩展开发

# 安装依赖
cd vscodePlugin/tzdlang
npm install

# 构建扩展
npm run compile

# 运行测试
npm test

# 打包扩展
npm run vsce-package

IDE 配置

{
    "files.associations": {
        "*.tzd": "tzdlang",
        "*.tzdlang": "tzdlang"
    },
    "editor.formatOnSave": true,
    "editor.codeActionsOnSave": {
        "source.fixAll": true
    }
}

标准库

核心库 (stdlib/core/)

Error.tzd - 错误处理和异常机制

// 自定义异常
throw new Error("错误消息", "错误代码");

// 异常捕获
try {
    // 可能抛出异常的代码
    riskyOperation();
} catch (err) {
    print("错误: " + err.message + " (代码: " + err.code + ")");
}

DatabaseConnectionError.tzd - 数据库连接错误处理

// 数据库连接错误处理
import "core/DatabaseConnectionError.tzd";

try {
    // 数据库操作
    db.connect();
} catch (err) {
    if (err in DatabaseConnectionError) {
        print("数据库连接失败: " + err.message);
    }
}

线程库 (stdlib/thread/)

Thread.tzd - 多线程支持

import "thread/Thread.tzd";

// 创建线程
fun workerThread() {
    for (var i = 0; i < 5; i++) {
        print("工作线程: " + i);
        sleep(1000);
    }
}

var t = new Thread(workerThread);
t.start();  // 启动线程
t.join();   // 等待线程完成

使用标准库

// 导入标准库
import "core/Error.tzd";
import "thread/Thread.tzd";

// 使用标准库功能
fun main() {
    // 使用异常处理
    try {
        throw new Error("测试错误", "TEST_ERROR");
    } catch (err) {
        print("捕获错误: " + err.message);
    }
    
    // 使用线程
    var thread = new Thread(fun() {
        print("在线程中执行");
    });
    thread.start();
    thread.join();
}

JIT 编译器性能优化

TzdLang 的 JIT 编译器基于 LLVM ORC JIT,经过多轮深度优化,在多项基准测试中超越 JDK HotSpot

构建说明

# 必须使用 VS Community 18 (MSVC v144) 构建
# 构建后如遇增量检测失败,删除 .obj 文件强制重编译
del x64\Release\TzdJit.obj
"C:\Program Files\Microsoft Visual Studio\18\Community\MSBuild\Current\Bin\MSBuild.exe" TzdTools.vcxproj /p:Configuration=Release /p:Platform=x64 /t:Build /m

运行基准测试

# 多操作基准测试(循环、递归、Ackermann、素数、函数调用等)
TzdTools.exe --runMainTzd=bench_compare.tzd

# 对象操作基准测试(创建、字段读取)
TzdTools.exe --runMainTzd=bench_object.tzd

# 与 Java 对比
javac BenchCompare.java && java BenchCompare

性能对比(TzdLang vs JDK 20 HotSpot)

操作 TzdLang JDK 倍率
函数调用 callOverhead(1M) 0.002s 0.005s TzdLang 快 2.5x
嵌套循环 nestedLoop(1k×1k) 0.003s 0.005s TzdLang 快 1.7x
简单循环 sumLoop(1M) 0.002s 0.003s TzdLang 快 1.5x
Ackermann(3,6) 0.001s 0.001s TzdLang 快 1.2x
Newton 平方根 0.000006s 0.000008s TzdLang 快 1.3x
fib(35) 递归 0.197s 0.061s JDK 快 3.2x
素数 primes(10k) 0.218s 0.003s JDK 快 72x
对象字段读取 field(100k) 0.002s 0.0005s JDK 快 4x

优化技术清单

Phase A: 运行时函数内联(GEP+Store)

  • inlineStoreNativeToPtr — 直接通过 offsetof GEP+Store 写 TzdValue 的 type 和 dVal 字段,消除 rt_store_native_to_ptr 函数调用

Phase B: 函数特化 / Partial Evaluation

  • 为每个函数生成原生 double workerdouble fib_worker_native(ptr interp, double n)
  • 自递归直接传 double 参数,完全消除 TzdValue arg array 分配、rt_init_tzd_valuert_store_native_to_ptrrt_to_double_fast
  • baseName 提取支持 _worker_native 后缀(14 字符)+ 版本号剥离

Phase C: LLVM 内联优化

  • AlwaysInline 属性标记 native worker
  • AlwaysInlinerPass(模块级 pass)内联自递归和跨函数调用
  • mem2reg + EarlyCSE + DCE 函数级优化

Phase D: 直接调度 + 整数取模

  • s_compiledNativeWorkers 编译时映射表,跳过 rt_call_sub_fast 字符串查找
  • % 运算自适应整数特化:FPToSI + SRem(单指令 idiv)替代 fmod(库调用)

Phase E: 相等性快速路径 + clock 修复

  • visitEqualityExpr 原生 double 快速路径:==!= 直接 CreateFCmpOEQ/ONE,消除 2 次堆分配 + 4 次外部调用
  • clock() 静态初始化顺序修复
  • AlwaysInlinerPass 从 CGSCC 改为模块级(修复 API 不匹配)
  • 数组索引 visitIndexExpr 始终返回 TzdValue* 指针(修复对象数组 bug)
  • visitVarDeclStmt 使用 CreateEntryBlockAlloca(使 mem2reg 可提升数值局部变量)

Phase F: 对象操作优化

  • rt_tzd_get_member + rt_to_double_fast 标记 ReadOnly 属性,LLVM CSE/LICM 消除循环中冗余字段读取
  • rt_store_field_ptr 轻量字段存储(拆分自 rt_tzd_store_member,配合 readonly get_member 可被 CSE)
  • rt_tzd_call_method 标记 NoCallback + WillReturn
  • visitNewExpr 跳过 rt_set_location 调试开销
  • 数组指针存储修复(arr[i] = object 使用 boxed 路径)

JIT 架构概览

TzdLang 脚本
    │
    ▼
ANTLR4 解析 → AST
    │
    ▼
TzdCompiler (AST → LLVM IR)
    ├── 每个函数生成 3 个版本:
    │   1. Entry function (void entry(ptr interp, ptr retVal)) — 供 C++ 解释器调用
    │   2. Worker function (double worker(ptr, ptr, ptr)) — 正常执行
    │   3. Native worker (double worker_native(ptr, double...)) — 原生 double 自递归
    │
    ▼
LLVM 优化管线
    ├── AlwaysInlinerPass (模块级 — 内联 AlwaysInline 函数)
    ├── PromotePass (mem2reg — alloca → SSA 寄存器)
    ├── EarlyCSEPass (公共子表达式消除 — 利用 ReadOnly 属性)
    └── DCEPass (死代码消除)
    │
    ▼
LLVM IR → 目标代码 (预编译为 .obj 避免 CRT 析构栈溢出)
    │
    ▼
JIT 执行 (LLJIT + ObjectLayer)

关键设计决策

  1. 预编译方式:IR → Object file(泄漏 Module 避免 CRT ABI 不匹配的析构栈溢出)
  2. 分析管理器泄漏ModuleAnalysisManager 等析构会栈溢出,故泄漏为 static 堆对象
  3. NoInline on Worker:正常 worker 标记 NoInline 防止过度内联;native worker 标记 AlwaysInline
  4. Native worker 仅在 argCount > 0 时创建:0 参数函数无特化收益
  5. 栈大小 256MB/STACK:"268435456" 应对深度递归

使用场景

  • 脚本开发
  • 教育和演示
  • 性能测试
  • 原型开发
  • 语言研究

许可证

[在此添加许可证信息]

贡献指南

  1. Fork 项目
  2. 创建功能分支
  3. 提交更改
  4. 发起 Pull Request

支持

如有问题或建议,请提交 Issue 或联系开发者。


TzdLang - 现代化的编程语言开发工具链

About

TzdTools is a development toolkit for the custom programming language TzdLang, including a language interpreter, VSCode extension support, and a rich standard library.

Resources

Stars

7 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages