Paper6 Paper6
v6.0.0
「最简单的动态,最片面的全面,最可开发的」
让 Win32 编程像在纸上画一样简单

📦 下载

📖 第一章:编译流程与主要用途

1.1 编译流程(7步管线)

Paper6 采用翻译型编译架构,源码经以下7步处理生成原生 Windows EXE:

// 步骤1:读取源码
// 步骤2:词法分析(Tokenize)
// 步骤3:语法分析(Parse → AST)
// 步骤4:加载标准库(pslib)
// 步骤5:代码生成(产出 C++ 代码)
// 步骤6:编译(调用 g++)
// 步骤7:清理临时文件

1.2 主要用途

Paper6 是一门面向 Windows 桌面开发的Transcompiler(翻译编译器),专门针对 Win32 GUI 开发设计:

📖 第二章:pslib 与 paper

2.1 pslib 标准库系统

pslib 是 Paper6 的标准库系统,采用纯文本文件组织,由 PslibBootloader 在编译期加载:

可用 .pslib 模块:

normal.pslib       // 常用库合集
win32.pslib        // Win32 API 封装
io.pslib           // 输入输出
math.pslib / math2.pslib   // 数学运算
string.pslib / text.pslib  // 字符串处理
array.pslib / list.pslib / dict.pslib
set.pslib / queue.pslib / stack.pslib
container.pslib / tree.pslib
file.pslib         // 文件系统
color.pslib        // 颜色处理
time.pslib         // 时间日期
json.pslib         // JSON 解析
regex.pslib        // 正则表达式
crypto.pslib       // 加密
http.pslib         // HTTP 请求
system.pslib       // 系统信息
numeric.pslib      // 数值工具
log.pslib          // 日志

2.2 paper 块声明式语法

paper 块是 Paper6 的核心特色,用于声明式描述 Win32 窗口和控件:

paper MyWindow {
    title = "我的窗口";
    width = 400;
    height = 300;
    icon = "icon/Paper6.ico";

    button btnOk {
        text = "确定";
        x = 10; y = 10; w = 80; h = 30;
        onClick() {
            alert("确定了!");
        }
    }
}

编译器自动将 paper 块翻译成等效的 C++ Win32 API 调用代码。

📖 第三章:变量与循环

3.1 变量声明

var x = 10          // 动态类型,运行时决定
let y = "hello"      // 可变的变量
const z = 3.14       // 常量,不可修改

3.2 数据类型

value  x = 100      // 动态类型
int    n = 42        // 整数
double pi = 3.14159 // 浮点数
string s = "Hello"  // 字符串
bool   b = true      // 布尔值

3.3 赋值与算术

x = x + 1           // 普通赋值
x += 1              // 复合赋值
result = a + b       // 算术运算

3.4 for 循环

for (int i in [0..10]) {
    alert(i);
}

for (item in myArray) {
    process(item);
}

3.5 while 循环

while (running) {
    update();
}

3.6 .all 批量操作

// 批量赋值
nums.all = 1

// 基于当前元素赋值
nums.all = this * 2

// 批量属性赋值
labels.all.text = "Hi"

// 批量方法调用
vec.all.show()

3.7 数组操作

// 数组创建
arr = {1, 2, 3}

// 下标访问
first = arr[0]

// 列表推导式
squares = [x*x for x in [1..10]]

📖 第五章:特性和语法糖

5.1 .all 批量操作

.all 是循环构造,将循环起点标记在 .all 处,后续表达式逐元素执行:

nums.all = 1               // for(int i=0; i<nums.size(); i++) nums[i] = 1;
nums.all = this * 2         // nums[i] = nums[i] * 2;
labels.all.text = "Hi"     // labels[i].text = "Hi";
.all 规则:
· .all 不能做右值(右侧出现 .all 直接报错)
· this/serial/index 只能在 .all 语句内使用
· 对 const 容器执行 .all 赋值报错

5.2 列表推导式

[x*x for x in [1..10]]
[x for x in [0..100] where x % 2 == 0]
[[x,y] for x in [1..3], y in [1..3]]

返回列表推导式是立即执行的 lambda,返回一个新数组(临时对象)。

5.3 when 编译期分支

when (x) {
    is int    -> 1;
    is string -> 2;
    else      -> 0;
}

根据 x 的 typeName 在不同分支中选择表达式,最终返回一个 Value。

5.4 therebe / have 编译期查询

therebe(class Student)  // 编译期:Student 类是否存在?
therebe(function foo)   // 编译期:函数 foo 是否已定义?
have(Student, .name)    // 编译期:Student 类是否有 name 字段或方法?

这三个表达式在编译时求值,结果直接替换为 true/false。

5.5 三元表达式

cond ? a : b
x > 0 ? "正数" : "负数"

5.6 链式访问

data.items[0].name
window.children[0].text.length()

📖 第四章:表达式

Paper6 表达式按优先级从低到高排列如下(同一行优先级相同):

4.1 赋值表达式

x = 10                    // 普通赋值
nums.all = 1                // 批量赋值(所有元素赋为 1)
labels.all.text = "Hi"      // 批量属性赋值
vec.all = this + 1            // 基于当前元素赋值
vec.all.show()              // 批量方法调用

4.2 逻辑运算

a && b     // 逻辑与
a || b     // 逻辑或
!a        // 逻辑非

4.3 比较运算

a == b     // 等于
a != b     // 不等于
a < b      // 小于
a > b      // 大于
a <= b     // 小于等于
a >= b     // 大于等于

4.4 算术运算

a + b       // 加(数值相加或字符串拼接)
a - b       // 减
a * b       // 乘
a / b       // 除(整数除法或浮点除法,取决于操作数类型)
a % b       // 取模

4.5 范围运算符

a .. b     // 区间:产生从 a 到 b 的整数序列
[1..5]          // {1, 2, 3, 4, 5}
[1..10, 2]       // {1, 3, 5, 7, 9}(步长为 2)

4.6 一元运算

-a          // 取负
!a          // 逻辑取反

4.7 成员访问与索引

obj.name         // 对象属性访问
arr[0]            // 容器下标访问
obj.method()       // 方法调用

4.8 函数调用

alert("hello")         // Win32 消息框
len(s)                 // 标准库函数
obj.method(args)       // 对象方法
ClassName{field=value}  // 对象构造表达式

4.9 字面量表达式

100              // 整数字面量
3.14             // 浮点数字面量
"hello"          // 字符串字面量
#FF0000          // 颜色字面量
true / false     // 布尔字面量
null             // 空值字面量

4.10 数组字面量

{1, 2, 3}              // 普通数组
{"a", "b", "c"}           // 字符串数组
{key: "value"}          // 映射字面量

📖 第六章:其他

6.1 函数定义

function greet(string name) value {
    return "Hello, " + name;
}

function add(int a, int b) int {
    return a + b;
}

6.2 脚本块

脚本块定义函数和事件处理器的作用域:

main.script {
    function onShow() {
        alert("窗口已显示");
    }

    function onClick() {
        alert("按钮被点击");
    }
}

6.3 import / using 机制

import "pslib/win32.pslib";    // 导入后直接使用,无命名空间
using math = "pslib/math.pslib";  // 导入后以别名访问

6.4 defer / expect

defer {
    cleanup();  // 函数退出时自动执行
}

expect (x != null, "x 不能为空");  // 条件断言,失败则抛出异常

6.5 错误处理

try {
    riskyOperation();
} catch (e) {
    alert("错误: " + e);
}

throw "出错了!";

6.6 类型判断 is()

is(x, int)           // 判断 x 的类型名是否为 "int"
is(x, Student)       // 判断 x 是否为 Student 类的实例
is(x, class)          // 判断 x 是否为某个类实例

📖 第七章:类与 able 接口

7.1 类定义

class Student {
    string name;
    int age;

    Student(string n, int a) {
        name = n;
        age = a;
    }

    function getInfo() string {
        return name + "," + age;
    }
}

7.2 able 接口

able Printable {
    function print() void;
}

class Student able Printable {
    string name;
    Student(string n) { name = n; }
    function print() void {
        alert(name);
    }
}

7.3 对象构造

var s = Student{name: "张三", age: 18};
var t = new Student("李四", 20);

📖 第八章:Paper 块(GUI 声明式语法)

Paper6 的核心特色:用声明式语法描述 Win32 窗口与控件,编译器自动翻译成 C++ Win32 API 调用。

8.1 基本窗口结构

paper MyWindow {
    title = "我的窗口";
    width = 400;
    height = 300;
    icon = "icon/Paper6.ico";

    button btnOk {
        text = "确定";
        x = 10; y = 10; w = 80; h = 30;
        onClick() {
            alert("确定了!");
        }
    }

    text lblMsg {
        text = "Hello Paper6";
        x = 100; y = 10; w = 200; h = 30;
    }
}

8.2 内置控件类型

支持 button、text、entry(单行输入)、textarea(多行)、checkbox、radio、combobox、listbox、slider、progress、panel、group、tab、canvas、picture、menu、timer、window。

8.3 控件属性

text    = "显示文本"
x       = 10        // 左上角 X 坐标
y       = 20        // 左上角 Y 坐标
w       = 100       // 宽度
h       = 30        // 高度
color   = #FF0000    // 前景色
background = #FFFFFF // 背景色
font    = "LXGWenKaiMono, 12"

📖 第九章:纸片化开发

9.1 什么是纸片化?

Paper6 的"纸片化"理念:像剪纸一样,把 UI 布局从代码中剥离出来,用声明式语法描述界面,逻辑与表现分离。

// 传统 Win32:写几百行 C++ 才能建一个窗口
// Paper6:几行 paper 块搞定一切

paper MainWindow {
    title = "我的应用";
    width = 600;
    height = 400;

    button btnClose {
        text = "关闭";
        x = 500; y = 350; w = 80; h = 30;
        onClick() {
            postQuitMessage();
        }
    }
}

9.2 逻辑与表现分离

paper 块只负责声明界面结构和事件绑定,具体逻辑写在 `script` 块或函数中:

paper Calculator {
    entry display {
        x = 10; y = 10; w = 280; h = 40;
        text = "0";
    }

    button btn1 {
        text = "1";
        x = 10; y = 60; w = 70; h = 40;
        onClick() { appendDigit("1"); }
    }
}

Calculator.script {
    value current = "0";

    function appendDigit(string d) {
        if (current == "0") current = d;
        else current = current + d;
        display.text = current;
    }
}

📖 第十章:调试与部署

10.1 调试模式

paper6c.exe hello.paper --debug --keep-cpp

--debug 生成调试辅助代码(断点、日志),--keep-cpp 保留生成的中间 C++ 文件便于排查问题。

10.2 生成中间文件位置

编译时生成的 C++ 中间文件位于源码目录下的 code_generation/ 子目录中,包含 main.cpp 和 import.hpp。

10.3 部署

Paper6 编译器自带便携工具链,生成的 EXE 仅依赖 Win32 系统库,无需额外安装运行环境:

10.4 性能优化建议

· 频繁使用的数值计算优先使用 int/double 而非 value

· 大数组操作考虑使用 container 而非 array

· 编译时添加 -Og 优化级别(已默认开启)

📖 第十一章:进阶特性

11.1 CPP 块——嵌入原生 C++

当 Paper6 语法无法满足需求时,可使用 cpp 块直接嵌入 C++ 代码:

cpp {
    // 原生 C++ 代码,直接编译
    std::cout << "Hello from C++!" << std::endl;
    MessageBoxW(NULL, "原生弹窗", "CPP块", MB_OK);
}

CSS 规则:

11.2 泛型支持

typename T;

function identity(T x) T {
    return x;
}

使用 typename T 声明泛型参数,编译器在实例化时生成对应特化版本。

11.3 宏(Macro)

macro LOOP_N(n) {
    for (int i = 0; i < n; i++) {
        yield;
    }
}

宏在预处理阶段展开,适合生成重复代码模式。

❓ 第十二章:常见问题

Q: 编译时提示 "file not found"?

确保 .paper 文件路径正确,或使用相对于 paper6c.exe 的路径。

Q: 中文显示乱码?

Paper6 自动处理 UTF-8 → GBK 转换。检查 .paper 文件是否保存为 UTF-8 编码。

Q: 如何嵌入图标?

将 .ico 文件放入项目目录,在 paper 块中指定 icon = "icon/Paper6.ico";

Q: 标准库函数在哪里?

pslib/ 目录下,每个 .pslib 文件对应一个功能模块。

Q: value 和 int 有什么区别?

value 是动态类型,运行时根据 typeName 决定含义;int 在编译时确定为整数类型。相同计算结果,int 执行效率更高,value 灵活性更强。

Q: .all 批量操作失败?

确保操作对象是容器类型(array/container),且右侧表达式能作用于单个元素。右侧出现 .all 会报错(.all 不能做右值)。this/serial/index 只能在 .all 语句内使用。

Q: 为什么 vec.all = [x*x for x in [1..10]] 报错?

右侧列表推导式返回数组,而 .all 要求右侧表达式结果与元素类型匹配。如需整体赋值,用 vec = [x*x for x in [1..10]](不带 .all)。

📋 标准类型

Paper6 内建以下类型(来自 TypeSet.hpp):

// 基础类型
value  // 动态类型,运行时决定
int    // 整数
double // 浮点数
string // 字符串
bool   // 布尔

// 集合类型
array    // 数组
container // 容器
map      // 键值映射

// 窗口控件类型
button, text, entry, textarea
checkbox, radio
combobox, listbox
slider, progress, panel, group
tab, canvas, picture, menu
timer, window

// 其他类型
color, font, position, size, rect
cursor, icon

⚙️ 编译命令

// 基础编译
paper6c.exe hello.paper

// 加载标准库
paper6c.exe hello.paper --normal

// 按需加载指定库
paper6c.exe hello.paper --win32 --io --math

// 调试模式(生成断点辅助代码)+ 保留中间 C++ 文件
paper6c.exe hello.paper --debug --keep-cpp

// 查看帮助
paper6c.exe --help
提示:paper6c.exe 会自动从自身所在目录向外搜索 g++ 编译器,支持便携部署,无需安装额外工具链。

📁 项目结构

Paper-6/
├── include/                            // 编译器核心(C++)
│   ├── core/
│   │   ├── common.hpp                  // 公共基础
│   │   ├── token.{hpp,cpp}             // Token 定义
│   │   └── value.{hpp,cpp}             // 动态类型 Value
│   ├── lexer/
│   │   └── lexer.{hpp,cpp}             // 词法分析器
│   ├── parser/
│   │   └── parser.{hpp,cpp}            // 递归下降语法分析器
│   ├── ast/
│   │   └── ast.{hpp,cpp}               // AST 节点定义
│   └── codegen/
│       ├── codegen_core.{hpp,cpp}       // 代码生成核心
│       └── codegen_build.{hpp,cpp}      // 代码生成构建器(GUI 相关)
├── parameter/
│   └── TypeSet.hpp                     // 标准类型集合
├── pslib/                              // 标准库(.pslib 文本文件)
│   ├── PslibBootloader.{hpp,cpp}       // 库引导加载器
│   ├── normal.pslib                    // 常用库合集
│   ├── win32.pslib                     // Win32 API 封装
│   ├── io.pslib                        // 输入输出
│   ├── math.pslib / math2.pslib       // 数学运算
│   ├── string.pslib / text.pslib      // 字符串处理
│   ├── array.pslib / list.pslib / dict.pslib
│   │   / set.pslib / queue.pslib / stack.pslib
│   ├── container.pslib / tree.pslib
│   ├── file.pslib                      // 文件系统
│   ├── color.pslib                     // 颜色处理
│   ├── time.pslib                      // 时间日期
│   ├── json.pslib                      // JSON 解析
│   ├── regex.pslib                     // 正则表达式
│   ├── crypto.pslib                    // 加密
│   ├── http.pslib                      // HTTP 请求
│   ├── system.pslib                    // 系统信息
│   ├── numeric.pslib                   // 数值工具
│   └── log.pslib                       // 日志
├── src/
│   └── main.cpp                        // 编译器入口(7步编译管线)
├── font/
│   └── LXGWWenKaiMono-Medium.ttf       // 默认字体
├── ico/
│   └── Paper6.ico                      // 应用图标
├── tools zips/                         // 便携工具链(压缩分卷,解压后含 g++)
│   ├── tools.7z.001 ~ tools.7z.006
├── paper6c.exe                         // 已编译的编译器可执行文件
├── resource.o                          // Windows 图标资源(预编译)
├── resource.rc                         // 资源脚本
├── index.html                          // 项目主页
└── Paper6 语法大清单.txt                // 语法速查文档

📎 附录:源码下载

源码文件清单

点击上方「下载全部项目文件」按钮可一次性打包下载所有源码与资源。以下列表供单独下载单个文件使用。

完整文件列表(按目录分组)

include/ 各模块独立下载

src/main.cpp

编译器入口文件,实现 7 步编译管线:

parameter/TypeSet.hpp

pslib/ 标准库