Current Release
Sourceforge
|
|
Last Modified:
June 05, 2008
|
|
TScript
Welcome to the TScript's homepage.
TScript is a script language originated by pure personal interest. It currently
includes a compiler, a virtual machine, two demos, together with some tiny games
written by friends in TScript.
The code was written mainly in 2004 and 2005, and it's covered fully by dust.
Considering the time spent on this, finally I get some time to publish it. Wish
the messy code can be useful to someone.
If you have any questions, comments, or complaints feel free to
email me or post in the
SourceForge Forums.
Origin & Introduction
- TScript is a script language with C-like grammar, but much weaker.
The source script of TScript runs on TScript Virtual Machine.
This project was originated purely by my interest after my graduation on 2004. What I
needed that time was something like:
"Hi, my cute computer, I have a symbol 'A' = 5, tell me A + 3 = ?"
var a
mov a, 5
add a, 3, a
display a
From then on I could not stop but continuously added something to it. Finally it came to
a script which has similar grammar to C:
void func1() {
int a = 5;
DisplayString("" + (a + 3) );
}
Here's another sample which prints Fibonacci series by recursive function call:
int f(int n) {
if(n < 2)
return 1;
return f(n - 1) + f(n - 2);
}
void main() {
for(int i = 0; i < 10; i++)
DisplayString( "" + f(i) );
}
Start From the Demos
Currently there're two demos.
- Demo with console functions
- The first one is a TScript Runner (the VM) implementation
with console functions. The implemented functions are only two functions - something like
"getchar" and "printf". Together with this implementation there're several tiny games
written in TScript by friends. The games include a Hannoi auto resolver, A* path finding,
an RPG game: Gladiator, and a few other ones. Because of the function limitation (only read char
and print out a string with line bread), do not expect much of them :)...
Originally the purpose of writing games in such Stone Age development environment is
to make more random test cases...finally more games added. Note that several of the games
contain Chinese characters. If you're interested, please refer to readme.txt in the package
on how to adjust your console to display these characters.
The demo locates in directory "env". To run the demo, issue:
"run_demo.bat" (for Windows)
or
"./run.sh demo" (for Linux)
To run your own script, just type
run <your script name> (for Windows)
./run.sh <your script name> (for Linux)
- The demo also contains some simple algorithm implementation, but TScript is not suitable for
complex algorithm. Just a demo here.
- Suspendable script demo
- This demo is for the suspendable feature. It's something like the Coroutine
in LUA and Squirrel. From script developer's perspective it looks like a manual-switched
threading. LUA creates coroutine within the language, but TScript hides this concept behind
the script, and the parallel execution of script is handled by the specific script loader.
This is similar to the scripting engine of a famous game: Neverwinter Nights (NWN).
This project also demonstrates the pattern of expending TScript VM by expanding
TsTarget classes.
The project was built only for Window. It locates in directory "ssdemo".
Please refer to the readme.txt in the project for details.
-
In this demo, there're several "sprites". The behavior of each sprite is controlled by
a script (though several sprites are configured with the same script). The scripts are
written from the perspective of "controllee": the sprites are all doing something endlessly,
so naturally the script is an endless loop. This is a natural way to define the
behavior of the object. Several scripts are executed parallelly,
without considering others. This is supported by script execution:
suspend execution -> execute another script -> resume a suspended execution. This
feature helps developers to focus on the logic of the target: as one writes
the script (AI) for an object, he views the world from the same perspective as the object itself.
It's not needed to concern the execution of scripts of other objects much.
Grammar
-
It's C-like, mixed with a few C++ grammar types.
Here's a list of general language feature supported:
Flow control
Complex expression calculation
User defined function
Function default parameter
Recursive function call
String operation
Include file
Macro definition
Suspending support
Global variable
Global initialization (complex expression)
...
Please refer to doc TScript Language Description in old doc
archive in the release package for details.
There're also many things that is different to C. For example, "i++" and
"++i" in TScript is treated the same as "++i" in C. "i++" should be implemented
as "move value i to register and increase i, use register value as expression value",
while "++i" means "increase i and move its value to register, use register value as
expression value". I lacked of that knowledge when I wrote the compiler.
How to Build
-
Please refer to src/readme.txt in the release package.
Generally, for Windows, you need MS Visual Studio 98. I've not tested on later version.
For Linux, only a simple build script is created without autoconf. Luckily it works on SLES10,
RHEL4, and also Cygwin, with gcc. In addition, different platforms have different STLs, and
STL also differs from each other. For example, STLPort do not support internal sharing feature
of string (copy on write), which makes the low efficiency script much worse.
TScript Workflow
-
Firstly a script file (*.tss) need to be compiled. The compiler (TSC) is responsible to compile
the source file into TScript binary image (*.tsb), with intermedium called TScript Assemble
File (*.tsa). Finally a concrete TScript runner (the VM) loads the binary (tsb) and executes it.
-
The binary (TSB) is then executed on the Virtual Machine, supported by native system. Native system
is a concept which represents any specific functionality you already have/want to access. For
example, it’s OS which provides standard IO if you want to use standard IO, or is existing product
which TSVM is embedded in.
Potential Use and How to Extend TScript
-
If you have a system and want it to be configurable at a script level, TScript may help you.
For example, to configure behavior of acting objects (simple AI).
It's simple to extend TScript. The basic steps to deploy it with your own system are:
- 1. Decide what methods you want to expose from your system. That is, the API provided
by your system. These APIs will be mapped to new functions in TScript.
- 2. Create your new Virtual Machine class: derive from TsRunner class in module "tsrbase",
implement your new APIs. In this step, it should be decided that how the new VM object is
embedded into the target system.
- 3. Modify "tsfdusr.tsd" and "TSFDUsr.tsh" in env/data directory, which is for the compiler
(TSC) to correctly compile TScript source which contains the new APIs.
That's all.
There're also some old comments on how to extend the VM in "doc" directory,
but I believe they're out of date. There're many changes after that.
If there're multiple targets in the system to be handled by scripts, it's recommended to use the TsLoader
together with TsLinker and TsTarget. TsLoader is a script manager, and TsLinker links event to
target and script. One of the two demos - ssdemo - demonstrates this pattern.
Please follow project "tsr" (TScript VM implementation with
simple console) or "ssdemo" (Suspendable script demo) source code as examples.
The first one has "getchar" & "displaystring" functions extended. The second one adds some demo
specific functions, and has several objects managed by separated AI scripts.
-
TScript VM has explicit logic (the static script)/context (the volatile
runtime memory)/VM (the runner)/target (the command receiver)
separation in code. So it's easy to suspend/store/restore/resume the execution at
any time and refactor the source for further use. For more info please refer to
Suspendable Script doc and ppt in the doc directory.
-
TScript virtual machine base (TsRunner) is written in C++. So if the target system is implemented
in other languages, some tricky bridge is required.
Advanced Topic: Weakness of TScript
- Memory model.
Here I'll introduce something that is really tricky, and describe the weakness
of this script language compiler and VM.
The VM has only one memory accessing method: by value. Normally a machine
should have two methods: by value and by value of value, or named "direct addressing"
and "indirect addressing". By value means something like "go and fetch things at
address 12345", and by value of value means "go and fetch things at address A.
What's A? It's the item stored in address 12345". This is the intrinsic limitation
of TScript. The reason? My laziness...Originally I didn't expect to do so much for this
plaything. This limitation is the greatest one, which limits the following things:
pointer, reference, natural function stack, dynamic object array allocation,
and so on... One may ask: "Then how can recursive function call be implemented
in the demos? How can those other demos implemented, which absolutely requires
dynamic array support?" Oh...That's all implemented trickily. Function recursive
call can be automatically implemented in C because each time a function is called,
a block of memory on stack is occupied for local variables of the function (stack grows).
This is very natural. TScript lacks of this, and doesn't need recursive function at the
beginning, until one of my friend yields "I MUST have this to implement my code!"
So it's implemented, ugly by VM native stack (push value, pop value). In fact, as
long as we have something with stack feature, it can be used to fulfill such
requirement, and then, the efficiency is a stranger here.
For dynamic array allocation limitation, string is a native type in TScript. It's
mapped to std::string, which is dynamically allocatable, so...another tricky implementations.
- Performance. Performance is not a concern at the very beginning for such a scripting language.
It's a drawback of all scripting language as well. The mechanism here looks like that of java
at the beginning: compile source to bytecode, and parse the bytecode during execution. Then
java has the JIT compiler, which greatly improves the performance. In addition, TScript has
no referencing mechanism according to the aforementioned memory details. So TScript is poor in
performance. Certainly, that's concluded by a comparison with some great languages.
- The language. From a high level perspective, TScript has no explicit "purpose",
it's something emerged from interest, more like a practice, though it can be of some use now. Without a
major purpose, it's developed with copying of features here and there. We like things to be elegant,
but TScript gets no chance to be embellished by the word from the beginning.
License
- The software is open source software and is licensed under MIT.
So it's extremely free. I'm happy that the experimental and messy code can be of help to someone. If
you're interested in it, it's nice of you to mail me what it can help you. I'm really interested in
that.
- Note that part of the source code (lex & yacc of the source (tss) to assemble (tsa) compiler)
is generated by Parser Generator (ParGen) 0.60 by P. D. Stearns in 1998. I believe that there's
updated version of that now. Thank Stearns for the powerful tool.
|