文档与readme更新

This commit is contained in:
2026-02-01 13:59:20 +08:00
parent ca4ae143b4
commit 61bffdc743
11 changed files with 1214 additions and 69 deletions

24
docs/zh_CN/01-简介.md Normal file
View File

@@ -0,0 +1,24 @@
# Fig 语言简介
## 概述
Fig 是一门动态类型、解释执行的编程语言,专注于简洁语法和实用的语言特性。它采用树遍历解释器架构,支持多种编程范式。
## 实际观察到的特性
1. **解释执行**:基于 AST 的树遍历解释器,无编译步骤
2. **动态类型系统**:运行时类型检查,支持类型注解但不强制
3. **混合范式**:支持函数式、面向对象和命令式风格
4. **模块系统**:支持代码组织和复用
5. **内置类型**:整数、浮点数、字符串、列表、映射等
6. **垃圾回收**:基于引用计数的自动内存管理
## 语言设计特点
- **渐进类型**:支持类型注解但不强制,兼顾灵活性和可读性
- **一等公民函数**:函数可以作为参数传递和返回
- **闭包支持**:完整的词法作用域和闭包
- **错误处理**:异常机制和 try-catch 结构
- **可变与不可变**const/var 区分,平衡安全与灵活
## 目标应用场景
- 脚本编写和自动化任务
- 教育用途和学习编程
- 配置语言和DSL

View File

@@ -0,0 +1,82 @@
# 快速开始
## 运行 Fig 程序
Fig 语言通过解释器直接执行源代码文件。基本执行命令如下:
`./Fig 你的脚本.fig`
### 查看帮助和版本
显示帮助信息:
`./Fig -h``./Fig --help`
显示版本信息:
`./Fig -v``./Fig --version`
### 示例
创建一个名为 `hello.fig` 的文件,内容为:
```go
import std.io;
io.println("Hello, Fig!");
```
在终端中运行:
`./Fig hello.fig`
你会看到输出:`Hello, Fig!`
## 程序示例
### 简单表达式程序
Fig 程序可以只包含表达式:
```go
1 + 2 * 3
```
运行此程序会输出计算结果 `7`
### 带变量的程序
```go
var x = 10;
var y = x * 2;
y + 5
```
运行输出 `25`
## 错误处理
当源代码有语法或类型错误时,解释器会显示详细的错误信息。例如:
```rust
An error occurred! Fig 0.4.2-alpha (2026-01-23 01:30:46)[llvm-mingw 64 bit on `Windows`]
TypeError: Variable `x` expects init-value type `Int`, but got 'Double'
at 1:14 in file 'your_file.fig'
var x: Int = 3.14;
^
```
错误信息包括:
- 错误类型和描述
- 发生错误的文件和位置
- 相关的堆栈跟踪信息
## 运行流程
1. **编写代码**:使用任何文本编辑器创建 `.fig` 文件
2. **保存文件**:确保文件扩展名为 `.fig`
3. **执行程序**:在终端中运行 `./Fig 文件名.fig`
4. **查看结果**:程序输出显示在终端中
5. **调试错误**:根据错误信息修改代码
## 注意事项
- Fig 源文件必须使用 UTF-8 编码
- 语句通常以分号结束,但程序最后一条表达式可以省略分号
- 文件路径可以包含空格,但建议使用引号包裹:`./Fig "my script.fig"`

View File

@@ -0,0 +1,213 @@
# 基础语法
## 注释
Fig 支持两种注释格式:
单行注释:
```go
// 这是一个单行注释
var x = 10; // 注释可以在语句后面
```
多行注释:
```go
/* 这是一个
多行注释 */
/* 注释内可以有 // 嵌套的单行注释 */
```
注释不能嵌套多个多行注释:`/* /* 嵌套 */ */` 会导致错误。
## 变量声明
### 可变变量
```go
var name = "Fig";
var count = 0;
count = count + 1; // 可以重新赋值
```
### 常量
```go
const PI = 3.14159;
const MAX_SIZE = 100;
// PI = 3.14; // 错误:常量不能重新赋值
```
常量必须在声明时初始化。
### 类型注解(可选)
```go
var name: String = "Fig";
var age: Int = 14;
const VERSION: Double = 0.4;
```
类型注解提供额外的类型信息,但解释器会在运行时进行类型检查。
## 标识符命名
### 规则
- 可以包含字母、数字和下划线
- 不能以数字开头
- 区分大小写
- 支持 Unicode 字符
### 有效示例
```go
var count = 0;
var user_name = "Alice";
var 计数器 = 0; // 中文标识符
var π = 3.14159; // Unicode 符号
var _private = true; // 以下划线开头
```
### 无效示例
```
var 123abc = 0; // 不能以数字开头
var my-var = 0; // 不能包含连字符
```
## 基本字面量
### 数字
```go
// 整数
var a = 42; // 十进制
var b = -100; // 负数
var c = 0; // 零
// 浮点数
var d = 3.14;
var e = 1.0;
var f = -0.5;
var g = 1.23e-10; // 科学计数法
```
### 字符串
```go
var s1 = "Hello";
var s2 = "World";
var s3 = "包含\"引号\"的字符串"; // 转义引号
var s4 = "第一行\n第二行"; // 转义换行符
```
多行字符串直接跨行书写:
```rust
var message = "这是一个
多行字符串
可以包含多行内容";
```
### 布尔值
```go
var yes = true;
var no = false;
```
### 空值
```dart
var nothing = null;
```
## 分号使用
所有语句都必须以分号结束:
```go
var x = 10; // 正确
var y = 20 // 错误:缺少分号
func add(a, b) {
return a + b; // return 语句需要分号
} // 函数体右花括号后不需要分号
```
表达式作为独立语句时也需要分号:
```go
1 + 2 * 3; // 表达式语句需要分号
io.println("test"); // 函数调用语句需要分号
```
## 表达式与语句
### 表达式
表达式会产生一个值(包括 `null`
```go
1 + 2 // 值为 3
x * y // 值为乘积
funcCall(arg) // 值为函数返回值
```
### 语句
语句执行操作但不产生值:
```go
var x = 10; // 声明语句
if condition {} // 条件语句
return value; // 返回语句
```
表达式可以作为语句使用(表达式语句):
```go
1 + 2; // 计算但丢弃结果
io.println("hi"); // 函数调用作为语句
```
## 关键字
Fig 语言的关键字包括:
| 类别 | 关键字 |
| -------- | ----------------------------------------------------------- |
| 声明 | `func`, `var`, `const`, `struct`, `interface`, `import` |
| 控制流 | `if`, `else`, `while`, `for`, `return`, `break`, `continue` |
| 错误处理 | `try`, `catch`, `throw`, `Finally` |
| 逻辑运算 | `and`, `or`, `not` |
| 类型相关 | `is`, `impl`, `new`, `public` |
这些关键字不能用作标识符名称。
## 操作符
### 算术运算符
`+`, `-`, `*`, `/`, `%`, `**`(幂运算)
### 比较运算符
`==`, `!=`, `<`, `>`, `<=`, `>=`
### 逻辑运算符
`and`, `or`, `not`, `&&`, `||`, `!`
### 位运算符
`&`, `|`, `^`, `~`, `<<`, `>>`
### 赋值运算符
`=`, `:=`, `+=`, `-=`, `*=`, `/=`, `%=`, `^=`
### 其他运算符
`.`(成员访问), `?`(三元运算), `...`(可变参数), `->`(箭头), `=>`(双箭头)
## 空白字符
Fig 对空白字符没有特殊要求:
- 空格和制表符可以互换使用
- 缩进不影响程序语义
- 操作符周围的空格是可选的(但建议添加以提高可读性)
## 代码示例
```go
// 完整的程序示例
import std.io;
func calculate(a: Int, b: Int) -> Int {
var result = a * b;
return result + 10;
}
const x = 5;
const y = 3;
var answer = calculate(x, y);
io.println("结果是:" + answer.toString());
```

View File

@@ -0,0 +1,156 @@
# 数据类型
## 类型系统
Fig 语言是动态类型语言,运行时进行类型检查。
## 基本类型
### Null 类型
表示空值,只有一个值 `null`
```dart
var a = null;
```
### Int 类型
64位有符号整数。
```go
var x = 42;
var y = -100;
```
### Double 类型
双精度浮点数。
```go
var pi = 3.14;
var speed = 2.998e8;
```
### String 类型
字符串。
```go
var s1 = "Hello";
```
### Bool 类型
布尔值,`true``false`
```go
var yes = true;
var no = false;
```
## 复合类型
### List 类型
有序集合。
```go
var list = [1, 2, 3];
var mixed = [1, "text", true];
```
可以通过 **length()** 方法获取长度返回Int
通过 **get()** 方法获取指定下标不存在的下标返回null
### Map 类型
键值对集合。
```go
var map = {"key": "value", "num": 42};
```
通过 **get()** 方法获取指定下标,不存在的下标返回 `null`
### Function 类型
函数。
```go
var f = func(x, y) { return x + y; };
```
## 自定义类型
### 结构体定义
```rust
struct Person {
name: String;
age: Int;
}
```
默认字段为私有,如需声明为外部可见的字段,使用 public关键字
```go
struct Person {
public name: String;
public age: Int;
public func greeting()
{
io.println("hello!");
}
}
```
### 创建实例
使用 `new` 关键字:
```go
var p = new Person {name: "Alice", age: 20};
```
支持三种初始化方式:
1. 命名参数:`new Person {name: "Alice", age: 20}`
2. 位置参数:`new Person {"Alice", 20}`
3. 简写方式:`new Person {name, age}`(使用同名变量)
## 类型操作
### 类型检查
使用 `is` 运算符:
```go
var x = "hello";
io.println(x is String); // true
var p = new Person {name: "Alice", age: 20};
io.println(p is Person); // true
```
### 获取类型
使用 `value.type()` 函数(获取内部类型)
```go
import std.value;
var num = 42;
var str = "hello";
var lst = [1, 2, 3];
io.println(value.type(num)); // 获取 num 的类型
io.println(value.type(str)); // 获取 str 的类型
io.println(value.type(lst)); // 获取 lst 的类型
```
## 类型转换
### 转换函数
通过 `std.value` 模块:
```go
import std.value;
var str = value.string_from(42); // "42"
var num = value.int_parse("123"); // 123
var dbl = value.double_parse("3.14"); // 3.14
```
## 错误处理
### try-catch 语法
```rust
try
{
// 可能抛出异常的代码
}
catch(e: ErrorType)
{
// 处理特定类型的错误
}
catch(e: AnotherError)
{
// 处理另一种错误
}
```

289
docs/zh_CN/05-函数.md Normal file
View File

@@ -0,0 +1,289 @@
# 函数
## 函数定义
### 基本语法
```go
func 函数名(参数列表) -> 返回类型 {
函数体
}
```
### 示例
```go
// 简单函数
func greet() -> Null {
io.println("Hello!");
}
// 带参数的函数
func add(a: Int, b: Int) -> Int {
return a + b;
}
// 省略返回类型(默认为 Any
func say(message: String) {
io.println(message);
// 没有 return返回 null
}
```
## 参数
### 必需参数
```go
func power(base: Double, exponent: Double) -> Double {
return base ** exponent;
}
```
### 默认参数
参数可以指定默认值:
```go
func createPerson(name: String, age: Int = 18) -> Null {
io.println(name + " is " + age + " years old");
}
// 调用
createPerson("Alice"); // 使用默认 age=18
createPerson("Bob", 25); // 指定 age=25
```
### 可变参数
使用 `...` 表示可变参数,接收一个 List
```go
func sum(numbers...) -> Int {
var total = 0;
var i = 0;
for i = 0; i < numbers.length(); i = i + 1 {
total = total + numbers.get(i);
}
return total;
}
// 调用
sum(1, 2, 3); // 返回 6
sum(1, 2, 3, 4, 5); // 返回 15
```
可变参数不支持类型限制,获取到的总是 List 类型。
## 返回值
### 显式返回
使用 `return` 语句返回值:
```go
func max(a: Int, b: Int) -> Int {
if a > b {
return a;
} else {
return b;
}
}
```
### 无返回值
函数如果没有 return 语句,返回 null
```go
func log(message: String) -> Null {
io.println("[LOG] " + message);
// 函数结束,返回 null
}
func process(data: List) {
if data.length() == 0 {
return; // 提前返回 null
}
// 处理数据...
// 函数结束,返回 null
}
```
## 函数作为值
### 函数赋值
函数是一等公民,可以赋值给变量:
```go
var addFunc = func(a: Int, b: Int) -> Int {
return a + b;
};
// 调用
var result = addFunc(3, 4); // result = 7
```
### 函数作为参数
```go
func applyOperation(x: Int, y: Int, op: Function) -> Int {
return op(x, y);
}
func multiply(a: Int, b: Int) -> Int {
return a * b;
}
// 调用
var product = applyOperation(3, 4, multiply); // product = 12
```
### 函数作为返回值
```go
func makeMultiplier(factor: Int) -> Function {
return func(x: Int) -> Int {
return x * factor;
};
}
// 调用
var double = makeMultiplier(2);
var triple = makeMultiplier(3);
io.println(double(5)); // 输出 10
io.println(triple(5)); // 输出 15
```
## 匿名函数
### Lambda 表达式
```go
// 完整形式
var square = func(x: Int) {
return x * x;
};
// 简写形式(单表达式)
var squareShort = func(x: Int) => x * x;
// 调用
io.println(square(5)); // 输出 25
io.println(squareShort(5)); // 输出 25
```
### 立即调用函数表达式
```go
var result = func(x: Int, y: Int){
return x + y;
}(3, 4); // result = 7
```
## 闭包
### 捕获外部变量
函数可以捕获其定义作用域中的变量:
```go
func makeCounter() -> Function {
var count = 0;
return func(){
count = count + 1;
return count;
};
}
// 使用
var counter = makeCounter();
io.println(counter()); // 输出 1
io.println(counter()); // 输出 2
io.println(counter()); // 输出 3
```
每个闭包有自己独立的捕获变量:
```go
var c1 = makeCounter();
var c2 = makeCounter();
io.println(c1()); // 输出 1
io.println(c1()); // 输出 2
io.println(c2()); // 输出 1独立的计数
```
## 递归函数
函数可以调用自身:
```go
func factorial(n: Int) -> Int {
if n <= 1 {
return 1;
}
return n * factorial(n - 1);
}
// 调用
io.println(factorial(5)); // 输出 120
```
### 嵌套函数定义
```go
func outer(x: Int) -> Int {
func inner(y: Int) -> Int {
return y * 2;
}
return inner(x) + 1;
}
// 调用
io.println(outer(10)); // 输出 21
```
## 函数调用
### 普通调用
```go
func calculate(a: Int, b: Int, c: Int) -> Int {
return a + b * c;
}
// 位置参数调用
var result = calculate(1, 2, 3); // 1 + 2*3 = 7
```
### 方法调用语法
对象的方法调用:
```go
var list = [1, 2, 3];
var length = list.length(); // 方法调用
```
## 函数示例
### 实用函数组合
```go
import std.io;
// 高阶函数示例
func compose(f: Function, g: Function) -> Function {
return func(x: Any) -> Any {
return f(g(x));
};
}
// 使用
func addOne(x: Int) -> Int {
return x + 1;
}
func double(x: Int) -> Int {
return x * 2;
}
var addThenDouble = compose(double, addOne);
io.println(addThenDouble(5)); // (5+1)*2 = 12
```
### 回调函数模式
```go
func processData(data: List, callback: Function) -> Null {
var i = 0;
for i = 0; i < data.length(); i = i + 1 {
var result = callback(data.get(i));
io.println("处理结果: " + result);
}
}
// 使用
var numbers = [1, 2, 3, 4, 5];
processData(numbers, func(x){
return x * x;
});
```

View File

@@ -0,0 +1,126 @@
# 面对对象
> Fig中只有结构体(`struct`) 遵循go圣经 组合由于继承 (struct组合尚未推出)
## 结构体定义
完整语法:
```cpp
struct Point
{
public x: Int; // 公开字段
public y: Int; // 公开字段
}
struct Person
{
name: String; // 私有字段,无法被外部访问
age: Int; // 私有字段,无法被外部访问
sex: String = "Airplane"; // 私有字段,无法被外部访问
public func getName() -> String // 公开类函数
{
return name;
}
}
```
## 结构体初始化
语法:
```go
// 位置参数构造
var person := new Person{
"Fig", // name
1, // age
"Language" // sex
};
```
```go
// 命名参数构造模式,可以无序
var person := new Person{
name: "Fig",
age: 1,
sex: "Language"
};
```
```go
// 语法糖:同名变量构造
const name := "Fig";
const age := 1;
const sex := "Language";
var person := new Person{sex, name, age}; // 可以无序,自动匹配
```
请注意,同名变量构造(shorthand)模式请规范使用:
&nbsp;
示例:定义
```cpp
struct Point
{
public x;
public y;
}
```
使用:
```go
var a := Point{1,2};
io.println(a.x, a.y); // 1 2
var x := 7;
var y := 6;
var b := Point{y, x};
io.println(b.x, b.y); // 7 6
// ??
```
使用该模式最好有序构造,如果你清楚你在做什么,完全可以利用它
## 结构体运算符重载
**目前不支持**
## 接口与实现
`interface``implement`
### 定义接口
```go
interface Printable
{
toString() -> String;
getName() -> String
{
return "Printable";
}
}
```
使用 `interface` + 名字 {内容}定义结构体
方法签名为 `method() -> type`,其中必须提供返回类型,这是约定。
提供默认方法将在子类实现为实现情况下自动替补
### 实现
```rust
struct Person
{
name: String;
age: Int;
}
impl Printable for Person
{
toString()
{
return name + ":" + age;
}
getName()
{
return "Person";
}
}
```
实现时不需要也不允许提供返回类型,必须与`interface`约定一致
内部通过动态派发 vtable实现