LPC (programming language)

from Wikipedia, the free encyclopedia

LPC is an object-oriented programming language , similar in syntax to C or C ++ , for network text adventure games ( Multi User Dungeons , MUDs for short).

LPC is a mixture of interpreter and compiler language. LPC-MUDs generally allow programs to be added, started and also subsequently changed at runtime without restarting the entire game. The LPC code is first converted into a bytecode by a compiler and then executed by an interpreter .

history

The name LPC is derived from the inventor of the language, Lars Pensjö . Pensjö developed LPC in the early 1990s and based it on the programming language C. Apart from the similar syntax, the two languages ​​have little in common.

The original implementations of LPC were compiler and bytecode - interpreter components of a single program, the basic, necessary for the operation of a multi-user dungeons functionality made available, the so-called Game Driver or shortly Driver . The MUD Amylaar also contributed significantly to the driver. This includes above all the operation as a server , to which a connection can be established with a Telnet or a special MUD client . This software was distributed under the name LPMud ; a modern further development based on the original LPMud source code is called LDMud (after the initials of the maintainer). Another implementation of the same concept including the LPC language is MudOS .

The independent script language Pike emerged from LPC . So far, this has not reached a high level of prevalence.

features

LPC supports the following programming techniques:

Differences from other C-like languages

The basic syntax of LPC corresponds to that of language C. This includes the characters used to identify blocks, functions, arguments and argument lists as well as the use of semicolons as the end character of a statement.

In contrast to C, LPC has no strongly typed variables. A variable can be created with a previously determined type, but it can still accept a value of a different type. In addition, there is the mixed type for untyped variables.

This also affects the return values ​​and parameters of functions: Normally, neither the arguments nor the return value need to be given types in the function signature. However, by specifying preprocessor directives, you can force a check for valid arguments at compilation time:

  • #pragma strong_types - types for arguments and return value must be specified
  • #pragma strict_types - the return value of methods called on foreign objects must be cast

The class library of a MUD

The LPC language knows only a small number of standard functions ( efuns ). These are implemented in the executing program ( gamedriver ), e.g. LPMud or LDMud . In addition, every MUD that is operated with such software has its own class library ( MUDlib ). The MUDlib contains interfaces with which the gamedriver can return part of the responsibility to you. This includes, among other things, the creation of a player object for a logged-in player or error handling. There is no standard MUDlib that is used by all MUDs. However, some of the MUDlibs that are in use are open source or can be used freely in some other way. Based on a few freely available MUDlibs, several widespread MUDlib branches have emerged that are used in many MUDs. In German-speaking countries, for example, descendants of the MUDlibs of the MUDs MorgenGrauen on the one hand and UNItopia on the other hand are widespread.

Differences related to the runtime environment

Aside from the linguistic side, LPC also differs from other programming languages in several points with regard to the definition of the runtime environment . Due to the original objective as the language of an online role-playing game, in which several developers with different rights can contribute their own code, the runtime environment contains, for example, so-called privileged functions that can only be called by a normal object after a prior check by a master object of the MUD .

Current LPC runtimes do not support threads . In a single thread all tasks are done one after the other. This necessarily results in a limit on the runtime that is set for handling a related event. In LDMuds this limit can be lifted or set dynamically for individual function calls.

Another special feature is the almost complete equivalence of built-in functions ( efuns ) with the class library of a MUDs ( MUDlib specified) simul_efuns . In this way it is possible to overwrite standard functions or to prohibit access to them.

Differences in object orientation

In contrast to many object-oriented programming languages, LPC does not distinguish between classes and objects . Normally, from a source - file a single object created. However, all objects in memory can be duplicated ( cloned ). The process of cloning is comparable to that of instantiation in other programming languages; However, the clone (are clone ) and the original ( blueprint ) equal and can theoretically be used in the same way both.

Special constructs

LPC knows the concept of shadowing . This is a way of intercepting all access to a function of an object from the outside, for example to filter it or to prevent it completely, similar to the decorator pattern. The principle is applied in that an object with the efun shadow () registers itself as the "shadow" of any other object. When a function of the target object is called that does not happen directly within the target object, the function of the same name is called in the shadow object if this object contains such a function. If there is no function with the same name in the shadow object, the call is treated like a normal function call in an object without a shadow. The shadow object also has the option of calling functions in the target object that it "overshadows".

Special data types

Functions are not first-class objects in LPC (first-order functions). Nevertheless, the language knows function references. The name closure for this data type is borrowed from the world of functional programming , based on the term closure . The referenced function can also be generated dynamically at runtime using the lambda () function. A new function is generated from an array of closures and symbols at runtime , which, like any other closure, can then be passed as a value or called as a function. The LPC advancement used in the LPMud variant LDMud also includes the option of creating closures for informally specified inline functions at compile time . The so-called smiley notation is used for this, in which normal LPC code is converted into a normal function of the object within (: and :) by the compiler and the expression is replaced by a closure referring to this function at the point where it occurs.

Arrays exist in LPC and can be created in the code with the individual elements separated by commas and enclosed by ({and}). Access to individual elements is done with the index operator [] comparable to C. There are also standard functions for handling arrays. Arrays, like other variables, are not typed. This means that the elements of an array can be of different types. Other arrays are also allowed as elements of an array. This makes it possible in LPC to build complex structures as arrays. A variable that should be able to hold an array is indicated by an asterisk (*) placed after the element type . However, no type test is carried out. Variable of type mixed may also contain an array.

LPC also knows so-called associative arrays comparable to the dictionaries of the Python language . The term mapping is used for this in LPC . These mappings are implemented as a hash table . A key element can be assigned a value in an associative array. A special feature of the associative arrays in LPC is the variable number of values ​​per key per mapping. For example, a mapping can contain any number of values ​​for each key, but the same number within the mapping. In order to address these values, a numerical index can be specified in addition to the key for an indexing operation.

Hello world program in LPC

The following object returns the text "Hello, world!" When it is loaded for the first time. because the create () method is usually called automatically when loading / cloning objects.

void create() {
  write("Hallo, Welt!");
}

More complex example object

LPC is mainly used to describe objects in role-playing games. In many cases, such objects are objects, inhabitants or spaces in a virtual world. The class library (MUDlib) therefore typically contains objects that generally represent an object - or a specific class of objects. The same applies to rooms, monsters and all other objects that often have to be created in different variations.

The following example relates to the use of LPC together with an existing class library that is not included with LPMud. It implements an apple and inherits from a standard object that implements edible food by the player. This includes the logic necessary to implement the eating process in the game. In the inheriting object, you only have to set the values ​​of properties that determine the effects of consumption within the scope of the possibilities of the base class. The MUDlib referenced in this example provides the SetProp () function for this purpose. The names of the properties are preprocessor macros. Depending on the MUD, it is also common to access properties via individual accessor functions .

inherit "/std/food";

#include <properties.h>
#include <language.h>
#include <food.h>

void create()
{
  if(!is_clone(this_object())) return;
  ::create();
  SetProp(P_SHORT, "Ein Apfel");
  SetProp(P_LONG, "Dieser Apfel ist schoen prall und rot. Er schmeckt sicher vorzueglich.");

  AddId( ({"apfel", "\napfel"}) );
  SetProp(P_NAME, "Apfel");
  SetProp(P_GENDER, MALE);
  SetProp(P_VALUE, 50);
  SetProp(P_WEIGHT, 50);
  SetProp(P_MATERIAL, ([ MAT_FRUIT: 100 ]) );
  SetProp(P_FOOD_INFO,
     ([ F_HEAL: ({10,10}),
        F_SOAK: 5,
        F_MSG: "Du isst den leckeren roten Apfel.",
        F_MSG_ROOM: "isst einen leckeren roten Apfel."]) );
}

Individual evidence

  1. Xyllomer.de: The LPC Reference Manual. Retrieved April 20, 2016 .