Massassi Forums Logo

This is the static archive of the Massassi Forums. The forums are closed indefinitely. Thanks for all the memories!

You can also download Super Old Archived Message Boards from when Massassi first started.

"View" counts are as of the day the forums were archived, and will no longer increase.

ForumsShowcase → SodiumScript
SodiumScript
2005-12-03, 10:00 PM #1
I'm writing a partial compiler for an 'in-house' scripting language based off C (like COG..) for that OpenGL project in thread:
http://forums.massassi.net/vb3/showthread.php?t=37630

I've been working on this as much as I can for the past few days, and it's coming out pretty good. Everything is being done by hand (screw Lexx and Yacc).

The resulting language is going to look pretty much like COG, which most everyone here is at LEAST somewhat familiar with. You will be able to declare new functions, and the scripts will be function-call based, versus COG's event messages. For example:

COG
Code:
symbols
message activated
model      cereal=cerealbox.3do         local
end
code
activated:
   player = GetSourceRef();
   dummy = GetSenderRef();
   x = 50;
   call doSomething;
   SetThingHealth(player, healthVal);
   SetThingModel(dummy, cereal);
   return;

doSomething:
   healthVal = x * 2;
   return;
end


Sodiumscript equivelant
Code:
function onActivated(dummy, activator)
{
   SetObjectHealth(activator, doSomething(50));
   SetObjectModel(dummy, "cerealbox");
}

function doSomething(x)
{
   return x * 2;
}


Done and/or mostly finished:
- Lexical Analyzer
Converts program text into tokens. This filters out whitespace, comments,
some potential errors, converts text numbers into real values, etc.
Strings, vectors, floats, and ints are supported for value types.
Plans to support structures.
- Statements and Expressions
Abstract statements and expression interfaces and MOST of their derivatives
are done. if() checks, for/while/do-while loops, etc. are all done.


Stuff I need to do:
- Identifier scope
Without really thinking ahead, all identifiers are global in a script,
which is actually the way COG works, except I want to support functions
with parameters, which complicates matters, edging me towards localizing
identifiers to the depth they are declared/first used within. Therefore,
global identifiers could still be used as long as they are differentiated
from locals by either requiring global or local variables to have a keyword
identifying them. For example, LUA scripting uses a 'local' keyword to
declare local variables, while otherwise they are assumed to be global.
I may take this approach.
- Postfix operators
Function calls, subscripting, dot operator for structures, and
increment/decrement are postfix operators.
'Function pointers' probably won't be supported, but I do hope to support
a better subscripting setup than COG has. You should be able to at least
subscript into strings to retrieve a particular characters. I definitely would
like to support strings better than COG since they can be quite useful in
higher-level programming. At the very least, function calls will be provided
for string manipulation, if not at least a little native support. For example,
concat'ing strings together using + operator should not be very difficult.

The 'compiler' is pretty much going to lex the program contents and form the syntax tree for each declared function. That's it. No virtual machine or bytecode result. To execute a script function within the engine, a string or hash ID for the requested function is fed to the Script object, and it spits back a pointer to that function if it found it. From there, execute() can simply be called. This will recursively execute each contained statement, and evaluate each statement's contained expression(s)/statement(s). Currently, executing a function is finished and works. The lexer is finished and works as well. Statement forming is finished and works. Expression forming is pretty much all that is left, and that requires order of operations and determining what type of expression (unary, binary, postfix, value, identifier).

Like I said, there's probably not going to be an internal 'machine' language or virtual machine for sodiumscript, so it'll run slower. Executing the test scripts didn't dent the framerate at all, so I'm not terribly worried. One benefit to this type of setup is that scripts can be compiled and used on the fly, while running the game. I'd like to pop up a big text field using a debug command, and allow you to write an event handler (like onActivated) for the particular object you are targetting.

This is a learning experience, I plan to rewrite the whole damn engine and compiler when I get a better sense of how to go about all of this stuff. The code works but its rather ugly ;)

[http://binarydemons.com/~strike/files/sodiumscript.JPG]
[ B A H ]
Bad *** by nature,
Hackers by choice
2005-12-03, 10:21 PM #2
You work damned hard apperantly JOIN THE SITH 2 TEAM!!
2005-12-03, 10:58 PM #3
Why no lex and yacc? Would have made it much easier, I think.
[This message has been edited. Deal with it.]
2005-12-04, 1:23 AM #4
Originally posted by Malus:
Why no lex and yacc? Would have made it much easier, I think.


Don't learn nothin using other people's easy do-it-yourself kits.. (same reason why people who only know VB are getting nowhere, I might add).

You can call it reinventing the wheel, but take a look around you at all the incredible technology today has to offer; and notice how stupid/ignorant most people still are.

Thats my rant =P
[ B A H ]
Bad *** by nature,
Hackers by choice
2005-12-04, 1:44 AM #5
Originally posted by Tiberium_Empire:
You work damned hard apperantly JOIN THE SITH 2 TEAM!!

word!!
2005-12-04, 4:13 AM #6
The problem with this sort of thing is you can't really compete by yourself. A scripting language already out with a lot of people contributing is nearly always better. So after you are done learning, you might decide to just use an off-the-shelf scripting language anyway. Try Angelscript when you do. [url]www.angelcode.com[/url]
2005-12-05, 6:43 AM #7
SodiumScript's expression parser is now functional, and I have been able to painlessly test a compilation and test run that worked on the fourth try or so. Only the binary subexpression parsing code is written, but the tokens are presorted by depth and precedence when forming individual sub expressions, so writing the other handlers (as well as finishing the rest of the whole thing) should be pretty basic. Hell yes with a capital W00T!

Sure there's more to build and probably a wagon load of problems that I will run into and need to fix, but check it!

[http://binarydemons.com/~strike/files/ss.JPG]
[ B A H ]
Bad *** by nature,
Hackers by choice
2005-12-05, 6:49 AM #8
Heres all the notebook paper I went through figuring out how to build the components of the compiler

[http://binarydemons.com/~strike/files/IM002136.JPG]
[ B A H ]
Bad *** by nature,
Hackers by choice
2005-12-05, 4:28 PM #9
I'm sure the satisfaction you're feeling right now is immense, Strike, but unfortunately these screenshots aren't going to be very impressing for the regulars here :) That's the hard part of being a programmer, only the superficial end results get attention, regardless of the methods used. Like when my boss asks me what I'm working on and I proudly mention some complex technical feat I've just accomplished, his usual response is "hmm, okay. Anything to see?"
Dreams of a dreamer from afar to a fardreamer.
2005-12-05, 7:43 PM #10
Function calls worked before, but now I've set up a basic framework for system calls, aka game commands.

This might be a little better example of how nicely the parser works

Code:
// this is our test command that is called when the engine starts up
//
function doSomething
{
  // this is a function call that is written at the bottom of this script
  // notice how you can use functions before they are defined  hehe
  MakeLotsOfBlanks();

  // example displaying string from a variable
  blackout = "Nighty-night in..";
  output(blackout);

  // start the count-down at 10.. in hex, for examples sake
  x = 0xA;

  // display the count-down
  for(; x; x--)
    output(x);               // example displaying number from a variable

  // oh no you only see blackness
  output("J00 CANT SEE !!");

  // sodium command call to destroy all lights
  destroyAllLights();
}


// this displays a bunch of blank lines to the output window
// to clear the display
//
function MakeLotsOfBlanks
{
  x = 50;
  while(x--) output();
}


[http://binarydemons.com/~strike/files/goodnight.JPG]


writing a new sys call is uber easy (in engine's code)
Code:
CValue output(CExpression *args)
{
	char buffer[512] = { 0 };
	if(args) args->evaluate().getFriendlyValue(buffer);
	SSIO->output(buffer);
	return CValue();
}

CValue WorldGetMaxObjects(CExpression *args)
{
        return CValue(WORLD->getMaxObjects());
}

REGISTER_SYSCALL(output);
REGISTER_SYSCALL(WorldGetMaxObjects);
[ B A H ]
Bad *** by nature,
Hackers by choice
2005-12-05, 9:09 PM #11
When you're done with this, you should seriously help SITH2, which has made tons of progress in this area already. (Full COG parser, level and 3DO rendering, sounds, and more)
2005-12-06, 10:13 AM #12
Yeah strike. If you ever find yourself with enough free time to help sith2 a little I think you should at least see if there's anything going on there you'd be interested in.

Get on MSN sometime...
</sarcasm>
<Anovis> mmmm I wanna lick your wet, Mentis.
__________
2005-12-06, 12:22 PM #13
I'm on MSN all the time

strike_1337@hotmail.com
[ B A H ]
Bad *** by nature,
Hackers by choice

↑ Up to the top!