LPC (programovací jazyk) - LPC (programming language)

LPC
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 .net
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.

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.ckterý 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.cje 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/roomobjektu. Tento příklad předpokládá, že /lib/roomobjekt 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 v object *, string *, int *. Typicky *lze na deklaraci použít pouze jedno , takže pokud bychom chtěli matici polí, deklarace by byla mixed *. 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í 
Hašovací mapa ( 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.
    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 <jméno> 
Unikátní pro LDMud 3.3 a vyšší; chová se jako C struktura .
    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í syntaxe this_player(), nebo efun::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 jako some_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í

externí odkazy

  • LPMuds.net , prostředek pro MUD, kteří používají LPC