增加了文档,目前只有中文。更新readme,简单修改import导入机制,导入impl registry。
This commit is contained in:
36
README.md
36
README.md
@@ -1,6 +1,7 @@
|
|||||||
# Fig Language - A Modern Scripting Language
|
# Fig Language - A Modern Scripting Language
|
||||||
|
|
||||||
[Fig-Gitea](https://git.fig-lang.cn/PuqiAR/Fig)
|
[Fig-Gitea](https://git.fig-lang.cn/PuqiAR/Fig)
|
||||||
|
Recommend view on Gitea Endpoint
|
||||||
|
|
||||||
[简体中文](README_ZH-CN.md "Chinese version")
|
[简体中文](README_ZH-CN.md "Chinese version")
|
||||||
|
|
||||||
@@ -55,35 +56,6 @@ xmake run Fig [file]
|
|||||||
|
|
||||||
Replace `[file]` with the path to your input file.
|
Replace `[file]` with the path to your input file.
|
||||||
|
|
||||||
### 📁 Project Structure
|
|
||||||
.
|
|
||||||
├── ExampleCodes # Example programs & performance tests
|
|
||||||
│ └── SpeedTest # Performance benchmark samples
|
|
||||||
├── LICENSE # Project license
|
|
||||||
├── Logo # Project logo assets
|
|
||||||
├── README.md # English README
|
|
||||||
├── README_ZH-CN.md # Chinese README
|
|
||||||
├── compile_flags.txt # Compiler flags helper
|
|
||||||
├── fig-vscode # VSCode extension project
|
|
||||||
│ ├── node_modules # Extension dependencies
|
|
||||||
│ ├── out # Built extension output
|
|
||||||
│ ├── src # Extension source code
|
|
||||||
│ └── syntaxes # Syntax highlighting definition
|
|
||||||
├── src # Core Fig language source
|
|
||||||
│ ├── Ast # AST definitions
|
|
||||||
│ ├── Context # Runtime context
|
|
||||||
│ ├── Core # Core utilities (UTF8/string/etc.)
|
|
||||||
│ ├── Error # Error handling system
|
|
||||||
│ ├── Evaluator # Interpreter / evaluator
|
|
||||||
│ ├── Lexer # Lexical analyzer
|
|
||||||
│ ├── Module # Modules and builtins
|
|
||||||
│ ├── Parser # Parser
|
|
||||||
│ ├── Token # Token definitions
|
|
||||||
│ ├── Utils # Utilities & helper headers
|
|
||||||
│ └── Value # Runtime type/value system
|
|
||||||
├── test.fig # Test script
|
|
||||||
└── xmake.lua # Xmake build config
|
|
||||||
|
|
||||||
## Language Philosophy
|
## Language Philosophy
|
||||||
Fig is designed around several core principles:
|
Fig is designed around several core principles:
|
||||||
|
|
||||||
@@ -94,3 +66,9 @@ Replace `[file]` with the path to your input file.
|
|||||||
Modern ergonomics - Developer experience matters
|
Modern ergonomics - Developer experience matters
|
||||||
|
|
||||||
Gradual learning - Simple to start, powerful when needed
|
Gradual learning - Simple to start, powerful when needed
|
||||||
|
|
||||||
|
## Language Documents
|
||||||
|
|
||||||
|
see ./docs/en_US/...
|
||||||
|
|
||||||
|
We're looking for translators to help translate our project and make it accessible to more language communities.
|
||||||
@@ -49,36 +49,6 @@ xmake run Fig [file]
|
|||||||
```
|
```
|
||||||
将`[file]`替换为输入文件的路径。
|
将`[file]`替换为输入文件的路径。
|
||||||
|
|
||||||
### 📁 项目结构
|
|
||||||
.
|
|
||||||
├── ExampleCodes # 示例代码与性能测试样例
|
|
||||||
│ └── SpeedTest # 性能相关测试示例
|
|
||||||
├── LICENSE # 项目开源协议
|
|
||||||
├── Logo # 项目标识资源
|
|
||||||
├── README.md # 英文 README
|
|
||||||
├── README_ZH-CN.md # 中文 README
|
|
||||||
├── compile_flags.txt # C/C++ 编译器参数提示
|
|
||||||
├── fig-vscode # VSCode 插件项目
|
|
||||||
│ ├── node_modules # VSCode 插件依赖
|
|
||||||
│ ├── out # 构建产物
|
|
||||||
│ ├── src # VSCode 插件源码
|
|
||||||
│ └── syntaxes # 语法高亮定义
|
|
||||||
├── src # Fig 语言核心源码
|
|
||||||
│ ├── Ast # 抽象语法树节点
|
|
||||||
│ ├── Context # 运行上下文
|
|
||||||
│ ├── Core # 核心基础设施(字符串/UTF8 等)
|
|
||||||
│ ├── Error # 错误系统
|
|
||||||
│ ├── Evaluator # 解释执行器
|
|
||||||
│ ├── Lexer # 词法分析器
|
|
||||||
│ ├── Module # 模块与内置库
|
|
||||||
│ ├── Parser # 语法解析器
|
|
||||||
│ ├── Token # Token 定义
|
|
||||||
│ ├── Utils # 实用工具与第三方 header
|
|
||||||
│ └── Value # 运行时类型系统与值表示
|
|
||||||
├── test.fig # 测试脚本
|
|
||||||
└── xmake.lua # Xmake 构建脚本
|
|
||||||
|
|
||||||
|
|
||||||
## 语言设计哲学
|
## 语言设计哲学
|
||||||
Fig 围绕几个核心原则设计:
|
Fig 围绕几个核心原则设计:
|
||||||
|
|
||||||
@@ -86,3 +56,7 @@ Fig 围绕几个核心原则设计:
|
|||||||
2. **默认为安全** - 在编译时防止常见错误
|
2. **默认为安全** - 在编译时防止常见错误
|
||||||
3. **现代人机工程学** - 开发者体验很重要
|
3. **现代人机工程学** - 开发者体验很重要
|
||||||
4. **渐进式学习** - 入门简单,需要时功能强大
|
4. **渐进式学习** - 入门简单,需要时功能强大
|
||||||
|
|
||||||
|
## 语言文档
|
||||||
|
在 docs/zh_CN/... 查看更多
|
||||||
|
我们正在寻找译者来帮助翻译项目文件以便于不同语言社区的使用
|
||||||
24
docs/zh_CN/01-简介.md
Normal file
24
docs/zh_CN/01-简介.md
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
# Fig 语言简介
|
||||||
|
|
||||||
|
## 概述
|
||||||
|
Fig 是一门动态类型、解释执行的编程语言,专注于简洁语法和实用的语言特性。它采用树遍历解释器架构,支持多种编程范式。
|
||||||
|
|
||||||
|
## 实际观察到的特性
|
||||||
|
1. **解释执行**:基于 AST 的树遍历解释器,无编译步骤
|
||||||
|
2. **动态类型系统**:运行时类型检查,支持类型注解但不强制
|
||||||
|
3. **混合范式**:支持函数式、面向对象和命令式风格
|
||||||
|
4. **模块系统**:支持代码组织和复用
|
||||||
|
5. **内置类型**:整数、浮点数、字符串、列表、映射等
|
||||||
|
6. **垃圾回收**:基于引用计数的自动内存管理
|
||||||
|
|
||||||
|
## 语言设计特点
|
||||||
|
- **渐进类型**:支持类型注解但不强制,兼顾灵活性和可读性
|
||||||
|
- **一等公民函数**:函数可以作为参数传递和返回
|
||||||
|
- **闭包支持**:完整的词法作用域和闭包
|
||||||
|
- **错误处理**:异常机制和 try-catch 结构
|
||||||
|
- **可变与不可变**:const/var 区分,平衡安全与灵活
|
||||||
|
|
||||||
|
## 目标应用场景
|
||||||
|
- 脚本编写和自动化任务
|
||||||
|
- 教育用途和学习编程
|
||||||
|
- 配置语言和DSL
|
||||||
82
docs/zh_CN/02-快速开始.md
Normal file
82
docs/zh_CN/02-快速开始.md
Normal 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"`
|
||||||
213
docs/zh_CN/03-基础语法.md
Normal file
213
docs/zh_CN/03-基础语法.md
Normal 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());
|
||||||
|
```
|
||||||
156
docs/zh_CN/04-数据类型.md
Normal file
156
docs/zh_CN/04-数据类型.md
Normal 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
289
docs/zh_CN/05-函数.md
Normal 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;
|
||||||
|
});
|
||||||
|
```
|
||||||
126
docs/zh_CN/06-面对对象.md
Normal file
126
docs/zh_CN/06-面对对象.md
Normal 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)模式请规范使用:
|
||||||
|
|
||||||
|
示例:定义
|
||||||
|
```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实现
|
||||||
@@ -142,14 +142,7 @@ namespace Fig
|
|||||||
throw RuntimeError(
|
throw RuntimeError(
|
||||||
FString(std::format("Variable '{}' already defined in this scope", name.toBasicString())));
|
FString(std::format("Variable '{}' already defined in this scope", name.toBasicString())));
|
||||||
}
|
}
|
||||||
variables[name] = std::make_shared<VariableSlot>(
|
variables[name] = std::make_shared<VariableSlot>(name, target->value, ti, am, true, target);
|
||||||
name,
|
|
||||||
target->value,
|
|
||||||
ti,
|
|
||||||
am,
|
|
||||||
true,
|
|
||||||
target
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
std::optional<Function> getFunction(std::size_t id)
|
std::optional<Function> getFunction(std::size_t id)
|
||||||
{
|
{
|
||||||
@@ -233,6 +226,13 @@ namespace Fig
|
|||||||
return parent && parent->hasImplRegisted(structType, interfaceType);
|
return parent && parent->hasImplRegisted(structType, interfaceType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::unordered_map<TypeInfo, std::vector<ImplRecord>, TypeInfoHash> getImplRegistry() const
|
||||||
|
{
|
||||||
|
return implRegistry;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unordered_map<TypeInfo, std::vector<ImplRecord>, TypeInfoHash> &getImplRegistry() { return implRegistry; }
|
||||||
|
|
||||||
std::optional<ImplRecord> getImplRecord(const TypeInfo &structType, const TypeInfo &interfaceType) const
|
std::optional<ImplRecord> getImplRecord(const TypeInfo &structType, const TypeInfo &interfaceType) const
|
||||||
{
|
{
|
||||||
auto it = implRegistry.find(structType);
|
auto it = implRegistry.find(structType);
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
#include <Evaluator/evaluator.hpp>
|
#include <Evaluator/evaluator.hpp>
|
||||||
#include <Evaluator/evaluator_error.hpp>
|
#include <Evaluator/evaluator_error.hpp>
|
||||||
|
|
||||||
|
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
@@ -33,7 +32,6 @@ namespace Fig
|
|||||||
return sr;
|
return sr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ContextPtr Evaluator::loadModule(const std::filesystem::path &path)
|
ContextPtr Evaluator::loadModule(const std::filesystem::path &path)
|
||||||
{
|
{
|
||||||
FString modSourcePath(path.string());
|
FString modSourcePath(path.string());
|
||||||
@@ -77,6 +75,8 @@ namespace Fig
|
|||||||
auto path = resolveModulePath(pathVec);
|
auto path = resolveModulePath(pathVec);
|
||||||
ContextPtr modCtx = loadModule(path);
|
ContextPtr modCtx = loadModule(path);
|
||||||
|
|
||||||
|
ctx->getImplRegistry().insert(modCtx->getImplRegistry().begin(), modCtx->getImplRegistry().end()); // load impl
|
||||||
|
|
||||||
// std::cerr << modName.toBasicString() << '\n'; DEBUG
|
// std::cerr << modName.toBasicString() << '\n'; DEBUG
|
||||||
|
|
||||||
if (ctx->containsInThisScope(modName))
|
if (ctx->containsInThisScope(modName))
|
||||||
|
|||||||
Reference in New Issue
Block a user