写在前面
Griffin Script(以下简称GS)是一种根据ECMAScript基本语法定义的一种针对物流实操和设备流程定义设计的DSL(领域编程语言),基本的语法和ECMAScript 2015 (也被称为ECMAScript 6或者ES6,以下简称ES6) 保持一致,可以参考相关文档学习基本语法,本文主要介绍和ECMAScript有差异的部分。
通用限制
GS运作在ES6的strict mode下,同时GS对于代码有更严格的检查和要求,比如ES6允许省略必要的参数,但是GS会对于缺失的参数报错。所以ES6里面能运行的代码在GS引擎上可能会报错。
语句
GiffinScript 的语句用分号分隔。
var statement = "hello griffin script";
变量
GS推荐使用let
定义变量,同时也支持通过var
来定义变量,两种语法的作用域符合ES6规范,但是GS不支持先使用再申明变量,未经申明的变量使用会产生编译期错误。
let a = "string";
let b; // 初始化为undefined
let c = {foo: "bar"}; // 简单对象
let d = 1;
let d = 2; // 错误,根据ES6规范let不允许重复定义
x = 1; // ES6允许但是GS定义为错误,禁止先使用再定义
var x;
// 正确
var va; // 初始化为undefined
var vb = 1;
var vc = "test";
var array = ["a","b"];
var json = {key: "value"};
var va = 1; // ES6规范允许var重复定义,此处相当于重新赋值
环境变量
GS引擎允许平台层通过Bindings
设置脚本运行时环境变量,这些变量有点类似JavaScript里面的window
或者console
,可以不需要声明直接使用,但是这些变量禁止赋值。
关键字
除了ES6规定的关键词以外,GS额外定义了一个关键字emit
,该关键字用于产生事件,请参考下文了解详细信息。同时字符@
作为特殊字符保留。
字母大小写
GS 对大小写敏感,所有的变量,函数名等都需要正确的大小写,因此函数foo()
与Foo()
是不同的函数,
变量myvariable
与MyVariable
也是不同的。
运算符
GS支持ES6规定的所有操作符,包括赋值、算术运算、比较,逻辑等符号,并且符合ES6规定的语义逻辑。
类型 | 实例 |
---|---|
赋值运算符 | = |
算术运算符 | + - * / ^ ! ++ — & | << >> |
比较运算符 | == != < > |
逻辑运算符 | || && ! |
算数运算符
使用算术运算符来计算值,使用赋值运算符给变量赋值。
// 加减乘除余 优先级:( ) * / % + -
var a = 1 + 1; // 2
var b = 1 - 1.1; // -0.10000000000000009
var c = 2 * 1.1; // 2.2
var d = 1 / 0.1; // 10.0
var e = 4 % 2; // 0
var f = -1; // -1
var g = !true; // false
var h = 1 + 2 * 3; // 7
var i = (1 + 2) * 3; // 9
var j = a++; // 2
var k = ++a; // 3
var l = a--; // 2
var m = --a; // 1
// 位运算
var n = 2 & 3; // 2
var o = 1 | 2; // 0
var p = 2 ^ 3; // 1
var q = ~1; // -2
var r = 1 << 3; // 8
var s = 8 >> 3; // 1
比较运算符
比较运算符在逻辑语句中使用,以测定变量或值是否相等。
- 注意:== 和 === 含义相同,对数据类型做强校验。
var x = 1;
var y = -1;
x > y // true
x >= y // true
x < y // false
x <= y // false
x === y // false
x == y // false
x != y // true
逻辑运算符
逻辑运算符用于测定变量或值之间的逻辑。var x = 1;
var y = true;
// && and
x < 5 // true
// || or
x < 0 || y // true
// ! not
!y // false
注释
GiffinScript 支持代码注释。
// 单行注释内容
/**
多行注释内容
多行注释内容
**/
var a = 16; // 行尾注释
数据类型
GiffinScript 支持多种数据类型:数字,布尔值,字符串,数组,JSON对象,日期时间,正则对象。
var number = 1.6; // Float 通过数字字面量赋值
var points = 16 * 10; // Integer 通过表达式字面量赋值
var bool = true; // Boolean 通过true/false赋值
var lastName = "Griffin"; // String 通过字符串字面量赋值
var firstName = new String("Griffin"); // String 创建字符串对象
var cars = ["BMW", "BENZ", "AUDI"]; // Array 通过数组字面量赋值
var person = {firstName:"Jack", lastName:"Tony"}; // Object 通过对象字面量赋值
var date = new Date(); // Date 创建日期对象
var math = new Math(); // Math 创建数学对象
var regexp = new RegExp("G\\S+", "i"); // RegExp 创建正则对象
整数/浮点数
支持数据之间的算数/比较。
支持字符串转换数字,使用Numer.parseInt()/parseFloat()进行转换。
var number = 123; // 123
var float = 12.3; // 12.3
var newNumber = new Number(123); // 123
// parseInt
var a = Number.parseInt("123"); // 123
var b = Number.parseInt("0x123"); // 291
var c = Number.parseInt("123x345"); // 123
var d = Number.parseInt("123", 16); // 291
// parseFloat
var e = Number.parseFloat("-12.3"); // -12.3
var f = Number.parseFloat("-12.3.4"); // -12.3
支持复杂数学运算,使用Math.xxx(num)进行计算。
支持三角函数(acos, asin, atan, atan2, cos, sin, tan),取整(ceil, round, floor),幂/指数计算(pow, sqrt, exp, log)
Math.random(); // (0,1)随机数
Math.abs(-1); // 1
Math.acos(1); // 0
Math.ceil(1.4); // 2
Math.round(1.6); // 2
Math.sqrt(4); // 2
Math.pow(2, 2); // 4
...
布尔值
字符串
支持字符串的拼装(+),截取(substring),修改(replace),长度(length),字符位置(indexOf),正则查找(search),正则匹配(match),拆分(split)方法。
var s0 = new String("Griffin Script");
var s = "Griffin" + "Script"; // "GriffinScript"
var substring = s.substring(0, 7); // "Griffin"
var replace = s.replace("Griffin", "Cainiao"); // "CainiaoScript"
var index = s.indexOf("Script"); // 7
var length = s.length; // 13
var searchIndex = s.search(".i"); // 1
var mList = "1+2=3".match("\\d+","g"); // [1, 2, 3]
var sList = s0.split(" "); // ["Griffin", "Script"]
方法 | 说明 | 备注 |
---|---|---|
substring | ||
replace | ||
indexOf | ||
search | ||
match | ||
split | ||
charAt |
数组
支持数组长度(length),增加数据([index], push),移除首位元素(shift),删除末尾元素(pop),组合(concat),查找(indexOf)方法。
var array = [1, 2, 3];
var length = array.length; // 3
array[5] = 6; // [1,2,3,null,null,6]
array.push(7); // [1,2,3,null,null,6,7]
array.shift(); // [2,3,null,null,6,7]
array.pop(); // [2,3,null,null,6];
array.indexOf(3); // 1
array.indexOf(100); // -1
var t = array.concat([8,9]); // [2,3,null,null,6,8,9]
方法 | 说明 | 备注 |
---|---|---|
concat |
||
copyWithin |
||
entries |
||
fill |
||
flat |
||
includes |
||
indexOf |
||
join |
||
keys |
||
lastIndexOf |
||
pop |
||
push |
||
reverse |
||
shift |
||
slice |
JSON对象
支持json对象,可以直接解析处理。
var person = {
name: "Jack",
age: 24,
feature: [
{ name:"company" , desc:"cainiao" },
{ name:"work" , desc:"Software Engineer" },
]
};
var name = person.name; // "Jack"
var work = person.feature[1].desc; // "Software Engineer"
person.IQ = 130;
var IQ = person.IQ; // 130
GS支持基本的JSON处理方法,包括JSON.stringify()
和JSON.parse()
,比如下面的例子:
var text = '{ "employees" : [' +
'{ "firstName":"John" , "lastName":"Doe" },' +
'{ "firstName":"Anna" , "lastName":"Smith" },' +
'{ "firstName":"Peter" , "lastName":"Jones" } ]}';
var obj = JSON.parse(text);
text = JSON.stringify(obj);
下面的语法暂时是不支持的。
// WARNING: NOT supported by Griffin Script
var myObj = {
myMethod: function(params) {
// ...
}
};
对象比较
两个对象使用 == 做比较,如果值相等,会返回true,例如:
var a = {key:"v1"};
var b = {key:"v1"};
a==b; //true
⚠️ 这个是不符合ecma规范的。
日期时间
支持创建日期对象,并支持获取具体时间数据,UTC时间数据,GMT格式(toString),自定义格式(format)。
var df = "yyyy-MM-dd HH:mm:ss";
var date = new Date(); // 当前时间
date.toString(); // Wed Apr 29 2020 15:06:29 z+0800
date.format(df); // 2020-04-29 15:06:29
date.getTime(); // 时间戳
date.getFullYear(); // 年
date.getMonth(); // 月
date.getDate(); // (月)日
date.getDay(); // (周)日
date.getHours(); // (24小时制)时
date.getMinutes(); // 分钟
date.getSeconds(); // 秒
date.getMilliseconds(); // 毫秒
// UTC时间
date.getUTCFullYear(); // 年
...
方法 | 说明 | 备注 |
---|---|---|
getDate | ||
getDay | ||
getFullYear | ||
getHours | ||
getMilliseconds | ||
getMinutes | ||
getMonth | ||
getSeconds | ||
getTime | ||
getTimezoneOffset | ||
getUTCDate | ||
getUTCDay | ||
getUTCFullYear | ||
getUTCHours | ||
getUTCMilliseconds | ||
getUTCMinutes | ||
getUTCMonth | ||
getUTCSeconds | ||
setDate | ||
setFullYear | ||
setHours | ||
setMilliseconds | ||
setMinutes | ||
setMonth | ||
setSeconds | ||
setTime | ||
setUTCDate | ||
setUTCFullYear | ||
setUTCHours | ||
setUTCMilliseconds | ||
setUTCMinutes | ||
setUTCMonth | ||
setUTCSeconds | ||
toDateString | ||
toISOString | ||
toString | ||
toUTCString | ||
format | 非ecma标准方法 |
正则对象
支持正则对象,可以通过正则对象进行正则表达式的匹配计算。
// 手机号校验
var regexp = new RegExp(/^1[3-9]\d{9}$/);
var p = regexp.test("13345678998"); // true
var regexp2 = new RegExp("G\\S+", "i");
var s = regexp2.exec("Hello GriffinScript"); // GriffinScript
条件语句
GiffinScript 支持 if - else if - else 条件语句。
- 处理逻辑不能为空,可以用空语句( ; )占位。
- 支持 ! 符号,运算优先级最低。 ```javascript var number = 1; if (number < 1){ ; } else if (number == 1){ ; } else { ; }
var a = true; if(a){ // true ; } if(!a){ // false; ; }
var jsonObj = {a: 1}; if(jsonObj.a){ // true ; } if(jsonObj.b){ // false ; } if(!jsonObj.b){ // true ; }
<a name="a2PlN"></a>
## 循环语句
GiffinScript 支持for/while/do-while循环,支持在循环中使用continue/break中断流程。
<a name="IalAg"></a>
### for循环
```javascript
var array = [1,2,3,4];
for (var i = 0; i < array.length(); i++) {
...
}
while循环
var i = 0;
while(i < 10){
i++;
}
do-while循环
var i = 0;
do{
i++;
}while(i < 10);
break 和 continue
- continue 跳出当前循环,进行下一个循环。
- break 中断循环。
```javascript
var array = [1,2,3,4];
var result = [];
for (var i = 0; i < array.length(); i++) {
if(array[i] % 2 == 0){
}continue;
}result[i] = array[i]; // [1,null,3]
for (var i = 0; i < array.length(); i++) { if(array[i] % 2 == 0){ break; } result[i] = array[i]; // [1] }
<a name="6kblM"></a>
## 函数
GiffinScript 支持函数。函数可以被程序直接调用,也可以被信号量调用。
- 函数需要定义在函数调用之前(先定义,再使用)。函数之间的调用,不要求函数的定义顺序。
- 函数名唯一(不支持重载)。
- 函数可以通过 return 返回。
```javascript
function foo(a, b){
bar();
return a + b;
}
function bar(){
return;
}
var result = foo(1, 2); // 3