LPC (programovací jazyk) - LPC (programming language)
Paradigma | multi-paradigma : objektově orientované , funkční , procedurální , prototypové |
---|---|
Navrhl | Lars Pensjö |
Vývojář | Lars Pensjö, Jörn Rennecke , Felix Croes , Tim Hollebeek, Lars Düning a další |
Psací disciplína | Slabý statický , silný dynamický |
webová stránka | lpmuds |
Hlavní implementace | |
LPMud | |
Dialekty | |
Amylaar, MudOS , FluffOS , LDMud , DGD , SWLPC | |
Ovlivněno | |
C , C ++ , Lisp , Perl | |
Ovlivněno | |
Štika |
LPC (zkratka pro Lars Pensjö C ) je objektově orientovaný programovací jazyk odvozený od C a vyvinutý původně Larsem Pensjöem, aby usnadnil budování MUD na LPMuds . Ačkoli byla navržena pro vývoj her , její flexibilita vedla k tomu, že byla použita pro různé účely, a k jejímu vývoji do jazyka Pike .
Syntaxe LPC ji umisťuje do rodiny jazyků podobných C, přičemž C a C ++ mají nejsilnější vlivy.
Obsah
Základní struktura
Téměř vše v LPC je objekt . LPC však přesně nepoužívá koncept třídy ( MudOS má něco, co se nazývá třída, ale je to opravdu struktura ). Místo toho jsou objekty LPC objekty plánu a klony objektů plánu, v prototypovém modelu programování . S objektem plánu lze zacházet stejně jako s třídou v jiných objektově orientovaných jazycích.
Každý objekt má proměnné (atributy) a funkce (metody). Proměnné ukládají stav objektu; funkce jsou spustitelné rutiny, které lze volat v objektu. Objekt je jednoznačně definován názvem souboru, ze kterého pochází, plus, pokud je to klon, číselným identifikátorem. V typické implementaci bude klon souboru, /lib/weapon.c
který je třetím klonem vytvořeným v aktuální relaci běhu /lib/weapon#3
. Odpovídající objekt plánu /lib/weapon.c
je jednoduše /lib/weapon
. Ve hře MUD zahrnují běžné objekty místnosti, zbraně, brnění a postavy , které nejsou hráči (NPC). Většina mudlib definuje dědičné objekty pro takové běžné věci. Například v LPMud 2.4.5 mudlib je nadřazený objekt pro všechny místnosti /lib/room
.
V LPC není možné syntakticky deklarovat metody a atributy pouze pro třídu nebo pouze pro instanci; ke všem funkcím a proměnným lze přistupovat shodně v plánech a klonech. Například "/lib/user"->number_of_users()
by zavolala number_of_users()
funkci přímo v instanci podrobného plánu /lib/user.c
. (Kontroverzní mechanismus v mnoha ovladačích, který se nazývá „stínování“, umožňuje do určité míry emulovat instance metody povolením jednoho objektu „překrýt“ jeho funkci nastavenou na jinou, což ve skutečnosti interponuje mezi voláním externích funkcí a stínovaným objektem.) Přímý externí přístup k proměnným také není podporován; všechny interakce mezi objekty se provádí pomocí volání funkce (bez ohledu na tom, že datové struktury poukázal na základě proměnných jsou nezávislé objektů a změny nich jsou viditelné ve všech objektech odkazujících ty datové struktury současně, a že některé ovladače mají privilegovaný funkce umožňující těžkopádné formu přístup k externí proměnné, který umožňuje kontrolu, ale nikoli mutaci).
Jednoduchá místnost v typickém mudlib
Protože LPC se obecně používá ke kódování MUD, jsou „místnosti“ často vytvářeny jako objekty, které ukládají informace popisující konkrétní scénu spolu s východy, které ukazují na jiné objekty místnosti. Toto je nejběžnější použití LPC. Jsou možná i jiná použití, která nesouvisí s hrou.
Následující příklad ukazuje velmi jednoduchou tradiční místnost, která využívá funkce definované v mudlib objektu /lib/room
. Ne všechny mudliby však definují nebo určují místnosti stejným způsobem, takže to není jediný způsob definování místnosti.
inherit "/lib/room";
void create() {
::create();
set_short("a simple room");
set_long("A simple room in a simple building.");
set_description("This is a simple room in a simple building. It is very nice.");
add_exit("north", "/realms/descartes/north_room");
}
První řádek říká objektu, aby zdědil funkčnost z /lib/room
objektu. Tento příklad předpokládá, že /lib/room
objekt definuje funkce pro ::create(), set_short(), set_long(), set_description(),
a add_exit()
.
Tento příklad obsahuje jedinou funkci, create()
. Většina ovladačů volá nebo může být nastavena tak, create()
aby umožnila inicializaci objektu spouštěcími hodnotami; je to standardní konstruktor . V tomto případě příklad volá funkce, které nastavují základní atributy místnosti zděděné /lib/room
. Zde volané funkce jsou velmi závislé na použitém mudlib, protože mudlib definuje skutečného rodiče místnosti.
Typy dat
Běžné datové typy
- objekt
- Libovolný objekt LPC, včetně plánů i klonů. K dispozici ve všech známých ovladačích. Nemá žádnou doslovnou formu jako takovou.
object obj = clone_object("/std/weapon");
- int
- Celé číslo, obvykle 32bitové (s mnoha ovladači bude kompilace na 64bitovou architekturu mít za následek 64bitové ints, ale stabilita při kompilaci na 64bitovou architekturu není u ovladačů LPMud běžnou funkcí). K dispozici ve všech známých ovladačích. Doslovná forma je holé číslo.
int number = 23;
- tětiva
- Řetězec znaků s proměnnou délkou. Člověk nemusí dělat žádnou formu správy paměti nebo správy hranic; LPC to zvládá. K dispozici ve všech známých ovladačích. Doslovná forma je řetězec znaků uzavřený do uvozovek.
string text = "Hello, world!";
- pole deklarované jako <typ> *
- Pole jiného datového typu. Ve většině ovladačů je pole definováno pomocí typu s
*
modifikátorem, jako vobject *, string *, int *
. Typicky*
lze na deklaraci použít pouze jedno , takže pokud bychom chtěli matici polí, deklarace by bylamixed *
. Pole LPC jsou obecně pole typu „gumička“, u kterých lze po přidělení upravit jejich délku. Pole jsou téměř všeobecně dostupná, ačkoli preferovaná syntaxe deklarací se v MudOS liší . Obvyklou doslovnou formou je seznam hodnot, oddělených čárkami (nepovinné za poslední hodnotou), uzavřené({
a})
hraniční značky.
int * numbers = ({ 1, 2, 3 });
string * words = ({ "foo", "bar", "baz" });
mixed * stuff = ({ 1, "green", 48.2 });
- mapování
-
asociativní pole ) klíčů k hodnotám. Podporováno většinou řidičů. Obvyklou doslovnou formou je
([
hraniční značka, za kterou následuje nula nebo více párů klíč – hodnota s dvojtečkou mezi klíčem a hodnotou a čárkou za hodnotou (volitelná u posledního páru klíč – hodnota) a])
hraniční značkou.
Hašovací mapa (
mapping map = ([
"hello" : 1,
"world" : 2,
]);
- plovák
- Číselná hodnota s plovoucí desetinnou čárkou, obvykle „s jednou přesností“ spíše než „s dvojitou přesností“. K dispozici ve všech známých ovladačích.
float number = 3.1415;
- smíšený
- Používá se k označení proměnných, které mohou obsahovat hodnoty různých typů. Efektivně to zakáže kontrolu typu při kompilaci proměnné. LPC má silné dynamické psaní; jeden by pracoval s proměnnými smíšeného typu kontrolou informací o typu za běhu. K dispozici ve všech známých ovladačích.
mixed value = random(2) ? "hello" : 1;
Méně běžné datové typy
- postavení
- Znamená to držet 1 nebo 0 a tak představuje true nebo false; v úmyslu ekvivalentní booleovskému typu. Ve většině ovladačů je implementován jako int, takže ve skutečnosti může obsahovat další hodnoty. Je zastaralý v MudOS , hlavně kvůli této nekonzistenci, a není vůbec podporován ovladačem hry Dworkin (DGD).
status flag = 1;
- uzavření
- Nejběžnější datový typ ukazatel funkce, o kterém je známo, že je podporován ovladači Amylaar LPMud a LDMud . Základní doslovná syntaxe pro získání uzavření funkce je značka hash, za kterou následuje jednoduchá uvozovka a za ní název funkce. Konstrukce uzávěrů lambda je mnohem složitější.
closure func = #'some_local_function;
- symbol
- Používají ovladače podporující konstrukci uzavření lambda (hlavně ovladače Amylaar LPMud a LDMud) pro vazbu na variabilní jmenný prostor v uzávěrech lambda. Doslovná syntaxe je jednoduchá uvozovka následovaná názvem symbolu.
symbol var = 'x;
- citované pole
- Používají jej také řidiči podporující konstrukci uzavření lambda, jedná se o speciální typ používaný k označení polí, aby nebyly interpretovány jako pokyny k uzavření. Doslovná forma je jednoduchá citace následovaná literálem pole. Nemá klíčové slovo deklarace typu, takže proměnné určené k držení citovaného pole by byly deklarovány jako smíšené .
mixed quoted_array = '({ 1, 2, 3 });
- <type> pole
- Forma deklarace pole preferovaná v systému MudOS.
<type> *
Forma je obvykle také k dispozici.
int array numbers = ({ 1, 2, 3 });
- třída <jméno>
- Unikátní pro MudOS; chová se jako C struktura . Není to třída v žádném objektově orientovaném smyslu slova.
class example {
int number;
string name;
};
class example instance = new(class example);
instance->number = 23;
instance->name = "Bob";
struct example {
int number;
string name;
};
struct example instance = (<example>);
instance->number = 23;
instance->name = "Bob";
- funkce
- MudOS typ funkce, ukazatel, podobný uzávěru , který je obvykle podporována jako alias. Anonymní funkce lze zadat v rámci
(: :)
hranic, použít$1, $2,
atd. Pro argumenty. LDMud také podporuje variantu této syntaxe pro hodnoty uzavření.
function op = (:
return sqrt($1 * $1 + $2 * $2);
:);
Pseudotypy a modifikátory typů
- prázdnota
- Používá se jako typ deklarace pro návratovou hodnotu funkce, určuje, že funkce nevrátí hodnotu. K dispozici ve všech známých ovladačích.
- varargy
- Modifikátor typu pro deklarace funkcí; Určuje, že seznam argumentů funkce má být proměnné délky. Podporováno většinou řidičů. Některé ovladače podporují rozšíření tohoto chování, kde proměnná v seznamu argumentů funkce varargs může sama přijímat modifikátor varargs, což způsobí, že bude fungovat jako proměnná „catch-all“ pro více argumentů v aktuálním seznamu argumentů, který obdrží zabaleno do pole.
- soukromé
- Modifikátor typu pro deklarace proměnné objektu a funkce; Určuje, že ovlivněná entita by neměla být k dispozici v oboru názvů žádných dědičů nebo v případě funkcí by neměla být volaná jinými objekty. Podporováno většinou řidičů.
- statický
- Modifikátor typu pro deklarace proměnné objektu a funkce. U proměnných určuje, že by neměly být serializovány. Pro funkce určuje, že by neměly být volat jinými objekty. Podporováno většinou ovladačů, ale často zastaralé ve prospěch rozumněji navržených modifikátorů typu.
- chráněný
- Modifikátor typu pro deklarace funkcí; specifikuje, že funkce by neměla být volaná jinými objekty, i když se na rozdíl od chování soukromého stále zobrazuje v oboru názvů funkcí dědiců . Podporováno mnoha řidiči.
- nosave
- Modifikátor typu pro deklarace proměnných objektů; určuje, že proměnná by neměla být serializována. Podporováno mnoha řidiči; v takových ovladačích je statická proměnná obecně zastaralá ve prospěch nosave .
- nomask
- Modifikátor typu pro deklarace funkcí; Určuje, že by nemělo být povoleno přepsat funkci nebo ji jinak zakrýt ve jmenném prostoru funkce. Je to podobné jako finální modifikátor typu v Javě nebo PHP . Podporováno většinou řidičů.
- veřejnost
- Obecně výchozí chování, které umožňuje neomezený přístup k proměnné nebo funkci, lze také obvykle použít jako modifikátor typu, který zabrání pozdějšímu přepsání veřejného přístupu k proměnné nebo funkci. Podporováno většinou řidičů.
- virtuální
- Modifikátor typu pro dědí; Určuje, že když se modul ve stromu dědičnosti vyskytne více než jednou, měla by se zachovat pouze jedna instance jeho proměnných. Podporováno mnoha řidiči.
- zastaralé
- Modifikátor typu pro deklaraci proměnné objektu a funkce; určuje, že dotčená entita je zastaralá a již by se neměla používat. Jakékoli použití způsobí varování. Podporováno LDMud 3.5.x.
Většina ovladačů také podporuje použití modifikátorů typu na zděděné příkazy, což způsobí, že se zděděný objekt chová s ohledem na svého dědice, jako kdyby byl modifikátor typu použit na jeho funkce a / nebo proměnné.
Pokud se výše používá výraz „objektová proměnná“, znamená to proměnnou, která je prvkem objektu (tj. Atribut), na rozdíl od lokální proměnné (existuje pouze v rámci funkce nebo bloku) nebo globální proměnné (neexistuje v LPC - pokud někdo mluví o globální proměnné ve vztahu k LPC, pravděpodobně to znamená objektovou proměnnou).
Předávání hodnot
Primitivní typy LPC (int, string, status, float atd.) Jsou předávány podle hodnoty. Typy datových struktur (objekt, pole, mapování, třída, struktura) jsou předávány odkazem.
Tato funkce může být výkonná, ale může také vést k bezpečnostním mezerám. Ve většině MUDů jsou lidé budující svět obecně méně důvěryhodní než zaměstnanci, kteří hru hrají. Pokud objekt předá mapování s citlivými hodnotami, jako jsou informace o řízení přístupu, autor jiného objektu to může upravit a tím zvýšit jejich přístupová práva. Mudlib vývojáři a správci serverů by proto měli být opatrní při předávání složitých typů objektům se sníženým přístupem.
Typy funkcí
Prostředí LPC obecně kategorizuje funkce do několika hlavních typů podle toho, jak jsou implementovány:
- zábavné
- Lfun neboli „místní funkce“ je definována objektem plánu. (Klony mají stejnou funkci jako jejich plán.) Jsou psány v LPC. Funkce v daném objektu mohou volat jiné funkce ve stejném objektu pomocí syntaxe
function_name()
, zatímco funkce v jiných objektech se obvykle nazývají pomocí syntaxe . Přetížené zábavné soubory definované v objektech, které jeden zdědí, lze volat pomocí syntaxe nebo .object->function_name()
::function_name()
object_name::function_name()
- efun
- Efun neboli „externí funkce“ je definována ovladačem. Efuns jsou psány v C a kompilovány staticky do ovladače, takže obvykle běží mnohem rychleji než jiné typy funkcí, ale je obtížnější je psát a chybí jim flexibilita. Jsou k dispozici v oboru názvů všech funkcí napsaných v LPC, takže například efun
this_player()
lze volat pomocí syntaxethis_player()
, neboefun::this_player()
pokud je potřeba obejít lfun nebo simul_efun. - simul_efun, sefun
- Simul_efun nebo sefun, „simulovaná externí funkce“, je zapsána v LPC v prostředí ovladače a umístěna do zvláštního objektu, jehož funkce napodobují efuns pro účely syntaxe. Takže
some_function()
je k dispozici sefun jakosome_function()
v oboru jmen všech LPC funkcí. - kfun
- Dworkin's Game Driver (DGD) používá termín kfun, „funkce jádra“, spíše než efun. DGD kfuns jsou většinou identické s efuns v jiných implementacích.
- auto
- DGD přesně nemá simul_efuns, ale spíše má „automatický objekt“, který funguje, jako by jej automaticky zdědily všechny ostatní objekty. To částečně napodobuje chování simul_efuns v jiných implementacích.
Hlavní objekt
Implementace LPC obecně mají „hlavní objekt“, což je konkrétní objekt LPC, který je načten nejprve ovladačem LPC a který v podstatě řídí, co se stane za tímto bodem. Hlavní objekt řidiči obvykle řekne, kde je objekt simul_efun, předem načte všechny objekty, které musí být přítomny při spuštění, definuje, jaké funkce budou volány při načtení objektu, a jinak nakonfiguruje činnost ovladače. Ovladač bude odkazovat zpět na hlavní objekt, když potřebuje interagovat s centrálním referenčním bodem pro běžící prostředí, například pro přijímání síťových připojení, zpracování chyb a ověřování pokusů o provedení privilegovaných operací.
Reference
Další čtení
- Busey, Andrew (1995). "13. Základy programování LPC (na LPMUD)". Tajemství mudlovských čarodějů . Publikace SAMS . 219–306. ISBN 0-672-30723-5 .
- Reese, George (1993-04-23). Základy LPC .
- Carlberg, Mats H. (březen 1998). NannyMUD LPC .
- Wikh, Ronny (08.07.2003). Výukový program LPC .
- Heron, Michael (duben 2009). Discworld MUD LPC pro figuríny, kniha 1 (PDF) (druhé vydání).
- Heron, Michael (duben 2009). Discworld MUD's LPC for Dummies, Book 2 (first ed.).http://discworld.starturtle.net/external/lpc_for_dummies/lpc2.pdf
externí odkazy
- LPMuds.net , prostředek pro MUD, kteří používají LPC