Compare commits

...

3 Commits

Author SHA1 Message Date
an 9025bda4ad fix tocgen regex 2019-04-05 19:35:04 -04:00
an 7e071b7622 standardize documentation code style 2019-04-05 19:34:55 -04:00
an cd38527f4d normalize link style, add small missing parts 2019-04-05 10:37:13 -04:00
15 changed files with 458 additions and 129 deletions

View File

@ -12,8 +12,10 @@ The user-defined stat numbers begin at `Thinker.STAT_USER` and end at
`Thinker.STAT_USER_MAX`. Do not attempt to use normal integers as stat numbers
except as relative to these two.
(Note to authors: These tables are not alphabetically organized as their
ordering is meaningful.)
<!--
NOTE: These tables are not alphabetically organized as their ordering is
meaningful.
-->
Thinkers which do not think and are elided from many checks:

10
api.md
View File

@ -22,12 +22,6 @@ sense to user code, but are fine to the engine. Because of this, the API shall
be documented in pseudo-ZScript which gives an idea of how it works for the
modder rather than for the engine.
Note to authors: Capitalization is normalized within this documentation to
encourage consistent code, and does not follow ZScript's original
capitalization exactly. Similarly, argument names in methods are sometimes
renamed. Note well that *arguments with defaults MAY NOT be renamed* as they
are part of the API.
# Actors
<!-- inter-toc actor -->
@ -113,7 +107,9 @@ For legacy reasons, many intermission-related things may be prefixed with `WI`
or `WB`. The abbreviation `WI` means *World Intermission* (the intermission
screen was originally called "World Map" by Tom Hall) and `WB` meaning *World
Buffer*, as this data was originally buffered into a specific memory address
for [statistics drivers](https://doomwiki.org/wiki/Statistics_driver).
for [statistics drivers][1].
[1]: https://doomwiki.org/wiki/Statistics_driver
# Level Data

View File

@ -4,6 +4,7 @@
* [ACS](#acs)
* [Actors](#actors)
* [Examples: Actor Replacement](#examples-actor-replacement)
* [Console Commands](#console-commands)
* [CVARINFO](#cvarinfo)
* [DECALDEF](#decaldef)
@ -22,7 +23,7 @@ itself, many interactions with the engine are not defined in ZScript. This
section describes all ZScript interactions with the engine, both inside and
outside of ZScript itself.
# ACS
## ACS
ACS has several functions for interfacing with ZScript: `SetUserVariable`
(callfunc `24`,) `GetUserVariable` (callfunc `25`,) `SetUserArray` (callfunc
@ -55,7 +56,7 @@ values, although more than one value will be ignored. The returned value may be
`double` (converted to fixed-point,) `name`, `sound` or `string` (converted to
ACS string.) If it is not one of these types, it will be ignored.
# Actors
## Actors
Actor classes can be replaced by the `replaces` class flag, which during
dynamic actor replacement will choose to spawn this class over its replaced
@ -63,72 +64,94 @@ actor, unless the replaced actor is later replaced again by another class.
Dynamic actor replacement can also be overridden with an event handler's
`CheckReplacement` virtual function.
For example:
### Examples: Actor Replacement
```
class MyActor : Actor replaces OtherActor {} // OtherActor will be dynamically replaced with MyActor
class MyOtherActor : Actor replaces OtherActor {} // OtherActor will now be replaced with MyOtherActor instead of MyActor
// Some actor.
class OtherActor : Actor
{
}
// OtherActor will be dynamically replaced with MyActor.
class MyActor : Actor replaces OtherActor
{
}
// OtherActor will now be replaced with MyOtherActor instead of MyActor.
class MyOtherActor : Actor replaces OtherActor
{
}
```
# Console Commands
## Console Commands
While ZScript cannot be directly called by console commands, one can use the
`event` and `netevent` console commands. `event` will dispatch a non-player
network event, and `netevent` will dispatch a network event for the player that
ran it.
# CVARINFO
## CVARINFO
Any CVars declared as a server CVar in `CVARINFO` or by the engine will be
accessible as a global variable in ZScript, which has a special type that can
be implicitly cast to the type of the CVar. They cannot be set this way, only
accessed.
# DECALDEF
## DECALDEF
`DECALDEF` can set the decal generator for a specific `Actor` class with the
`generator` keyword. An actor can also define its generator and inherited
classes' generators with the `Decal` property.
# DECORATE
## DECORATE
TODO: lots of things to note here
# LOCKDEFS
## LOCKDEFS
Key and lock groups in `LOCKDEFS` are defined as groups of `Inventory` or `Key`
descendants.
# GLDEFS
## GLDEFS
Lights can be associated with `Actor` classes and frames in `GLDEFS`.
# KEYCONF
## KEYCONF
TODO: this can be used for custom buttons
# MAPINFO
## MAPINFO
In `MAPINFO`, the `GameInfo` block (referred to as `MAPINFO`/GameInfo in this
document) the following properties interact directly with ZScript:
- `EventHandlers` and `AddEventHandlers` override or add to the list of `StaticEventHandler` or `EventHandler` classes registered by the game (as opposed to event handlers registered per-map.)
- `MessageBoxClass` sets the `MessageBoxMenu` class to use for message boxes used by the engine's GUI.
- `PlayerClasses` and `AddPlayerClasses` override or add to the list of `PlayerPawn` classes the game provides.
- `PrecacheClasses` will pre-cache all sprites used by an `Actor` class. Note that this also works for `StateProvider` degenerates like `Weapon`.
- `StatScreen_CoOp` sets the `StatusScreen` class to use for co-op intermission screens.
- `StatScreen_DM` sets the `StatusScreen` class to use for Deathmatch intermission screens.
- `StatScreen_Single` sets the `StatusScreen` class to use for single-player intermission screens.
- `StatusBarClass` sets the status bar class used by the game to the provided `BaseStatusBar` class.
- `WeaponSlot` sets the game's default weapon slots to the provided `Weapon` classes.
- `EventHandlers` and `AddEventHandlers` override or add to the list of
`StaticEventHandler` or `EventHandler` classes registered by the game (as
opposed to event handlers registered per-map.)
- `MessageBoxClass` sets the `MessageBoxMenu` class to use for message boxes
used by the engine's GUI.
- `PlayerClasses` and `AddPlayerClasses` override or add to the list of
`PlayerPawn` classes the game provides.
- `PrecacheClasses` will pre-cache all sprites used by an `Actor` class. Note
that this also works for `StateProvider` degenerates like `Weapon`.
- `StatScreen_CoOp` sets the `StatusScreen` class to use for co-op intermission
screens.
- `StatScreen_DM` sets the `StatusScreen` class to use for Deathmatch
intermission screens.
- `StatScreen_Single` sets the `StatusScreen` class to use for single-player
intermission screens.
- `StatusBarClass` sets the status bar class used by the game to the provided
`BaseStatusBar` class.
- `WeaponSlot` sets the game's default weapon slots to the provided `Weapon`
classes.
TODO: there are other things here as well, like map event handlers
# MENUDEF
## MENUDEF
TODO: this directly uses ZScript classes
# TERRAIN
## TERRAIN
The `SmallSplash`, `SplashBase` and `SplashChunk` properties of `Splash` blocks
use `Actor`s.

View File

@ -1,5 +1,7 @@
# Concepts
<!-- vim-markdown-toc GFM -->
* [Action Scoping](#action-scoping)
* [Object Scoping](#object-scoping)
* [Format String](#format-string)
@ -7,7 +9,13 @@
* [Game Tick](#game-tick)
* [Interpolation](#interpolation)
TODO
<!-- vim-markdown-toc -->
Here is a cursory view of concepts vital to ZScript and ZDoom in general. If
you can't find something here, it's likely inherited directly from Doom, so you
should check [the Doom Wiki][1] for more relevant information.
[1]: https://doomwiki.org/wiki/Entryway
## Action Scoping
@ -61,15 +69,18 @@ Here is a chart of data access possibilities for each scope:
A format string is a string that specifies the format of a conversion from
arbitrary data to a contiguous character string. A format string contains
normal characters and *conversion specifiers*. See [this
page](https://en.cppreference.com/w/c/io/fprintf) for more information.
Differences between C's `printf` and ZScript formats include:
normal characters and *conversion specifiers*. See [this page][2] for more
information. Differences between C's `printf` and ZScript formats include:
- Since there's no `char` type, `int` is used for `%c`.
- `%s` also works for `name`.
- No `%n` specifier.
- An additional conversion specifier `%B` exists which converts a number to binary.
- An additional conversion specifier `%H` exists which works like `%g` but automatically selects the smallest appropriate precision.
- An additional conversion specifier `%B` exists which converts a number to
binary.
- An additional conversion specifier `%H` exists which works like `%g` but
automatically selects the smallest appropriate precision.
[2]: https://en.cppreference.com/w/c/io/fprintf
## Sprite
@ -81,7 +92,9 @@ the file and state block representations, not a character, but an integer. The
number `0` for instance represents the letter `A`, `1` to `B`, etc.
For more information on sprites and rotations, please refer to [the relevant
Doom Wiki article](https://doomwiki.org/wiki/Sprite).
Doom Wiki article][3].
[3]: https://doomwiki.org/wiki/Sprite
## Game Tick
@ -108,7 +121,9 @@ simulation in the same way:
smoother rendering.
For more information on ticks, please refer to [the relevant Doom Wiki
article](https://doomwiki.org/wiki/Tic).
article][4].
[4]: https://doomwiki.org/wiki/Tic
## Interpolation

257
glossary-Style.md Normal file
View File

@ -0,0 +1,257 @@
# Style
<!-- vim-markdown-toc GFM -->
* [Capitalization Conventions](#capitalization-conventions)
* [Rationale](#rationale)
* [Word Choice](#word-choice)
* [Rationale](#rationale-1)
* [Naming Type Members](#naming-type-members)
* [Rationale](#rationale-2)
* [Layout Conventions](#layout-conventions)
* [Rationale](#rationale-3)
* [Commenting Conventions](#commenting-conventions)
* [Rationale](#rationale-4)
* [Language Guidelines](#language-guidelines)
* [Rationale](#rationale-5)
<!-- vim-markdown-toc -->
This is a style guide for the ZScript documentation to encourage best-practice
coding with it, focused on clarity and consistency of formatting. It is also
intended to be a general style guide for writing new code, but this purpose is
ancillary and can be ignored. Within the abstract of each component of style
will be rationale for choices made.
## Capitalization Conventions
ZScript is case insensitive, however this guide aims to give a way to
consistently capitalize all identifiers in the language. Due to case
insensitivity, it may be difficult to apply these guidelines to real code, but
nonetheless a consistent capitalization style should be followed. Do note that
you must not rely on case differences in identifiers due to this.
Capitalize the first letter of each word in an identifier. Acronyms over 2
characters in length are considered whole words, so for instance prefer
`XmlWidget` over `XMLWidget` but `IOStream` over `IoStream`. Acronyms of one
character also count, so prefer `PrintF` over `Printf`.
For identifiers of parameter names and local scope variables do not capitalize
the first word. In these cases, prefer `xmlWidget` over `XmlWidget` or
`ioStream` over `IOStream`. The same for acronyms of one character, so `typeF`
over `TypeF` or `nChars` over `NChars`. (Note that the former two are malformed
names, however. See the "Word Choice" section for more information.)
Identifiers used for flags (declared with `flagdef`) and constants (declared
with `const`, `static const`, or `enum`) must be all uppercase, except the `b`
prefix on flags, and can separate words with underscores.
Argument names in base archive methods may be renamed, but arguments with
defaults may not be renamed as they are part of the API.
### Rationale
Case insensitivity in programming is generally regarded as bad practice because
the lack of strictness is often a failing in language design. It is not
imperative here to reason for or against case insensitivity, however. Code
within this style is to be written as uniformly as possible, therefore
capitalization is also to be uniform. It is the user's choice whether to follow
this rule or not, just as any other, but for authors of this documentation the
sole imperative is consistency.
This style of acronym capitalization has been chosen so as to defer to prior
art, primarily C#'s standard, which has been in use for over a decade now. The
purpose of not capitalizing more than two characters is to make it more natural
to read acronyms where normally they are forced to be next to other capitalized
words.
Not capitalizing the first word of parameter and local scope variables is also
decided by deferring to prior art. The majority of programming style guides
written advocate for this. The purpose in ZScript is primarily moot due to case
insensitivity, but we apply these rules to make reading easier and more
consistent with most other programming languages that have existed.
Capitalizing constants, enumerations, and flags is an artifact of the way they
are declared in ZDoom, and also in the original Linux Doom source code. This is
extended to static arrays for consistency.
## Word Choice
In new identifiers, do not add underscores anywhere within the identifier,
unless explicitly stated in this style guide or necessary because of
unmodifiable code (such as that in GZDoom's base archive.) Do not use Hungarian
notation.
Do not use keywords or types as names except for the identifier "`name`". Do
not, for instance, declare `string Class;`, even though the language will allow
you to do so, although `string Name;` is fine.
It is generally favorable to use shortened terminology, for instance `CanMoveZ`
instead of `CanMoveVertically`. Try to make names readable in English, however:
`CanThrowItem` instead of `ThrowableItem`.
In the same vein, use abbreviations where conventional, but avoid them where
unnecessary. Prefer `GetMobj` to `GetMapObject` but also `GetAngle` to
`GetAng`.
### Rationale
The forbidding of underscores and Hungarian notation are in accordance with
ZDoom's coding style. These choices are also present in other prior art, but
the main deciding factor is that of the engine itself.
The usage of most keywords in variable names is allowed in ZScript because the
parser considers most identifiers to be contextual. In many contexts, keywords
are allowed in places they shouldn't be by most standards. Besides the
precedence of prior art, it appears that the engine itself also avoids
(ab)using this relaxation of context.
The engine and this style do, however, allow use of the identifier "`name`" in
variables and members because it is a frequently used word and would be absurd
to disallow.
Shortened terminology such as abbreviations or contractions are favored due to
long-standing conventions within ZDoom's source code. This is also historically
relevant because of engines such as Unreal Engine which ZDoom takes inspiration
from. Common terminology which may be shortened can be found on [the Doom
Wiki.][2]
[2]: https://doomwiki.org/wiki/Category:Doom_engine
## Naming Type Members
Always name methods with verbs or verb phrases, such as "`Split`" or
"`CompareTo`." Always try to make names forward compatible, i.e. such that they
will likely not conflict with new functions when they are added to the engine.
In mods, this can even involve prefixing method names with one unique to the
mod. Avoid violent words such as `Die`, `Destroy`, `Kill`, except where
literally applicable. Prefer for instance `Stop`, `Drop`, `Halt`.
Always name members with nouns, noun phrases or adjectives. Boolean values
should often be prefixed with `Is`, `Has`, and other existential present-tense
verbs. All members of class types should be prefixed with `m_`, despite rules
against Hungarian notation and underscores. Try to name members productively
rather than vaguely, instead of `RefInt` write `RefCount`.
### Rationale
Forwards compatibility is necessary primarily in mods. In this documentation it
should be taken into account when writing example code, often when writing
examples that involve inheriting from a class in the engine. ZScript will hard
error on load if there is more than one definition of a function, so it is
necessary to never have a conflict in names, including capitalization-wise.
The purpose of avoiding violent words in method names is to not unnecessarily
invoke potentially uncomfortable or triggering imagery. In much of the base
class code, it is literally the action being taken, as Doom is indeed a violent
game. In these cases it is entirely normal to use such verbs. An example of
when this is entirely wasteful is ZDoom's garbage collector (which is exposed
with different naming conventions) in which the flag for objects marked for
finalization upon the next collection cycle is named `EuthanizeMe`. This kind
of wording is certainly jocular and potentially amusing, but a 'funny' name
such as this serves no real purpose, and could easily be re-worded to prevent
potential discomfort.
Members are prefixed with `m_` in order to defuse potential clashes with local
variables, since case sensitivity cannot defuse them. The alternative to this
is to prefix all member variable accesses with `self.`. However, this is
potentially excessive and is not entirely productive in writing short and
readable examples. This also provides a layer of forward compatibility, as
ZDoom does not use `m_` prefixes anywhere within its code. For the opposite
reason, as structure types cannot inherit, there is no need to prefix their
members, and so this prefix is omitted within them.
## Layout Conventions
Use 3 spaces for indentation. Indent at each block, but do not indent `case`
labels. Align all code to 80 columns.
Write only one statement or declaration per line, except in the case of
multiple-assignment operations, in which case pairing all of the related
declarations and the statement on the same line is allowed as long as it does
not exceed 80 columns.
Always add one blank line between separate method definitions, and between
member declarations and member definitions. Add one blank line between local
variable declarations and statements, unless specified otherwise. Add one blank
line between conditional statements, except the `else` block of an `if`
statement.
Do not place a space before the parentheses of a conditional or loop statement
such as `if` or `for`. Always write `if()` and not `if ()`.
Always place opening braces on their own line. Using braces is not necessary
when there is a single sub-statement, for instance with `if(x) y = z;`.
### Rationale
The convention of 3 spaces for indentation comes from [Eternity Engine's style
guideline.][1] There is no other reason for this decision, other than it is
pleasing to the eye while not being excessive. The indentation and blank line
rules are generally the same as the majority of C-like language style
guidelines.
Alignment to 80 columns is for the purpose of reading the raw documentation
text under standard size Linux terminals. This is useful, for instance, when
reading diff files under the `git` console client. This guideline can generally
be ignored outside of this documentation.
Writing multiple-assignment operations all on one line serves the purpose of
grouping all of the relevant information together. In most languages with
multiple assignment, you are able to do the declaration and assignment in one
line, so this crudely mirrors a more well implemented language syntax.
Placing opening braces on their own line greatly increases code readability,
especially for people hard of sight. Other styles make it easy to confuse where
a block begins and create a less clear visual line between the start and end.
The purpose of this is to increase readability of this documentation, and not
to make code look more pleasing.
[1]: https://github.com/team-eternity/eternity/blob/master/docs/ee_style_guide.md
## Commenting Conventions
Do not use block comments, except for the purpose of example or code that will
intentionally not work. Comments may be placed anywhere except at the end of
the opening line of a conditional or loop statement, the opening brace of a
block, or the ending brace of a block. Always use proper case and punctuation
when writing comments. Always put one space between the comment delimiter and
comment text.
### Rationale
Block comments are mostly an adage of old programming languages made to be
printed on paper. In modern times they are most useful for commenting out large
blocks of code. They are rather clumsy to format well, and so single-line
comments are to be used instead of them. One could argue that if a consistent
formatting style was added, this would not be a problem. However, it is
generally easier and more readable to just use line comments.
## Language Guidelines
Use `let` declarations when the type of the object will be obvious from what it
is assigned. Do not use them if it is not obvious, or in example when it is
necessary to proclaim the type to make reading easier.
Don't use integer types except for `int` except in example. Similarly, do not
use float types except for `double` except in example.
No restrictions are placed on the usage of parentheses. Always place spaces
between the operands of binary expressions (`1 + 1`) but never unary
expressions (`-5`.)
Do not place semicolons at the end of `enum` or `struct` definitions. However, always place commas at the end of the last enumeration variant.
### Rationale
Integer and floating-point types other than `int` and `double` are primarily
for internal use. They can be used by user types, but often it's not necessary
and can be harmful.
Placing semicolons at the end of top-level items is not meant to be used by end
users. Its main purpose is to make ZScript easier to port from C++. On the
other hand, placing a comma at the end of the last enumeration in a set is a
common practice, as it allows the user to place more variants without touching
much.
<!-- EOF -->

View File

@ -5,6 +5,7 @@
* [Classes](glossary-Classes.md)
* [Concepts](glossary-Concepts.md)
* [Structures](glossary-Structures.md)
* [Style](glossary-Style.md)
* [Versions](glossary-Versions.md)
<!-- end -->

View File

@ -22,7 +22,7 @@ creating within the language.
All classes inherit from other classes. The base class can be set within the
class header, but if it is not the class will automatically inherit from
Object.
`Object`.
Classes are subject to Scoping. They are also implicitly reference values, and
therefore can be null. Use `new` to instantiate a new class object.
@ -64,23 +64,38 @@ In place of the class header.
## Example: Class headers
```
class MyCoolObject // automatically inherits Object
// Automatically inherits Object, similar to the "actor" keyword in DECORATE.
class MyCoolObject
{
}
class MyCoolScopedObject play // has Play scope
// Equivalent to the above.
class MyCoolObjectExplicit : Object
{
}
class MyCoolThinker : Thinker // inherits Thinker
// Has "Play" scope.
class MyCoolScopedObject play
{
}
// Inherits Thinker and can override functions on it.
class MyCoolThinker : Thinker
{
}
// Some actor.
class OtherActor : Actor
{
}
// Replaces "OtherActor."
class MyCoolActor : Actor replaces OtherActor
{
}
class MyCoolInterface abstract // can only be inherited
// Can only be inherited.
class MyCoolInterface abstract
{
}
```
@ -92,8 +107,10 @@ Basic class definition with a member variable and member function.
```
class BasicClass
{
// "m_Thing" is attached to any "instance" of BasicClass.
int m_Thing;
// Changes "m_Thing" to 500 on an instance of BasicClass.
void ChangeThing()
{
m_Thing = 500;
@ -104,11 +121,12 @@ class BasicClass
Alternate syntax usage.
```
// This class spans from this point to the end of the file.
class TheWholeFileIsAClassOhNo;
int m_MyMember;
// end of file
// End of file, end of class.
```
# Class Flags
@ -167,15 +185,19 @@ A class with some properties.
```
class MyCoolActor : Actor
{
// You can set defined properties in a "default" block like in DECORATE.
// This will also be available in DECORATE code that inherits your class!
default
{
MyCoolActor.MyCoolMember 5000;
MyCoolActor.MyCoolMemberList 501, 502;
}
// Declare some members.
int m_MyCoolMember;
int m_CoolMember1, m_CoolMember2;
// Declare some properties attached to our members.
property MyCoolMember: m_MyCoolMember;
property MyCoolMemberList: m_CoolMember1, m_CoolMember2;
}
@ -219,18 +241,25 @@ A class with some flags.
```
class MyCoolActorWithFlags : Actor
{
// You can set defined flag in a "default" block like in DECORATE.
// This will also be available in DECORATE code that inherits your class!
// Hey, those sentences sounded familiar...
default
{
+MYCOOLACTORWITHFLAGS.THIS_ONE_IS_ON
-MYCOOLACTORWITHFLAGS.THIS_ONE_IS_OFF
}
// Declare a flag field for all of the flags. This can hold up to 32 flags.
int m_Flags;
flagdef This_One_Is_On: m_Flags, 0;
flagdef This_One_Is_Off: m_Flags, 1;
flagdef This_One_Aliases_On: m_Flags, 0;
// Declare the flags, one at a time...
flagdef THIS_ONE_IS_ON: m_Flags, 0;
flagdef THIS_ONE_IS_OFF: m_Flags, 1;
flagdef THIS_ONE_ALIASES_ON: m_Flags, 0;
// Unnecessary, since you can just access it directly, but this demonstrates
// how declared flags can be used in methods.
bool CheckIfOnIsOn()
{
return bTHIS_ONE_IS_ON;

View File

@ -19,10 +19,12 @@ type.
## Example: Constant definitions
Making an integer constant from a double.
```
const MY_COOL_INT = int(777.7777);
// Making a regular integer constant.
const MY_COOL_NUMBER = 777;
// Making an integer constant from a double.
const MY_COOL_NUMBER_FROM_BEYOND = int(777.7777);
```
# Static array definitions

View File

@ -35,28 +35,24 @@ Identifier $[ = Expression]$
## Example: Enumeration definitions
Basic enumeration.
```
// Basic enumeration.
enum MyCoolEnum
{
A, // has value int(0)
B, // 1 ...
C, // 2 ...
D // and 3
A_THING, // Has value int(0) ...
BEES, // ... 1 ...
CALCIUM, // ... 2 ...
DEXTROSE, // ... and 3.
}
```
Less trivial example.
```
// Less trivial example.
enum MyCoolerEnum : int16
{
A = 500, // has value int16(500)
B, // 501
A = 500, // Has value int16(500),
B, // 501,
C = 200,
D, // 201
E, // 202
};
D, // 201,
E, // and 202.
}
```
<!-- EOF -->

View File

@ -56,9 +56,9 @@ character. Character escapes include:
| `\xnn` or `\Xnn` | Byte `0xnn`. |
| `\nnn` | Byte `0nnn` (octal.) |
To quote [cppreference](https://en.cppreference.com/w/cpp/language/escape), "of
the octal escape sequences, `\0` is the most useful because it represents the
terminating null character in null-terminated strings."
To quote [cppreference][1], "of the octal escape sequences, `\0` is the most
useful because it represents the terminating null character in null-terminated
strings."
String literals, also like C and C++, will be concatenated when put directly
next to each other. For example, this:
@ -69,6 +69,8 @@ next to each other. For example, this:
Will be parsed as a single string literal with the text `"text 1text 2"`.
[1]: https://en.cppreference.com/w/cpp/language/escape
## Class type literals
Class type literals take the same form as string literals, but do note that

View File

@ -22,10 +22,19 @@ $[Member-declaration-flags...]$ Type Variable-name $[ , Variable-name]$... ;
Some basic member variables.
```
// An integer. Visible to and modifiable by everything.
int m_MyCoolInt;
// Three separate integers, defined short-hand.
int m_CoolInt1, m_CoolInt2, m_CoolInt3;
// Ten integers in one variable.
int[10] m_CoolIntArray;
// Can only be seen by this type.
private int m_CoolPrivateInt;
// Read-only (part of the class data, can only be seen by descendant types.
protected meta int m_CoolMetaInt;
```

View File

@ -57,31 +57,25 @@ Or, the entire list may simply be `void` or empty.
## Example: Method argument lists
With the function:
```
void Fn(int one, int two, int a = 0, int b = 0);
```
// With the function:
void DoSomething(int one, int two, int a = 0, int b = 0);
One could do the following:
// One could do the following:
DoSomething(4, 5);
DoSomething(5, 6, 7);
DoSomething(6, 7, 8, 9);
```
Fn(4, 5);
Fn(5, 6, 7);
Fn(6, 7, 8, 9);
```
// Or using named default arguments,
DoSomething(5, 6, a: 7);
Or using named default arguments,
// Equivalent to:
DoSomething(5, 6, 7);
```
Fn(5, 6, a: 7);
Fn(6, 7, b: 8);
Fn(7, 8, a: 9, b: 10);
// equivalent to:
Fn(5, 6, 7);
// (no equivalent, must use above)
Fn(7, 8, 9, 10);
// And more examples:
DoSomething(6, 7, b: 8);
DoSomething(7, 8, a: 9, b: 10);
DoSomething(7, 8, 9, 10);
```
# Method Definition Flags

View File

@ -53,12 +53,13 @@ Expression ;
## Example: Expression statements
Some basic expressions.
```
// Some basic expressions.
MyCoolFunction(5, 4);
m_MyCoolMember = 500;
5 * 5; // does nothing of course, but valid
// Does nothing, of course, but valid.
5 * 5;
```
# Conditional Statements
@ -72,16 +73,14 @@ if ( Expression ) Statement $[ else Statement]$
## Example: Conditional statements
Simple conditional.
```
// Simple conditional.
if(a)
B();
```
Simple conditional, with else statement and a block.
// Simple conditional, with else statement and a block.
```
if(a)
{
B();
@ -102,17 +101,23 @@ switch ( Expression ) Statement
## Example: Switch statements
A switch demonstrating fall-through and default cases.
```
// A switch demonstrating fall-through and default cases.
switch(a)
{
case 500: Console.PrintF("a is 500"); break;
case 501: Console.PrintF("a is 501"); // falls through to next case
case 502: Console.PrintF("a is 501 or 502"); break;
case 500:
Console.PrintF("a is 500");
break;
case 501:
Console.PrintF("a is 501");
// Falls through to the next case.
case 502:
Console.PrintF("a is 501 or 502");
break;
default:
Console.PrintF("not sure what a is!");
// break is implied here
// "break" is implied here.
}
```
@ -185,49 +190,51 @@ return $[Expression $[ , Expression]$...]$ ;
## Example: Control flow statements
Use of `continue`.
```
// Use of "continue."
for(int i = 0; i < 50; i++)
{
if(i == 25) continue; // don't do anything on 25!
// Don't do anything when "i" is 25.
if(i == 25)
continue;
DoThing(i);
}
```
Use of `break`.
```
// Use of "break."
for(int i = 0; i < 50; i++)
{
if(i == 25) break; // exit the loop at 25!
// "break" when "i" is 25.
if(i == 25)
break;
DoThing(i);
}
```
Use of `return` in various contexts.
```
// Use of `return` in various contexts.
void ReturnsNothing()
{
if(m_Thing != 50) return; // exit early if m_Thing isn't 50.
// Exit early if "m_Thing" isn't 50.
if(m_Thing != 50)
return;
DoThing(m_Thing);
}
int ReturnsInt()
{
// "m_Thing" is 50, so return 50.
if(m_Thing == 50)
return 50; // m_thing is 50, so return 50.
return 50;
return 0; // must have a return eventually
// Must have a return, eventually.
return 0;
}
int, int ReturnsTwoInts()
{
return 1, 2; // returns 1 and 2.
// Returns 1 and 2.
return 1, 2;
}
```
@ -264,12 +271,9 @@ Note that the surrounding brackets are literal and not an optional element.
## Example: Multi-assignment statements
Getting the actor out of `A_SpawnItemEx`.
```
Actor mo;
bool spawned;
[spawned, mo] = A_SpawnItemEx("MyCoolActor");
// Getting the actor out of "A_SpawnItemEx."
Actor mo; bool spawned; [spawned, mo] = A_SpawnItemEx("MyCoolActor");
```
# Static Array Statements

View File

@ -34,9 +34,8 @@ Optionally followed by a semicolon.
## Example: Structure definitions
Simple structure.
```
// Simple structure.
struct MyCoolStructure
{
int X;

View File

@ -15,7 +15,7 @@ def filter_emit r
end
def find_toc_areas f
re = /^(<!-- inter-toc ([^\s]+)\s+-->)(?:.|\n)*?(<!-- end -->)/i
re = /^(<!-- inter-toc\s*([^\s]+)\s*-->)(?:.|\n)*?(<!-- end -->)/i
f.to_enum(:scan, re).map{$~}
end