写在前面

Griffin Script(以下简称GS)是一种根据ECMAScript基本语法定义的一种针对物流实操和设备流程定义设计的DSL(领域编程语言),基本的语法和ECMAScript 2015 (也被称为ECMAScript 6或者ES6,以下简称ES6) 保持一致,可以参考相关文档学习基本语法,本文主要介绍和ECMAScript有差异的部分。

通用限制

GS运作在ES6的strict mode下,同时GS对于代码有更严格的检查和要求,比如ES6允许省略必要的参数,但是GS会对于缺失的参数报错。所以ES6里面能运行的代码在GS引擎上可能会报错。

语句

GiffinScript 的语句用分号分隔。

  1. var statement = "hello griffin script";

变量

GS推荐使用let定义变量,同时也支持通过var来定义变量,两种语法的作用域符合ES6规范,但是GS不支持先使用再申明变量,未经申明的变量使用会产生编译期错误。

  1. let a = "string";
  2. let b; // 初始化为undefined
  3. let c = {foo: "bar"}; // 简单对象
  4. let d = 1;
  5. let d = 2; // 错误,根据ES6规范let不允许重复定义
  6. x = 1; // ES6允许但是GS定义为错误,禁止先使用再定义
  7. var x;
  8. // 正确
  9. var va; // 初始化为undefined
  10. var vb = 1;
  11. var vc = "test";
  12. var array = ["a","b"];
  13. var json = {key: "value"};
  14. var va = 1; // ES6规范允许var重复定义,此处相当于重新赋值

环境变量

GS引擎允许平台层通过Bindings设置脚本运行时环境变量,这些变量有点类似JavaScript里面的window或者console,可以不需要声明直接使用,但是这些变量禁止赋值

关键字

除了ES6规定的关键词以外,GS额外定义了一个关键字emit,该关键字用于产生事件,请参考下文了解详细信息。同时字符@作为特殊字符保留。

字母大小写

GS 对大小写敏感,所有的变量,函数名等都需要正确的大小写,因此函数foo()Foo()是不同的函数,
变量myvariableMyVariable也是不同的。

运算符

GS支持ES6规定的所有操作符,包括赋值、算术运算、比较,逻辑等符号,并且符合ES6规定的语义逻辑。

类型 实例
赋值运算符 =
算术运算符 + - * / ^ ! ++ — & | << >>
比较运算符 == != < >
逻辑运算符 || && !

算数运算符

使用算术运算符来计算值,使用赋值运算符给变量赋值。

  1. // 加减乘除余 优先级:( ) * / % + -
  2. var a = 1 + 1; // 2
  3. var b = 1 - 1.1; // -0.10000000000000009
  4. var c = 2 * 1.1; // 2.2
  5. var d = 1 / 0.1; // 10.0
  6. var e = 4 % 2; // 0
  7. var f = -1; // -1
  8. var g = !true; // false
  9. var h = 1 + 2 * 3; // 7
  10. var i = (1 + 2) * 3; // 9
  11. var j = a++; // 2
  12. var k = ++a; // 3
  13. var l = a--; // 2
  14. var m = --a; // 1
  15. // 位运算
  16. var n = 2 & 3; // 2
  17. var o = 1 | 2; // 0
  18. var p = 2 ^ 3; // 1
  19. var q = ~1; // -2
  20. var r = 1 << 3; // 8
  21. var s = 8 >> 3; // 1

比较运算符

比较运算符在逻辑语句中使用,以测定变量或值是否相等。

  • 注意:== 和 === 含义相同,对数据类型做强校验。
    1. var x = 1;
    2. var y = -1;
    3. x > y // true
    4. x >= y // true
    5. x < y // false
    6. x <= y // false
    7. x === y // false
    8. x == y // false
    9. x != y // true

    逻辑运算符

    逻辑运算符用于测定变量或值之间的逻辑。
    1. var x = 1;
    2. var y = true;
    3. // && and
    4. x < 5 // true
    5. // || or
    6. x < 0 || y // true
    7. // ! not
    8. !y // false

注释

GiffinScript 支持代码注释。

  1. // 单行注释内容
  2. /**
  3. 多行注释内容
  4. 多行注释内容
  5. **/
  6. var a = 16; // 行尾注释

数据类型

GiffinScript 支持多种数据类型:数字,布尔值,字符串,数组,JSON对象,日期时间,正则对象。

  1. var number = 1.6; // Float 通过数字字面量赋值
  2. var points = 16 * 10; // Integer 通过表达式字面量赋值
  3. var bool = true; // Boolean 通过true/false赋值
  4. var lastName = "Griffin"; // String 通过字符串字面量赋值
  5. var firstName = new String("Griffin"); // String 创建字符串对象
  6. var cars = ["BMW", "BENZ", "AUDI"]; // Array 通过数组字面量赋值
  7. var person = {firstName:"Jack", lastName:"Tony"}; // Object 通过对象字面量赋值
  8. var date = new Date(); // Date 创建日期对象
  9. var math = new Math(); // Math 创建数学对象
  10. var regexp = new RegExp("G\\S+", "i"); // RegExp 创建正则对象

整数/浮点数

支持数据之间的算数/比较。

支持字符串转换数字,使用Numer.parseInt()/parseFloat()进行转换。
  1. var number = 123; // 123
  2. var float = 12.3; // 12.3
  3. var newNumber = new Number(123); // 123
  4. // parseInt
  5. var a = Number.parseInt("123"); // 123
  6. var b = Number.parseInt("0x123"); // 291
  7. var c = Number.parseInt("123x345"); // 123
  8. var d = Number.parseInt("123", 16); // 291
  9. // parseFloat
  10. var e = Number.parseFloat("-12.3"); // -12.3
  11. 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)

  1. Math.random(); // (0,1)随机数
  2. Math.abs(-1); // 1
  3. Math.acos(1); // 0
  4. Math.ceil(1.4); // 2
  5. Math.round(1.6); // 2
  6. Math.sqrt(4); // 2
  7. Math.pow(2, 2); // 4
  8. ...

布尔值

支持布尔值true/false。

字符串

支持字符串的拼装(+),截取(substring),修改(replace),长度(length),字符位置(indexOf),正则查找(search),正则匹配(match),拆分(split)方法。

  1. var s0 = new String("Griffin Script");
  2. var s = "Griffin" + "Script"; // "GriffinScript"
  3. var substring = s.substring(0, 7); // "Griffin"
  4. var replace = s.replace("Griffin", "Cainiao"); // "CainiaoScript"
  5. var index = s.indexOf("Script"); // 7
  6. var length = s.length; // 13
  7. var searchIndex = s.search(".i"); // 1
  8. var mList = "1+2=3".match("\\d+","g"); // [1, 2, 3]
  9. var sList = s0.split(" "); // ["Griffin", "Script"]
方法 说明 备注
substring
replace
indexOf
search
match
split
charAt

数组

支持数组长度(length),增加数据([index], push),移除首位元素(shift),删除末尾元素(pop),组合(concat),查找(indexOf)方法。

  1. var array = [1, 2, 3];
  2. var length = array.length; // 3
  3. array[5] = 6; // [1,2,3,null,null,6]
  4. array.push(7); // [1,2,3,null,null,6,7]
  5. array.shift(); // [2,3,null,null,6,7]
  6. array.pop(); // [2,3,null,null,6];
  7. array.indexOf(3); // 1
  8. array.indexOf(100); // -1
  9. 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对象,可以直接解析处理。

  1. var person = {
  2. name: "Jack",
  3. age: 24,
  4. feature: [
  5. { name:"company" , desc:"cainiao" },
  6. { name:"work" , desc:"Software Engineer" },
  7. ]
  8. };
  9. var name = person.name; // "Jack"
  10. var work = person.feature[1].desc; // "Software Engineer"
  11. person.IQ = 130;
  12. var IQ = person.IQ; // 130

GS支持基本的JSON处理方法,包括JSON.stringify()JSON.parse(),比如下面的例子:

  1. var text = '{ "employees" : [' +
  2. '{ "firstName":"John" , "lastName":"Doe" },' +
  3. '{ "firstName":"Anna" , "lastName":"Smith" },' +
  4. '{ "firstName":"Peter" , "lastName":"Jones" } ]}';
  5. var obj = JSON.parse(text);
  6. text = JSON.stringify(obj);

下面的语法暂时是不支持的。

  1. // WARNING: NOT supported by Griffin Script
  2. var myObj = {
  3. myMethod: function(params) {
  4. // ...
  5. }
  6. };

对象比较

两个对象使用 == 做比较,如果值相等,会返回true,例如:

  1. var a = {key:"v1"};
  2. var b = {key:"v1"};
  3. a==b; //true

⚠️ 这个是不符合ecma规范的。

日期时间

支持创建日期对象,并支持获取具体时间数据,UTC时间数据,GMT格式(toString),自定义格式(format)。

  1. var df = "yyyy-MM-dd HH:mm:ss";
  2. var date = new Date(); // 当前时间
  3. date.toString(); // Wed Apr 29 2020 15:06:29 z+0800
  4. date.format(df); // 2020-04-29 15:06:29
  5. date.getTime(); // 时间戳
  6. date.getFullYear(); // 年
  7. date.getMonth(); // 月
  8. date.getDate(); // (月)日
  9. date.getDay(); // (周)日
  10. date.getHours(); // (24小时制)时
  11. date.getMinutes(); // 分钟
  12. date.getSeconds(); // 秒
  13. date.getMilliseconds(); // 毫秒
  14. // UTC时间
  15. date.getUTCFullYear(); // 年
  16. ...
方法 说明 备注
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标准方法

正则对象

支持正则对象,可以通过正则对象进行正则表达式的匹配计算。

  1. // 手机号校验
  2. var regexp = new RegExp(/^1[3-9]\d{9}$/);
  3. var p = regexp.test("13345678998"); // true
  4. var regexp2 = new RegExp("G\\S+", "i");
  5. 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