TeaScript-语法快速浏览
优质
小牛编辑
126浏览
2023-12-01
一、语句
TeaScript 代码属于 C 风格,但是没有 C 语言那么严谨。在某种意义可以理解为 Python、Ruby 的 C 风格版本。
1. 注释
同 C 语言,使用 // 和 /**/ 来表示注释。此外,还支持 /// 开头的文档注释。
/// 表示一个数组。 // 这是一个文档注释。
class Array {
}
2. 变量定义
变量无需定义,第一次赋值即相当于定义。变量总是定义在当前作用域。
a = 1
3. if 语句
if 语句同其它 C 风格语言。
if (a) {}
if (a) {} else {}
if (a) {} else if (b) else {}
4. for 语句
TeaScript 中没有 while 和 do while 语句,统一使用 for 语句。
for (i = 0; i < 100; i++) {}
for (i < 100) {} // 相当于其它 C 风格语言的 while 语句。
for {} // 等效于 for (true) {}
5. switch 语句
switch 和其它 C 风格语言有两个不同点:1. 每个 case 之间不会互相贯穿。 2. 默认语句使用 case else。
switch(val) {
case 1:
b = 1;
case 2:
goto case 1; // 使用 goto 强制跨 case 。
case 3, 4: // 允许多个值使用逗号分开,而不是写多个 case 。
b = 2;
case 5 ~ 7: // 允许区间匹配。
b = 3;
case else: // 匹配剩余情况。
b = 4;
}
switch {} // 等效于 switch(true) {}
6. try 语句
try 语句允许单独出现,一个 try 语句最多只能有一个 catch 段和一个 finnaly 段。
try {} // 表示忽略任何错误。
try {} catch {} // 在 catch 段中使用 @error 代表当前的错误对象。
try {} finally {]
try {} catch {} finally {]
throw "Error";
7. 跳转语句
break;
continue;
label: // 定义一个标签。
goto label; // 跳转到指定标签。
8. 调试输出语句
在代码中经常需要调试输出一些变量。语言中内置一个语句用于调试输出。
>> 'hello world'; // 相当于 Debugger.trace('hello world');
9. let 语句
let 语句用于控制特定变量,保证资源被正确释放。
let(sql = MySql.open("连接字符串")){ // 打开一个数据库连接。
sql.execute("SQL 语句");
} // 在代码执行完后,系统自动调用 sql.close() 关闭数据库连接资源。
10. lock 语句
lock 语句控制一段代码不会在多个线程内同时执行。
lock { } // lock 里面的代码不会同时执行。
lock (myLockObj) // 使用自定义的线程锁标记。
二、 表达式
1. 常量
以下的值是可以被直接理解的常量值。
0
0xFFFFFF
-1.2
true
false
null
undefined
[1, 2, 3] // 同 JavaScript 的 Array
[aa:1, bb:2] // 同 JavaScript 的 JSON
'' // 单引号是无任何转义的字符串。
"" // 双引号是支持\转义的字符串。
`` // 分隔符是支持$转义和换行的模板字符串。如存储 HTML 片段。
2. 函数
函数定义只需一个 {}, 函数的参数不需声明可以直接使用。
a = { // 定义一个函数。
Console.write(@value); // 通过@标示为参数。
};
a("Hello"); // 函数调用。
a(value: "Hello"); // 使用命名参数传参。
函数还允许输出参数。
a = {
@value = 2; // 输出参数。
};
a(value=>b); // 将参数 value 的值传递给 b 。
3. 操作符
基本操作符
以下操作符同其它语言:
+, -, *, /, %(取余), ++, --, ==, !=, <=, >=, <, >, ||, &&, ! =, +=, -=, *=, /=, %=, ?:
TeaScript 中不直接提供位运算操作符。
区间操作符
a = 1 ~ 6; // 等效于 a = [1, 2, 3, 4, 5, 6]
反向赋值操作符
a => b; // 等效于 b = a;
变量测试操作符
a = value | "a"; // 如果 value 未定义,则值为 "a", 否则值为 value 。
b = {
Console.write(@value | "You don't have money.");
}
b(value: "I have money"); // 输出 "I have money"。
b(); // 对函数 b 来说, 参数 @value 未定义。 输出 "You don't have money."
索引访问操作符
a[0] // 访问索引 0 的值。
a[0 ~ 4] // 访问索引 0 到 4 的子数组。
成员访问操作符
a.b
a.(true ? "a" : "b") // 动态调用
a..b // 链式点操作,如 a..b()..c()..d() 相当于 a.b();a.c();a.d()
类型操作符
a is String // 判断 a 是否是 String
a as String // 将 a 转为 String
or 操作符
fn() or null // 相当于 `try{return fn()}catch{return null}`
三、面向对象和模块化
1. 类
class Duck : Animal {
Duck{} // 构造函数
fun {} // 定义1个方法
fun(value){} // 函数重载
fun(value: String = 100){} // 默认值和 自动转换的类型。
fun(val?){} // 可选参数。
get pro{} // 定义1个属性
set pro{} // 定义1个属性
val = 1 // 定义1个静态字段。
+{} // 操作符的重载
}
类成员函数支持重载。
类的字段、只读属性和事情不需声明。而是通过成员函数直接赋值。
如果类的成员是私有的,请为名字加上前缀 _ 。
class Duck : Animal {
setProps {
this._name = "1"; // 设置一个私有字段。
this.@name2 = "1"; // 设置一个公开的字段。
this.readOnlyProp = "2"; // 设置一个只读属性。
this.click = {} // 设置一个事件。
}
}
extend Duck {
// 通过此方法扩展存在的类成员。
}
2. 其它类型
struct Type [}
interface Interface2 {}
enum Flags {}
namespace Math {} // 仅仅作为名字空间使用的对象。
3. 模块系统
编译器会负责自动导入系统模块。用户也可以通过 import 手动导入模块。
import "path/to/my.code" ; // 导入模块,作为全局的模块。
import "path/to/my.code" => modulename; // 导入模块,作为一个子模块。
四、容错与纠错
在非严格模式下,编译器允许出现一些不是非常重要的语法错误。
1. 省略分号
语句后的分号可以用换行代替。
2. 多余一个逗号
所有逗号分隔的表达式都允许在末尾多一个逗号。
3. 省略 if for switch 语句的小括号
if a < 2 { } // 省略括号
4. 省略最外层函数调用的括号。
Console.write "hello";