PDA

View Full Version : One night fun - Script language



Super Vegeta
26-01-2012, 12:16 AM
Yesterday night I read an article about writing a script language and decided to give it a try. When I suddenly realised it's over 4 A.M., I decided it's time to sleep... Still, as for the first time coding something like this, it turned out quite well, I daresay.

Contains nothing more than text drawing, variable handling, ifs, repeat and label+goto, but if someone has too much spare time - what do I care, check it out.

Download: 'ere (http://svgames.pl/trash/parser.zip)
Thing requires SDL, SDL_ttf and SDL_gfx. Linux and Win32. Usage: ./parser < scriptfile



A short guide:
- One command per line
- All fields separated by a space
- Commands are case-sensitive, must be in lowercase

Commands:
windowsize W H - create a window with given size
drawtext X Y COL TXT - print TXT at X,Y with COL color. Variables can be printed too.
clrscr COL - fill the screen with given color
line XA YA XB YB COL ALPHA - draw a line between points. Alpha is optional.
rect XA YA XB YB COL ALPHA - fill a rectangle with color. Alpha is optional.
circle XA YA XB YB RAD COL ALPHA - draw a filled circle. Alpha is optional.
trigon XA YA XB YB XC YC COL ALPHA - draw a trigon. Alpha is optional.
random VAR MIN MAX - assign a random value in range (MIN - MAX) to VAR.
If Min is ommited, range is (0 - MAX-1).
If both are ommited, range is (0, 100).
updategfx - self-explanatory
autoupdate on/off - turn on/off automatic updategfx call after every command
delay TIME - sleep for TIME miliseconds
windowname TXT - set TXT for window name
quit - halt the whole thing

Declaring an integer: int NAME VALUE
Referencing an integer: $NAME
Freeing an integer: trash $NAME
Assigning a value: $NAME := VALUE
If no value is specified, variables are set to 0 on declaration. If a variable is not assigned, referencing it will return 0. If a variable name is in use, declaring a new variable shadows the old one (making it completely inaccesible!) until the new one is trashed.

Math expressions must be put in brackets - [VAL1 OPER VAL2]. No spaces between values and brackets!
Operator list:
+ - * /
% modulo
^ power
& | X and or xor
_ cut off modulo VAL2 (8 _ 3 is 6)

VALs can be variables, expressions or constants. Hex constants can be written like this: #HEXVAL.
Example: $VAR := [[$POS + 50] _ #20]

You can also use the short operators:
+= -= *= /= %= ^= &= |= X= _=

Conditionals:
if VAL1 OPER VAL2
command
else
command
fi

Loop:
repeat
command
until VAL1 OPER VAL2

Boolean operators:
= < > >= <= <>
&= all VAL2 bits are set in VAL1
_= VAL1 is divisable by VAL2
Boolean expressions not implemented. ([$A - $B] = [$B - $C] is possible, but not [$A > $B] = [$B > $C])

Procedures - declaration:
proc NAME
some code here
corp

Procedures - calling:
call NAME ARG ARG ARG ARG (...)

Arguments can be retrieved inside a function using $ARG:X: variables, where :X: is the argument number, beginning from 0. Note that procedure declaration does not specify its argcount - amount of arguments passed is left solely to the decision of the caller. The aforementioned amount is stored in the $ARG? variable (yes, with the qoutation mark). You can use the return VAL command to force quit a procedure and, optionally, return a value. It will be available in the $RESULT variable. All variable handling is done in the same global context, so you can access all variables normally - but You also must remember to trash all variables created by a procedure. ARGs are trashed automatically when a procedure ends and should NOT be freed manually, as automatic trash will still occur, corrupting the variable set. (Easily noticeable in a recursive procedure).

Example:
proc power
if $ARG1 = 0
return 1
fi
if $ARG1 _= 2
call power $ARG0 [$ARG1 / 2]
return [$RESULT * $RESULT]
fi
call power $ARG0 [$ARG1 - 1]
return [$ARG0 * $RESULT]
corp
(Tested to work, works circa 10x slower than the built-in ^ operator.)

The parser itself creates and updates seven variables.
$MOUSEX - mouse position
$MOUSEY - as above
$CLICK - 0 for no click, 1 - left button, 2 - middle, 3 - right
$CLICKX - click position
$CLICKY - as above
$TICKS - time running (in ms)
$QUITREQUEST - when the user presses the "Close" button, this is set to 1

I think that's all. A few sample scripts are included.

WILL
27-01-2012, 02:11 AM
Neat! :)

I remember my first game 'script' I made up for my top-down space shooter. Never released the game/engine (not even as an alpha) but it was fun to make. The idea of mine was to script events or triggers within the level/mission. Idea being that you could script each mission you player, much like the old X-Wing level editors, only in text script. I may consider going back to doing something like that in a future project. Maybe something for the iPad. :)

Ñuño Martínez
27-01-2012, 12:09 PM
Nice work. The simpler, the better. I like it. :)

Some years ago I did an scripting engine based in FORTH, but I never used it. Actually it was very ugly and scripts were dirty; anyway it was funny and I learned a lot. :)

Super Vegeta
02-02-2012, 12:36 AM
Gave it some extra work. Added drawing primitives (easy), but mostly - procedures. Took me quite a while to convey a way to make it all work, but I am very satisfied with the result. All necessary info was updated in the first post.

code_glitch
17-02-2012, 05:16 PM
Damn.... This sure beats the config file based scripts I feed into my engines.... tut tut tut. And it has procedures to boot! Thats a lot of features for a small one night project :)

Super Vegeta
19-02-2012, 09:50 AM
Well, as seen from the post above, procedures were added later, the first, truly one-night project had label+goto. But I'm glad it has found some appreciation.

Hm, since PGM4 still isn't around, maybe I could write an article on this...

paul_nicholls
21-02-2012, 01:29 AM
Nice work Super Vegeta :)
I remember fondly my first scripting language a few years ago...it worked ok, but could have been written better LOL