值
VSL能识别以下类型的值:
数字,如123、3.14159、'v'或0xe0d02090 逻辑布尔值:true或false 字符,如"Virtools,The Behavior Company" 特殊关键字 null等于
类型
VSL是一种类型化的语言,这意味着如我们所知的在编译时(compilation time)每个变量和每个表达式都带有类型。类型决定了运算的意义;强类型可以帮助在编译时检查错误。
VSL类型划分为3类:
基本类型 VSL结构类型 C++ 类/结构类型
基本类型即布尔型(bool)与数字类型。数字类型为整型(char,int)及浮点型(float)。
类型 | 内容 | 大小 | 取值范围 |
bool | bool类型是一种整数类型。它用两个可能的值(用true或false来表示)代表逻辑数 | 4 Bytes | true 或false (0 or 1) |
char | char类型也是一种整数类型,通常包含了ASCII字符集成员的执行。 | 4 Bytes | -128 to 127 |
int | int类型也是一种整数类型。等价于C/C++中的无符号的int类型。 | 4 Bytes | ?147483647? to 2147483647 |
float | float类型是一种浮点数类型。等价于C/C++中的float类型。 | 4 Bytes | -3.402823466e+38F to 3.402823466e+38F |
str | str类型等价于C/C+中的char*类型。 | 4 Bytes | - |
正如你所见,所有VSL基本类型都是以4个字节实现的,在内存中是字组对齐方式,不受它们是否需要更多空间的情况约束。例如,char类型仅需一个字节来表示ASCII码表中的成员,但在VSL中仍用了4个字节。
VSL结构是在VSL中创建自定义数据类型的一种方式。VSL结构可以有零个或多个成员,这些成员可以是任何VSL中的已知类型。VSL结构和C的结构非常相似。
结构声明实例:
struct Car
{
Entity3D entity;
Vector direction;
float gaz;
};
VSL可以操作C/C++类型。在VSL中使用类(class)之前,你必须绑定它。
VSL来源于很多Virtools SDK中的约束类(bound classes)。大多数情况下,类的名称从Virtools SDK到VSL会发生改变。对于Virtools SDK用户来说,CK3dEntity是熟知的一个类,但到了VSL它的名字就变为"Entity3D"了。
变量
变量是一个存储单元,且带有一个相关联的类型,可能是基本类型、VSL结构或C/C++类。变量总是包含一个和它的类型相兼容的所赋的值。变量值通过赋值或前缀式或后缀式 ++ / --运算符来进行改变。
这里有些在VSL中进行变量声明的实例:
// Declare an integer variable named "i" int i;
// Declare an array of 123 float named "table" float table[123];
// Declare a Vector variable named "speed", initialized with values 1.0, 2.0 and 3.0 Vector speed(1.0,2.0,3.0);
// Declare a variable referencing an Entity3D Entity3D bird;
变量范围
VSL里变量名仅能在程序的特定区域中使用。这个区域叫做变量名的适用范围。适用范围觉得累变量名(指非静态或非共享变量)的生命周期。适用范围也决定了在调用类的构造器或析构器时变量名的可见性,及什么时候进行局部变量的初始化。
void foo(int a) // start of the function foo scope { if (a) // start of if scope { } // end of if scope } // end of the function foo scope
让我们通过一个简单的实例来考察一下变量的生命周期:
float angle; // Declaring a global variable void foo() { angle = 0.01; // ok } void foo2(int a) { angle = a*180/P; // error, P is not yet declared float P = 3.14159; if (a) // ok { float angle2 = 360-angle; // ok } bc.OutputToConsole(angle2); // it doesn't exist outside of the scope of the enclosing braces {...}
}
当你在一个函数外声明了一个变量时,它会以全局变量方式被调用,因为在当前VSL脚本的各个地方都是有用的。
静态与共享全局变量
我们的全局变量可以是共享式的或静态的。
- 静态全局变量具有在某个脚本的两次执行中保持它的值的特性。
- 共享全局变量具有保持它的值静态不变的能力,但所有对该变量进行了声明的脚本间都可以共享该变量。
怎样声明静态或共享全局变量
shared int a; // a is a shared global variable static float b; // b is a static global variable void main() { shared int i;// i is not a shared variable (shared keyword is ignored) static float j;// j is not a static variable (static keyword is ignored) // ... }
在声明静态或共享全局变量时,你无法初始化或调用那种没有默认构造器环境的变量。
shared int a = 0; // error static Vector v(1.0,2.0,3.0); // error void main() { static int b = 0; // Not an error because static keyword is ignored shared Vector w(-1,0,0); // Not an error because shared keyword is ignored // ... }
静态全局变量
实例:
// ... static int a; void main() { if (iIn1) { // iIn1 is a boolean global variable a = 0; } else { ++a; } }
如果在我们第一次执行脚本的时候,iIn1为true,a等于0。
然后,为了下一次脚本执行时a的值增加,我们将iIn1设为false,所以到时候第二次执行会将a设为1,而第三次则会将a设为2,等等。
共享全局变量
实例:
// First script
shared Vector pos;
void main()
{
pos.Set(0,1,0.5);
}
// Second script shared Vector pos; // the second script also declares pos as a shared Vector void main() { Vector test(0,1,0.5) if (pos == test) { // ... } }
如果我们在第二个脚本执行了第一个脚本,pos的值是 {0,1,0.5} ,所以在第二个脚本中条件 pos == test 为true。
变量名
在VSL中,一些特定的名字是不能作为变量名使用的,如类/结构名及以下保留字:
main int short float char while do bool |
if for then else true false TRUE FALSE |
NULL null struct class enum extern shared static |
switch |
编译器按以下顺序搜索名字,当找到了名字时就停止:
从当前范围到全局范围搜索 搜索看名字是否为枚举值 搜索看名字是否为定义的常量
void foo(int a)
{
bc.OutputToConsole(pi); // print 3.14159 (pi is a constant in VSL) float pi = 1.0; if (a) { float pi = 0.5; bc.OutputToConsole(pi); // print 0.5 } bc.OutputToConsole(pi); // print 1.0 }
enum Const
{
pi,
epsilon,
maxint,
};
void foo(int a) { bc.OutputToConsole(pi); // print 0 float pi = 1.0; if (a) { float pi = 0.5; bc.OutputToConsole(pi); // print 0.5 } bc.OutputToConsole(pi); // print 1.0 }