找回密码
 点一下
查看: 1457|回复: 1

Galaxy++ editor

[复制链接]
发表于 2011-5-29 11:56:11 | 显示全部楼层 |阅读模式
此为中文测试版,不支持中文输入,但支持中文复制。支持中文程序名自动转换。纯英文版见猛击此处


Galaxy___editor_chinese_test_2.zip (1.61 MB, 下载次数: 14)
Documentation



General


Galaxy++ is a programming language that extends upon the original galaxy language, adding a lot more features. This means that any galaxy code you have should run exactly the same way when feeding it to the galaxy++ compiler.
Like most other programming languages, comments and whitespace is ignored by the compiler, so they can be placed pretty much anywhere without changing the behavior of the program.
If you feel some of your questions still go unanswered after reading this, or you find errors in the documentation, please pm me or post a reply. I will get back to you, and perhaps add to the documentation.

Compiler options


Although they might not classify as a language feature, I feel it's relevant to highlight some of the options in the compiler.

Obfuscation


There are a couple of tools for obfuscating the code. One is to rename everything to short names such as a, b, c. The other is to obfuscate string literals. What this will do is to "encrypt" every string so it is not readable by humans, and "decrypt" them when starting the map.
Please note that no code obfuscation can completely prevent others from reading, understanding and stealing your code. It just makes it difficult.

1: Declarations



1.1: Namespaces


You have the option to define a namespace for each file. The namespace must be declared as the first thing in the file. You declare a namespace with

#namespace myNameSpace
By default, you can only directly refer to things in your own namespace or the default namespace. If you want to refer to declarations outside your current namespace, you can use the dot notation. For example, if the method method() is in the namespace otherNS you can refer method with

otherNS.method()
If you want to be able to directly refer to everything in another namespace you can add a #using declaration. These must be at the top of the file, directly below the namespace declaration if present.

#using otherNS

1.2: Initializers and Library definitions


Initializes are basically methods that are run at first, when the map loads. Unless you made your own call to initialize the standard library, this call will be inserted before calling the initializers. You can make a simple initialize with

#Initializer{[statements]}
The initializers can also contain data about a library you are defining. There are 4 different library fields: #LibraryName, #LibraryVersion, #SupportedVersions and #RequiredLibraries. An example of a library initializer is

#Initializer(#LibraryName = "my library"#LibraryVersion = "enterprise",#SupportedVersions = "trial, basic"#RequiredLibraries = "other lib 1:version2, (otherLib2:v1.7.4)"){[statements]}
All the library fields are optional, except you need both a name and a version in order for others to add it as a requirement. If your library version is not on the list of supported versions, it will be added. You may not use “:”, “(“, “)” or “,” in the name or versions, and all leading and trailing whitespace is ignored. The method block is optional. It can be replaced with a semicolon.
If an initializer has defined any required libraries, the initializers of those libraries will be called first. In case of cyclic dependencies, a warning is reported, and as few dependencies as possible are ignored.

1.3: Includes


Any custom includes are ignored. Includes will be inserted by the compiler as needed, but all code except for the standard libraries are required in the project.

1.4: Methods


Unlike normal galaxy, it is not needed to have defined the method before using it.

1.4.1: Inline methods


Inline methods are marked with the keyword #inline. When compiling a call to an inline method, the contents of the method is inserted instead of calling the actual method. This is done in a way so that there is no semantic difference to calling the method instead.

#inline int method(...){...}
Note that inline methods may not be recursive i.e. they may not be called from themselves.

1.4.2: Trigger methods


There is a #trigger keyword in galaxy++, but it no longer has any effect. It was previously used to identify methods that were triggers, but this is now done by searching for a string in a call to TriggerCreate. The keyword is kept for backward compatibility.

1.4.3: Reference parameters and extra return values


You can mark parameters with the #ref or #out keywords. Arguments passed to parameters marked with one of these must be variables. The effect of #ref is that any changes done to the variable during the method call is reflected back in the calling method after the call. #out is similar. Like with #ref the changes done to this variable will also be done after the call, but unlike #ref, it is required that the called method assigns a value to an #out parameter, and he cannot read the parameter before he assigns a value to it. After compilation, an #out parameter is not actually passed to the function, it is only returned, so it can be used as extra return values.

string[17] strings;string Next(#ref int i, #out bool hasNext){hasNext = i + 1 < strings.length;if (hasNext)return strings[++i];return "";}

1.4.4: Passing bulkcopy data


Another thing to not is that it is now possible to pass types that would otherwise result in a bulk copy error between methods. This includes struct types and arrays. From your point of view, they are passed in exactly the same way as normal types. The compiler will send them via the data table instead.

1.5: Fields


Fields are pretty much what they are in galaxy, except that you don't have to have defined them above where you use them.

1.6: Structs


Like with fields and methods, you don't have to define structs above where you use them.
A new thing in galaxy++ is that structs can now contain methods. Simply place a method inside a struct, and that method will be a struct method. Struct methods will always be called with a specific instance of the struct. It is possible to directly refer to the members of the struct that is being called on by just typing the name of the member.

struct Foo{int[10] elements;int GetSum(){int sum = 0;for (int i = 0; i < elements.length; i++)sum += elements;return sum;}}...void Method(Foo foo){if (foo.GetSum() > 9000)......}

1.7 Bank preload statement


The preload bank statement from GUI is not an actual method call in code, so I added extra functionality to call this.

#PreloadBank("BankName", 2);
I felt that it would be misleading to place it inside functions, since it is not a statement which is executed there, but rather just a message to Starcraft II to load the bank when loading the map. Therefore it is placed out next to methods and fields. Note that the name and playerNr must be literals. I.e. you can not use any kind of variables or expressions other than what you see above.

2: Statements


A statement is basically the members of functions where it doesn't make sense to talk about it having a type. Examples of statements in galaxy are while statements, if statements and expression statements. In this documentation I will only cover statements that are new or have added functionality in galaxy++.

2.1: If statements


In galaxy you were forced to place a block inside if statements, now you can also place a single statement without the block.

if (i < ar.length)i++;

2.2: For statements


I added for statements in galaxy++.

for ([init]; [test]; [update])[body]
Basically, what it will do is first execute the init, then for as long as the test evaluates to true, the body and then the update is executed. Like GUI for sentences.

2.3: Switch statements


I also added switch statements.

int ammount;bool isRanged = false;#switch (GetUnitTypeString()){#case "Zergling":ammount = 100;break;#case "Marine":isRanged = true;#case "Zealot":ammount = 50;break;#case GetSuperUnitName():ammount = 1;break;#default:ammount = 10;break;}
It will test the expression it gets in the first parenthesis against every case in the order they are listed. When one of them equals, it will execute the contents of the case. If no cases were equal to the expression, the contents of default will be executed. Note that it is possible to fall through to the next case if one doesn't write break, like it is done from marine to zealot. Another thing to mention is that the method GetUnitTypeString() will only be called once, no matter how many cases there are. Also, GetSuperUnitName() is only called if none of the above cases matched.

2.4: AsyncInvoke statement


The AsyncInvoke statement will call a method in a new thread, and continue its own thread. This is done by running a new trigger, so the operator stack is also reset in the process (in case you are wondering, this is a good thing :)). If you wanted to call a method like

int CallMe(int a, bool b){...}
you could write

#AsyncInvoke<CallMe>(2, false);
In case CallMe is in another namespace called OtherNS, you can write

#AsyncInvoke<OtherNS.CallMe>(2, false);
Since the target function is called in a new thread, it is not possible to return a value from it, so any return values are ignored.

2.5: Local declarations


I made it possible to make multiple local declarations in one statement as long as they are of the same type.

int a = 2, b, c = a + 1;

3: Expressions


Expressions are everything that can have a type. Examples of this is method calls, references to local, global or struct variables, binary operations (+, -, *, /, %), etc. Like with statements, I won't cover the expressions that are the same in galaxy as in galaxy++.

3.1: The ++ and -- expressions


I added support for the ++ and -- expressions. They can be placed before and after a variable, and will increment or decrement the variable. When placed after the variable, the current value of the variable is placed where the expression is, and then the variable is updated. For instance, if you write

int i = 0;ar[i++] = i;
then then you will have set the 0th index of ar to 1. Placing it before the variable will update the variable, and then the updated value is placed where the expression is. E.g.

int i = 0;ar[++i] = i;
will set the 1st index of ar to 1. This is most commonly used as a quick way of writing i = i + 1;

3.2: Invoke


Similar to the AsyncInvoke statement, this expression will call the target method via a trigger in order to reset the operator stack. Unlike AsyncInvoke however, this is not done in a separate thread. This means that all return values can still be fetched.

#Invoke<namespace.methodName>(args);

3.3: Assignments


With galaxy++ you can now place assignments inside expressions rather than just in statements. For instance you can write

a = b = c = d = 2;
and all of them will have the value 2. Note that the type of the assignments are the type of the left side. What this means is that for instance if c is of type fixed, and b is an integer, you will get an error since fixed is not assignable to int.

3.4: Array length


You can get the length of an array by calling .length on it.

String[2] ar;return ar.length;    //returns 2

3.5 Casts and implicit casts


I added cast expressions. They are a quick way of converting between types that can be converted between.

fixed f = 2.2;int i = (int) f;
I also made some implicit casts, which means that between some types the cast occurs automatically.

int i = 2;UIDisplayMessage(playergroupAll(), c_messageAreaSubtitle, "i = " + i);
In this example, the i is cast to a string, then the two strings are concatenated, and the whole string is cast to a text.

Pointers


This is placed a little out of place compared to the structure of the rest of the documentation, but I thought I would keep everything regarding pointers together.

Pointer types


You can define a type as a pointer by appending *. For instance

int* i;string** s;
Here i will be a pointer to an int, and s will be a pointer to a pointer to a string.

Dynamic array types


You can define a dynamic array type by not specifying array bounds. For instance

int[] ar1;int*[] ar2;
Here, ar1 is a dynamic array of type int, and ar2 is a dynamic array of pointers to int's.

The * expression


If you have an expression of pointer type, and you would like to get the value of that expression, you prefix it with *. For instance

void foo(string* s){UIDisplayMessage(PlayerGroupAll(), c_messageAreaSubtitle, (text)(*s));}
Here, the *is needed to get the actual contents of s. Also note that *s is in a parenthesis. If this was not the case the compiler would have tried to multiply a variable called text with the variable s.

The -> expression


The -> expression is really just a quick way of writing (*foo).bar.

struct Foo{int bar;}void method(Foo* foo){foo->bar = 2;(*foo).bar = 2;}
Here, the two statements are equivalent. In both cases, bar will be set to 2.

The #new expression


To create new pointers or dynamic arrays, use the #new expression. For instance

int* i = #new int();int[] ar1 = #new int[*i]();
Here, i is initialized to a new integer, and ar1 is initialized to a dynamic array of size *i (which will be 0 in this case).
Note that the #new expression allocates a new instance in the data table. To avoid memory leaks, remember to call #delete after you are done with the instance.

The #delete statement


The delete expression will remove the supplied pointer or dynamic array from the data table. You should make sure that you call #delete if you are done with your pointer or dynamic array. Note that the #delete statement will only remove the actual pointer you supply to it. So writing

void foo(int*[] intAr){#delete intAr;}
Will remove the array, but will not remove any of the child pointers. If you wish to purge all allocated instances, you can clear the global data table with the method.

DataTableClear(true);
So, note that you shouldn't call this unless you wish to lose all pointers and dynamic arrays.
发表于 2011-6-6 02:35:45 | 显示全部楼层
Hi.. I don't mind people spreading the word about the compiler, but I think it would be best ifyou link to the sc2mapster thread.
The tool is constantly evolving, and there has been two versions released since the "secret chinese test" version, which I didn't actually release, since the feature for Chinese characters wasn't complete.

Anyway, new versions can be found on mapster or on my ftp server.
This forum won't let me link, but the thread is in the third party tools section of the sc2mapster forum.
That thread is also where I will be looking in case you have any suggestions, find any bugs, or have general questions about the editor.
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 点一下

本版积分规则

Archiver|移动端|小黑屋|地精研究院

GMT+8, 2024-4-25 02:27 , Processed in 0.313180 second(s), 22 queries .

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表