mio 是一种编译型编程语言,是 mio 解释器的进化版。首个编译版本使用 C 语言实现,第二版使用 C++ 语言实现。编译器将 .mio 源文件翻译为 LLVM IR,再直接生成原生可执行文件。
访问 Releases 页面下载对应平台的二进制文件。
Note
如果遇到依赖库缺失问题,建议从源代码编译。
环境要求: c++17 兼容编译器(GCC / Clang / MSVC),LLVM 22.1.x
g++ -std=c++17 -o mioc src/main.cpp -lLLVM# 查看版本与许可证
mioc -v
mioc --version
# 编译 mio 源文件(自动生成同名可执行文件)
mioc hello.mio
# 指定输出文件
mioc hello.mio -o hello.exe
# 仅生成汇编代码
mioc hello.mio -S
# 仅编译为目标文件(不链接)
mioc hello.mio -c
# 添加头文件搜索路径
mioc hello.mio -I ./include
# 定义宏
mioc hello.mio -D DEBUG
# 优化级别(-O0 / -O1 / -O2 / -O3)
mioc hello.mio -O2
# 发布模式(自动 -O2 + 缓存)
mioc hello.mio --release
# 静态链接
mioc hello.mio -static- HZY1618yzh
- lindan5563
- blvmwd
- ZHANG_CHI
- dFszheng
排名按照加入 mio 团队的顺序排列。
# 后面的内容为注释,直到行尾:
# 这是一行注释
var x=10; # 行末注释
关键字: import
使用方法: 导入 mio 头文件,必须写在文件顶层。可以用 -I 命令指定头文件路径。
mioc hello.mio -I ./includeimport stdio; # 导入 C 标准库
import "mylib.mio"; # 导入 mio 文件(用引号包裹)
import stdio,"lib"; # 同时导入多个
关键字: macro,@[if,elif,else,end]
使用方法: 定义宏来替换代码和条件编译防止重复引入。可以用 -D 命令定义宏。
mioc hello.mio -D DEBUGmacro DEBUG;
macro RELEASE;
@if DEBUG
printf("DEBUG\n");
@elif RELEASE
printf("RELEASE\n");
@else
printf("UNKNOWN\n");
@end
关键字: var(可变)、const(常量)
使用方法:
var 变量名: 类型=初始值; # 变量
const 常量名: 类型=初始值; # 常量(不可修改)
| 类型 | 说明 |
|---|---|
i8 / i16 / i32 / i64 / i128 |
有符号整数 |
u8 / u16 / u32 / u64 / u128 |
无符号整数 |
isize / usize |
指针宽度整数(32/64 位自适应) |
f32 / f64 |
浮点数 |
bool |
布尔值(true / false) |
char |
单个字符 |
T[N] |
长度为 N 的数组 |
*T、**T... |
指针类型 |
&T |
可变引用类型 |
&&T |
不可变可变引用类型,在模板里可以隐式转换成 &T |
var x: i32=42;
const PI: f64=3.14;
# 同时声明多个
var a: i64=1,b: i32=2;
# 数组
var arr: i32[3]={1,2,3};
有初始值时可以省略类型,编译器自动推导:
var x=42; # i32
var pi=3.14; # f64
var flag=true; # bool
var nums={1,2,3}; # i32[3]
var s: char*="hello"; # 字符串字面量
var ch: char='A'; # 字符字面量
用 :: 前缀访问全局变量(避免与局部变量同名冲突):
var x: i32=10;
void foo() {
var x: i32=20;
printf("%d\n",::x); # 访问全局 x,输出 10
printf("%d\n",x); # 访问局部 x,输出 20
}
关键字: if、else
条件必须用括号括起来
if (条件) {
代码块
} else if (条件) {
代码块
} else {
代码块
}
if (score >= 90) {
printf("A\n");
} else if (score >= 80) {
printf("B\n");
} else {
printf("C\n");
}
单语句可以省略大括号:
if (x > 0) printf("正数\n");
关键字: while
条件必须用括号括起来
var i: i32=0;
while (i < 5) {
printf("%d\n",i);
i=i+1;
}
关键字: for
格式: for (初始化; 条件; 更新) { 代码块 }
var sum: i32=0;
for (i=0; i < 10; i=i+1) {
sum=sum+i;
}
var i: i32=0;
for (; i < 5; i=i+1) { # 省略初始化
printf("%d\n",i);
}
while (true) {
if (x > 100) {
break; # 跳出循环
}
if (x % 2 == 0) {
x=x+1;
continue; # 跳过本次迭代剩余部分
}
x=x+1;
}
关键字: goto
定义标签: :标签名
var i: i32=0;
:loop
printf("%d\n",i);
i=i+1;
if (i < 5) {
goto loop;
}
| 运算符 | 说明 |
|---|---|
+ - * / % |
加减乘除取模 |
- |
取负(一元) |
~ |
按位取反 |
| 运算符 | 说明 |
|---|---|
== != |
等于 / 不等于 |
< > <= >= |
小于 / 大于 / 小于等于 / 大于等于 |
| 运算符 | 说明 |
|---|---|
&& || ! |
逻辑与 / 逻辑或 / 逻辑非 |
| 运算符 | 说明 |
|---|---|
& | ^ |
按位与 / 按位或 / 按位异或 |
<< >> |
左移 / 右移 |
| 运算符 | 说明 |
|---|---|
= |
赋值 |
+= -= *= /= %= |
复合赋值 |
&= |= ^= <<= >>= |
位复合赋值 |
在结构体或类中定义 operator+、operator- 等方法实现运算符重载:
struct Point {
x: f64;
y: f64;
Point operator+(other: Point) {
return Point(this.x+other.x,this.y+other.y);
}
}
使用 C 风格的类型转换语法:
var x: f64=3.14;
var y: i32=i32(x); # 浮点数转整数(截断)
var z: i64=i64(y); # 整数扩展
var n: u32=u32(-1); # 有符号转无符号
返回类型 函数名(参数名: 参数类型,...) {
函数体
}
# 显式返回
i32 add(a: i32,b: i32) {
return a+b;
}
# 隐式返回(最后一行不加分号)
i32 add(a: i32,b: i32) {
a+b
}
# 无返回值
void say_hello() {
printf("hello\n");
}
# 静态函数(仅当前文件可见)
static void helper() {
printf("helper\n");
}
# 仅声明函数(其他文件定义)
extern i32 printf(fmt: char*,...);
var result=add(10,20);
say_hello();
关键字: class
类与结构体类似,但支持继承、虚函数和访问控制。类默认使用引用语义(通过指针操作)。
class 类名 {
访问控制:
字段名: 类型;
方法定义...
}
| 关键字 | 说明 |
|---|---|
public: |
公开成员,外部可访问 |
private: |
私有成员,仅类内部可访问 |
protected: |
受保护成员,类及其子类可访问 |
构造函数名与类名相同,析构函数以 ~ 开头:
class Animal {
public:
name: char*;
Animal(name: char*) {
this.name=name;
}
~Animal() {
printf("Animal destroyed\n");
}
}
使用 类名(父类:访问控制) 语法继承父类:
class Dog(Animal:public) {
public:
Dog(name: char*) {
this.name=name;
}
}
用 virtual 声明虚函数,子类用 override 重写:
class Animal {
public:
virtual void speak() {
printf("Animal speak\n");
}
};
class Dog(Animal:public) {
public:
override void speak() {
printf("Dog: woof!\n");
}
};
class Animal {
public:
name: char*;
Animal(name: char*) {
this.name=name;
printf("Animal ctor: %s\n",name);
}
~Animal() {
printf("Animal dtor: %s\n",this.name);
}
virtual void speak() {
printf("Animal speak\n");
}
};
class Cat(Animal:public) {
public:
Cat(name: char*) {
this.name=name;
printf("Cat ctor: %s\n",name);
}
override void speak() {
printf("Cat %s: meow!\n",this.name);
}
};
i32 main() {
var dog=Dog("Buddy");
var cat=Cat("Kitty");
dog.speak(); # Dog: woof!
cat.speak(); # Cat: meow!
return 0;
}
关键字: enum
enum 枚举名 {
变体名,
变体名=初始值,
...
}
enum Color {
Red,
Green,
Blue
}
enum Status {
Ok=0,
Error=-1
}
var c=Color.Red;
var s=Status.Ok;
关键字: union
union 联合体名 {
字段名: 类型;
字段名: 类型;
...
}
union Value {
int_val: i32;
float_val: f64;
bool_val: bool;
}
var v: Value;
v.int_val=42;
printf("%d\n",v.int_val);
v.float_val=3.14;
printf("%f\n",v.float_val);
Note
联合体所有字段共享同一块内存,一次只能使用其中一个字段。
关键字: namespace
命名空间用于组织代码,避免名称冲突。命名空间可以嵌套。
namespace math {
i32 add(a: i32,b: i32) {
return a+b;
}
i32 sub(a: i32,b: i32) {
return a-b;
}
}
i32 main() {
var x=math::add(10,20); # 用 :: 访问命名空间成员
return x;
}
Note
命名空间必须在文件顶层定义,不能出现在函数内部。
关键字: template、typename
模板用于编写泛型代码,支持多个模板参数、指定类型和默认值,以及自动类型推导和显式类型参数。支持模板函数和模板类,他们都是在语义解析的时候实例化。
template$T:typename$
template$T:typename,len:i32=100$
T:typename— 类型参数(简写:T等同于T:typename)len:i32=100— 值参数,类型为i32,默认值为100
template$T:typename$
T max(a: T,b: T) {
if (a > b) {
return a;
}
return b;
}
i32 main() {
var x=max(10,20); # 自动推导 T=i32
var y=max$f64$(3.14,2.71); # 显式指定 T=f64
return 0;
}
函数参数可以指定默认值,调用时可以省略有默认值的参数:
i32 add(a: i32,b: i32=10) {
return a+b;
}
i32 main() {
var x=add(5); # x=15 (b 使用默认值 10)
var y=add(5,20); # y=25
return 0;
}
以下内容只能出现在文件顶层,不能在函数内部定义:
importclassenumunionnamespacetemplate
用 {} 包围的代码块可以嵌套,内部定义的变量在块结束后销毁:
void test() {
var x=10;
{
var y=20; # y 只在此块内有效
var z=30;
}
# y 和 z 在这里不可见
}