XLang - Lightweight programming language
Project description
XLang
1. 简介
XLang(X Lang)是一种轻量级、动态类型的脚本语言,结合了函数式和面向对象编程范式的特点。它的设计目标是提供最简单抽象的语法去实现最复杂的功能。XLang 采用基于栈的虚拟机架构执行中间表示代码,适用于快速原型开发、脚本自动化和通用编程任务。
2. 语法基础
2.1 程序结构
XLang 程序由一系列语句组成,每条语句以分号 ; 结尾。代码块使用花括号 {} 包围。分号分隔的表达式序列会返回最后一个表达式的值,空表达式默认返回 null。
// 单行注释以双斜杠开头
statement1;
statement2;
/*
多行注释使用斜杠星号
可以跨越多行
*/
{
// 代码块
statement3;
statement4;
}
// 表达式序列返回最后一个表达式的值
result := (a = 1; b = 2; a + b); // result 的值为 3
2.2 标识符与关键字
标识符用于命名变量和函数,由字母、数字和下划线组成,但不能以数字开头。XLang 的关键字包括:
if,else,while,break,continue,returntrue,false,nullcopy,ref,deref,keyof,valueof,selfof,assert,importself
3. 数据类型
XLang 提供以下数据类型:
3.1 基本类型
整数 (Int)
x := 42;
浮点数 (Float)
y := 3.14;
字符串 (String)
XLang 支持多种字符串表示形式:单引号、双引号、三引号,并支持字符串转义序列。
name1 := "XLang";
name2 := 'XLang';
multiline := '''
多行
字符串
''';
布尔值 (Bool)
isValid := true;
空值 (NoneType)
data := null;
3.2 复合类型
元组 (Tuple)
元组是值的有序集合,可包含不同类型:
coordinates := (10, 20, 30);
键值对 (KeyValue)
键值对用于关联键和值:
point := ('x': 10, 'y': 20);
函数 (Lambda)
adder := (a, b) -> {
return a + b;
};
命名参数 (Named)
namedArg := name => "default";
内置函数 (BuiltIn)
系统提供的内置函数类型。
4. 变量
4.1 变量声明和赋值
使用 := 声明新变量,使用 = 为已声明变量赋值:
// 变量声明
age := 25;
// 变量赋值
age = 26;
4.2 作用域
XLang 使用动态作用域规则,但闭包变量需要在参数声明中显式捕获:
x := 10;
{
// 新的作用域
y := 20; // 只在本作用域内有效
x = 15; // 可访问并修改外部作用域的变量
}
// y 在此处不可访问
// x 在此处值为 15
// 闭包必须显式捕获外部变量
outer := 100;
func := (captured => outer) -> { // 显式捕获outer变量
return captured + 1;
};
注意:XLang 允许访问调用者的作用域!
5. 运算符
5.1 运算符优先级
根据AST解析器代码分析,XLang的运算符优先级从高到低排列如下:
-
最高优先级
- 变量/常量/括号表达式/作用域 (优先级1)
- 成员访问:
.,[],()(函数调用)(优先级2) - 修饰符:
copy,ref,deref,keyof,valueof,selfof,assert,import(优先级3)
-
算术运算符
- 乘法级:
*,/,%(优先级9) - 加法级:
+,-(优先级10) - 一元运算符:
+,-(与加法级相同)
- 乘法级:
-
比较运算符
- 比较级:
>,<,>=,<=,==,!=(优先级11)
- 比较级:
-
逻辑运算符
- 逻辑级:
not(优先级12) - 逻辑与:
and(优先级13) - 逻辑或:
or(优先级14)
- 逻辑级:
-
控制结构
break,continue(优先级19)if(优先级20)while(优先级21)
-
其他运算符
- 键值对:
:(优先级22) - 命名参数:
=>(优先级23) - 赋值:
=(优先级30) - 变量声明:
:=(优先级40) - 函数定义:
->(优先级4) - 元组:
,(优先级59) return(优先级60)- 语句分隔:
;(优先级70)
- 键值对:
5.2 算术运算符
+: 加法-: 减法*: 乘法/: 除法%: 取模
sum := 5 + 3;
difference := 10 - 4;
product := 6 * 7;
quotient := 20 / 4;
remainder := 10 % 3;
5.3 比较运算符
==: 相等!=: 不相等<: 小于>: 大于<=: 小于等于>=: 大于等于
isEqual := x == y;
isGreater := age > 18;
5.4 逻辑运算符
not: 逻辑非and: 逻辑与or: 逻辑或
isValid := age > 18 and hasID;
isEligible := hasLicense or hasPermit;
5.5 成员访问运算符
.: 属性访问[]: 索引访问(): 函数调用
person := ('name': "John", 'age': 30);
personName := person.name; // 自动将name视为'name'字符串进行属性访问
firstChar := name[0];
result := func(arg); // 函数调用
6. 控制结构
6.1 条件语句
XLang 支持两种条件语句形式:
// 块形式
if condition { // condition为单个token或者被括号包围的表达式
// 条件为真时执行
} else {
// 条件为假时执行
};
// 表达式形式
result := if condition 1 else 0;
支持 else if 组合:
if (operator == "+") {
// 加法操作
} else if (operator == "-") {
// 减法操作
} else if (operator == "*") {
// 乘法操作
} else {
// 默认操作
};
6.2 循环语句
while condition { // condition为单个token或者被括号包围的表达式
// 条件为真时重复执行
};
6.3 中断语句
while (condition) {
if (breakCondition) {
break; // 跳出循环
};
if (skipCondition) {
continue; // 跳到下一次迭代
};
};
XLang 的 break 和 continue 可以穿透内部作用域,直接控制最近的循环:
while (i < 5) {
{
// 内部作用域
if (condition) {
break; // 跳出外层while循环
};
};
i = i + 1;
};
7. 函数
7.1 函数定义
add := (a => 0, b => 0) -> {
return a + b;
};
7.2 函数调用
result := add(5, 3);
7.3 默认参数和命名参数
XLang 严格要求使用 => 操作符声明命名参数:
greet := (name => "World", greeting => "Hello") -> {
return greeting + ", " + name + "!";
};
result1 := greet(); // 使用默认参数
result2 := greet(greeting => "Hi", name => "Alice"); // 使用命名参数
7.4 闭包与变量捕获
XLang 中的闭包必须显式捕获外部变量作为参数:
createCounter := (startValue => 0) -> {
return (count => startValue) -> { // 显式捕获startValue
count = count + 1;
return count;
};
};
counter := createCounter(10);
value1 := counter(); // 11
value2 := counter(); // 12
7.5 自引用与方法
通过 self 关键字实现对对象自身的引用:
person := (
'name': "John",
greet => () -> {
return "Hello, my name is " + self.name;
}
);
重要特性:方法可以单独提取并调用,仍然保持对原始对象的引用:
method := person.greet;
greeting := method(); // "Hello, my name is John"
8. 数据结构操作
8.1 元组操作
// 创建元组
numbers := (1, 2, 3, 4, 5);
// 获取长度
length := len(numbers);
// 索引访问
first := numbers[0];
// 切片
subset := slice(numbers, 1, 3); // (2, 3)
// 合并元组
combined := numbers + (6, 7, 8);
注意:元组在构建时会遍历所有元素,如果元素Named下的Lambda类型,会将元组自身引用传递给Lambda的self属性,这样Lambda就可以访问元组的成员。
8.2 对象式操作
XLang 使用键值对创建类似对象的结构:
// 创建对象
person := (
'name': "John",
'age': 30,
greet => () -> {
return "Hello, my name is " + self.name;
}
);
// 访问属性
name := person.name; // 注意:这里name会被自动解析为'name'字符串
// 调用方法
greeting := person.greet();
9. 特殊操作符
9.1 引用与解引用
// 创建引用
x := 10;
xRef := ref x;
// 解引用
deref xRef = 20; // 修改引用指向的值
// x 的值现在是 20
9.2 值操作符
// 键值操作
obj := ('a': 1, 'b': 2);
keys := keyof obj; // 获取所有键
values := valueof obj; // 获取所有值
// 自引用操作
self := selfof func; // 获取函数的 self 对象
// 复制操作
copied := copy obj; // 创建深拷贝
9.3 断言
assert(x > 0); // 如果条件为假,抛出错误
10. 模块系统
10.1 导入模块
XLang 中模块是以特殊格式存储的 IR 代码,使用 import 关键字导入:
// 导入模块并传递默认参数
// 注意:import返回一个lambda函数,需要调用它获取实际模块内容
mathModule := import "path/to/module.xir" => (config => defaultConfig);
// 调用模块获取实际值
math := mathModule();
// 使用模块功能
result := math.add(5, 3);
10.2 创建模块
模块实际上是返回对象的代码:
// 在module.xir文件中
print(config); // 使用导入时传入的参数
(
add => (a => 0, b => 0) -> {
return a + b;
},
subtract => (a => 0, b => 0) -> {
return a - b;
}
)
11. 内置函数
XLang 提供以下内置函数:
11.1 输入输出
print(...args): 输出参数值input(): 读取用户输入
11.2 类型操作
type(value): 返回值的类型名称int(value): 转换为整数float(value): 转换为浮点数str(value): 转换为字符串bool(value): 转换为布尔值repr(value): 返回值的详细字符串表示
11.3 集合操作
len(collection): 返回集合长度range(start, end, step): 创建数字序列sum(collection): 计算集合元素之和max(collection): 返回集合中最大元素min(collection): 返回集合中最小元素slice(collection, start, end): 返回子集合del(collection, index): 删除集合中的元素replace(collection, key, value): 替换集合中的元素
12. 高级功能
12.1 迭代器模式
XLang 运行迭代语法,但同样可以实现迭代器模式:
iterator := (
iter => (container => ('T' : null), n => 0) -> {
n = n + 1;
E := valueof container; // 获取容器的值引用
T := keyof container; // 获取容器的键
if (n <= len(T)) {
(deref E) = T[n - 1]; // 更新引用值
return true;
} else {
return false;
};
},
loop => (func => (n => 0) -> {return false}) -> {
return (n => 0, func => func) -> {
while (func(n)) {
n = n + 1;
};
};
}
);
// 使用迭代器
loop_func := iterator.loop((n => 0) -> {
print(n);
return n < 5; // 继续条件
});
loop_func(); // 执行迭代
12.2 函数式编程
XLang 支持高阶函数和函数式编程范式:
// Z组合子实现匿名递归函数
Z := (f => (x => null) -> { return x(x); }) -> {
return f((x => null, f => f) -> {
return f(Z(f))(x);
});
};
// 使用Z组合子实现阶乘函数
factorial := Z((f => null) -> {
return (n => 0, f => f) -> {
if (n <= 1) {
return 1;
} else {
return n * f(n - 1);
};
};
});
print(factorial(5)); // 120
13. 示例代码
13.1 简单函数
add := (a => 0, b => 0) -> {
return a + b;
};
print(add(5, 3)); // 输出: 8
13.2 对象和方法
person := (
'name': 'Alice',
greet => (message => 'Hello') -> {
return message + ", " + self.name + "!";
}
);
print(person.greet()); // 输出: Hello, Alice!
method := person.greet;
print(method()); // 仍然输出: Hello, Alice!
13.3 闭包和状态
createCounter := () -> {
count := 0;
return (count => count) -> { // 返回闭包,显式捕获count
count = count + 1;
return count;
};
};
counter := createCounter();
print(counter()); // 输出: 1
print(counter()); // 输出: 2
13.4 条件表达式
max := (a, b) -> {
return if a > b a else b;
};
print(max(5, 3)); // 输出: 5
13.5 复杂对象操作
// 创建一个"类"
Person := (name => '', age => 0) -> {
return (
'name': name,
'age': age,
greet => () -> {
return "Hello, I'm " + self.name;
},
birthday => () -> {
self.age = self.age + 1;
return "Happy birthday! Now I'm " + str(self.age);
}
);
};
// 创建实例
john := Person("John", 30);
greeting := john.greet();
birthday_message := john.birthday();
13.6 复杂表达式的优先级示例
// 算术运算符优先级
result := 2 + 3 * 4; // 等于 2 + (3 * 4) = 14
// 成员访问优先级高于其他操作符
obj := ('value': 5, 'multiplier': 2);
result := obj.value * obj.multiplier; // 10
// 函数调用优先级与成员访问相同
add := (a, b) -> { return a + b; };
result := add(2, 3) * 4; // (2+3) * 4 = 20
// 赋值优先级低于大多数操作
x := 0;
x = 1 + 2; // x = (1+2) = 3
// 逻辑运算符优先级
condition := 5 > 3 and 10 < 20; // (5 > 3) and (10 < 20) = true
14. 错误处理
XLang 使用异常进行错误处理,运行时错误会导致程序终止并提供详细的错误信息:
- 代码位置 (行号和列号)
- 错误类型和消息
- 调用堆栈追踪
- 相关代码段
使用 assert 可以进行条件检查:
// 断言条件为真,否则抛出错误
assert(x > 0);
15. 最佳实践
-
显式变量捕获
outer := 10; // 正确:显式捕获外部变量 func := (captured => outer) -> { return captured + 1; }; -
使用命名参数提高可读性
createPerson(name => "John", age => 30); -
使用元组实现面向对象编程
person := ( 'name': "John", greet => () -> { return "Hello, " + self.name; } ); -
模块化代码
// 创建可复用的模块 mathModule := ( add => (a => 0, b => 0) -> { return a + b; }, multiply => (a => 0, b => 0) -> { return a * b; } ); -
使用引用类型管理共享状态
shared := ('count': 0); sharedRef := ref shared; -
使用分号分隔表达式序列
// 多个表达式,返回最后一个表达式的值 result := (x = 1; y = 2; x + y); // result为3 -
合理运用运算符优先级
// 使用括号明确优先级 result := (1 + 2) * 3; // 而不是依赖默认优先级
16. 局限性与注意事项
- 闭包变量必须显式捕获:所有在闭包中使用的外部变量必须作为参数显式捕获。
- 分号要求:所有表达式末尾必须有分号(除了最后一个表达式),包括控制结构。
- 动态类型检查:类型错误在运行时检测,没有静态类型检查。
- 条件表达式括号:块形式的
if和while语句的条件如果是复杂表达式必须用括号包围。 - 模块导入机制:模块被视为Lambda表达式,必须先调用才能获取实际内容。
- 属性访问自动转换:当使用点操作符访问对象属性时,如
obj.name,标识符name会被自动解析为字符串'name'。 - 表达式序列:分号分隔的表达式序列会返回最后一个表达式的值,空表达式返回
null。 - 运算符优先级:注意运算符的优先级顺序,特别是在复杂表达式中,必要时使用括号明确意图。
- 参数缓存:Lambda函数的参数会被缓存,也就是说,如果不显示指定参数的值,那么参数会使用上一次的值。
- 元组Lambda捕获:元组在构建时会遍历所有元素,如果元素是Named类型的值且值是Lambda类型,会将元组自身引用传递给Lambda的self属性,这样Lambda就可以访问元组的成员。
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file xlang-script-0.1.0.post6.tar.gz.
File metadata
- Download URL: xlang-script-0.1.0.post6.tar.gz
- Upload date:
- Size: 42.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/5.1.1 CPython/3.10.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
13cfff010bf4c9ab4f5c2aaa951718aa544ef2dc279703f51f107bff90799164
|
|
| MD5 |
a9fbb20a25853b73c3be4f55b2b9f793
|
|
| BLAKE2b-256 |
69e0df38d48ac503e3b8f2cb1c0f437d873ccfbe97c0fa3247bd7d214b0a1f16
|
File details
Details for the file xlang_script-0.1.0.post6-py3-none-any.whl.
File metadata
- Download URL: xlang_script-0.1.0.post6-py3-none-any.whl
- Upload date:
- Size: 38.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/5.1.1 CPython/3.10.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d9353310511a122417a2870a4559dcc4f6acf60bdda66e3aed510c638a129cc2
|
|
| MD5 |
ea6e65690163c2631c69c13c6af37682
|
|
| BLAKE2b-256 |
9625507e013b04e349c739370df4d58c7642cf26e8fdb96c4d7cb674c1d1df95
|