English | 中文
Caution
MPCC Project 当前仍未完成编写,您也许不能按照给定的方式编译和运行。
MPC 是一种脚本式、解释性、强类型的编程语言。MPC 是一款面向对象的编程语言,支持类、封装、构造函数、析构函数、继承、多态等功能。
class IntegerClass {
private value _value = 0;
constructor(v : Integer) {
_value = v;
print("An integer class created."); // library "io" required.
}
public method isok() {
return typestr(_value) == "integer"; // library "type-utils" required.
}
destructor {
print("An integer calss destructed.");
}
public method valueOf() {
return _value;
}
}
let a = new IntegerClass(114514);
MPCC Project 是一款使用 C++ 编程语言的跨平台半解释性编程语言。MPC 表示 Mirekintoc PL Code。它的代码精简,不需要太长的时间用于理解,同时也易于修改、装载插件。
MPCC Project 当前支持绝大多数常见的操作系统,包括但不限于 Windows、macOS、Linux, 并且可以基于 Windows API 或 POSIX API 加载外置的插件。这种插件不需要更改 MPCC Project 的源代码即可运行,而是被 MPCC Project 从本地动态库读取而运行。这不是一个必须的功能,但通常会启用它,当然你也可以禁用它。另外,请注意您选中的插件是否跨平台。理论上没有安装插件的 MPCC Project 可以在任意支持 CMake 和 C++17 的操作系统上运行。
MPCC Project 并不依赖于某种特定的指令集,常见的,例如 x86、arm、RISC-V、PowerPC 都可以运行,只要符合上一条。
由于 coredef 等功能使用 Module
类进行解析依赖于 nlohmann_json
库,如果您的系统不兼容该库,请尝试在 CMakeList.txt
中删除该项,并将 NO_MODULE
改为 true
。请注意,这将导致标准库不可外部更改。如果移动程序时没有一并移动 res
目录,则会产生同样的效果。
在开始前,您需要安装 CMake 和对应的编译套件,然后运行以下命令:
cmake -B build -S . -D BUILD_TYPE=Release
cmake --build build --config Release
运行一个代码文件:
mpcc e <fileName>
以 REPL (Read-Evaluate-Print Loop) 模式运行:
mpcc r
运行一个二进制文件 (*.mpe
):
mpcc x <fileName>
创建一个二进制文件 (*.mpe
):
mpcc c <inputFileName> <outputFileName>
把代码转换为 TokenList (.tokens.txt
):
mpcc s <inputFileName> <outputFileName>
把代码转换为 AST JSON (.ast.json
):
mpcc t <inputFileName> <outputFileName>
注意:您不能同时使用多种模式!
- Token 解析器 (Lexer) 用于划分源代码部件
- 语法解析器 (Parser) 用于解析源代码为 AST
- 虚拟机 (VM) 用于运行 AST
- 转换器 (Convertor) 用于将二进制/内存格式转换为人类可读形式。
二进制 AST 保存文件的 Magic 是 MirekE09
要创建一个内置插件,您需要:
创建一个位于 include/registry
目录的文件,例如 my_plugin.hpp
。
写入下述内容。示例是对若干个整数求和,您也可以换成自己想要的。
#pragma once
#include "registry/base.hpp"
class MyPlugin : public Plugin {
public:
MyPlugin() : Plugin() {}
void attach(std::shared_ptr<Environment> env) const override {
env->set("sum", std::make_shared<NativeFunction>(sum));
}
public:
static NativeFunction::resulttype sum(NativeFunction::arglist args, Environment* env) {
if (args.size() == 0) {
return FormatError();
}
long long _sum = 0;
for (auto i : args) {
if (i->type != Object::Type::Integer) {
return FormatError();
}
_sum += std::dynamic_pointer_cast<Integer>(i)->value;
}
return std::make_pair(NativeFunction::Result::OK,std::make_shared<Integer>(_sum));
}
};
NativeFunction::resulttype
表示 std::pair<NativeFunctions::Result, std::shared_ptr<Object>>
.
NativeFunction::arglist
表示 std::vector<std::shared_ptr<Object>>
.
枚举 NativeFunction::Result
包含 4 个值: OK
,FORMAT_ERR
,DATA_ERR
和 UNHANDLED_ERR
。它们分别表示:
OK
:没有错误发生FORMAT_ERR
:以错误的格式调用DATA_ERR
:以错误的参数数据调用UNHANDLED_ERR
:未经处理的错误
修改 src/main.cpp
,添加对该插件的注册行为。
最后重新构建整个项目。
MPC 提供多种类型。除 Naitve 和 Instance 具有不确定的类型字段,其他类型(如 Integer、String、Float、Boolean、Executable、Null、Error)都有固定了类型字段。
type-utils
库(include/registry/typeutils.hpp
)提供的 typestr
函数可以获取一个值的类型。一个类和它的实例具有相同的编号(不是完整的类型字段)。
支持运算:
- 算数运算:加、减、乘、除、取模、正、负
- 位运算:按位与、按位或、按位取反、按位异或、左移、右移
- 逻辑运算:与、或、非
- 比较运算:等于、不等于、大于、小于、大于等于、小于等于
名称 | 文件 | 功能 | 操作系统 |
---|---|---|---|
dynamic-load | include/registry/dynamic_load.hpp | 加载外置插件 | Windows/POSIX |
io | include/registry/io.hpp | 输入输出 | 任意 |
constants | include/registry/constants.hpp | 常见的常量或判断函数 | 任意 |
fileio | include/registry/fileio.hpp | 文件输入输出 | 任意 |
type-utils | include/registry/type_utils.hpp | 类型转换和查询 | 任意 |
system | include/registry/system.hpp | 使用系统命令 | 任意 |
math | include/registry/math.hpp | 简单的数学功能 | 任意 |
algorithm | include/registry/algorithm.hpp | 常见算法和函数 | 任意 |
base | include/registry/base.hpp | 基本语言功能 | 任意 |
用户可以自己加载以下自带的插件:
名称 | 文件 | 功能 | 操作系统 |
---|---|---|---|
eval | include/registry/more/eval.hpp | 运行字符串中的代码 | 任意 |
win32-windowing | include/registry/win32w.hpp | Win32 窗口编程 | Windows |
import
关键字被用于导入文件或二进制中的代码。
被导入的文件路径以字符串形式接在 import
关键字后,并且仅通过字符串比较来避免重复导入。
mstdlib
是 MPCC Project 使用的默认标准库,在 res/standard.json
中可以增减标准库以及设置默认。
欢迎为这个项目提交 PR 或 issue,我会非常高兴看到它!
感谢 lighzy-interpreter
提供的代码参考和 CMake 模板
该项目在 MIT 协议下分发,另见 LICENSE。