一个简单的编译型语言
include | ||
src | ||
unit | ||
.gitignore | ||
CMakeLists.txt | ||
input.txt | ||
LICENSE | ||
README.md |
Hydrogen 语言大纲
[toc]
1. 语法文档
1.1 变量
变量支持自动类型推导
var foo = 1; // foo的类型自动推导为int
if (true) {
var foo = 2; // foo在不同作用域下允许重复声明
}
不使用类型推导
i8 f1 = 12; // 整型字变量默认为i32,支持自动类型转换
i16 f2 = 12;
string s = "hello world"; // 字符串类型
char c = '中' // 字符类型,支持中文
float64 f3 = 3.124; // 浮点型字变量默认为float64
i32 f4; // ERROR,声明的变量必须赋初始值
支持的数值类型
整型 | 浮点型 | 布尔类型 | 字符类型 |
---|---|---|---|
i8 / u8 | float64(默认) | bool | char |
i16 / u16 | float32 | ||
i32(默认) / u32 | |||
i64 / u64 |
支持的复合类型
类型名称 | 存储位置 | 语法 | 示例 | 说明 |
---|---|---|---|---|
string | heap | string |
string str = "hello"; |
字符串类型 |
array | stack | [T;n] |
[int;4] a = [1,2,3,4] |
固定长度数组 |
vector | heap | [T] |
[int] list = [1,2,3,4] |
动态数组 |
struct | stack | struct | struct {int x} |
结构体 |
tuple | heap | (T) |
(int, bool) t = (1, true) | 元组 |
1.2 注释
单行注释
单行注释使用 //
开头,后面跟随注释内容。例如:
// 这是一个单行注释
多行注释
多行注释使用 /*
开头,并以 */
结束。例如:
/*
这是一个多行注释
可以跨越多行
*/
1.3 控制结构
if 语法
if condition {
// 当 condition 为 true 时执行的代码
} else {
// 当 condition 为 false 时执行的代码
}
condition 的类型必须是 bool
可以使用 else 语法来检查多个条件,示例:
int foo = 23
if foo > 100 {
print('foo > 100')
} else if foo > 20 {
print('foo > 20')
} else {
print('else handle')
}
for 语法
for
语句用于循环执行代码块。Nature 语言中的 for
语句有三种主要形式:经典循环、条件循环。
- 经典循环
经典循环用于执行固定次数的循环。基本语法如下:
var sum = 0
for int i = 1; i <= 100; i += 1 {
sum += i
}
println('1 +..+100 = ', sum)
在这个示例中,循环从 i = 1
开始,每次循环 i
增加 1,直到 i
大于 100。最终输出 1 +..+100 = 5050
。
- 条件循环
条件循环用于根据条件执行循环,类似于 C 语言中的 while
表达式。基本语法如下:
var sum = 0
var i = 0
for i <= 100 {
sum += i
i += 1
}
println('1 +..+100 = ', sum)
在这个示例中,循环会一直执行,直到 i
大于 100。最终输出与经典循环相同。
-
循环的中断与跳过
关键字
break
用于退出当前循环,continue
则跳过本次循环逻辑立刻进入到循环判断逻辑。
1.4 内置函数
打印任意数量的参数到标准输出,不添加换行符。
print("Hello", 42, true) // 输出: Hello42true
println
打印任意数量的参数到标准输出,并在多个参数之间添加空格,末尾添加换行符。
println("Hello", 42) // 输出: Hello42\n
1.5 算术运算符
优先级 | 关键字 | 使用示例 | 说明 |
---|---|---|---|
1 | () | (1 + 1) | (expr) |
2 | - | -12 | -number_expr 负数 |
2 | ! | !true | !bool_expr 逻辑非 |
2 | ~ | ~12 | ~integer_expr 按位取反 |
3 | / | 1 / 2 | 除 |
3 | * | 1 * 2 | 乘 |
3 | % | 5 % 2 | 余数 |
4 | + | 1 + 1 | 加 |
4 | - | 1 - 1 | 减 |
5 | << | 100 << 2 | 按位左移 |
5 | >> | 100 >> 2 | 按位右移 |
6 | > | 1 > 2 | 大于 |
6 | >= | 1 >= 2 | 大于等于 |
6 | < | 1 < 2 | 小于 |
6 | <= | 1 <= 2 | 小于等于 |
7 | == | 1 == 2 | 等于 |
7 | != | 1 != 2 | 不等于 |
8 | & | 1 & 2 | 按位与 |
9 | ^ | 1 ^ 2 | 按位异或 |
10 | | | 1 | 2 | 按位或 |
11 | && | true && true | 逻辑与 |
12 | || | true || true | 逻辑或 |
13 | = | a = 1 | 赋值运算符 |
13 | %= | a %= 1 | 相当于 a = a % 1 |
13 | *= | a *= 1 | a = a * 1 |
13 | /= | a /= 1 | a = a / 1 |
13 | += | a += 1 | a = a + 1 |
13 | -= | a -= 1 | a = a - 1 |
13 | |= | a |= 1 | a = a | 1 |
13 | &= | a &= 1 | a = a & 1 |
13 | ^= | a ^= 1 | a = a ^ 1 |
13 | <<= | a <<= 1 | a = a << 1 |
13 | >>= | a >>= 1 | a = a >> 1 |
1.6 函数
函数声明语法如下
fn 函数名(参数名:参数类型,....) -> 返回类型 {
...
}
注意:最后一个表达式如果没有分号,其值默认为返回值
例子:
fn add(x:i8, y:i8) -> i8 {
x+y
}
1.7 结构体
结构体声明语法如下
struct point {
x:i8,
y:i8
}
a = point {x:24, y:43};
2. 实现细节
2.1 词法分析的符号表结构
关键字表
name | id |
---|---|
var | 1 |
i8 | 2 |
i16 | 3 |
i32 | 4 |
i64 | 5 |
u8 | 6 |
u16 | 7 |
u32 | 8 |
u64 | 9 |
float32 | 10 |
float64 | 11 |
char | 12 |
for | 13 |
if | 14 |
else | 15 |
bool | 16 |
string | 17 |
vector | 18 |
array | 19 |
struct | 20 |
tuple | 21 |
22 | |
println | 23 |
界符表
id | 关键字 |
---|---|
1 | - |
2 | ! |
3 | ~ |
4 | / |
5 | * |
6 | % |
7 | + |
8 | - |
9 | << |
10 | >> |
11 | > |
12 | >= |
13 | < |
14 | <= |
15 | == |
16 | != |
17 | & |
18 | ^ |
19 | | |
20 | && |
21 | || |
22 | = |
23 | %= |
24 | *= |
25 | /= |
26 | += |
27 | -= |
28 | |= |
29 | &= |
30 | ^= |
31 | <<= |
32 | >>= |
33 | ( |
34 | ) |
35 | < |
36 | > |
37 | , |
38 | . |
39 | [ |
40 | ] |
41 | ? |
42 | : |
43 | -> |
44 | : |
常量表
id | type | val |
---|---|---|
1 | i8 | 33 |
2 | i64 | 100 |
3 | char | 指向'c'的pointer |
4 | string | 指向'hello,world'的pointer |
标识符表
id | name |
---|---|
1 | a |
2 | tot |
3 | my_vector |
4 | ans |
Hydrogen样例
struct Point {
x:i8;
y:i8;
}
[Point:105] tmp;
fn MergeSort([Point:20] v,i8 l,i8 r) -> {
if l>r {
return ;
}
var mid = l + r >>1;
MergeSort(v,l,mid);
MergeSort(v,mid+1,r);
i8 i=l,j=mid+1,k=l;
for ;i <= mid && j <= r;k+=1 {
if v[l] < v[r]
{
tmp[k] = v[l];
l +=1;
}
else{
tmp[k] = v[r];
r += 1;
}
}
for ; i<=mid; {
tmp[k] = tmp[i];
k += 1,i+=1;
}
for ; j <=r ; {
tmp[k] = tmp[j];
k +=1 , j += 1;
}
}
fn main()->i8{
[Point:20] d;
[Point] d;
for i8 i = 0;i< 20; i++ {
d[i] = {x:i * i,y:i};
}
MergeSort(d,d+20);
0
}