内容
# AdvPP - 编译器 AdvPL/TLPP(使用 Go 语言)
AdvPL 和 TLPP 编程语言的全功能编译器和解释器,使用 Go 语言构建。
## 功能
- **词法分析器**:完整的 AdvPL/TLPP 语法标记器,包括关键字、运算符、代码块和预处理器指令
- **预处理器**:处理 `#include`、`#define`(包括多行)、`#ifdef`/`#ifndef`/`#else`/`#endif`,以及 `#xCommand`/`#command`/`#xTranslate`/`#translate`,具有实际的模式匹配(`<name>` 标记,可选子句 `[...]`,标志 `[<name:LITERAL>]`,结果为 `<{name}>`/`<.name.>`)
- **解析器**:完整的递归下降解析器,生成抽象语法树(AST)
- **编译器**:生成具有 88 条指令的优化字节码
- **字节码序列化**:将编译后的字节码保存到磁盘上,以便后续执行
- **独立可执行文件**:使用 go:embed 构建具有嵌入式字节码的自包含可执行文件
- **虚拟机**:具有所有指令实现的完整虚拟机
- **运行时**:本机函数(ConOut、MsgInfo、AllTrim、Str、Val、aAdd、aScan、Len 等)
- **图形 IDE**:使用 Fyne 的图形开发环境,具有代码编辑器、文件浏览器和集成编译器
- **UI 框架**:使用 Fyne 的图形应用程序(对话框、表单、网格、按钮、菜单)
- **数据库**:基于 Workarea 的数据库操作(DbSelectArea、DbSeek、DbSkip、RecLock 等)
- **类**:具有 Data/Method/Constructor 的完整类系统,支持 `from` 继承
- **代码块**:可执行代码块 `{|| ... }`
- **MVC**:支持 FWFormModel、FWFormView、FWFormBrowse,具有字段验证和事件处理
- **多线程**:`StartJob()`(在隔离的虚拟机中执行,具有工作进程语义)和 `FWGridProcess`(具有 `SetThreadGrid`、`CallExecute`、`StopExecute`、`IsFinished`、度量和日志的线程池);`advplc check arq1 arq2 ...` 并行检查多个文件
- **Web 渲染器(PO-UI)**:`advplc serve programa.prw` 在服务器上执行程序,并使用 PO-UI(嵌入二进制文件)在浏览器中渲染界面:实时控制台和对话框,`FWMBrowse`→`po-table`,具有 SX3 词典,`po-dynamic-form` 表单,遗留 MSDIALOG(`@ SAY/GET/BUTTON`)作为模态对话框,通过网格启发式
- **LLM 推理引擎**(`pkg/llm` + `LLM` 类):加载 GGUF 量化模型(I2_S 比特网络/Falcon3-1.58bit),并直接从 AdvPL/TLPP 生成文本 - 100% Go,无 CGO,具有 amd64 上的 AVX2 SIMD 内核和任何其他架构上的标量后备
- **MCP 服务器**(`pkg/mcp` + `MCPServer` 类):将 AdvPL/TLPP 函数作为真实 MCP 服务器的“工具”(JSON-RPC 2.0 via stdio)- 有效,与官方 MCP SDK 验证
## MCP 服务器(`MCPServer`)
```advpl
User Function McpDemo()
Local oMCP := MCPServer():New("my-server", "1.0.0")
oMCP:AddTool("sum", "Sum two numbers", ;
'{"type":"object","properties":{"a":{"type":"number"},"b":{"type":"number"}},"required":["a","b"]}', ;
"ToolSum")
oMCP:Serve() // 阻塞读取/写入 stdin/stdout
Return
User Function ToolSum(oArgs)
Return cValToChar(oArgs:A + oArgs:B)
```
正常运行 `advplc run my_program.prw` - 不需要新命令。不同于 REST 支持(`WSRESTFUL`/`@Get`/`@Post`),它今天只识别语法并丢弃(没有 HTTP 服务器或实际调度),`MCPServer` **有效**:在纯 Go 中实现 MCP 协议(JSON-RPC 2.0 via stdio)- 无 CGO,无外部依赖。每个调用的工具都在隔离的虚拟机中运行相应的 AdvPL 函数(与 `StartJob` 相同的机制)。
| 方法 | 描述 |
| --- | --- |
| `New(cName, cVersion)` | 创建服务器 |
| `AddTool(cName, cDescription, cJsonSchema, cFunctionName)` | 注册工具;函数接收具有参数的对象 (`oArgs:Field`) 并返回结果文本 |
| `Serve()` | 启动 stdio 循环(阻塞) |
使用官方 MCP Python SDK 验证(`cmd/advplc/mcp_integration_test.go`)。
## LLM 推理引擎(`LLM`)
```advpl
User Function LlmDemo()
Local oLLM := LLM():New("/path/to/Falcon3-3B-Instruct-1.58bit/ggml-model-i2_s.gguf")
ConOut(oLLM:Generate("The capital of France is", 6, 0)) // 提示,nMaxTokens,nTemperature(0=贪婪)
oLLM:Close()
Return
```
用于 **量化 GGUF 模型(I2_S)** 的推理引擎(权重三值 -1/0/+1,BitNet 和 Falcon3-3B-Instruct-1.58bit 等使用的格式)- 完全用 Go 编写(`pkg/llm`),无 `llama.cpp`,无 CGO 和外部依赖。在 Linux、Windows 和 macOS(amd64/arm64)上编译和运行完全相同;在 amd64 上使用 SIMD 内核(AVX2),在任何其他 CPU/架构上使用标量后备。
`LLM` 类的方法:
| 方法 | 描述 |
| --- | --- |
| `New(cGGUFPath)` | 加载模型和分词器 |
| `Generate(cPrompt, nMaxTokens, nTemperature)` | 生成文本(阻塞直到完成;`nTemperature<=0` = 贪婪) |
| `Tokenize(cText)` | 返回 token ID 数组 |
| `Decode(aTokens)` | 将 token ID 转换回文本 |
| `Close()` | 释放模型 |
与参考 `llama.cpp` 进行 **token-to-token** 验证(参见 `pkg/llm/validate_test.go`)。限制:仅支持 GGUF 架构 `"llama"`,权重为 I2_S;无流式传输(参见 CHANGELOG 获取完整列表)。
## Web 渲染器(`advplc serve`)
```bash
advplc serve tests/mvc_browse_test.prw # http://localhost:8080
advplc serve program.prw --port 9000 --watch # 自定义端口 + 热重载
```
AdvPL/TLPP 程序在服务器的虚拟机中运行(与所有工具共用相同的 `ADVPP.db` 数据库),浏览器作为界面终端 - 与 SmartClient HTML 相同。PO-UI/Angular 前端嵌入二进制文件中(`embed.FS`):生产环境中无额外依赖。
- `ConOut` → 实时控制台(SSE)
- `MsgYesNo`/`MsgInfo`/ ... → 阻塞 VM 直到响应的 PO-UI 对话框
- `FWMBrowse` 在别名上 → 具有 SX3 列标题和 CRUD 的 `po-table`(生成的 `po-dynamic-form`,默认软删除)
- `DEFINE MSDIALOG` + `@ line,column SAY/GET/BUTTON` → PO-UI 模态对话框;输入的值返回到程序变量
- `--watch`:保存源代码时重新编译并重新加载浏览器
要修改前端:`make web`(需要 Node 20+;编译结果已版本化,因此 `go build` 无需 Node)。
## MVC 框架
AdvPP 编译器包含一个完整的 MVC(模型-视图-控制器)框架,用于构建结构化应用程序:
### MVC 组件
**FWFormModel** - 具有字段定义和验证的数据模型:
```advpl
oModel := FWFormModel("CustomerModel")
```
**FWFormView** - 具有组件和事件处理的表单视图:
```advpl
oView := FWFormView("CustomerView", oModel)
```
**FWFormBrowse** - 用于数据展示的网格/浏览组件:
```advpl
oBrowse := FWFormBrowse("CustomerBrowse", oModel)
```
### 资源
- 字段验证(必填、长度、区间、自定义)
- 事件处理(onChange、onClick、onGotFocus、onLostFocus)
- **Fyne 小部件完整渲染**(TButton、TGet、TComboBox、TCheckBox、TLabel)
- 具有视觉渲染的组件数据结构
- 对话框支持(对话框、菜单、工具栏、状态栏)
- 浏览事件(onLineChange、onDbClick、onHeaderClick)
**注意**:UI 组件现在使用 Fyne 可视化渲染。事件处理程序已定义,但尚未连接到用户操作。
### 示例
```advpl
User Function MVCTest()
Local oModel := FWFormModel("CustomerModel")
Local oView := FWFormView("CustomerView", oModel)
Local oBrowse := FWFormBrowse("CustomerBrowse", oModel)
// 使用 MVC 组件...
Return .T.
```
## 编译
```bash
# 编译所有工具(advplc、advcfg、adveditor、advpp-ide)
make build
# 运行测试(构建 + 测试所有测试夹具)
make test
# 为 Linux/Windows/macOS(amd64 和 arm64)交叉编译 CLI 到 dist/
make cross
# 在 dist/ 中生成版本化软件包(.tar.gz/.zip)
make package VERSION=1.1.0
```
### 在 GitHub 上发布新版本
```bash
make release VERSION=1.1.0
```
这会创建并发布标签 `v1.1.0`。然后 GitHub Actions 会编译 **本地** 的 Linux、Windows 和 macOS(包括 Fyne GUI),生成软件包(`.tar.gz`、`.zip`、`.deb`)并自动将所有内容附加到 Release 中。
## 共享数据库
所有工具(advplc、advcfg、adveditor、advpp-ide)都可以访问 **相同** 的 SQLite 数据库,按以下顺序解析:
1. 显式标志 (`advplc run prog.prw --db-path /path/to/bank.db`)
2. 环境变量 `ADVPP_DB`
3. `~/.advpp/advpp_config.json` 中配置的数据库
4. 默认:`~/.advpp/ADVPP.db`(由 advcfg 自动创建)
SQLite 驱动程序是 100% Go(modernc.org/sqlite)- 无 CGO,无外部依赖,在 Linux、Windows 和 macOS 上相同。
## 用法
### 命令行编译器
```bash
# 执行 AdvPL/TLPP 源文件(在内存中编译并执行)
./advplc run program.prw
# 将源文件编译为字节码文件
./advplc compile program.prw -o program.bytecode
# 执行编译后的字节码文件
./advplc exec program.bytecode
# 构建独立可执行文件(嵌入字节码和运行时)
./advplc build program.prw -o program
# 仅检查语法
./advplc check program.prw
# 打印 AST 结构
./advplc ast program.prw
# 打印字节码
./advplc bytecode program.prw
```
### 图形 IDE
```bash
# 启动图形开发环境
./advpp-ide
```
图形 IDE 提供:
- **代码编辑器**:具有多行支持的文本编辑器,适用于 .prw、.tlpp 和 .prg 文件
- **文件操作**:新建、打开、保存、另存为功能
- **项目浏览器**:显示当前目录的文件浏览器,突出显示源文件
- **构建集成**:编译、运行和编译并运行命令
- **输出控制台**:显示编译结果和程序输出
- **对话框支持**:MsgInfo、MsgStop、MsgAlert 和 MsgYesNo 函数显示 Fyne 对话框
- **100% 兼容性**:所有 MVC 组件、UI 渲染和功能在 IDE 中完美运行
## 语言支持
### AdvPL 功能
- User Function、Static Function、Function 声明
- 变量作用域:Local、Private、Public、Static
- If/ElseIf/Else/EndIf、For/Next、While/EndDo、Do Case/EndCase
- 错误处理:Begin Sequence/Recover/End Sequence
- 代码块 `{|| expr }`
- Class/EndClass,具有 Data、Method、Constructor
- 实现类外部的方法
- 别名字段访问 `SA1->A1_NAME`
- 自引用 `::property`
- 所有 AdvPL 数据类型:Character、Numeric、Logical、Date、Array、Code Block、Nil、Object
### TLPP 附加功能
- 使用 `as` 关键字进行静态类型定义
- Try/Catch/EndTry 错误处理
- 命名空间声明
- 访问修饰符(Public、Private、Protected)
- REST 注解(@Get、@Post、@Put、@Delete)- 仅解析
- 内联 JSON 支持,具有 JsonObject 方法
- 标识符长(具有命名空间)
- 整数、双精度、十进制、变体、变长参数类型
- WSRESTFUL/WSSERVICE 语法解析
**注意**:REST 注解和 WSRESTFUL 语法被解析但不执行。需要 HTTP 服务器集成才能执行 REST 端点。