<h1>KScript</h1>

<h2>What is KScript?</h2>

KScript is an untyped interpreter language. Its main features are:
<ul>
<li> DCOP support for KDE application scripting
<li> Object oriented, including multiple inheritance
<li> Exceptions
<li> Native support for sigals and slots
<li> Perl style usage of regular expressions
<li> Easy manipulation of lists and maps.
<li> Support for structs
<li> Python style object model (You can add methods at runtime, properties, etc.)
<li> Python style module concept
<li> Can be easily embedded in KDE applications
</ul>

If you are known to C++, Perl and Python then you will have an easy time
learning KScript since it is very much inspired by these languages.

<h1>KScript Basics</h1>

<h2>Hello World</h2>
A "Hello World" app in kscript looks like this
<code>
main
{
    println("Hello World1");
}
</code>

The <tt>main</tt> function is executed automatically, if a
script is run. To do so, enter on the command line:
<pre>
kscript helloworld.ks
</pre>

<h2>Printing to Stdout</h2>

The most important function for output is <tt>println</tt>.
This function takes any amount of parameters. These parameters
can be of any kind: Lists, Maps, Strings, Objects, Classes ....
It will always try to generate a meaningful output.

Due to kscripts design you can use the <tt>println</tt> function
(which is in the global scope of all kscript interpreters) as member
function of any object. So the following lines show the same result:

<code>
println("Hello");
"Hello".println();
</code>

In addition you may have noticed that a string constant in kscript is treated
like a string object, so you can call methods on it.

If you dont want to emit a newline, then use <tt>print</tt> instead of <tt>println</tt>.

<h2>Commandline Parameters</h2>

Command line arguments are used as parameters to the main function.
The following script:
<code>
main( in arg1, in arg2 )
{
	println( arg1, arg2 );
}
</code>

can be started like this:
<pre>
kscript myscript.ks Hello World
</pre>

The value of <tt>arg1</tt> will be "Hello" and the value of
<tt>arg2</tt> "World".

<h2>Strings</h2>

The methods available for strings try to resemble the functions offered by
Qts QString class. <todo>Only few are implemented right now</todo>

If you want to create new strings, then you can use concatenation and
the <tt>arg</tt> function like this:

<code>
str = "Hello %1, today is %2 november".arg( "Torben" ).arg( 29 );
str += " in the year 2000";
</code>

<h2>Mathematics</h2>

For most operations KScript features the same operators as C++:
<ul>
<li> =  : assignment (all types)
<li> += : add and assignment (numerical,string,list,map,date+int,time+int)
<li> -= : add and assignment (numerical,date-date,date-int,time-time,time-int)
<li> == : test equal (all types)
<li> != : test unequal (all types)
<li> >  : greater (numerical)
<li> >= : greater or equal (numerical)
<li> <  : less (numerical)
<li> <= : less or equal (numerical)
<li> << : shift left (numerical)
<li> >> : shift right (numerical)
<li> +  : addition or positive sign (numerical,string,list,map,date+int,time+int)
<li> -  : subtraction or negative sign (numerical,date-date,date-int,time-time,time-int)
<li> /  : division (numerical)
<li> *  : multiplication (numerical)
<li> %  : modulo (numerical)
<li> ^
<li> ~
<li> &  : bitwise and (numerical)
<li> |  : bitwise or (numerical)
<li> && : boolean and (boolean)
<li> || : boolean or (boolean)
<li> !  : not (boolean)
<li> ++ : post or prefix increment (numerical)
<li> -- : post or prefix decrement (numerical)
</ul>

Furthermore, it supports regular expressions as shown below.
Of course you can put paranthesis around terms. The predence of
operators is the same as for C++.

KScript has few predefined constants:
<ul>
<li> TRUE  : boolean
<li> FALSE : boolean
</ul>

<h2>Regular expressions</h2>

KScript features Perl style regular expressions:

<code>
main
{
	str = "12Torben Weis";
	if ( str =~ /([A-Za-z]+) (.+)/ )
	{
		println("Match '%1' '%2' '%3'".arg( $0 ).arg( $1 ).arg( $2 ) );
	}
	else
	{
		println("No Match");
	}

	if ( str =~ s/[0-9]([0-9]+)/Hello (\1) / )
	{
		println("Match '%1'".arg( str ) );
	}
	else
	{
		println("No Match");
	}
	
}
</code>

In order of matching regular expressions, use the "=~" operator. It returns TRUE
if the match was successful or FALSE otherwise. If you used groups in the
regular expression, you can access them via "$1", "$2" etc.
"$0" has a special meaning. It returns the complete substring that was matched by
the last match.

When using the <tt>&lt;&gt;operator</tt> or at least when <tt>$_</tt> is assigned
some value, you can save some keystrokes when dealing with regular expressions.
This is the same as in perl. A construct like <tt>/pattern/</tt> is matched against
the value of <tt>$_</tt>. The following code illustrates that:
<code>
main( in input )
{
	while( <> )
	{
		if ( /Torben/ )
		{
			print( $_ );
		}
	}

	println("I am done");
}
</code>

<h2>Lists</h2>

KScript makes processing of lists very easy like the following example shows:

<code>
list = [ "Hello", 100, 1.2, TRUE ];
hello = list[0];
len = list.length();
empty = list.isEmpty();
list += [ "End, "Really end" ];
</code>

Lists can be added and you can access the entries by index using the "[]" operator.

Of course you can embed lists in lists:

<code>
list = [ [ 1, 2 ], [ "Torben", "Weis" ] ];
println( list[0], list[1] );
</code>

Output:
<pre>
[ 1, 2 ]
[ "Torben", "Weis" ]
</pre>

In contrast to Perl the deep structure is not lost. And in contrast to C++ you can
put different data types in one list at the same time.

<h2>Maps</h2>

KScript can map strings to any kind of objects. That works like this:

<code>
map = { ( "Ettrich", "Matthias" ), ( "Gulbrandsen", "Arnt" ), ( "Mr. X", 42 ) };
map[ "Weis" ] = "Torben";
println( map[ "Weis" ] );
map += { ( "Stadlbauer", "Reggie" ) };
println( map.isEmpty() );
println( map.length() );
</code>

Output:
<pre>
Torben
FALSE
5
</pre>

Like in lists you can put different kinds of data types in a map, but the key
data type must always be a string.

<h2>Functions</h2>

You can define your own functions easily in kscript:

<code>
func( in a, in b )
{
	return a * b;
}

main
{
	y = 100;
	x = func( y, 2 );
}
</code>

As you see there is no need to define a return type or parameter types
since KScript is dynamically typed. Instead of "in" you have two other choices:
<ul>
<li> in    : Modifications of <tt>a</tt> dont change <tt>y</tt>.
<li> out   : The value of <tt>a</tt> changes the value of <tt>y</tt>
<li> inout : The value of <tt>y</tt> is copied to <tt>a</tt> and the other way
             round upon return of the function.
</ul>

We recommend not to use "out" or "inout" if this is not really needed.

<h2>Constants</h2>

You can put any kind of constants in a module like this:

<code>
const answer = 42;
const name = "Joe";

main { }
</code>

It is not allowed to have multiple functions with different parameter lists but
the same name. The same applies for object methods.

<h2>Variables and scope</h2>

Variables must, like all other identifiers in KScript, start with A-Z a-z or _
and may continue with A-Z a-z _ or 0-9.

Scoping in KScript is a bit complicated to explain, but easy to use. There following
scopes always exist:
<ul>
<li> Global
<li> Module
<li> Function
</ul>

In a function you can create more scopes by doing like this:
<code>
func( in a )
{
    a = 100;
    b = 200;
    {
        a = 99;
	c = 300;
    }
}
</code>

The second use of <tt>a</tt> does NOT shadow the first one <tt>a</tt>. It will
just overwrite its value.

If a function calls another function, then only the scope of the current function
is visible. It is not possible to access the scope of the calling function.

Basically KScript works like this:

It searches in the most specific scope and continue until the global scope is reached.
If the identifier was still not found then it is created in the most specific scope.

Lets look at the following example:

</code>
const x = 42;

func( in x )
{
	println( x );
}

func2( in a )
{
	// This is an error
	x = 200;
}

main
{
	println( x );
	func( 100 );
}
</code>

Output:
<code>
42
100
</code>

The parameter <tt>x</tt> shadows the global variable x. But in <tt>func2</tt> you
can see an error. The identifier is found in the global namespace, but it is const
and can not be overwritten.

Scoping becomes a little bit more complicated with objects.

<h2>Garbage collection</h2>

KScript does an automatic garbage collection for you which is reference based.
That means an object is deleted whenever nobody references it any more.

When assigning an object to another variable, the object is not copied. Instead
only a new reference is created. But kscript supports value based objects, too,
which are called structs. They are copied on assignment like all the basic data types, too.
Basic data types are: Strings, Doubles, Integers, Lists, Boolean and Maps.

<h2>Classes and Objects</h2>

In KScript creating new classes works like in C++:

<code>
class MyClass
{
	const c = 0.7;

	MyClass( in this, in v )
	{
		this.z = v;
	}

	method( in this, in x )
	{
		println( x * this.z * MyClass.c );
	}

	static_method( in a )
	{
		println( a );
	}
};

main
{
	m = MyClass( 100 );
	m.method( 3 );
	println( MyClass.c );
	println( MyClass.static_method( 20 ) );
}
</code>

The function with the name of the class is the constructor. It can be there, but it may be missing.
The first parameter of any object method is always a reference on the object. Python hackers will be used
to that concept.

Static methods can be easily implemented as above. They just treat the first parameter not to be
an object reference. As a matter of that you can treat every object method as a static method like this:
<code>
MyClass.method( m, 3 );
</code>

Writing <pre>m.method( 3 );</pre> is just a more convenient way to write it down.
The only exception is the constructor. Calling the constructor creates a new object
and puts the object reference in the first parameter automatically.

Classes and Objects do not really have a usual new namespace like in C++. Instead you have
to explicitely select their namespace like in <tt>this.z</tt> or <tt>MyClass.c</tt>.

Once you have created an object, you can add any amount of properties. That means, an object
is not fixed to a certain number of properties. Even more, you can add new member functions during
runtime:
<code>
func( in this )
{
	println( this.z );
}

main
{
	m = MyClass( 100 );
	m.text = "Hello";
	func( m );
	m.method2 = func;
	m.method2();
	m.z = 200;
	m.method2();
}
</code>

Output:
<code>
100
100
200
</code>

A destructor can be defined like this:
<code>
class MyClass
{
	delete( in this )
	{
		println("Destruct MyClass");
	}
};
</code>

It is called if nobody references it any more.

<h2>Inheritance</h2>

Inheritance looks like this:
<code>
class MyClass2 : MyClass
{
	MyClass2( in this, in v )
	{
		println("Look here");
		this.MyClass( v );
		println("And here");
	}

	delete( in this )
	{
		println("Destruct MyClass2");
	}
};
</code>

You can even do multiple inheritcan like this:
<code>
class MyClass2 : MyClass, OtherClass { }
</code>

All destructors are virtual. That means KScript takes care of calling the
most specific destructor first, then the less specific one and so on ...

You can call the constructors of your base class in any order and even after
executing some other commands (unlike C++, but like in Python).

All KScript methods are considered to be virtual (even the static member functions).
Overloading a member function works like this:
<code>
class MyClass2 : MyClass
{
	method( in this, in x )
	{
		println( "Poooooops", x * this.z * MyClass.c );
	}
};
</code>

If you are in need to call the method you overloaded, then do it like this:
<code>
MyClass.method( this, 200 );
</code>

<h2>Implicit Casts</h2>

The following data types are casted implicitely:
<ul>
<li> String -> Bool
<li> Integer -> Double
<li> Double -> Integer
</ul>
<todo>More things have to be casted</todo>

<h2>Reading Input</h2>

The following script reads in a file and writes it back to
stdout without any change:
<code>
main( in input )
{
	while( <> )
	{
		print( $_ );
	}
}
</code>

You can call this script like this:
<pre>
kscript myscript.ks input_file
</pre>

Like in Perl you can use <tt>$_</tt> to access the last line read by
the <tt>&lt;&gt;operator</tt>. It es even possible to assign values to <tt>&lt;&gt;</tt>.

The <tt>&lt;&gt;operator</tt> reads in a new line and returns it. The line read includes
a trailing newline. When <tt>&lt;&gt;operator</tt> returns an empty string then no more input
is available. The above <tt>while</tt> construct loops until the <tt>&lt;&gt;operator</tt>
returns an empty string.

It is legal to write something like this:
<code>
main( in input )
{
	line1 = <>;
	line2 = <>;
	line3 = <>;
}
</code>

to read the first three lines from the input.

If you want to read from stdin, do it like this:
<code>
main
{
	while( <> )
	{
		print( $_ );
	}
}
</code>

You can call this script like this:
<pre>
kscript myscript &lt;input_file
</pre>

The important difference in the above script is that the <tt>main</tt>
function does not take any parameter.

You can read the content of multiple files in sequence like this:
<code>
main( in input1, in input2, in input3 )
{
	while( <> )
	{
		print( $_ );
	}
}
</code>

<h2>File Operations</h2>

KScript supports a very short syntax for getting informations about files.
The following script illustrates that:
<code>
main( in file )
{
	if ( -r(file) )
	{
		println("File %1 is readable".arg( file ) );
		println("Owner=%1".arg( -o(file) ) );
		println("Group=%1".arg( -g(file) ) );
	}
	else
	{
		println("File %1 is NOT readable".arg( file ) );
	}
}
</code>

The following operators are available:
<ul>
<li> -r(filename) : TRUE if the file is readable
<li> -w(filename) : TRUE if the file is writeable
<li> -d(filename) : TRUE if the file is a directory
<li> -l(filename) : TRUE if the file is symlink
<li> -f(filename) : TRUE if the file is regular file
<li> -e(filename) : TRUE if the file is executable
<li> -x(filename) : TRUE if the file exists
<li> -g(filename) : The name of the files group
<li> -o(filename) : The name of the files owner
<li> -s(filename) : The size of the file
</ul>

<h2>Structs</h2>

<h2>Exceptions</h2>

<h2>Signals & Slost</h2>

<h2>Modules</h2>

<h2>DCOP</h2>

<h2>Qt Bindings</h2>

<h3>Value based classes</h3>

<h3>QObject based classes</h3>

<h3>Signals & Slots</h3>

<h3>Inheritance</h3>

<hr>
(c) Torben Weis <weis@kde.org>, November 1999
