diff --git a/README.md b/README.md index b7d06bb..f0d808e 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,7 @@ # Fig Language - A Modern Scripting Language [Fig-Gitea](https://git.fig-lang.cn/PuqiAR/Fig) +Recommend view on Gitea Endpoint [简体中文](README_ZH-CN.md "Chinese version") @@ -55,35 +56,6 @@ xmake run Fig [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 Fig is designed around several core principles: @@ -93,4 +65,10 @@ Replace `[file]` with the path to your input file. Modern ergonomics - Developer experience matters - Gradual learning - Simple to start, powerful when needed \ No newline at end of file + 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. \ No newline at end of file diff --git a/README_ZH-CN.md b/README_ZH-CN.md index 8b3b6e3..a5427cf 100644 --- a/README_ZH-CN.md +++ b/README_ZH-CN.md @@ -49,40 +49,14 @@ xmake run Fig [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 围绕几个核心原则设计: 1. **清晰优于巧妙** - 代码首先应该可读 2. **默认为安全** - 在编译时防止常见错误 3. **现代人机工程学** - 开发者体验很重要 -4. **渐进式学习** - 入门简单,需要时功能强大 \ No newline at end of file +4. **渐进式学习** - 入门简单,需要时功能强大 + +## 语言文档 +在 docs/zh_CN/... 查看更多 +我们正在寻找译者来帮助翻译项目文件以便于不同语言社区的使用 \ No newline at end of file diff --git a/docs/zh_CN/01-简介.md b/docs/zh_CN/01-简介.md new file mode 100644 index 0000000..d0a577b --- /dev/null +++ b/docs/zh_CN/01-简介.md @@ -0,0 +1,24 @@ +# Fig 语言简介 + +## 概述 +Fig 是一门动态类型、解释执行的编程语言,专注于简洁语法和实用的语言特性。它采用树遍历解释器架构,支持多种编程范式。 + +## 实际观察到的特性 +1. **解释执行**:基于 AST 的树遍历解释器,无编译步骤 +2. **动态类型系统**:运行时类型检查,支持类型注解但不强制 +3. **混合范式**:支持函数式、面向对象和命令式风格 +4. **模块系统**:支持代码组织和复用 +5. **内置类型**:整数、浮点数、字符串、列表、映射等 +6. **垃圾回收**:基于引用计数的自动内存管理 + +## 语言设计特点 +- **渐进类型**:支持类型注解但不强制,兼顾灵活性和可读性 +- **一等公民函数**:函数可以作为参数传递和返回 +- **闭包支持**:完整的词法作用域和闭包 +- **错误处理**:异常机制和 try-catch 结构 +- **可变与不可变**:const/var 区分,平衡安全与灵活 + +## 目标应用场景 +- 脚本编写和自动化任务 +- 教育用途和学习编程 +- 配置语言和DSL \ No newline at end of file diff --git a/docs/zh_CN/02-快速开始.md b/docs/zh_CN/02-快速开始.md new file mode 100644 index 0000000..65a5d73 --- /dev/null +++ b/docs/zh_CN/02-快速开始.md @@ -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"` \ No newline at end of file diff --git a/docs/zh_CN/03-基础语法.md b/docs/zh_CN/03-基础语法.md new file mode 100644 index 0000000..58be436 --- /dev/null +++ b/docs/zh_CN/03-基础语法.md @@ -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()); +``` \ No newline at end of file diff --git a/docs/zh_CN/04-数据类型.md b/docs/zh_CN/04-数据类型.md new file mode 100644 index 0000000..5bede44 --- /dev/null +++ b/docs/zh_CN/04-数据类型.md @@ -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) +{ + // 处理另一种错误 +} +``` \ No newline at end of file diff --git a/docs/zh_CN/05-函数.md b/docs/zh_CN/05-函数.md new file mode 100644 index 0000000..b2bedea --- /dev/null +++ b/docs/zh_CN/05-函数.md @@ -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; +}); +``` \ No newline at end of file diff --git a/docs/zh_CN/06-面对对象.md b/docs/zh_CN/06-面对对象.md new file mode 100644 index 0000000..7d4f46f --- /dev/null +++ b/docs/zh_CN/06-面对对象.md @@ -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实现 \ No newline at end of file diff --git a/src/Evaluator/Context/context.hpp b/src/Evaluator/Context/context.hpp index 3a030b4..3b850fc 100644 --- a/src/Evaluator/Context/context.hpp +++ b/src/Evaluator/Context/context.hpp @@ -142,14 +142,7 @@ namespace Fig throw RuntimeError( FString(std::format("Variable '{}' already defined in this scope", name.toBasicString()))); } - variables[name] = std::make_shared( - name, - target->value, - ti, - am, - true, - target - ); + variables[name] = std::make_shared(name, target->value, ti, am, true, target); } std::optional getFunction(std::size_t id) { @@ -233,6 +226,13 @@ namespace Fig return parent && parent->hasImplRegisted(structType, interfaceType); } + std::unordered_map, TypeInfoHash> getImplRegistry() const + { + return implRegistry; + } + + std::unordered_map, TypeInfoHash> &getImplRegistry() { return implRegistry; } + std::optional getImplRecord(const TypeInfo &structType, const TypeInfo &interfaceType) const { auto it = implRegistry.find(structType); diff --git a/src/Evaluator/evaluator.cpp b/src/Evaluator/evaluator.cpp index 19093bf..f6057c5 100644 --- a/src/Evaluator/evaluator.cpp +++ b/src/Evaluator/evaluator.cpp @@ -4,7 +4,6 @@ #include #include - #include #include #include @@ -33,7 +32,6 @@ namespace Fig return sr; } - ContextPtr Evaluator::loadModule(const std::filesystem::path &path) { FString modSourcePath(path.string()); @@ -77,6 +75,8 @@ namespace Fig auto path = resolveModulePath(pathVec); ContextPtr modCtx = loadModule(path); + ctx->getImplRegistry().insert(modCtx->getImplRegistry().begin(), modCtx->getImplRegistry().end()); // load impl + // std::cerr << modName.toBasicString() << '\n'; DEBUG if (ctx->containsInThisScope(modName))