初始化仓库

This commit is contained in:
Gary Gan 2025-06-02 15:28:10 +08:00
parent d233a2cc81
commit 1fa3bf3979
8 changed files with 7391 additions and 2 deletions

4
.gitignore vendored
View File

@ -86,3 +86,7 @@ Module.symvers
Mkfile.old
dkms.conf
# cmake build files
build/
.cache/

24
CMakeLists.txt Normal file
View File

@ -0,0 +1,24 @@
cmake_minimum_required(VERSION 3.10)
project(Hydrogen)
enable_testing()
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_EXPORT_COMPILE_COMMANDS 1)
include_directories(${CMAKE_SOURCE_DIR}/include)
file(GLOB SOURCES ${CMAKE_SOURCE_DIR}/src/*.cpp)
add_executable(Hydrogen ${SOURCES})
file(GLOB TEST_SOURCES ${CMAKE_SOURCE_DIR}/unit/*.cpp)
foreach(TEST_SOURCE ${TEST_SOURCES})
get_filename_component(TEST_NAME ${TEST_SOURCE} NAME_WE)
add_executable(${TEST_NAME} ${TEST_SOURCE} ${SOURCES})
add_test(NAME ${TEST_NAME} COMMAND ${TEST_NAME})
endforeach(TEST_SOURCE ${TEST_SOURCES})
install(TARGETS Hydrogen DESTINATION bin)

195
README.md
View File

@ -1,3 +1,194 @@
# Hydrogen
<h1 align="center"> Hydrogen 语言大纲</h1>
一个简单的编译型语言
[toc]
## 1. 语法文档
### 1.1 变量
变量支持自动类型推导
```go
var foo = 1; // foo的类型自动推导为int
if (true) {
var foo = 2; // foo在不同作用域下允许重复声明
}
```
不使用类型推导
```go
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
打印任意数量的参数到标准输出,不添加换行符。
```
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 |

7134
include/doctest.h Normal file

File diff suppressed because it is too large Load Diff

1
include/factorial.hpp Normal file
View File

@ -0,0 +1 @@
int factorial(int number);

3
src/factorial.cpp Normal file
View File

@ -0,0 +1,3 @@
int factorial(int number) {
return number <= 1 ? number : factorial(number - 1) * number;
}

22
src/main.cpp Normal file
View File

@ -0,0 +1,22 @@
#define DOCTEST_CONFIG_IMPLEMENT
#include "doctest.h"
int main() {
doctest::Context context;
context.addFilter("test-case-exclude", "*math*"); // exclude test cases with "math" in their name
context.setOption("abort-after", 5); // stop test execution after 5 failed assertions
context.setOption("order-by", "name"); // sort the test cases by their name
context.setOption("no-breaks", true);
int res = context.run();
if(context.shouldExit()) // important - query flags (and --exit) rely on the user doing this
return res; // propagate the result of the tests
int client_stuff_return_code = 0;
// your program - if the testing framework is integrated in your production code
return res + client_stuff_return_code; // the result from doctest is propagated here as well
}

10
unit/factorial_test.cpp Normal file
View File

@ -0,0 +1,10 @@
#include "doctest.h"
#include "factorial.hpp"
TEST_CASE("testing the factorial function") {
CHECK(factorial(1) == 1);
CHECK(factorial(2) == 2);
CHECK(factorial(3) == 6);
CHECK(factorial(10) == 3628800);
}