Overview of a Scripting Language

The common term referred to as scripting language is actually more than just a language. It is composed of two separate components: the language that defines the syntax rules for writing the scripts, and an interpreter that can execute the script. Examples of scripting languages are Lua, Python, and MEL™ Script (Maya Script). They all have their own grammar rules and an interpreter that executes scripts.

The interpreter, which is responsible for carrying out the computations defined in a segment of script, is referred to as the scripting engine or the virtual machine. The interpreter is essentially an emulator. It is responsible for looking at a segment of script and performing what the script is trying to do.

Before a script can be executed by the interpreter, its syntax must be verified to make sure that it follows the rules of the specific language. When the syntax has been verified, the script must be compiled into a series of instructions that can be executed one at a time. Even a simple arithmetic expression has to be broken down. In the following example, code must be broken down so that force/mass is computed, the result is added to velocity, and the final result is stored into velocity.

velocity = velocity + force/mass

Similarly, a loop must be broken down into several lower-level instructions, such as initializing the loop counter, checking termination condition, and incrementing the loop counter. The interpreter can perform the velocity computation using LOAD, STORE, ADD, and DIV instructions. Likewise, a loop can be carried out using LOAD, STORE, ADD, conditional check, and conditional branch instructions. A form of LOAD and STORE instructions is required to read from and write to variables.

The process of verifying the syntax and translating a script is in many ways similar to what happens when a source of a static language such as C/C++ is compiled. A C/C++ compiler takes the source code and converts it to the assembly instructions of a specific CPU. For example, the Microsoft Visual C++ 6.0 compiler converts C++ source to Intel 8086 instructions. If the target platform is of a different architecture, the corresponding compiler must be used to generate code that can be executed by the target CPU. For example, the Sony PS 2 Vector Unit instruction set is entirely different from the Intel 8086 instruction set. In contrast, the compiler of a scripting language always converts the source to the assembly instructions of an abstract or virtual machine. These instructions are typically referred to as bytecodes.

A virtual machine can be modeled after different types of machines. The most generic and simple is a stack-based machine, which does not have special-purpose registers. For example, some Pentium opcodes rely on a specific register for their operands. A stack machine, however, simply uses a stack to store the operands and the output for all operations. The instructions of a stack-based machine pop their operands from the stack and push their results back onto the stack.

An interpreter typically compiles scripts at runtime. When the interpreter comes upon a block that needs to be executed, it compiles the block and executes it. Almost every scripting language also has a support to precompile the scripts. This practice reduces the overhead during runtime and allows for more efficient script execution. In addition, it helps to catch some errors ahead of time.

It is fundamental for a scripting language to provide a mechanism to call native functions (functions implemented in languages such as C/C++ or Assembly) from a script because some tasks must be accomplished in native code. For example, it is not possible to even open a file unless some native code can be executed (directly or indirectly) from the script so that it can talk with the underlying operating system. More important, without the ability to call native functions from a script, it would not be possible to write scripts that manipulate a native application or library such a game engine. A scripting language should also allow a native application to launch its virtual machine. Because both the operating systems and the virtual machines are typically written in native languages, a native application must be launched, which can in turn launch the interpreter.

A scripting engine also has a form of memory manager. The memory manager is responsible for allocating memory and collecting memory that is no longer used. It maintains the heap and compacts data in the heap so that it can have a large contiguous free space ready for future allocation made by a script.



Practical Java Game Programming
Practical Java Game Programming (Charles River Media Game Development)
ISBN: 1584503262
EAN: 2147483647
Year: 2003
Pages: 171

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net