Page 1 of 1

Introduction to Pawn Pawn is a very tiny language, good for hosts where speed is critical.

#1 Seta00  Icon User is offline

  • D.I.C Head
  • member icon

Reputation: 14
  • View blog
  • Posts: 84
  • Joined: 22-September 10

Posted 25 September 2010 - 08:53 PM

Introduction

Quote

Pawn is a simple, typeless, 32-bit extension language with a C-like syntax. A Pawn "source" program is compiled to a binary file for optimal execution speed. The Pawn compiler outputs P-code (or bytecode) that subsequently runs on an abstract machine. Execution speed, stability, simplicity and a small footprint were essential design criteria for both the language and the abstract machine.


The Pawn toolkit can be downloaded from http://www.compuphas...n.htm#DOWNLOAD.

Pawn should be very easy to learn by intermediate programmers or even beginners, since the language was designed to be friendly and detect the most common beginner mistakes.
One of the most notable features of Pawn nowadays is its incredible speed. Lewis Van Winkle did a series of comparisons between famous game scripting languages on his blog, Code Plea, and you can easily see Pawn's speed is notable.

Along this tutorial I'll be using the IDE included in the package, a modified version of Quincy IDE. If you prefer to use your own IDE, C++ syntax highlighting fits quite well with Pawn code.

Before starting, be sure to copy the binaries from the bin folder to the Pawn installation root, so it's easier to run the example files.

Note: some anti-virus software are known to detect malicious code in some of the Pawn binaries. This is a false positive, there's no malware in the Pawn toolkit.

Getting started with the language syntax.

Note: Pawn's syntax is somehow flexible. You don't need to use semicolons to end statements nor parenthesis to enclose function parameters, but I highly recommend you to use them, as the code is clearer and more C-like.

1. Hello World! of course
main() {
    printf("Hello world!\n");
}



Yeah, simple as that. The main function, just like in C, is the first function that gets called when the script is executed by the host, in this case, pawnrun.
The printf native is included from the console.inc file, which is automatically included by pawnrun.
Wait a second, what's this native thing you speak of? In Pawn, natives are the functions exposed by the host. Their signatures are written in the include .inc files so the compiler can know the native call structure.

Alternate forms of the Hello World script would be
main()
    printf("Hello world!\n"); // You don't need to use curly brackets on single-statement functions


main()
    printf "Hello world!\n" // Parenthesis embracing function parameters are optional



A little detail: The first function isn't necessarily main, this is particular to pawnrun.

2. Variables
main() {
	new var = 42;
	printf("variable = %d", var);
}

The new keyword is used to declare a new variable. You may initialize it to a value on declaration.
main() {
	new myString[] = "Hello world, %s\n";
    printf(myString, "coder");
}


Okay, so we have some new things now:
  • Like in C, square brackets on declaration denote an array
  • The printf native supports almost everything on C's printf syntax.


In this code, we are creating a new variable named myString, which is an array, and initializing it to some value.
The myString array will have exactly 17 cells, the size of the string it's initialized to plus the 0 terminator, like C.
Just like expected, the %s on the string is replaced with the second parameter to printf, "coder".

3. Control Strucutures
main() {
	new userInput[5];
	printf("Type in your age: ");
	getstring(userInput);
	
	new age = string_to_int(userInput);
	
	if (age < 18) {
		printf("Hello, young coder!");
	} else if (age < 30) {
		printf("Hello, coder!");
	} else {
		printf("Hello, experienced coder!");
	}
}


Whoa, complex stuff! Actually it isn't complicated, let's break it down to small pieces:
new userInput[5];
printf("Type in your age: ");
getstring(userInput);


Here we declared an array to store user input, used printf to ask the user to input his age, and used the getstring native from console.inc to read a line from the standard input.

new age = string_to_int(userInput);
	
if (age < 18) { // if the expression evaluates to true, execute the following code block
	printf("Hello, young coder!");
} else if (age < 30) { // otherwise, run this block if this other expression evaluates to true
	printf("Hello, coder!");
} else { // if none of the conditions above were met, run this code block
	printf("Hello, experienced coder!");
}


Here's our control structures! Pawn has C-like if-else structure support.

Now that we know what all that code is doing, just one thing is left behind: what's string_to_int?
Since pawnrun doesn't provide a way to convert a string to an integer, I used this little function to accomplish it:
#include <string> // for strlen

stock string_to_int(string[]) {
	new value, decimal, mult, length = strlen(string);

	for (new i = 0; i < length; ++i) {
		decimal = string[i]-'0';
		
		mult    = (length-i-1)*10;
		if (!mult) mult = 1;

		value += decimal*mult;
	}
	
	return value;
}

Try not to stuck trying to understand this code, we'll get to loop structures and stocks in a bit.

4. Loop Structures
main() {
	for (new countdown = 10; countdown > 0; countdown--) {
	    printf("%d... ", countdown);
	}
	printf("BOOM!!!");
}


Here we are using the for structure to loop through the array cells.
In Pawn the for works just like in C++:
for (declaration; condition; increment) { /* body */ }
declaration gets called before the start of the loop, then condition is checked. If it's false, the for ended, otherwise:
Execute the body, execute increment, and check condition again. If it's false, the for ended, otherwise, repeat this line.

Another loop structure is while. This is an equivalent to the above code using while instead of for:
main() {
	new countdown = 10;
	while(countdown > 0) {
    	printf("%d... ", countdown);
		countdown--;
	}
	printf("BOOOM!");
}



5. Tags
On the very beginning of this tutorial, the Pawn description said "Pawn is a simple, typeless...". What's this lack of type mentioned?
In Pawn, all variables are cells, which are 32 bits integers. An array is just a bunch of cells indexed under the same name.

"But what about those strings we've used?!"
Strings are just syntax sugar, in fact, when you do new array[] = "Dream.In.Code", it's exactly the same of doing
new array[14];
array[0] = 68;   // ascii value for 'D'
array[1] = 114;  // ascii value for 'r'
array[2] = 101;  // ascii value for 'e'
array[3] = 97;   // ascii value for 'a'
array[4] = 109;  // ascii value for 'm'
array[5] = 46;   // ascii value for '.'
array[6] = 73;   // ascii value for 'I'
array[7] = 110;  // ascii value for 'n'
array[8] = 46;   // ascii value for '.'
array[9] = 67;   // ascii value for 'C'
array[10] = 111; // ascii value for 'o'
array[11] = 100; // ascii value for 'd'
array[12] = 101; // ascii value for 'e'
array[13] = 0;   // 0 terminator


The above could also be done like this:
new array[14] = {
	68, 114, 101, 97, 109, 46,
	73, 110, 46, 67, 111, 100,
	101, 0
}



But Pawn gives us a way to define meaning rather than type, tags:
#include <float>

main() {
	new userInput[10];
    printf("Enter your weight in kilograms: ");
	getstring(userInput);
	new Float:weight = strfloat(userInput);

	printf("Enter your height in meters: ");
	getstring(userInput);
	new Float:height = strfloat(userInput);

	new Float:IMC = weight / (height * height); // or floatpower(height, 2)
	printf("Your IMC is %.2f", IMC);
}


We include float to have the Float tag and floating point functions like strfloat and floatpower. The operators for Float math are also defined in there.
You'll notice that if you remove the Float tag from one of the float variables, the compiler will emit a warning, but the program will still compile and run, although not having the expected result. This is because tags are just a way to give meaning to a variable, not directly its type.

6. Enums
enum Action {
	Walk,
    Eat,
    Sleep	
}

main() {
	new Action:action = Sleep;
}


Here we are enumerating constants and defining a new tag correspondent to our enum.
This is useful to avoid hard coding constants into the code, and variables that have a determined set of values.

Pawn features a nasty syntax candy: you can use enums to index arrays just like C structures. See:
#include <string> // for strcopy

enum Person {
	Name[30],
	Age,
	AwesomeLevel
}

main() {
	new Seta00[Person];
	strcopy(Seta00[Name], "Seta00");
	Seta00[Age] = 18+random(6);
	Seta00[AwesomeLevel] = 9001;
	
	printf("Seta00's info:\nName: %s\nAge: %d\nAwesome Level: %d", Seta00[Name], Seta00[Age], Seta00[AwesomeLevel]);
}



6. Functions
In Pawn, like in almost every language, we can define functions to divide our code into small, concise pieces.
#include <string>

enum Person {
	Name[30],
	Age,
	AwesomeLevel
}

stock PrintInfo(person[Person]) {
	printf("%s's info:\nAge: %d\nAwesome Level: %d", person[Name], person[Age], person[AwesomeLevel]);
}

main() {
	new Seta00[Person];
	strcopy(Seta00[Name], "Seta00");
	Seta00[Age] = 18+random(6);
	Seta00[AwesomeLevel] = 9001;
	
	PrintInfo(Seta00);
}

Here we isolated the printing code into a smaller function, PrintInfo. The stock keyword is useful for code snippets, because the compiler will simply ignore them if not used in the code. That way you can build your own include files with useful functions like PrintInfo and string_to_int.

Conclusion
This tutorial should give you a good introduction to the tiny but useful Pawn language. I'll see if I throw up a Pawn embedding tutorial later, so you guys can script your own software with Pawn.

Useful Links
Pawn Language Guide (PDF File) - The complete documentation for the Pawn language. (Comes in the Pawn toolkit, see your doc folder.
AMX Mod X - Having the largest Pawn scripting community out there, AMX Mod X is a server-side modding tool for multiplayer GoldSrc games, like Counter-Strike and Team Fortress Classic.
SourceMod - Server-side modding tool for Source games, like Counter-Strike: Source and Team Fortress 2. Uses SourcePawn, an improved version of Pawn.
SA-MP San Andreas Multiplayer mod for Grand Theft Auto - The second largest Pawn scripting community.

Is This A Good Question/Topic? 0
  • +

Page 1 of 1