#### Archived

This topic is now archived and is closed to further replies.

# Scripting Language Syntax Proposal

This topic is 5041 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

I''ve spent roughly a week trying to find just the right scripting language for my online game framework project. Many of the languages I''ve looked at have elements I like, but all of them have elements I can''t stand. So yesterday, out of frustration more than ambition, I spent several hours working on syntax examples for what I hope will one day be a new scripting language. Some comments before I give my examples: 1) I wrote all my sample code from a perspective of Game Development, so I don''t know yet how well it would translate to other applications, but it seems pretty flexible to me. 2) Don''t bother whining about how this is just a syntax proposal (don''t even have the BNFs worked out) and its a whole other ballgame to actually build a compiler and/or interpreter. I''m aware of the sheer magnitude of the task. 3) A few words about the thoughts that drove me to certain syntactical decisions: In my recent post, "Choosing a Scripting Language," I said I wanted a language that was C-like, because C++, PHP, and JavaScript are what I am most familiar with. A lot of people whined and moaned and scoffed at that. So I decided to take a slightly different approach -- the actual language usage would be based on C-style, but I''d reluctantly do away with the ;''s and {}''s. In the end, the code looked so neat and clean to me that I had very little trouble adapting. I''m hoping others on both sides of the C-like-code debate will agree. There are two things I''m hoping for in posting this... the first being that people will offer the comments, constructive criticism, and advice on the syntax and style of the language. The second is more of a P.I.T.S... I''m hoping that someone (PeterTarkus, you reading this? ) will actually find the language interesting enough to consider working with me on a compiler/interpreter. The sample scripts will follow.. **************************************** Brian Lacy ForeverDream Studios Comments? Questions? Curious? "I create. Therefore I am."

##### Share on other sites
1   // A Simple Example Script2   3   include ("io.script")4   5   var strHello = "Hello!"6   var nTest = IO.Input()7   print ("Enter a number: ")8   var lenHello = strHello.Length()9   10  if (lenHello / 2 == nTest)11      for (var nI = 0, i < lenHello, i++)12          print (strHello[nI] + "\n")13      end14  else15      print ("Wrong answer.")16  end if17
OUTPUT (note that []'s indicate user input)

Enter a number: [3]

H
e
l
l
o
!

[edited by - irbrian on April 13, 2004 12:11:11 PM]

##### Share on other sites
While it looks pretty straightforward, there are some interesting things going on here. The first thing to consider is that the 'var' keyword has some very cool properties (imo). The 'var' keyword defines a variable that is not soft-typed, but is dynamically typed. In other words, variables are given a permanent type when they are assigned a value of a specific type.

Consider 'strHello' declared on line 5. When the interpreter reads 'var strHello' it creates a new variable with type unknown . At this point, we could have assigned it an integer value, and it would be an integer. But immediately following, the variable is assigned the value "Hello!" -- a string. So, it assigns the type of strHello to a string. Assigning it an integer value after this would not work.

Now look at line 8. Notice the 'strHello.Length()'? This works because each type is actually a class containing useful functions associated with that type. And like JavaScript, all variables are instances of the object class. In fact, 'var' itself is of the 'unknown' class -- meaning it too has some useful functions. I'll get to that later.

But why bother, you may ask? Why not just specify the type and be done with it? Well, for one thing, I think its a bit easier for new users to pick up on -- they needn't worry about type assignments because its all done automatically. Furthermore, because 'var' objects can be assigned a type dynamically, it may be useful in a script to assign a value without knowing its type, and then ask it later.

An example might be line 6. The IO object on line 6 is an interface object (included on line 3, naturally) which contains a method called Input(). This method gets input from the input stream (specified inside the C++ application, here it would probably be console or keyboard input) and assigns the value, in this case, to nTest. nTest has not been assigned a type yet. The IO.Input() method converts the input to the most appropriate type -- in this case, 3 alone is an integer, so the return type is an integer.

The program now knows that nTest is an integer. But the scripter does not. Well, we can find out by simply using the isInteger() method:
if ( nTest.isInteger() )    // do something integer-esqueend if
This works because the unknown type, 'var', is the base class of all types, and each type inherits methods from 'var' to determine what type of variable it is.

[edited by - irbrian on April 13, 2004 12:10:39 PM]

##### Share on other sites
I''ll post some more examples later today. My Linux class is starting.

##### Share on other sites
Looks like you''ve pretty much just reinvented Python.

[ MSVC Fixes | STL Docs | SDL | Game AI | Sockets | C++ Faq Lite | Boost
Asking Questions | Organising code files | My stuff | Tiny XML | STLPort]

##### Share on other sites
uhh.. no. I'm don't know much about python, but python's syntax bears little resemblence to what I'm trying to describe here, even though the functionality may be similar in some ways. The syntax style has much more in common with PHP or JavaScript than it does Python.

And I realize that to some of you syntax is irrelevant, but that's not the case for me.

I intended to post more examples much sooner to help demonstrate, but hadn't found the time yet. I'll post some more examples now.. hopefully it will become more evident what I'm going for.
// A MUD or I.F. function that returns the Room ID of// a given entity, such as a character, monster, or// other mobilefunction SearchRooms (var Entity, var StartRoom, var EndRoom)    for (var z = StartRoom, z < EndRoom, z++)        if ( Game.Rooms[z].hasEntity (Entity) )            return z        end if    endend
The only new thing in the above listing is the use of a general 'function' keyword to specify a function definition block.
// A class to create a simple container.// 'Container' is an abstract class we can use// to simplify the creation of container types.class Jar extends Container        var isOpen    var LidTightness    var MaxLidTightness        // Constructor -- called when new Jar is created    function Jar ()                isOpen = false        LidTightness = 10        MaxLidTightness = 20        MaxWeight = 05.00         // Auto-formatted float?                                  // ...just a thought         MaxContentsSize = 10        ContentsSize = 0        ContentsWeight = 0        EmptyContents ()          // Inherited method to set                                  // the container to empty    end        function Add (var Item)         if (Item.GetSize() < MaxContentSize - ContentSize)             if (Item.GetWeight() < MaxWeight - ContentsWeight)                 if (isOpen)                     Container.Add (Item)                 else                     // Tell player it won't happen...                     // More on Feedback another time                     Game.Feedback (this, "LidClosed")                     return                 end if             else                 Game.Feedback (this, "ItemTooHeavy")                 return             end if         else             Game.Feedback (this, "ItemTooBig")             return         end if                  Game.Feedback (this, "ItemAdded")     endend

[edited by - irbrian on April 13, 2004 11:35:35 PM]

##### Share on other sites
quote:
Original post by irbrian
uhh.. no. I''m don''t know much about python, but python''s syntax bears little resemblence to what I''m trying to describe here, even though the functionality may be similar in some ways. The syntax style has much more in common with PHP or JavaScript than it does Python.

After you''ve learned one language, syntax is the most important thing about it, because it''s the thing you''ve slaved over trying to get right. Once you''ve learned another, the strange and foreign feel of the syntax makes it that language''s most prominent feature, too. Once you''ve learned a dozen or so, you begin to realize that judging a language by its syntax is very much like judging a book by its cover. Trust me on this: good syntax does not make a good language.

"Sneftel is correct, if rather vulgar." --Flarelocke

##### Share on other sites
Don''t get me wrong, I agree wholeheartedly that the overall value of the language is not determined by the syntax.

Think about it this way: Price, performance and capability factors being equal, would you rather drive a Landrover, or an Escalade? Maybe you''d prefer the Landrover for its reputation for rugged outdoor adventuring. On the other hand, I might choose the Escalade, ''cause I like a smooth ride, nice handling, tons of options, and leather seats. Is one choice inherently better or worse than the other? Of course not. But that doesn''t mean I should satisfy myself with driving a Landrover my whole life.

Ultimately, I think syntax is about comfort. You find a style you like and you stick to it when you can. Well, this is about me sticking with a style I like.

If you''re still not convinced it matters, I''ve got a perfectly road-worthy ''96 Ford I can sell ya.

##### Share on other sites
Suggestion: drop the var-keyword. It''s not necessary. If you say var x = y or you say x = y, it''s basically the same thing. You can only assign something to a variable. Just check to see if the variable already exists: if it doesn''t, just create it. Defining a function? function fn(var x, var y) can be replaced by function fn(x, y).
KISS: Keep It Simple, Sydney.

---
tommy online: http://users.pandora.be/tommycarlier

##### Share on other sites
irbrian, i wouldn''t mind helping you out. It seems to me you have some solid ideas, i like that. I agree that syntax doesn''t "make" a language powerful, but I also agree that it
makes a language "comfortable" to a new user. Irbrian, I have been spending the last year researching compiler implementations, VMs, Interpeters, and script overall. I was
working on designing my own scripting language (i won''t go into a lot of details here, but i can send you some). I have a lot
of design down for the compiler\parser\virtual proccessor implemenation, but I am currently just beginging developement,
but, I would like to offer my assistance. I really like your
ideas on this style of syntax for scripting. I think it would
be easy on the designers writing scripts for the first time.
I do have a few suggestions, but I will save that for an email, or another post. I am off.

##### Share on other sites
I'm also writting a scripting language..
Written in visual basic... and i'm still writting it

< code >
dim [xy]
dim [input]
dim [out]
goto main
< io >

< /io >
SUB main
[out] = [input]* 2
if ([input] = ) ! (1 = 1)
goto main
end if
< miasm >
nop
jmp 0
< /miasm >
exit
< /code >

I was wondering if we could work together to finish a language which is as easy to write as your pythonish script, and is as simple as my basic c html ish script (by the way, the tags , ect. change how the interpreter(sp?) interpretes(sp?) the code afterwood, adding extra stuff for those who ask (the miasm is nifty too, its build on my VT (found at Planetsourcecode.com to allow the faster asm code to bu run rather then the slow script).

Hopefully you could use some of these ideas (and or merge the languages together)
EG.
< script>
< Efunct>
< code>

5 var strHello = "Hello!"
6 var nTest = IO.Input()
7 print ("Enter a number: ")
8 var lenHello = strHello.Length()
9
10 if (lenHello / 2 == nTest)
11 for (var nI = 0, i < lenHello, i++)

12 out = (strHello[nI] + "\n")

13 end if
14 else
16 end if
< /code >
< /Efunc >
< /script >
??

[edited by - Nice coder on April 14, 2004 6:00:38 AM]

##### Share on other sites
quote:
Original post by Tommy Carlier
Suggestion: drop the var-keyword. It's not necessary. If you say
var x = y
or you say
x = y
it's basically the same thing. You can only assign something to a variable. Just check to see if the variable already exists: if it doesn't, just create it. Defining a function?
function fn(var x, var y)
can be replaced by
function fn(x, y)

I understand how the var keyword must seem extraneous. However there's still a reason for it, which I haven't really gotten to yet (because I didn't want to throw too many features into the mix just yet). I'll get to that in a little while, and you guys can certainly point out any suggestions for improving it.

[edited by - irbrian on April 14, 2004 10:57:12 AM]

##### Share on other sites
quote:
Original post by I_Animated
irbrian, i wouldn''t mind helping you out... I do have a few suggestions, but I will save that for an email, or another post. I am off.
I''d be interesting in hearing your ideas, I_Animated. Shoot off an email at me when you''ve got a spare minute.

****************************************

Brian Lacy
ForeverDream Studios

"I create. Therefore I am."

##### Share on other sites
I personally like the ability to define a variable without assigning it a variable, even just as a way to indicate to the programmer that this is a new variable and isn''t going to be changed by anything outside this scope.

##### Share on other sites
I absolutely dislike the idea of skipping a definition keyword. if you have x = y; create a new variable, that might seem quite handy, but there is one very huge drawback (just thinking of actionscript in flash). if you spell a variable only slightly wrong, that would lead to a very hard to debug code, since a new variable would be created without any warning / error.

myfancyvariable = 3;

myfnacyvariable = 5; // spelled wrong --> new variable

print(myfancyvariable);

the above code would output the value 3, although i would have wanted it to be 5 by this time. that was only a small sample pointing out my main idea.

Indeterminatus

--si tacuisses, philosophus mansisses--

##### Share on other sites
These issues are the primary reasons I chose to require variable declaration. The issues of scope clarity, preventing variable mix-ups, etc, are things I really don''t like about many soft-typed languages.

I also wanted to allow scripters to declare a variable with a specific type, so that even initial attempts to assign it a value of another type would be rejected. Sometimes it may be helpful to actually declare a variable as a certain type, or to declare it as a constant. Consider the following lines:
var w                // Declares a variable of unknown type ''w''var x = 3            // Declares int ''x'' with value 3var int y            // Declares int ''y'' with value 0 (null int)var const int z = 3  // Declares constant int ''z'' with value 3
I haven''t decided for sure on allowing the following optional notation, but it seems natural. Basically, if and only if a type or const is specified, the ''var'' keyword is optional, as follows:
int aconst int b = 3const c = 8
Even in the latter cases, the ''var'' unknown type is at work here, forming the foundation of the variable. Also, as a matter of elegance, to me it would seem disruptive to not use variable declaration except when declaring a typed or constant variable.

##### Share on other sites
quote:
var w // Declares a variable of unknown type ''w''
w = None

quote:
var const int z = 3 // Declares constant int ''z'' with value 3
I fail to see the use of a constant value in a scripting language, which is inherently about mutability.

@Indeterminatus:
That''s a relatively minor problem. Maybe it''s just me, though, but I prefer 90% solutions. var doesn''t have enough benefits IMO, especially when typed declarations still exist (exactly how redundant is var const int z = 3?)

@irbrian:
Your Landrover/Escalade analogy doesn''t wash. Just because two pairs of objects are internally comparable does not make them cross-comparable.

##### Share on other sites
quote:
Original post by Oluseyi
w = None
I fail to see how that is any more elegant a solution. Personally, I find it downright ugly.
quote:
I fail to see the use of a constant value in a scripting language, which is inherently about mutability.
You may have a point. C++ offers this option, but maybe its not necessary for the scripting language. Still, my main concern is offering scripters options without making things confusing. If its confusing to others maybe I'll throw it out. Thanks for the input.
quote:
@Indeterminatus:
That's a relatively minor problem. Maybe it's just me, though, but I prefer 90% solutions. var doesn't have enough benefits IMO, especially when typed declarations still exist (exactly how redundant is var const int z = 3?)
Confusing code is never a minor problem. And personally, I don't like incomplete solutions. Oh, and the redundancy issue is the primary supporting argument for allowing the alias, const int z = 3.

Three of the primary design goals with this language are Elegance/Readability, C-familiarity, and Accessibility. The var keyword plays heavily into the first two, and I don't feel it negatively impact the third.
quote:
@irbrian:
Your Landrover/Escalade analogy doesn't wash. Just because two pairs of objects are internally comparable does not make them cross-comparable.
I think my analogy was clear and highly relevant. The purpose of an analogy is to make a point. If you didn't understand my point, then I feel you could have said "I didn't understand your analogy." Simply stating that my analogy "doesn't wash" is unclear, and in my opinion, is not very polite or professional either.

[edited by - irbrian on April 14, 2004 2:43:19 PM]

##### Share on other sites
I too am looking into creating a simple scripting language, but at the moment I've just been working on syntax for a configuration file (which I'm treating as a subset of the scripting language). Personally I like the use of braces and the semicolon as it keeps things "in the C family" so-to-speak and it's just something I'm used to.

Plus using if-endif is too BASIC-like...uh, I mean "wordy" for me

You can think of my configuration file format as a script that is limited to variable creation and assignment only. Later, I will expand it into a full-featured language as needed.

We start with five types of properties/variables: bool, int, real, string and composite. In the interest of getting some feedback in the same vein as irbrian, here is an example:

// Both C++ /* and C-style comments    are allowed*/Title = "title1.jpg"; // stringAutoSaveOn = ShowTitleScreen = true; // multiple assignment okPlayer { // this is a composite property/variable named "Player"  MaxHealth = 40; // int  XPosition = 0.0; // real  YPosition = 0.0;  ZPosition = 0.0;  Name = "Jeff";  Backpack { // composite within composite allowed    Color = "Brown";    MaxItems = 10;  }}

I have done away with using a "DIM" or "var" keyword as I, too, feel it is superfluous. I have also made each property/variable a sort-of variant type that can be re-assigned a different type (i.e. if you later did AutoSaveOn = "false", it would be turned into a string property).

I have already written the BNF for the above format (the hardest part was getting the string description correct for escape codes). I have already coded up a parser using boost::spirit (very cool, btw!). Now I'm just working on the wrapping class that takes the parsed symbols and creates the above structure in code...

I'm wondering if I need an array type? I like how PHP allows objects/composites to be viewed as arrays and vice-versa so I may do something similar down the line.

Regards,
Jeff

Edit: Fixed some typos

[edited by - rypyr on April 14, 2004 3:37:05 PM]

##### Share on other sites
quote:
Original post by rypyr
I too am looking into creating a simple scripting language, but at the moment I''ve just been working on syntax for a configuration file (which I''m treating as a subset of the scripting language). Personally I like the use of braces and the semicolon as it keeps things "in the C family" so-to-speak and it''s just something I''m used to.

Plus using if-endif is too BASIC-like...uh, I mean "wordy" for me

You can think of my configuration file format as a script that is limited to variable creation and assignment only. Later, I will expand it into a full-featured language as needed.

We start with five types of properties/variables: bool, int, real, string and composite. In the interest of getting some feedback in the same vein as irbrian, here is an example:

If you''re only having one integer type, I hope it will do something cool like type migration?

##### Share on other sites
quote:
Original post by Zahlman
If you''re only having one integer type, I hope it will do something cool like type migration?

What, do you mean: unsigned vs. signed and short vs. long ?

For scripting I have found that this is rarely a concern and that if I internally store all integers as signed long that it should not be a concern. But yes, there may be cases where a) this is overkill (i.e. to store a single byte) and b) overflow issues would need to be carefully documented

Or have I missed your point?

Regards,
Jeff

##### Share on other sites
quote:
Original post by rypyr

// Both C++ /* and C-style comments    are allowed*/Title = "title1.jpg"; // stringAutoSaveOn = ShowTitleScreen = true; // multiple assignment okPlayer { // this is a composite property/variable named "Player"  MaxHealth = 40; // int  XPosition = 0.0; // real  YPosition = 0.0;  ZPosition = 0.0;  Name = "Jeff";  Backpack { // composite within composite allowed    Color = "Brown";    MaxItems = 10;  }}

What I found a little bit interesting is that the previous code example''s syntax is almost the same as Lua.

Title = "title1.jpg";AutoSaveOn, ShowTitleScreen = true;Player = {    MaxHealth = 40, -- int    XPosition = 0.0, -- real    YPosition = 0.0,    ZPosition = 0.0,    Name = "Jeff",    Backpack = { -- composite within composite allowed        Color = "Brown";        MaxItems = 10;    }}

##### Share on other sites
Its difficult to sort out which comments are directed toward me, and which are directed toward rypyr or Nice Coder. Not to be rude, but is there any chance you guys could take your ideas to separate threads? I was hoping to get a little more feedback on my own.

##### Share on other sites
Sorry irbrian, didn''t mean to highjack your thread. Even though I was being a little bit of a leach, please re-interpret my post as the "comments, constructive criticism, and advice on the syntax and style of the language" that you are asking for in your original post.

My feeling is, don''t let the moans and whines of script kiddies ruin your ideas for what you feel is a consistent syntax. Also, you will never please everyone with a syntax, because syntax is just the formatting as Sneftel indicates. So posting the syntax and then asking for comments will spawn multiple arguments one way or the other with no one way being the right way.

- Does "end" really make things look nicer than using braces to you? To me it''s one more character I have to type , but in your favour, I guess it''s one less key to have to press if you include the Shift key :D ).

- why does "if" terminate with "end if" while everything else seems to terminate with just "end". A little consistency would be nice there.

- I think dynamically typing variables is good, but why not make them variants as well? You state that having a new user choose the variable type at declaration is going to confuse them, but you don''t think "locking" the type once he has chosen it is confusing? i.e. I wouldn''t make choosing a type a one-way street, the scripter should be able to re-assign a new type to a variable and it should be implicitly cast following rules you will have to enumerate (i.e. does a string value of "1" get converted to a bool value of true? what about a string value of "false"?)

- What do I do in your syntax if I want to write a really long line of code? Do you force me to horizontally scroll in the editor or do you provide a line-continuation character? I think the semicolon makes this easier to implement but that''s just my own bias again.

- What other features does "var" allow that you hint at? Can you divulge?

Regards,
Jeff

##### Share on other sites
quote:
Original post by rypyr
Indeed, though I feel a small amount of argument can be constructive, and I do want to get feedback. If enough people have issues with something, its worth re-considering.
quote:
- Does "end" really make things look nicer than using braces to you? To me it's one more character I have to type , but in your favour, I guess it's one less key to have to press if you include the Shift key :D ).
I should have mentioned that code-block closing delimeters is one area I am most uncertain about. I decided to drop {}'s because while I wanted a C-like syntax, I still want it to appeal to people who consider ;'s and {}'s "line noise." I thought maybe dropping {}'s for 'end' was a way to do that.. I do think its highly readable, and in practice, not so much effort to write as I originally thought.
quote:
- why does "if" terminate with "end if" while everything else seems to terminate with just "end". A little consistency would be nice there.
Yeah, this is the other part of closing delimiters that's been bothering me. I was surprised no one commented on it sooner. I worried that tons of 'end's would start to blur together, and end if is a pretty standard syntax in many scripting languages (i.e. BASIC). On the other hand, writing 'end function' and 'end for' and 'end while' is definitely more typing. What do you guys think -- would it be better to
1) use 'end' to end each code block
2) use {}'s
3) make it optional (end OR {}'s)
4) use block-specific delimeters: end func, end while, etc
quote:
- I think dynamically typing variables is good, but why not make them variants as well? You state that having a new user choose the variable type at declaration is going to confuse them, but you don't think "locking" the type once he has chosen it is confusing? i.e. I wouldn't make choosing a type a one-way street, the scripter should be able to re-assign a new type to a variable and it should be implicitly cast following rules you will have to enumerate (i.e. does a string value of "1" get converted to a bool value of true? what about a string value of "false"?)
I realize this is another sensitive issue. The reasoning behind it is primarily that I feel it makes for more elegant code. If you allow users to re-assign new value types to variables, they will invariably do so, and I believe that's ugly, and poor coding practice. On the other hand, what you're describing does make the language simpler.

I may re-evaluate, but in the interest of making the language as clean as possible, I will probably keep the locked-types, and scripters will just have to create new variables.

However, I've been assuming thus far that assignment would auto-cast as you're suggesting. Assigning a boolean value of true to a locked integer variable would cast it as a one for instance. I don't know about the string "false" being converted to boolean false though. I was thinking a string would be cast as either empty->false, or contains string -> true.
quote:
- What do I do in your syntax if I want to write a really long line of code? Do you force me to horizontally scroll in the editor or do you provide a line-continuation character? I think the semicolon makes this easier to implement but that's just my own bias again.
Honestly, I like the ;'s, and the {}'s as well. But enough people have made the point that a scripting language ought to eliminate so-called "line-noise" as much as possible. Instead, I was thinking of taking a Visual Basic approach and using the _ character:
if (MyNewVariableA == GetIntFrom (target, testVarA) && _      MyNewVariableB == GetIntFrom (target, testVarB) && _      MyNewVariableC == GetIntFrom (target, testVarC) )    // Do somethingend if
quote:
- What other features does "var" allow that you hint at? Can you divulge?
I've mentioned a few, but I've been considering one more big feature: the ability to nest objects, like in JavaScript. Existing objects could also be attached to other objects. Functions could also be attached to objects to become methods. For lack of a decent way to explain it, I suppose you could say the attachment thing is a bit like multiple inheritance, without the inheritance. The only language I know of that does this is WME Script, which is more or less proprietary. I didn't want to get too far into this quite yet, but there's the general idea.

[edited by - irbrian on April 14, 2004 6:20:57 PM]