跳转至

包(Packages)

包属性描述

MQl 源文件

单文件运行

MirrorQL 编译器对包的处理方式

使用方法

包属性描述

包的属性由其根目录的package.toml描述:

[package]
name = "hello" # 包名(必须)
version = "0.1.0" # 版本号(必须)
entry = "main" # 入口点文件,缺省为"main",即src/main.mql,对应一个容器路径(定义下面有)
author = "foo" # 作者(可选)
language = "java" # 分析语言(可选,仅作标识)
is_lib = false # 是否为库,缺省为false。若为库,则没有入口点

[deps] # 依赖列表
std = "1.0.0" # semver
java = "1.0.0"

hello为例, 包的典型目录结构如下:

hello/
├── package.toml
└── src
    └── main.mql

MQl 源文件

MirrorQL程序的最小单位是MirrorQL源文件。

[output]
fn out(x:str){
    x="Hello world"
}

MirrorQL源文件中可以包括以下元素:

  • use语句
  • 谓词定义
  • 类(class)定义
  • 模块(module)定义
  • 带参数模块实例化(use module
  • trait定义与impl
  • MirrorQL程序行为无影响的语法元素,如注释
  • MirrorQL文件中定义的实体包括谓词、类、模块、带参模块、实例化的模块、trait。之所以叫实体,是因为这些元素都是独立的功能单位,且都有一个名字。 实体的名字是唯一的,一个文件中不能出现两个名字相同的实体,例如同时定义class A和谓词A是非法的,同时定义两个class A也是非法的。

单文件运行

为了便于开发者快速编写简短的MirrorQL程序,MirrorQL编译器也提供了单文件运行的能力。

假设要运行的文件名为test.mql,编译器行为等价于执行以下操作后再运行test包:

创建user_prog包,

package.toml内容如下:

[package]
name = "user_prog"
version = "0.1.0"
entry = "test"
is_lib = false

目录结构如下:

hello包的典型目录结构如下:

user_prog/
├── package.toml
└── src
    └── test.mql

MirrorQL 编译器对包的处理方式

只有带有package.toml中含entry属性的MirrorQL包可以被编译运行,entry是入口点文件的容器路径。库中可能有很多文件,但真正被用户程序用到的MirrorQL文件只占少数。MirrorQL编译器只会处理真正被用户程序用到的MirrorQL文件。

MirrorQL编译器运行包时,首先进行以下操作:

解析entry对应的文件,加入集合S(当前程序用到的MirrorQL文件集合),并加入队列Q(待处理的文件列表)

Q中取出一个文件,解析其中所有的use语句,每个use语句引用一个定义路径,从定义路径中得到容器路径,加入集合S,若插入成功,再将路径加入队列Q 重复步骤 2,直到队列Q为空

此时,集合S就是用户程序用到的所有MirrorQL文件列表。MirrorQL编译器只会编译集合S内的所有文件。

使用方法

MirrorQL中,可以使用use语句导入其他MirrorQL文件中定义的实体。use语句可以导入本包文件的实体,也可以跨包导入实体。

use语句的具体用法与行为参见 use 用法