Skip to content

zccrs/zScript

Folders and files

NameName
Last commit message
Last commit date

Latest commit

8b82f88 · Feb 1, 2020
Jan 31, 2020
May 28, 2016
Feb 1, 2020
May 29, 2016
Feb 1, 2020
Feb 1, 2020
Feb 1, 2020
Mar 20, 2016
Feb 1, 2020
May 28, 2016
May 4, 2016

Repository files navigation

编译&运行

Linux(Debian)

先安装编译依赖:

sudo apt install qt5-default flex bison g++ make

克隆代码:

git clone https://github.com/zccrs/zScript

编译:

cd zScript
mkdir build && cd build
qmake ..
make

运行:

./zScript ../demo/snake.zs

Windows

先安装编译依赖:

到 http://download.qt.io/official_releases/qt/ 下载并安装最新版的Qt

克隆代码:

git clone https://github.com/zccrs/zScript

打开项目并编译,可在“项目” --> “Build&Run” --> “Run” --> “Command line arguments:” 中添加命令行参数来执行要执行的代码文件。

zScript

变量的定义

变量使用关键字“var”进行定义。 zScript提供了两种形式的变量定义语句。

1.直接定义的形式,该语句的一般形式为:
var 标识符;

该语句的含义是:定义变量名为“标识符”的变量。例如:

var a;

该语句的作用是:定义一个名为“a”的变量。

2.定义同时给变量初始化赋值,该语句的一般形式为:
var 标识符 = 表达式;

该语句的含义是:定义变量名为“标识符”的变量,且给变量赋值为表达式的结果。例如:

var a = 1 + 2;

该语句的作用是:定义一个名为“a”的变量,且赋值为3。 “var”关键字可同时定义多个变量,每个变量之间使用符号“,”分割。

数组的定义

数组定义的一般形式为:

var a = [表达式1, 表达式2, ...];

该语句的含义是:生成一个数组,数组元素为中括号中表达式的结果。例如:

var a = [1, 2, 3];

该语句的作用是:定义一个包含三个元素的数组,元素的值分别为1、2、3,然后赋值给变量a; 数组使用“[”“]”定义,中间内容可以为空、一个表达式、多个表达式,多个表达式之间使用“,”隔开。

a = a[0];

取数组元素语法和C语言一样,都是中括号中写入数组下标。

选择控制语句

一个选择结构,包括一组或若干组操作,每组操作称为一个分支。通过选择控制语句可以实现选择结构。选择控制语句包括if语句、switch语句及起辅助控制作用的break语句。 If语句用于计算给定的表达式,根据表达式的值是否为假,决定是否执行某一组操作。 Switch语句首先求解一个表达式,然后根据计算结果的值,从哈希表中查询该从哪一组操作开始执行。 Break语句用于switch结构中,用于终止当前switch结构的执行。

if语句

zScript提供了两种形式的if语句。

1.单if子句的if语句。该if语句的一般形式为:
if (表达式) {
	语句组
}

该语句的含义是:只有表达式的值为非零值时,才执行其内部的语句组。例如:

if ( a > b ) {
	console.log(“hello”);
}

该语句的作用是:当a的值大于b的值时(此时,“a>b”的值为真,为非假值),在屏幕上显示“hello”;否则,不显示“hello”。

2.带else子句的if语句。该if语句的一般形式为:
if ( 表达式 ) {
	语句组1
} else {
	语句组2
}

该语句的含义是:当表达式的值为非假时,执行语句组1,而不执行语句组2;否则,即表达式的值为假时,执行语句组2,而不执行语句组1。例如:

if ( a > b ) {
	console.log(“hello1”);
} else {
	console.log(“hello2”);
}

该语句的作用是:若a的值大于b的值(此时“a>b”为真,为非假值),则在屏幕上显示“hello1”,而不显示“hello2”;否则,即表达式的值为假时,显示“hello2”,而不显示“hello1”。

switch语句

Switch语句与if语句一样,也可以实现分支选择。但if语句是判断一个表达式的值是否为假,决定是否执行某个分支;而switch语句是计算一个表达式的值,根据计算结果,从哈希表查询从哪个分支开始执行代码。Switch语句的一般形式为:

switch( 表达式 ) {
	case 常量1:{
		语句组1
	}
	case 常量2:{
		语句组2
	}
	...
	case 常量n:{
		语句组n
	}
	default: {
		语句组 n + 1
	}
}

switch语句的执行过程:

  • 1.求解“表达式”的值;
  • 2.如果“表达式”的值与某个case后面的“常量”的值相同,则从这里开始顺序执行语句。结果switch执行有两种形式:一是遇到break语句为止;二是未遇到break语句,则程序依次执行完所有语句组。
  • 3.如果“表达式”的值与任何一个case后面的“常量”的值都不相同,当有default子句时,则执行default后面的语句,如果没有default子句,则结束switch。

注:与C++语言不通的是,case后可跟任意常量,不仅限于整数。case语句后的代码需使用“{}”包裹

循环控制语句

while语句

while语句的一般形式为

while( 表达式 ) {
	循环体
}

while语句的执行过程:

  • 1.求解小括号中表达式的值。如果表达式的值为真,转第2步;否则转第3步。
  • 2.执行循环体,然后转第1步。
  • 3.执行while语句后面的语句。

小括号中表达式的值是否为假,决定着循环体是终止还是继续循环。因此,该表达式的值为循环条件。while循环语句的执行特点是,先判断循环条件是否成立,然后决定是否执行循环体。 当while语句的循环体只包含一条语句时,包含该循环体的“{}”可以省略。

带else的while语句
while( 表达式 ) {
	循环体
} else {
	...
}

当while语句的循环体正常结束时将执行else语句中的代码,否则不执行。由表达式的值为假时导致的循环结束视为循环体正常结束,由break语句导致的循环体结束视为非正常结束。

正常结束的示例:

var i = 0;
while( i++ < 3 ) {
	console.log(i);
} else {
	console.log("正常结束");
}

此段代码的执行结果为:

1
2
3
正常结束

非正常结束的示例:

var i = 0;
while( i++ < 3 ) {
	console.log(i);
	break;
} else {
	console.log("正常结束");
}

此段代码的执行结果为:

1

for语句

在两种循环语句中,for语句最为灵活。for语句的一般形式为:

for (表达式1; 表达式2; 表达式3)
{
	循环体
}

for语句的执行过程:

  • 1.求解表达式1的值。
  • 2.求解表达式2的值,若其值为假,则结束循环,转第4步;若其值为真,则执行循环体。
  • 3.求解表达式3。
  • 4.结束循环。

同while语句,for语句也可以存在else分支语句,表现形式也跟while语句一致。

对象的定义

对象定义的一般形式为:

{
	属性名1: 属性的值,
	属性名2: 属性的值,
	...
	属性名n: 属性的值,
	属性名n+1: 属性的值
}

例如:

var object = {
	name: "张三",
	age: 18
};

变量object即是一个对象,它包含两个属性。

注:当对一个对象不存在的属性赋值时会将此属性加入到对象中,例如:

object.sex = '男';

对象object中就会多出一个“sex”属性。

函数的定义

函数定义的一般形式为:

var fun_name = (形参列表) {
	语句组
};

该语句的含义是:生成一个函数对象,例如:

var print = (a) {
	console.log(a);
};

print(1);

此段代码执行结果为:

1

该语句的作用是:定义一个函数,它有一个名为“a”的形参,执行此函数会将a的值打印到屏幕上。 形参列表,可为空、一个、多个,多个形参之间使用“,”分割。

函数值的返回

和JavaScript类似,函数的定义中不必包含返回值的说明,直接在函数体任意位置添加 return 语句即可结束函数的执行,并且返回指定的值。

单值返回
var test = (arg1, arg2) {
	return arg1 + arg2;
};

console.log(test(1, 2));

此段代码执行结果为:

3
多值返回
var test = (arg1, arg2) {
	return arg1, arg2;
};

console.log(test(1, 2));

此段代码执行结果为:

<1, 2>

return语句在实现上其实仅支持返回一个值,能“多值返回”是因为

表达式1, 表达式2, ..., 表达式n,...

的写法是定义了一个“元组”类型的数据。

元组

定义

元组是一种特殊的数据类型,此类型无法直接被定义,通常和函数的return语句配合使用,可通过函数创建一个元组数据,如:

var tuple = () {
	return 1, 2, 3;	
}();

console.log(tuple);

此段代码的执行结果为:

<1, 2, 3>

使用console.log打印元组类型的数据时,会使用 “<”、“>”将其包括起来,并且使用“,”分割每个元素的值。

赋值操作

var tuple = () {
	return 1, 2;
}();
var a, b;
a, b = tuple;
console.log(a, b);

元组作为右值时,如果左值为 “表达式1, 表达式2, ...” 的写法,则会依次将元组中的值赋值给:表达式1、表达式2、...。否则,当左值为单个表达式时,则跟普通赋值一致,将元组整体赋值给此表达式。

作用域

作用域比较明显的标识的是:"{}",如if、while、for、函数体等语句皆是使用"{}"作为作用域限制的标识。"{}"也可以不依附于if、while、for等语句单独使用,如:

{
	var a = 1;
}

console.log(a);

此段代码的执行结果为:

[Error]: undefined reference: a

值得注意的是,多个连续的“{}”代码块之间至少要包含一句普通代码。如:

if (true) {
	{
    	console.log(1);
	}
}

这段代码无法通过语法检查,可在两个代码块间添加空语句避免这种情况,如:

if (true) {
	;
	{
    	console.log(1);
	}
}

break语句

break语句用于结束当前作用域,可用于 while for switch-case "{}" 等语句产生的作用域中。如:

{
	console.log(1);
	break;
	console.log(2);
}

console.log(3);

此段代码执行结果为:

1
3

break可以多个连用来结束多层作用域。如:

while (true) {
	console.log(1);

	{
    	console.log(2);
    	break, break;
    	console.log(3);
	}

	console.log(4);
}

console.log(5);

此段代码的执行结果为:

1
2
5

break, break, ... 的组合形式还可以配合 continue 一起使用,不过,continue 只能是列表中的最后一个。如:

for (var i = 0; i < 2; ++i) {
	console.log(1);
	{
    	console.log(2);
    	break, continue;
    	console.log(3);
	}

	console.log(4);
}

此段代码的执行结果为:

1
2
1
2

About

script interpreter for zScript

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published