Skrypt pisany jest w stylu języka C (a przynajmniej operatory).
Wskazówka 1: wtyczka sprawdza wielkości liter.
Wskazówka 2: wtyczka prawie wcale nie sprawdza błędów. Więc POWINIENEŚ sprawdzać swój skrypt dwa razy nim go uruchomisz :)
Uruchom plik MathTest.Exe i przekonaj się sam. Po kilku minutach testów powinieneś być w stanie sam napisać swój skrypt. Aby dołączyć go do skryptu NSIS po prostu wstaw poniższe wywołanie:
Math::Script "TwójSkrypt1" Math::Script "TwójSkrypt2" Math::Script "TwójOstatniSkrypt"
Jak tego używać? Bardzo łatwo:
Strcpy $0 "Brainsucker" Math::Script "a = 'Skrypt'; B = 'Math'; r0 += ' chce użyć ' + a + '::' + b +'!'" DetailPrint "$0"
Ten łańcuch znaków zapełni r0 jakimiś danymi.
Inne przykłady:
10! (factorial, r0 będzie zawierać '10! = 362880'): r0 = '10! = ' + (1*2*3*4*5*6*7*8*9) tak samo: a = b = 1; #{++a <= 10, b = b*a}; r0 = (a-1) + '! = ' + b Kilka przykładów dla operacji zmiennoprzecinkowych: Strcpy $R0 "1e1" Math::Script "pi = 3.14159; R1 = 2*pi*R0; r0 = 'Obwód okręgu z promieniem ' + R0 + ' = ' + R1 + '.'" Detailprint "$0"
NSIS: r0-r9 -> $0-$9. R0-R9 -> $R0-$R9.
Również CL ($CMDLINE), ID ($INSTDIR), OD ($OUTDIR), LG ($LANG), ED ($EXEDIR). Definiowalne przez użytkownika: nazwy zaczynające się od znaku, przy długości do 28 liter.
Obsługiowane są dwa stosy: Stos NSIS oraz własny stos wtyczki. Nie widzę żadnego powodu, aby używać stosu wtyczki, ale jeśli będziesz chciał pamiętaj, że wtyczka przechowuje zmienne używane w funkcji przed wywołaniem tej funkcji i przywraca je po wykonaniu. Dlatego zalecam używanie stosu NSIS. Powinieneś używać go tylko dla operacji wejścia/wyjścia.
Jak go używać? Działanie opiera się na stylu zmiennych. Stos wtyczek jest powiązany ze zmienną S, a stos NSIS jest powiązany ze zmienną NS. Aby odłożyć na stos, użyj po prostu składni "S=0" lub "NS=0". Aby zdjąć ze stosu, użyj składni "a=S" lub "b=NS". Obsługiwane są również operacje złożone: "S += 1.5" zwiększy wartość na górze stosu o 1.5.
Obsługiwane typy: int (w rzeczywistości __int64), float (w rzeczywistości typ double), string (łańcuch znaków).
liczby, mogą zawierać znaki
-123.456, 123.456e-78, 123e-45
Jakiś tekst w cudzysłowiu ("", '', ``)
Istnieje również typ tablicowy. Aktualnie jest typem referencyjnym, więc jeśli b jest tablicą i jeśli wpiszesz "a=b", a oraz b będą wskazywały na jedną tablicę. Aby utworzyć kopię tablicy, użyj funkcji ca: dest = ca(source). Tak przy okazji, nie możesz kontrolować rozmiaru tablicy - jest on przydzielany automatycznie.
Aby zadeklarować tablicę:
a = {};
Aby zadeklarować tablicę i zainicjować kilka jej elementów jakimiś wartościami:
{"Cześć!", "Użyj", "typów mieszanych", 1.01e23, "takich jak ten" ,1234};
Aby uzyskać dostęp do tablicy:
a[index] = "Fajnie";
Również operacje [] winne być używane w łańcuchach znaków. Str[x] daje ci pojedynczy znak z indeksem x (od zera) jako nowy łańcuch znaków. Str[-x] - to samo, co wyżej, ale x odlicza od końca łańcucha znaków (więc ostatnim znakiem łańcucha znaków jest -1). Str[x,y] daje ci znaki w zakresie x-y (włącznie z tymi znakami), zarówno x jak i y powinny być <0 - w takim przypadku są one odliczane od końca łańcucha znaków.
Poniższa funkcja powinna być przydatna - konwertuje typ tablicowy na łańcuch znaków i na odwrót.
Przykład:
a = a("Cześć"); str = s(a);
Po uruchomienu takiego skryptu tablica zawierać będzie 6 liczb całkowitych (znaków i zera na końcu - koniec łańcucha znaków), a str będzie zawierać twój łańcuch znaków.
Operatory (niektóre binarne, niektóre jednoargumentowe):
>>= <<= -= += /= *= |= &= ^= %= -- ++ >> << && || <= =< >= => != == = + - * / % < > & | ^ ~ !
Tylko niektóre z nich odnoszą się do zmiennoprzecinkowych float (logiczne & arytmetyczne) oraz oczywiście łańcuch znaków string (+ oraz logiczne).
Inne przypadki: Operatory referencji/dereferencji (& oraz *). & da ci referencję do argumentu, który powinien być zmienną (NSIS, użytkownik, element tablicy, stos), a * skonwertuje to z powrotem na zmienną oryginalną. Na przykład (a=&b; *a=10) ustawi b na wartość 10. Wyrażenie (*&a) jest równe wyrażeniu (a).
Skrypt jest zbiorem wyrażeń (w większości matematycznych) rozdzielonych znakiem średnika ';'. Wykonywanie takiego skryptu następuje zgodnie z regułami matematycznymi (2+2*2 da w wyniku 6), operacje wykonywane są w kolejności zgodnej z C (pierwszeństwo).
if-then-else like: #[if-expression, then-expr, else-expr] przykład: #[a==0, b=1; c=2, b *= (--c); c/=10] C eq: if (a==0) { b=1; c=2;} else { b*=(c++);c-=10; } while (expr) do; like #{expr, do} przykład: #{(c<1.1e25)&&(b < 10), b++; c*=1.23} C eq: while ((c<1.1e25)&&(b<10)) { b++; c*=1.23; }
UWAGA
Znak przecinka (,) oddziela if-expr, then-expr, oraz else-expr od siebie. Wszystkie podwyrażenia rozdzielane znakiem średnika (;) są częścią jednego wyrażenia, a wynik ostatniej z tych podwyrażeń jest wynikiem całego wyrażenia.
Wszystko inne (zmienne i funkcje) zostaną zachowane pomiędzy wywołaniami.
Konwersje typów: l(łańcuch_znaków) Zwraca długość łańcucha znaków lub argument tablicy s(źródło) Konwertuje źródło na typ łańcucha znaków string i(źródło) Konwertuje źródło na typ całkowity int f(źródło) Konwertuje źródło na typ zmiennoprzecinkowy float c(źródło) Jeśli źródło jest łańcuchem znaków, zwraca wartość całkowitą int pierwszego znaku, jeśli źródło jest typu całkowitego int, zwraca łańcuch znaków pojedynczych znaków (źródło) (+0 znak końca). a(źródło) konwertuje źródło na tablicę (obsługiwane są tylko łańcuchy znaków) ff(float, format) konwertuje typ zmiennoprzecinkowy float na łańcuch znaków string, z opcjami formatowania format. Opcje = Precyzja + Flagi. Precyzja mówi o tym ile zer po przecinku zostanie pokazanych. Flagi: 16 (lub 0x10) - Bez postaci wykładniczej (liczby wyświetlane jako 123.123) 32 (lub 0x20) - Tylko postać wykładnicza (liczby wyświetlane jako 123.12e123) 64 (lub 0x40) - Użyj znaku 'E' zamiast 'e' Domyślnie wtyczka sama decyduje jak mają być wyświetlane liczby. Math (opis wszystkich poniższych funkcji dostępny jest na MSDN. Aby je znaleźć użyj w zapytaniu drugiej podanej nazwy): sin(x), sin Sinus argumentu cos(x), cos Kosinus argumentu cel(x), ceil Najmniejsza liczba całkowita >= argumentowi (brak reszty) csh(x), cosh Kosinus hiperboliczny argumentu exp(x), exp Wykładnik abs(x), abs Wartość absolutna (uwaga: float) flr(x), floor Podstawa argumentu (brak reszty) asn(x), asin Arkus-sinus argumentu acs(x), acos Arkus-kosinus argumentu atn(x), atan Arkus-tanges argumentu ln(x), log Logarytm wykładniczy log(x), log10 Logarytm dziesiętny snh(x), sinh Sinus hiperboliczny argumentu sqt(x), sqrt Pierwiastek argumentu tan(x), tan Tanges argumentu tnh(x), tanh Tanges hiperboliczny argumentu Funkcje przyjmujące dwa argumenty at2(x, y) atan2 Arkus-tanges wartości (y/x) pow(x, y) pow Potęga, x^y fmd(x, y) fmod Reszta liczby zmiennoprzecinkowej fex(x, o) frexp Pobiera mantyse (wynik = r) oraz wykładnik (o) liczby zmiennoprzecinkowej liczba (x): x = r*(2^o) mdf(x, o) modf Rozdziela wartość zmiennoprzecinkową na ułamkową i składającą się z części całkowitej.
To jest bardzo proste. Przykład:
test(a,b) (a+b);
Po tej operacji test(1,2) daje w wyniku 3.
test2(a,b) (a=a+b; b *= a);
Wynik funkcji jest zawsze wynikiem ostatniego wyrażenia. Jak napisano wcześniej lepiej nie używać stosu (S) pomiędzy wywołaniami funkcji. Lepiej jest oprogramować funkcje z bezpiecznymi zmiennymi, np. funkcje, które nie psują zmiennych. Aby to zrealizować powinieneś raczej odłożyć/pobrać je ze stosu, lub zadeklarować jako dodatkowe argumenty, które nigdy nie zostana użyte. Przykład:
test3(a,b,c) (c=10; #{--c > 0, a=sqrt(a*b)}; a)
Nie ważne jak wiele argumentów zostanie przypisanych funkcji, wartości wszystkich trzech zmiennych (a,b,c) zostana zachowane.
Niektóre funkcje chroniące zmienne powinny być rekursywne:
Math::Script 'rec(a) (#[a > 0, rec(a-1), 0]+a);' Math::Script 'R1 = rec(10)'
ustawi R1 na prawidłowy wynik 55.
Niekiedy istnieje potrzeba, by funkcje zwracały więcej niż jedna wartość. W takim przypadku powinieneś zadeklarować argument jako referent (b na przykład):
test4(a, &b) (*b = a*a; a*a*a)
W takim przypadku test4 zwróci a^3 i jeśli wywołamy ją jako test4(a,c), przypisze a^2 do c.
UWAGA
Powinieneś użyć dereferencji (*) ze zmienną, na przykład *b.
OSTRZEŻENIE
Nigdy nie używaj tej samej zmiennej jako zmiennej wewnętrznej referencji funkcji oraz zmiennej zewnętrznego argumentu (na przykład test4(a,b)). Użycie takiej składni na pewno nie powiedzie się. Również: jeśli zadeklarujesz argument jako referencję - nie powinieneś nigdy podawać stałego wyrażenia do niego. Może to być zarówno element tablicy (array[1]), rejestr NSIS R0, dowolna ze zmiennych użytkownika (poza zmiennymi o tych samych nazwach:), ale nigdy nie zmienna.
Inną, mogącą byc przydatną możliwością jest redeklaracja funkcji (zwyczajowa deklaracja w czasie gdy funkcja już zdefiniowana, wywoła tę funkcję). Dla takiego zadania powinieneś użyć "#name", jak "func()(1); #func()(2);". Ale uwaga, deklaracja funkcji następuje w czasie parsowania , więc nie jest możliwym wykonanie płynnie kontrolowanej deklaracji.
NIEMOŻLIWE: "#[a<0, #func()(1), #func()(2)]" PO PROSTU ZDEFINIUJE #func jako (2), jako ostatni wariant.