CatBase 是一种静态类型编程语言,设计目标是简洁、易学,同时具备强大的功能。它支持网络编程、多线程、文件操作等常用特性,并且可以导入 C 语言库。
下面是 CatBase 的 Hello World 程序:
def main(args:list) {
print("Hello, World!")
}
CatBase 编译器(catcc)将 .cat 文件编译为可执行文件。
# 编译源文件
catcc source.cat
# 编译并运行
catcc source.cat && ./source
| 参数 | 说明 |
|---|---|
-no-emit-obj | 编译后不生成 .o 目标文件 |
-shared | 生成共享库(.so)而不是可执行文件 |
编译成功后,会生成以下文件:
source - 可执行文件(无扩展名)source.o - 目标文件(可通过 -no-emit-obj 禁用)out/source.zig - 生成的 Zig 中间代码libsource.so - 共享库(使用 -shared 参数时生成)编译器使用可执行文件所在目录作为基准目录:
catcc/
├── bin/
│ └── zig # Zig 编译器
├── out/
│ └── runtime/ # 运行时库
└── catcc # 编译器可执行文件
无论从哪个目录运行 catcc,它都会自动找到上述目录。
CatBase 要求所有变量必须显式声明类型。变量声明使用冒号 : 分隔变量名和类型。
变量名:类型 = 初始值
def main(args:list) {
// 整数类型
age:int = 25
// 浮点数类型
price:float = 19.99
// 字符串类型
name:str = "CatBase"
// 布尔类型
is_active:bool = True
print("Name: ", name, "\n")
print("Age: ", age, "\n")
print("Price: ", price, "\n")
print("Active: ", is_active, "\n")
}
def main(args:list) {
numbers:list = [1, 2, 3, 4, 5]
print("Numbers: ", numbers, "\n")
print("First: ", numbers[0], "\n")
}
def main(args:list) {
person:dict = {"name": "Tom", "age": 20}
print("Person: ", person, "\n")
print("Name: ", person["name"], "\n")
}
def main(args:list) {
x = 10 // 错误:必须显式声明类型
}
编译错误:line 3: [Type Error] Variable 'x' must be explicitly declared with a type
函数使用 def 关键字定义。
def 函数名(参数:类型, ...) : 返回类型 {
// 函数体
return 值
}
def greet() {
print("Hello, World!")
}
def main(args:list) {
greet()
}
def greet(name:str) {
print("Hello, ", name, "!")
}
def main(args:list) {
greet("CatBase")
}
def add(a:int, b:int) : int {
return a + b
}
def main(args:list) {
result:int = add(5, 3)
print("5 + 3 = ", result, "\n")
}
每个 CatBase 程序必须包含一个 main 函数作为入口点。
CatBase 使用 // 进行单行注释。
def main(args:list) {
// 这是一个注释
print("Hello") // 这也是注释
}
| 类型 | 说明 | 示例 |
|---|---|---|
int | 整数 | 42, -10 |
float | 浮点数 | 3.14, -0.5 |
str | 字符串 | "Hello" |
bool | 布尔值 | True, False |
list | 列表 | [1, 2, 3] |
dict | 字典 | {"key": "value"} |
bytes | 字节序列 | bytes(256) |
def main(args:list) {
nums:list = [1, 2, 3, 4, 5]
print("First: ", nums[0], "\n")
print("Last: ", nums[4], "\n")
nums[0] = 10
print("Modified: ", nums, "\n")
print("Length: ", len(nums), "\n")
}
def main(args:list) {
person:dict = {"name": "Tom", "age": 20}
print("Name: ", person["name"], "\n")
person["age"] = 21
print("Updated: ", person, "\n")
person["country"] = "China"
print("After add: ", person, "\n")
}
bytes 类型表示字节序列,用于处理二进制数据。
def main(args:list) {
data:bytes = bytes(256)
data[0] = 72
data[1] = 101
print("bytes length: ", len(data), "\n")
}
| 函数 | 说明 |
|---|---|
int(x) | 将 x 转换为整数 |
float(x) | 将 x 转换为浮点数 |
str(x) | 将 x 转换为字符串 |
def main(args:list) {
n:int = int("42")
print("int('42') = ", n, "\n")
s:str = str(123)
print("str(123) = '", s, "'\n")
f:float = float(10)
print("float(10) = ", f, "\n")
}
| 运算符 | 说明 | 示例 |
|---|---|---|
+ | 加法 | 5 + 3 → 8 |
- | 减法 | 5 - 3 → 2 |
* | 乘法 | 5 * 3 → 15 |
/ | 除法 | 5 / 2 → 2 |
% | 取余 | 5 % 2 → 1 |
| 运算符 | 说明 | 示例 |
|---|---|---|
== | 等于 | 5 == 5 → True |
!= | 不等于 | 5 != 3 → True |
< | 小于 | 3 < 5 → True |
> | 大于 | 5 > 3 → True |
| 运算符 | 说明 | 示例 |
|---|---|---|
and | 逻辑与 | True and False → False |
or | 逻辑或 | True or False → True |
not | 逻辑非 | not True → False |
def main(args:list) {
age:int = 18
if age >= 18 {
print("成年人\n")
} else {
print("未成年人\n")
}
}
def main(args:list) {
nums:list = [1, 2, 3, 4, 5]
for i in nums {
print("Value: ", i, "\n")
}
}
def main(args:list) {
i:int = 0
while i < 5 {
print("i = ", i, "\n")
i = i + 1
}
}
CatBase 使用 try...catch 语句来处理异常。
def main(args:list) {
try {
result:int = 10 / 0
print("Result: ", result, "\n")
} catch {
print("Error occurred!\n")
}
}
def add(a:int, b:int) : int {
return a + b
}
def main(args:list) {
result:int = add(5, 3)
print("5 + 3 = ", result, "\n")
}
def factorial(n:int) : int {
if n <= 1 {
return 1
}
return n * factorial(n - 1)
}
def main(args:list) {
print("5! = ", factorial(5), "\n")
}
def main(args:list) {
print("Hello\n")
print("Number: ", 42, "\n")
print("Bool: ", True, "\n")
}
| 函数 | 说明 |
|---|---|
abs(x:int) | 返回绝对值 |
max(a:int, b:int) | 返回较大值 |
min(a:int, b:int) | 返回较小值 |
sum(list) | 返回列表所有元素的和 |
pow(base:int, exp:int) | 返回幂运算结果 |
round(x:float) | 四舍五入 |
| 函数 | 说明 |
|---|---|
int(x) | 转换为整数 |
float(x) | 转换为浮点数 |
str(x) | 转换为字符串 |
bin(x:int) | 转换为二进制 |
oct(x:int) | 转换为八进制 |
hex(x:int) | 转换为十六进制 |
chr(x:int) | 整数转换为字符 |
ord(x:str) | 字符转换为整数 |
| 函数 | 说明 |
|---|---|
exec(cmd:str) | 执行系统命令 |
sleep(seconds:int) | 暂停执行 |
input(prompt:str) | 从标准输入读取用户输入 |
type(x) | 返回变量的类型名称 |
isinstance(x, type_name:str) | 检查变量是否为指定类型 |
len(x) | 返回长度 |
range(n:int) | 生成范围 |
def main(args:list) {
name:str = input("Please enter your name: ")
print("Hello, ", name, "!\n")
}
def main(args:list) {
a:int = 10
b:str = "hello"
print("type(10) = ", type(a), "\n")
print("type('hello') = ", type(b), "\n")
}
def main(args:list) {
a:int = 10
print("isinstance(10, 'int') = ", isinstance(a, "int"), "\n")
print("isinstance(10, 'str') = ", isinstance(a, "str"), "\n")
}
open(filename:str, mode:str) : File
"r" - 读取模式"w" - 写入模式(覆盖)"a" - 追加模式def main(args:list) {
f = open("test.txt", "w")
f.write("Hello, CatBase!")
close(f)
f2 = open("test.txt", "r")
content:str = f2.read()
close(f2)
print("Content: ", content, "\n")
}
tcpConnect(host:str, port:int) : TCPClient
tcpListen(port:int) : TCPServer
| 函数 | 说明 |
|---|---|
httpGet(url:str) | 发送 HTTP GET 请求 |
httpPost(url:str, data:str) | 发送 HTTP POST 请求 |
udpCreate() : UDPSocket
spawn(func, args) - 创建新线程
def worker(id:int) {
print("Worker ", id, " started\n")
sleep(1)
print("Worker ", id, " finished\n")
}
def main(args:list) {
print("Main thread started\n")
spawn(worker, 1)
spawn(worker, 2)
sleep(2)
print("Main thread finished\n")
}
| 函数 | 说明 |
|---|---|
mutex() | 创建互斥锁 |
lock(mutex) | 加锁 |
unlock(mutex) | 解锁 |
join(thread) | 等待线程结束 |
Mutex(互斥锁)是一种用于多线程编程的同步机制。在多线程程序中,当多个线程同时访问共享资源(如变量、文件、数据库连接等)时,可能会产生竞态条件(Race Condition)和数据不一致的问题。
Mutex 的作用是:
假设有多个线程同时对同一个计数器进行加法操作:
没有 mutex 的情况:
线程A读取counter=0 线程B读取counter=0 (A还没写回) 线程A写回counter=1 线程B写回counter=1 (覆盖了A的结果,丢失了一次加法) 结果:counter=1(应该是2)
有 mutex 的情况:
线程A获取mutex锁 → 线程A读取counter=0 → 计算 → 写回counter=1 → 释放锁 线程B获取mutex锁 → 线程B读取counter=1 → 计算 → 写回counter=2 → 释放锁 结果:counter=2(正确)
| 特性 | 说明 |
|---|---|
| 作用 | 保护共享资源,防止数据竞争 |
| 特性 | 独占性、不可重入(同一线程不能重复加锁) |
| 适用场景 | 多线程访问同一变量、文件、数据库等共享资源 |
| 函数 | 说明 |
|---|---|
atomic_add(ptr, value) | 原子加法 |
atomic_sub(ptr, value) | 原子减法 |
atomic_load(ptr) | 原子读取 |
atomic_store(ptr, value) | 原子写入 |
原子操作(Atomic Operations)是指不可中断的操作,即操作在执行过程中不会被线程调度机制中断。在多线程编程中,原子操作确保某个操作要么完全执行,要么完全不执行,不会出现"执行一半"的情况。
为什么需要原子操作?
在多线程环境下,普通的变量操作(如 counter = counter + 1)实际上包含多个步骤:
这些步骤之间可能被其他线程插入,导致数据竞争。使用原子操作可以确保这一系列步骤作为单一不可分割的操作执行。
| 特性 | 原子操作 | Mutex |
|---|---|---|
| 性能 | 更快,开销更小 | 较慢,有锁开销 |
| 适用场景 | 简单数值操作 | 复杂临界区 |
| 用途 | 计数器、标志位等 | 保护代码块 |
什么情况下使用原子操作:
使用注意事项:
i64、int)有效CatBase 支持将代码编译为共享库(.so 文件),供其他程序或 CatBase 代码导入使用。
使用 -shared 参数将 CatBase 代码编译为共享库:
# 编译生成共享库 libmylib.so
catcc -shared mylib.cat
首先创建一个包含公共函数的 CatBase 源文件:
// mylib.cat - 定义公共函数
def add(a:int, b:int) {
result:int = a + b
print("add: ", a, " + ", b, " = ", result, "\n")
}
def multiply(a:int, b:int) {
result:int = a * b
print("multiply: ", a, " * ", b, " = ", result, "\n")
}
编译为共享库:
catcc -shared mylib.cat
这将生成 libmylib.so 文件。
编译生成共享库后,可以在其他 CatBase 代码中导入使用:
import "./libmylib.so" as mylib
def main(args:list) {
mylib.add(5, 3)
mylib.multiply(4, 7)
}
CatBase 支持导入 C 语言编写的共享库(.so)和静态库(.a)。
import "./libtest.so" as test
def main(args:list) {
result:int = test.add(5, 7)
print("5 + 7 = ", result, "\n")
}
import "./libtest.a" as test
def main(args:list) {
result:int = test.add(5, 7)
print("5 + 7 = ", result, "\n")
}
import "libm.so" as math
def main(args:list) {
result:float = math.sqrt(16.0)
print("sqrt(16) = ", result, "\n")
}
| 关键字 | 说明 |
|---|---|
def | 定义函数 |
if | 条件语句 |
else | 否则 |
for | 循环 |
while | 循环 |
return | 返回值 |
try | 尝试块 |
catch | 捕获异常 |
spawn | 创建线程 |
import | 导入模块 |
| 类型 | 说明 |
|---|---|
int | 整数 |
float | 浮点数 |
str | 字符串 |
bool | 布尔值 |
list | 列表 |
dict | 字典 |