Ogólny opis języka 54980 3

O temacie

Autor

Zaczęty 20.01.2008 roku

Wyświetleń 54980

Odpowiedzi 3

Kazzmir
  • Gość

Kazzmir
Gość

Ogólny opis języka
2008-01-20, 22:17(Ostatnia zmiana: 2009-07-06, 15:54)
Cytat: Zysk link=topic=104.msg144#msg144 date=Jul 30 2006, 22:17\'
Nie będzie to niestety kurs, a raczej informacje o składni skryptów

1. Zmienne i stałe (wartości):
Aby używać wartości należy ją zadeklarować:
var typ nazwa;
const typ nazwa = wartość;
var dla zmiennych
const dla stałych
W ten sposób tworzymy wartość typu "typ" (najczęściej int-liczba całkowita, choć mogą być inne np. string-łańcuch znaków) o nazwie "nazwa" (po której będziemy się do zmiennej odwoływać) i zawierającą na początku "wartość_początkowa". Jeśli zmienną deklarujemy w miejscu poza wszelkimi funkcjami to będzie to wartość globalna dostępna wszędzie, w przeciwnym wypadku będzie usunięta po wyjściu z przedziału wyznaczonego przez operatory #msgote author=Zysk link=topic=104.msg144#msg144 date=Jul 30 2006, 22:17\']Nie będzie to niestety kurs, a raczej informacje o składni skryptów

1. Zmienne i stałe (wartości):
Aby używać wartości należy ją zadeklarować:
var typ nazwa;
const typ nazwa = wartość;
var dla zmiennych
const dla stałych
W ten sposób tworzymy wartość typu "typ" (najczęściej int-liczba całkowita, choć mogą być inne np. string-łańcuch znaków) o nazwie "nazwa" (po której będziemy się do zmiennej odwoływać) i zawierającą na początku "wartość_początkowa". Jeśli zmienną deklarujemy w miejscu poza wszelkimi funkcjami to będzie to wartość globalna dostępna wszędzie, w przeciwnym wypadku będzie usunięta po wyjściu z przedziału wyznaczonego przez operatory {#msgote author=Zysk link=topic=104.msg144#msg144 date=Jul 30 2006, 22:17\']Nie będzie to niestety kurs, a raczej informacje o składni skryptów

1. Zmienne i stałe (wartości):
Aby używać wartości należy ją zadeklarować:
var typ nazwa;
const typ nazwa = wartość;
var dla zmiennych
const dla stałych
W ten sposób tworzymy wartość typu "typ" (najczęściej int-liczba całkowita, choć mogą być inne np. string-łańcuch znaków) o nazwie "nazwa" (po której będziemy się do zmiennej odwoływać) i zawierającą na początku "wartość_początkowa". Jeśli zmienną deklarujemy w miejscu poza wszelkimi funkcjami to będzie to wartość globalna dostępna wszędzie, w przeciwnym wypadku będzie usunięta po wyjściu z przedziału wyznaczonego przez operatory  i #msgote author=Zysk link=topic=104.msg144#msg144 date=Jul 30 2006, 22:17\']Nie będzie to niestety kurs, a raczej informacje o składni skryptów

1. Zmienne i stałe (wartości):
Aby używać wartości należy ją zadeklarować:
var typ nazwa;
const typ nazwa = wartość;
var dla zmiennych
const dla stałych
W ten sposób tworzymy wartość typu "typ" (najczęściej int-liczba całkowita, choć mogą być inne np. string-łańcuch znaków) o nazwie "nazwa" (po której będziemy się do zmiennej odwoływać) i zawierającą na początku "wartość_początkowa". Jeśli zmienną deklarujemy w miejscu poza wszelkimi funkcjami to będzie to wartość globalna dostępna wszędzie, w przeciwnym wypadku będzie usunięta po wyjściu z przedziału wyznaczonego przez operatory }#msgote author=Zysk link=topic=104.msg144#msg144 date=Jul 30 2006, 22:17\']Nie będzie to niestety kurs, a raczej informacje o składni skryptów

1. Zmienne i stałe (wartości):
Aby używać wartości należy ją zadeklarować:
var typ nazwa;
const typ nazwa = wartość;
var dla zmiennych
const dla stałych
W ten sposób tworzymy wartość typu "typ" (najczęściej int-liczba całkowita, choć mogą być inne np. string-łańcuch znaków) o nazwie "nazwa" (po której będziemy się do zmiennej odwoływać) i zawierającą na początku "wartość_początkowa". Jeśli zmienną deklarujemy w miejscu poza wszelkimi funkcjami to będzie to wartość globalna dostępna wszędzie, w przeciwnym wypadku będzie usunięta po wyjściu z przedziału wyznaczonego przez operatory .
Przykłady:
var int Kapitel;
const int DurstigeBauern = 10;
Istnieje jeszcze możliwość tworzenia tablic zmiennych:
var typ nazwa[ilość];Ilość określa jak duża będzie tablica. W ten sposób powstają nam zmienne:
var typ nazwa[0];
var typ nazwa[1];
...
var typ nazwa[ilość-1];
Jak widać są one numerowane od zera.
2. Operatory i wyrażenia warunkowe
Operatory wstawiamy pomiędzy dwie wartości (dwuargumentowe) lub przed konkretną wartością (jednoargumentowe).
Pierwszym jaki poznamy będzie operator przypisania:
zmienna=wartość;Operator ten, jak sama nazwa wskazuje przypisuje zmiennej "zmienna", wartość "wartość".
Następnie mamy pięć podstawowych działań:
(wartość_a+wartość_b)
(wartość_a-wartość_b)
(wartość_a*wartość_b)
(wartość_a/wartość_b)
(wartość_a%wartość_b)//Modulo, reszta z dzielenia
Jak się tego używa? Na przykład można:
a=b+c;W ten sposób zmiennej #msgote author=Zysk link=topic=104.msg144#msg144 date=Jul 30 2006, 22:17\']Nie będzie to niestety kurs, a raczej informacje o składni skryptów

1. Zmienne i stałe (wartości):
Aby używać wartości należy ją zadeklarować:
var typ nazwa;
const typ nazwa = wartość;
var dla zmiennych
const dla stałych
W ten sposób tworzymy wartość typu "typ" (najczęściej int-liczba całkowita, choć mogą być inne np. string-łańcuch znaków) o nazwie "nazwa" (po której będziemy się do zmiennej odwoływać) i zawierającą na początku "wartość_początkowa". Jeśli zmienną deklarujemy w miejscu poza wszelkimi funkcjami to będzie to wartość globalna dostępna wszędzie, w przeciwnym wypadku będzie usunięta po wyjściu z przedziału wyznaczonego przez operatory a#msgote author=Zysk link=topic=104.msg144#msg144 date=Jul 30 2006, 22:17\']Nie będzie to niestety kurs, a raczej informacje o składni skryptów

1. Zmienne i stałe (wartości):
Aby używać wartości należy ją zadeklarować:
var typ nazwa;
const typ nazwa = wartość;
var dla zmiennych
const dla stałych
W ten sposób tworzymy wartość typu "typ" (najczęściej int-liczba całkowita, choć mogą być inne np. string-łańcuch znaków) o nazwie "nazwa" (po której będziemy się do zmiennej odwoływać) i zawierającą na początku "wartość_początkowa". Jeśli zmienną deklarujemy w miejscu poza wszelkimi funkcjami to będzie to wartość globalna dostępna wszędzie, w przeciwnym wypadku będzie usunięta po wyjściu z przedziału wyznaczonego przez operatory  przypiszemy sumę liczb #msgote author=Zysk link=topic=104.msg144#msg144 date=Jul 30 2006, 22:17\']Nie będzie to niestety kurs, a raczej informacje o składni skryptów

1. Zmienne i stałe (wartości):
Aby używać wartości należy ją zadeklarować:
var typ nazwa;
const typ nazwa = wartość;
var dla zmiennych
const dla stałych
W ten sposób tworzymy wartość typu "typ" (najczęściej int-liczba całkowita, choć mogą być inne np. string-łańcuch znaków) o nazwie "nazwa" (po której będziemy się do zmiennej odwoływać) i zawierającą na początku "wartość_początkowa". Jeśli zmienną deklarujemy w miejscu poza wszelkimi funkcjami to będzie to wartość globalna dostępna wszędzie, w przeciwnym wypadku będzie usunięta po wyjściu z przedziału wyznaczonego przez operatory b#msgote author=Zysk link=topic=104.msg144#msg144 date=Jul 30 2006, 22:17\']Nie będzie to niestety kurs, a raczej informacje o składni skryptów

1. Zmienne i stałe (wartości):
Aby używać wartości należy ją zadeklarować:
var typ nazwa;
const typ nazwa = wartość;
var dla zmiennych
const dla stałych
W ten sposób tworzymy wartość typu "typ" (najczęściej int-liczba całkowita, choć mogą być inne np. string-łańcuch znaków) o nazwie "nazwa" (po której będziemy się do zmiennej odwoływać) i zawierającą na początku "wartość_początkowa". Jeśli zmienną deklarujemy w miejscu poza wszelkimi funkcjami to będzie to wartość globalna dostępna wszędzie, w przeciwnym wypadku będzie usunięta po wyjściu z przedziału wyznaczonego przez operatory  i #msgote author=Zysk link=topic=104.msg144#msg144 date=Jul 30 2006, 22:17\']Nie będzie to niestety kurs, a raczej informacje o składni skryptów

1. Zmienne i stałe (wartości):
Aby używać wartości należy ją zadeklarować:
var typ nazwa;
const typ nazwa = wartość;
var dla zmiennych
const dla stałych
W ten sposób tworzymy wartość typu "typ" (najczęściej int-liczba całkowita, choć mogą być inne np. string-łańcuch znaków) o nazwie "nazwa" (po której będziemy się do zmiennej odwoływać) i zawierającą na początku "wartość_początkowa". Jeśli zmienną deklarujemy w miejscu poza wszelkimi funkcjami to będzie to wartość globalna dostępna wszędzie, w przeciwnym wypadku będzie usunięta po wyjściu z przedziału wyznaczonego przez operatory c#msgote author=Zysk link=topic=104.msg144#msg144 date=Jul 30 2006, 22:17\']Nie będzie to niestety kurs, a raczej informacje o składni skryptów

1. Zmienne i stałe (wartości):
Aby używać wartości należy ją zadeklarować:
var typ nazwa;
const typ nazwa = wartość;
var dla zmiennych
const dla stałych
W ten sposób tworzymy wartość typu "typ" (najczęściej int-liczba całkowita, choć mogą być inne np. string-łańcuch znaków) o nazwie "nazwa" (po której będziemy się do zmiennej odwoływać) i zawierającą na początku "wartość_początkowa". Jeśli zmienną deklarujemy w miejscu poza wszelkimi funkcjami to będzie to wartość globalna dostępna wszędzie, w przeciwnym wypadku będzie usunięta po wyjściu z przedziału wyznaczonego przez operatory .
Za chwilę poznamy operatory porównania.
Oto jak wygląda wyrażenie warunkowe:
if (warunek)
{
...
//instrukcje gdy spełniony
...
};
lub
if (warunek)
{
...
//instrukcje gdy spełniony
...
}//tu nie ma średnika
else
{
...
//instrukcje gdy nie spełniony
...
};
Teraz tylko trzeba wiedzieć, jak określić warunek. Pierwszym sposobem jest podanie liczby, wtedy warunek będzie spełniony, gdy owa wartość będzie niezerowa. Drugim sposobem jest użycie operatorów porównania:
(wartość_a==wartość_b) //Uwaga! Gdy pomylimy z operatorem przypisania, nie dostaniemy nawet komunikatu o błędzie!
(wartość_a!=wartość_b) //nierówne
(wartość_a>=wartość_b)//większe lub równe
(wartość_a<=wartość_b)
(wartość_a<wartość_b)
(wartość_a>wartość_b)
//Wyrażenie (wartość_a>wartość_b>wartość_c) NIE jest poprawne.
Możemy jeszcze wykonywać działania na warunkach:
(!warunek)//Negacja, prawdziwe wtedy i tylko gdy "warunek" nie jest spełniony.
(warunek_a&&warunek_b)//Koniunkcja, prawdziwe wtedy i tylko wtedy, gdy oba warunki są spełnione
(warunek_a||warunek_b)//Alternatywa, prawdziwe wtedy, gdy co najmniej jeden warunek jest spełniony.
Kolejność działań zmieniamy tak jak w matematyce, wstawiając nawiasy.
Przykłady:
a=2*(b+c);//przypisz a wartość
((a<b)&&(b<c))//sprawdź, czy a<b<c
(a||b)//sprawdź, czy przynajmniej jedna z tych wartości jest różna od zera
a=-b;

3. Funkcje
Funkcje zawierają wszystkie skryptowe instrukcje jakie Gothic przetwarza podczas gry, więc trzeba umieć się nimi posługiwać. Funkcje przyjmują pewną ilość parametrów (może być zerowa) i zwracają pewien typ danych (może być pustka (void)). Definicja funkcji wygląda następująco:
func typ_wartości_zwracanej nazwa(var typ_a zmienna_a,var typ_b zmienna_b...)
{
...
instrukcje
...
};
Funkcja może wewnątrz siebie używać tylko wartości globalnych, parametrów tej funkcji i zmiennych zadeklarowanych wewnątrz tej funkcji (a ściślej tego wywołania tej funkcji). Parametry są nowymi zmiennymi, kopiami wartości podanych podczas wywołania, więc zmienianie ich nie wpłynie na te zmienne.
Jeżeli funkcja ma zwracać jakąś niepustą wartość należy użyć w jej ciele instrukcji return:
return wartość_zwracana;
Oczywiście "wartość_zwracana" musi być typu "typ_wartości_zwracanej". Tej funkcji można użyć w następujący sposób:
nazwa(wartość_a,wartość_b...)Uwaga! Nawet jeśli funkcja ma zerową ilość parametrów wpisujemy nawias otwierający i zamykający.
Teraz pora na konkretniejszy przykład:
var int tab[3];
func int zmiana(var int a, var int b)
{
a=a+2;
return b+4;
};

tab[0]=2;
tab[1]=3;
tab[2]=zmiana(tab[0],tab[1]);
Po wywołaniu ostatnich instrukcji tab[0]=2, tab[1]=3, tab[2]=7. tab[0] się nie zmienia ponieważ zmienialiśmy tylko parametr funkcji, a nie to skąd ten parametr wzięliśmy. tab[2] jest równe 7 ponieważ przypisaliśmy mu wartość zwracaną przez funkcję.
Jeżeli nie chcemy nic robić z wartością zwracaną przez funkcję (np. gdy to jest pustka) wtedy możemy wywołać funkcję tak
nazwa(parametry);
Czasem używamy jednak nazwy funkcji bez nawiasów. Jest to wtedy, gdy chcemy przekazać nie wartość zwracaną przez funkcję, ale samą funkcję (tak naprawdę to jej adres). Takim przypadkiem jest obiekt rozmowy, któremu przekazujemy, aż 2 funkcje, ale o tym kiedy indziej.
4. Klasy i obiekty

Wszystkie klasy są zdefiniowane w _intern\classes.d, ale nas będą interesować tylko c_item, c_info, c_npc. Niezależnie od tego jaką klasą się posługujemy należy zdefiniować instancję - w przypadku c_item charakteryzuje ona jeden rodzaj przedmiotów (np. Smażone mięso), w wypadku c_info jeden temat (dialog), natomiast c_npc jeden rodzaj istot (np. Szkielet-wojownik (wszyscy mają tę samą), Szkielet maga z wieży mgieł, Gorn, Ścierwojad (wszystkie mają tą samą), każdy Szkodnik ma oddzielną).
Ogólnie instancję definiujemy tak:
instance nazwa_instancji (klasa)
{
//Czynności wykonywane przy tworzeniu obiektu
};
W przypadku c_info to czynności to jedynie przypisanie polom obiektu odpowiednich wartości, a stworzenie instancji to wszystko co trzeba zrobić (poza zdefiniowaniem funkcji wywoływanych przez obiekt. W tym przypadku można również modyfikować instancję:
nazwa_instancji.pole=wartość;W pozostałych przypadkach (c_item i c_npc) należy jeszcze wprowadzić obiekt (lub obiekty) danej instancji do gry.
Obiekty z c_item można wstawiać w Spacerze, można różnymi funkcjami, najczęściej CreateInvItem. Omówimy ją później gdyż dotyczy c_npc, których zbyt dobrze nie znamy.
Natomiast z klasy c_npc wprowadzamy funkcją Wld_InsertNpc, którą wywołujemy następująco:
wld_insertnpc(instancja,waypoint); //Waypointy ustawiamy w Spacerze, nazwę (w funkcji) należy poprzedzić i zakończyć cudzysłowem (ponieważ jest to łańcuch znaków - string).

Podczas gry oba można stworzyć przy pomocy konsoli, pisząc "insert instancja".
Można również posługiwać się konkretnymi postaciami, definiujemy zmienną zawierającą postać:
var c_npc postac;
Następnie ustawiamy na istotę danej instancji:
postac=Hlp_GetNpc(instancja);
Możemy jej teraz użyć w różnych funkcjach np. we wspomnianej funkcji CreateInvItem:
createinvitem(postac,instancja_przedmiotu);
Podczas wstawiania postaci jest ona (wstawiana postać) przechowywana w zmiennej self, co pozwala na przekazanie jej do funkcji np. ustawiających model, nie znam się na tym za bardzo, więc nie będę ich opisywał.
EDIT BY LESTEREK: Jak widać ten tutorial także naprawiłem
Dziękuję i życzę miłego dnia
 

Lehona

Lehona

Użytkownicy
posty196
Propsy190
  • Użytkownicy
For those that love formal language definitions, I've got a grammar for Daedalus, it's in BNF:

"Name"     = 'Daedalus 2'
"Author"   = 'Lehona'
"Version"  = '0.1'
"About"    = 'This is basically Daedalus extended (not yet, though)'

"Start Symbol" = <Program>

! -------------------------------------------------
! Character Sets
! -------------------------------------------------

{ID Head}      = {Letter} + [_] + [ü] + [Ü] + [ä] + [Ä] + [ö] + [Ö] + [ß]
{ID Tail}      = {Alphanumeric} + [_]+[^]+[@] + [ü] + [Ü] + [ä] + [Ä] + [ö] + [Ö] + [ß]
{String Chars} = {Printable} - ["] + [´] + [`]

! -------------------------------------------------
! Terminals
! -------------------------------------------------

Comment Start = '/*'
Comment End   = '*/'
Comment Line  = '//'

ID = {ID Head}{ID Tail}*
           
!keywords = 'class' | 'func' | 'instance' | 'prototype' | 'const' | 'var' | 'return'
             
StringLiteral = '"' ({String Chars}|ü|Ü|ä|Ä|ö|Ö|ß)* '"'
Integer         = {Number}+
Float           = {Number}+ '.' {Number}+
<Number>        ::= Integer | Float

! -------------------------------------------------
! Rules
! -------------------------------------------------

! The grammar starts below
<Program> ::= <type decl> <Program>
            | <function decl> <Program>
            | <var decl> <Program>
            | <glob decl> <Program>
            |
           

<identifier> ::= ID | 'class' | 'func' | 'instance' | 'prototype' | 'const' | 'var' !| 'return'
                 


<Expression List> ::= <Expression> <Expression List Tail>
                   |

<Expression List Tail> ::= ',' <Expression> <Expression List Tail>
                        |
                       

   
               
<Expression> ::= <Logic And> '||' <Expression>
               | <Logic And>
               
<Logic And>  ::= <Bit Or> '&&' <Logic And>
               | <Bit Or>
               
<Bit Or>     ::= <Bit And> '|' <Bit Or>
               | <Bit And> !<Bit Xor>
               
!<Bit Xor>    ::= <Bit And> '^' <Bit Xor>      NB. Currently not supported
!               | <Bit And>
               
<Bit And>     ::= <Equal> '&' <Bit And>
               | <Equal>
               
<Equal>      ::= <Comparison> '==' <Equal>
               | <Comparison> '!=' <Equal>
               | <Comparison>
         
<Comparison> ::= <Bit Shift> '<' <Comparison>
               | <Bit Shift> '>' <Comparison>
               | <Bit Shift> '<=' <Comparison>
               | <Bit Shift> '>=' <Comparison>
               | <Bit Shift>
               
<Bit Shift>  ::= <Add> '<<' <Bit Shift>
               | <Add> '>>' <Bit Shift>
               | <Add>
             
<Add>        ::= <Mult> '+' <Add>
               | <Mult> '-' <Add>
               | <Mult>

<Mult>       ::= <Mult> '*' <Unary>
               | <Mult> '/' <Unary>
               | <Mult> '%' <Unary>
               | <Unary>

<Unary>      ::= '-' <Unary>
               | '!' <Unary>
               | '~' <Unary>
               | '+' <Unary>
               |  <Value>
               
<Value>       ::= <Var>
               |  '(' <Expression> ')'
               | <Number>
               | StringLiteral
               | <call exp>
               
<Var>         ::= <Array>
               | <identifier> '.' <Array>
               
<Array>       ::= <identifier> '[' <Num> ']'
               | <identifier>
               
<Num>         ::= <identifier>
               | <Number>

 
 <call exp> ::= <identifier> '(' <expression list> ')'

 

 <statement list> ::= <statement>  <statement list>
                |

 <statement> ::= <assignment> ';'
                | <if block>
                | ';'
                | <jump statement> ';'
                | <call exp> ';'
                | <Var> ';'
                | <declaration>';'
               
 <assignment> ::= <Var>  '=' <expression>
                | <Var> '+=' <expression>  
                | <Var> '-=' <expression>
                | <Var> '*=' <expression>
                | <Var> '/=' <expression>  
                                               

 <statement block> ::= '{' <statement list> '}'

 <if block> ::= if <Expression> <Statement block>      
              | if <Expression> <Statement block> else <Statement Block>
              | if <Expression> <Statement block> else <if block>
               


 <jump statement> ::= 'return'
                | 'return' <expression>

 <declaration list> ::= <var decl> <declaration tail>
                |

 <declaration tail> ::= ',' <var decl>  <declaration tail>
                |
 
 <declaration block> ::= '{' <var decl list> '}' ';'

 <var decl list> ::= <var decl sublist> ';' <var decl list>
                |
               
 <var decl sublist> ::= <var decl> <var decl sublist tail>
                     |
                   
 <var decl sublist tail> ::= ',' <identifier> <var decl sublist tail>
                          |


 <declaration> ::=  <var decl>
                | <const  decl>
 

 <var decl> ::= 'var' <identifier> <var decl sub>
                 | 'var' <identifier> <identifier> ',' <var decl>
                 | 'var' <identifier>  <identifier> '[' <Value> ']' ',' <var decl>  
               
 <var decl sub> ::= <identifier>
                 | <identifier> '[' <Value> ']'
                 | <identifier> ',' <var decl sub>
                 | <identifier> '[' <Value> ']' ',' <var decl sub>
               
 <const decl> ::= 'const' <identifier> <identifier> '=' <Expression>
               | 'const' <identifier> <identifier> '[' <Value> ']' '=' '{' <Expression List> '}'
               
 
 <type decl> ::= <class decl>
                | <prototype decl>
                | <instance decl>

 <class decl> ::= 'class' <identifier> <declaration block> !Gothic kann var int a1,a2; in Klassen und nutzt das auch standardmäßig, ich darf es also nicht einfach ignorieren.

 <prototype decl> ::= 'prototype' <identifier>'(' <identifier> ')' <statement block> ';'

 <instance decl> ::= 'instance' <identifier> <var decl sublist tail> '(' <identifier> ')' <statement block> ';'
                | 'instance' <identifier> <var decl sublist tail> '(' <identifier> ')' ';'

 <function decl> ::= 'func' <identifier> <identifier> '(' <declaration list> ')' <statement block> ';'
                 

 <glob decl> ::= <declaration> ';'    

Every script I've tested so far (including all of the original G2NotR scripts) has been successfully parsed, though I'm quite sure that this grammar allows some constructs the parser will not allow (If anyone finds or sees one feel free to mention it to me).

I will update the grammar as I continue with the development of my parser, an up-to-date version can always be found here: https://www.assembla.com/code/daedalus-parser/subversion/nodes/Daedalus.grm
 
Unless specified otherwise, my posts are always about Gothic 2 Night of the Raven.

Adanos

Adanos

Administrator
Szara eminencja
posty5204
Propsy3870
ProfesjaProgramista
  • Administrator
  • Szara eminencja

Adanos
Administrator

Ogólny opis języka
#2 2012-06-11, 23:31(Ostatnia zmiana: 2012-06-11, 23:50)
<Unary>      ::= '-' <Unary>
               | '!' <Unary>
               | '~' <Unary>
               | '+' <Unary>
               |  <Value>
Does your grammar allow to produce a sequence "-!+-!+"?

Lehona

Lehona

Użytkownicy
posty196
Propsy190
  • Użytkownicy
The grammar does, I'm not quite sure about the parser (the parser does allow !!!!!!var, but that's the only unary operator I've tested).
 
Unless specified otherwise, my posts are always about Gothic 2 Night of the Raven.


0 użytkowników i 1 Gość przegląda ten wątek.
0 użytkowników
Do góry