├── .gitignore
├── dma
├── gta3
│ ├── limits.adoc
│ ├── entity-def.adoc
│ ├── string-constant-def.adoc
│ ├── expressions.adoc
│ ├── scope.adoc
│ ├── references.adoc
│ ├── statements.adoc
│ ├── elements.adoc
│ ├── definitions.adoc
│ ├── introduction.adoc
│ ├── general.adoc
│ ├── index.adoc
│ ├── alternator-def.adoc
│ ├── parameters.adoc
│ └── command-def.adoc
└── index.adoc
├── core
├── appendix-complex-commands.adoc
├── appendix-grammar.adoc
├── scope.adoc
├── introduction.adoc
├── index.adoc
├── references.adoc
├── appendix-ambiguity.adoc
├── alternators.adoc
├── structure.adoc
├── appendix-grammar-lex.adoc
├── definitions.adoc
├── general.adoc
├── expressions.adoc
├── command-def.adoc
├── concepts.adoc
├── appendix-miss2.adoc
├── parameters.adoc
├── elements.adoc
├── alternator-def.adoc
└── statements.adoc
├── tools
├── asciidoctor-grammar-preprocessor.rb
├── asciidoctor-python3.rb
└── asciidoctor-grammar-preprocessor.py
├── LICENSE
├── deploy.sh
├── index.adoc
└── docinfo.html
/.gitignore:
--------------------------------------------------------------------------------
1 | *.html
2 | !docinfo.html
3 | *.css
4 |
--------------------------------------------------------------------------------
/dma/gta3/limits.adoc:
--------------------------------------------------------------------------------
1 | [[limits]]
2 | == Implementation Limits
3 |
4 | TODO
5 |
--------------------------------------------------------------------------------
/dma/gta3/entity-def.adoc:
--------------------------------------------------------------------------------
1 |
2 | [[entity-def]]
3 | == Supporting Entity Types
4 |
5 | TODO
6 |
7 |
--------------------------------------------------------------------------------
/dma/gta3/string-constant-def.adoc:
--------------------------------------------------------------------------------
1 | [[string-constant-def]]
2 | == Supporting String Constants
3 |
4 | TODO
5 |
6 |
--------------------------------------------------------------------------------
/core/appendix-complex-commands.adoc:
--------------------------------------------------------------------------------
1 | [appendix]
2 | [[complex-commands]]
3 | == Complex Commands
4 |
5 | TODO list of special command names (user cannot write these, include AND/OR/NOT)
6 |
7 |
--------------------------------------------------------------------------------
/tools/asciidoctor-grammar-preprocessor.rb:
--------------------------------------------------------------------------------
1 | require_relative './asciidoctor-python3'
2 |
3 | Asciidoctor::Extensions.register do
4 | preprocessor python3_preprocessor("asciidoctor-grammar-preprocessor.py")
5 | end
6 |
--------------------------------------------------------------------------------
/core/appendix-grammar.adoc:
--------------------------------------------------------------------------------
1 | [appendix]
2 | [[grammar]]
3 | == Grammar Summary
4 |
5 | // The build process automatically joins all the grammar
6 | // in the specification into the following line
7 | AUTO_REPLACE_WITH_GRAMMAR
8 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The contributors of this work has dedicated all copyright to the public domain
2 | worldwide under the CC0 Public Domain Dedication located at .
3 |
4 | This specification is distributed without any warranty.
5 |
--------------------------------------------------------------------------------
/dma/gta3/expressions.adoc:
--------------------------------------------------------------------------------
1 | [[expressions]]
2 | == Expressions
3 |
4 | [[assignment-expressions]]
5 | === Assignment Expressions
6 |
7 | The ternary assignments `a = b - c`, `a = b / c`, `a = b +@ c` and `a = b -@ c` where `a` is the same name as `c` are ill-formed.
8 |
9 |
--------------------------------------------------------------------------------
/core/scope.adoc:
--------------------------------------------------------------------------------
1 | [[scope]]
2 | == Scope
3 |
4 | This document is targeted at implementation writers and perhaps curious community members.
5 |
6 | This document specifies the syntax, constraints and semantic rules of the GTA3script language.
7 |
8 | This document does not specify a runtime system nor does it specify mechanisms by which the language is transformed for use by such a system.
9 |
--------------------------------------------------------------------------------
/deploy.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | set -e
3 | git clone https://github.com/gtamodding/gta3script-specs.git /tmp/gta3script-specs
4 | cd /tmp/gta3script-specs
5 | ./build.sh
6 | mkdir build build/dma build/extensions
7 | cp *.html *.css build/
8 | git checkout gh-pages
9 | cp build/*.html build/*.css ./
10 | rm -r build docinfo.html
11 | git add .
12 | git commit -m "Deploy"
13 | git push origin gh-pages
14 | cd /tmp && rm -rf gta3script-specs
15 |
--------------------------------------------------------------------------------
/dma/gta3/scope.adoc:
--------------------------------------------------------------------------------
1 | [[scope]]
2 | == Scope
3 |
4 | This document is an extension to the GTA3script language. It provides the necessary changes to the translation (and part of the execution) environment to accomodate the details of the implementation used in 2001's GTA III.
5 |
6 | <> provides important context and specification for this extension. The sections of this document should be read as if merged to the original sections of <>.
7 |
--------------------------------------------------------------------------------
/dma/gta3/references.adoc:
--------------------------------------------------------------------------------
1 | [bibliography]
2 | [[references]]
3 | == References
4 |
5 | - [[[gta3script-core,GTA3script Specification]]] link:./core.html[GTA3script Core Specification].
6 | - [[[gta3script-config,GTA3script Configuration]]] https://github.com/GTAmodding/gta3script-config[GTA3script Configuration Files for Compilers and Disassemblers].
7 | - [[[gtamodswiki-opcodes,GTAMods Wiki]]] https://gtamods.com/wiki/List_of_opcodes[GTAMods Wiki -- List of opcodes].
8 | - [[[gtag-opcodes,GTAG Opcode Database]]] http://gtagmodding.com/opcode-database/[GTAG Modding -- Opcode Database].
9 |
--------------------------------------------------------------------------------
/dma/gta3/statements.adoc:
--------------------------------------------------------------------------------
1 | [[statements]]
2 | == Statements
3 |
4 | [[statement-scope]]
5 | === Scope Statements
6 |
7 | *Semantics*
8 |
9 | The activation of a lexical scope causes the declaration of two local variables of integer type named `TIMERA` and `TIMERB` which are timers counting up.
10 |
11 | [[statement-variable-declaration]]
12 | === Variable Declaration Statements
13 |
14 | Text label variables are not supported.
15 |
16 | Array variables are not supported.
17 |
18 | *Constraints*
19 |
20 | The name of a variable shall not be `TIMERA` nor `TIMERB`.
21 |
22 |
--------------------------------------------------------------------------------
/dma/gta3/elements.adoc:
--------------------------------------------------------------------------------
1 | [[elements]]
2 | == Elements
3 |
4 | [[element-command]]
5 | === Commands
6 |
7 | [[element-identifier]]
8 | ==== Identifiers
9 |
10 | As text label variables are not supported, the first character of an identifier shall not be a dollar.
11 |
12 | [[element-string-literal]]
13 | ==== String Literals
14 |
15 | String literals are not supported.
16 |
17 | [[element-variable-reference]]
18 | ==== Variable References
19 |
20 | As text label variables are not supported, the first character of a variable name shall not be a dollar.
21 |
22 | As array variables are not supported, subscripts are ill-formed.
23 |
24 |
--------------------------------------------------------------------------------
/dma/gta3/definitions.adoc:
--------------------------------------------------------------------------------
1 | [[definitions]]
2 | == Terms and Definitions
3 |
4 | For the purposes of this document, the terms and definitions given in <> and the following apply.
5 |
6 | mission:: TODO
7 |
8 | collectable:: TODO
9 | //_Collectables_ are pickups that provide the player a reward once certain amounts of them are picked up.
10 |
11 | progress points:: TODO
12 |
13 | timer:: TODO
14 | //These variables are automatically updated each time the script resumes execution by adding the time elapsed in seconds since the last automatic update.
15 |
16 | model:: TODO
17 |
18 | level model:: TODO
19 |
20 | text key:: TODO
21 |
22 |
--------------------------------------------------------------------------------
/dma/gta3/introduction.adoc:
--------------------------------------------------------------------------------
1 | [[introduction]]
2 | == Introduction
3 |
4 | Grand Theft Auto III was released in 2001 to great critical acclaim, becoming one of the most important titles of all time and changing the gaming landscape forever with its immersive open world sandbox.
5 |
6 | To support this open world, a scripting language was created in order to fasten development, reducing the complexities of programming languages for less-skilled personnel.
7 |
8 | This is an attempt to produce a formal language specification for this language. More specifically, this document is an extension to <>, providing details specific to the implementation of the language in GTA III.
9 |
10 |
--------------------------------------------------------------------------------
/dma/gta3/general.adoc:
--------------------------------------------------------------------------------
1 | [[general]]
2 | == General Principles
3 |
4 | [[conformance]]
5 | === Implementation Conformance
6 |
7 | Other extensions may expand and alter this document for the purpose of specifying other implementations, provided they still conform to <>.
8 |
9 | [[document-structure]]
10 | === Structure of this Document
11 |
12 | Section <> through <> provides changes to the sections of same name in <>.
13 |
14 | Section <> and <> describes the set of string constants and entity types necessary to support this implementation.
15 |
16 | Section <> provides the limits of this implementation.
17 |
--------------------------------------------------------------------------------
/tools/asciidoctor-python3.rb:
--------------------------------------------------------------------------------
1 | require 'asciidoctor'
2 | require 'asciidoctor/extensions'
3 | require 'open3'
4 |
5 | include Asciidoctor
6 |
7 | def python3_preprocessor(name)
8 | klass = Class.new(Asciidoctor::Extensions::Preprocessor) do
9 | class << self
10 | attr_accessor :script
11 | end
12 | def process document, reader
13 | script = self.class.script
14 | out, err, s = Open3.capture3("python3 #{script}", :stdin_data => reader.read)
15 | if not s.success?
16 | $stderr.puts(err)
17 | exit 1
18 | end
19 | return Reader.new out.split("\n")
20 | end
21 | end
22 | klass.script = File.join(File.dirname(__FILE__), name)
23 | return klass
24 | end
25 |
--------------------------------------------------------------------------------
/dma/index.adoc:
--------------------------------------------------------------------------------
1 |
2 | TODO creating packages and such are declarations too (not only var decls)
3 | TODO interesting NOP is not compiled
4 | TODO timera timerb (remember, only within scope; cannot declare var with same name; global shall not be named timera/timerb)
5 | TODO SAN ANDREAS ALLOWS IDENTIFIERS TO BEGIN WITH UNDERSCORES
6 | TODO translation limits
7 | LIMITS
8 | TODO gxtsema gxt key length <8
9 | TODO gxtsema filename (excluding extension must be) <16
10 | TODO label name \<=38
11 | TODO varname <40
12 | TODO scriptname \<=7
13 | TODO scriptnames \<= 300
14 | TODO \<=9216 gvar storage words
15 | TODO \<=16 lvars storage words
16 | TODO \<=255 array size
17 | TODO \<=35000 label refs
18 | TODO \<=255 line
19 | TODO \<=127 string
20 |
--------------------------------------------------------------------------------
/index.adoc:
--------------------------------------------------------------------------------
1 | = GTA3script Language Specifications
2 | :!sectnums:
3 | :nofooter:
4 | :idprefix:
5 | :idseparator: -
6 |
7 | Welcome to the home of specifications for the GTA3script scripting language.
8 |
9 | GTA3script is an imperative, strong and statically typed scripting language built by DMA Design (now Rockstar North) to design the mission scripts in Grand Theft Auto.
10 |
11 | This is a community effort to formalize the original language as well as document community extensions to it.
12 |
13 | [[language-specs]]
14 | == Language Specification
15 |
16 | * link:./core.html[GTA3script Core Specification] -- Defines the core language for all implementations.
17 | * link:./gta3.html[GTA3script extensions for GTA III] -- Extensions for the core language to support GTA III.
18 |
19 | [[community-specs]]
20 | == Community Extensions
21 |
22 | None.
23 |
24 |
--------------------------------------------------------------------------------
/core/introduction.adoc:
--------------------------------------------------------------------------------
1 | [[introduction]]
2 | == Introduction
3 |
4 | This is an attempt to produce a formal language specification for the GTA3script language.
5 |
6 | GTA3script is an imperative, strong and statically typed scripting language built by DMA Design (now Rockstar North) to design the mission scripts in Grand Theft Auto.
7 |
8 | The DMA Design compiler is very basic and contains a huge amount of bugs. These bugs introduce a lot of inconsistencies and quirks to the language. This document attempts to resolve these issues and set a coherent language.
9 |
10 | The language specified by this document is thus a subset of the language accepted by the in-house compiler. Any source code translated by an implementation of this should be able to be translated by the original compiler. The reverse is not true. A known list of differences is presented in <>.
11 |
--------------------------------------------------------------------------------
/dma/gta3/index.adoc:
--------------------------------------------------------------------------------
1 | = GTA3script extensions for GTA III
2 | :toc: macro
3 | :toc-title:
4 | :toclevels: 9
5 | :sectnums:
6 | //:revnumber: {release-version}
7 | :revdate: {localdate}
8 | :nofooter:
9 | :sectanchors:
10 | :idprefix:
11 | :idseparator: -
12 | :xrefstyle: short
13 | :!section-refsig:
14 |
15 |
16 | NOTE: This is a draft. It may be wrong, incomplete and subject to change.
17 |
18 | toc::[]
19 |
20 | // Introduction
21 |
22 | :!sectnums:
23 |
24 | include::introduction.adoc[]
25 |
26 | :sectnums:
27 |
28 | include::scope.adoc[]
29 |
30 | include::definitions.adoc[]
31 |
32 | include::general.adoc[]
33 |
34 | // Language
35 |
36 | include::elements.adoc[]
37 |
38 | include::parameters.adoc[]
39 |
40 | include::expressions.adoc[]
41 |
42 | include::statements.adoc[]
43 |
44 | // Supporting Commands
45 |
46 | include::command-def.adoc[]
47 |
48 | include::alternator-def.adoc[]
49 |
50 | include::string-constant-def.adoc[]
51 |
52 | include::entity-def.adoc[]
53 |
54 | // Implementation Limits
55 |
56 | include::limits.adoc[]
57 |
58 | // Appendix
59 |
60 | // References
61 |
62 | include::references.adoc[]
63 |
--------------------------------------------------------------------------------
/core/index.adoc:
--------------------------------------------------------------------------------
1 | = GTA3script Specification
2 | :toc: macro
3 | :toc-title:
4 | :toclevels: 9
5 | :sectnums:
6 | //:revnumber: {release-version}
7 | :revdate: {localdate}
8 | :nofooter:
9 | :sectanchors:
10 | :idprefix:
11 | :idseparator: -
12 | :xrefstyle: short
13 | :!section-refsig:
14 |
15 |
16 | NOTE: This is a draft. It may be wrong, incomplete and subject to change.
17 |
18 | toc::[]
19 |
20 | // Introduction
21 |
22 | :!sectnums:
23 |
24 | include::introduction.adoc[]
25 |
26 | :sectnums:
27 |
28 | include::scope.adoc[]
29 |
30 | include::definitions.adoc[]
31 |
32 | include::general.adoc[]
33 |
34 | // Language
35 |
36 | include::concepts.adoc[]
37 |
38 | include::elements.adoc[]
39 |
40 | include::parameters.adoc[]
41 |
42 | include::alternators.adoc[]
43 |
44 | include::expressions.adoc[]
45 |
46 | include::statements.adoc[]
47 |
48 | include::structure.adoc[]
49 |
50 | // Supporting Commands
51 |
52 | include::command-def.adoc[]
53 |
54 | include::alternator-def.adoc[]
55 |
56 | // Appendix
57 |
58 | include::appendix-grammar.adoc[]
59 |
60 | include::appendix-grammar-lex.adoc[]
61 |
62 | include::appendix-ambiguity.adoc[]
63 |
64 | include::appendix-complex-commands.adoc[]
65 |
66 | include::appendix-miss2.adoc[]
67 |
68 | // References
69 |
70 | include::references.adoc[]
71 |
--------------------------------------------------------------------------------
/core/references.adoc:
--------------------------------------------------------------------------------
1 | [bibliography]
2 | [[references]]
3 | == References
4 |
5 | - [[[itvocabulary,ISO/IEC 2382:2015]]] https://www.iso.org/standard/63598.html[Information technology -- Vocabulary].
6 | - [[[ebnf,ISO/IEC 14977:1996]]] https://www.iso.org/standard/26153.html[Information technology -- Syntactic metalanguage -- Extended BNF].
7 | - [[[ascii,ISO 646:1991 IRV]]] https://www.iso.org/standard/4777.html[Information technology -- ISO 7-bit coded character set for information interchange].
8 | - http://gtamp.com/GTA2/gta2script.7z[Official GTA2script Compiler V9.6] by DMA Design.
9 | - https://public.thelink2012.xyz/gta3/GTA2%20Scripting.html[Official GTA2script Scripting Information] by DMA Design.
10 | - https://www.dropbox.com/s/7xgvqo8b9u1qw02/gta3sc_v413.rar[Official GTA3 Script Compiler V413] by Rockstar North.
11 | - https://public.thelink2012.xyz/gta3/gta3_main_source.7z[GTA III 10th Anniversary Multiscripts Source Code] by Rockstar North, War Drum Studios.
12 | - http://pastebin.com/raw/Pjb0Ezkx[GTA3 Script Compiler V413 Strings] organized by Wesser.
13 | - https://www.dropbox.com/s/zkn59hrw7o76ry7/gta3vc_sc_defines.rar[GTA3 Script Compiler V413 Definitions] organized by Wesser.
14 | - https://pastebin.com/raw/2VczpwK7[GTASA Mobile Symbol Listing] organized by LINK/2012.
15 | - http://pastebin.com/raw/YfLWLXJw[Work-In-Progress SCM Language Article] by Wesser.
16 | - http://web.archive.org/web/20170111193059/http://www.gtamodding.com/wiki/GTA3script[Ancient SCM Language Article] by Wesser.
17 |
--------------------------------------------------------------------------------
/core/appendix-ambiguity.adoc:
--------------------------------------------------------------------------------
1 | [appendix]
2 | [[ambiguity]]
3 | == Ambiguity
4 |
5 | Not only the language, but the grammar presented in this document is ambiguous. Here are all the instances of ambiguity, which is the correct derivation, and suggestions to avoid users getting trapped in them.
6 |
7 | [discrete]
8 | [[ambiguity-if-goto]]
9 | === IF GOTO
10 |
11 | ----
12 | IF COMMAND goto other
13 | COMMAND goto other
14 | ----
15 |
16 | The first line could mean an command, taking two arguments, `goto` and `other`. Or, it could mean that if the command returns true, a jump should be performed into the `other` label. The correct interpretation is the latter.
17 |
18 | The second line is unambiguous due to context.
19 |
20 | We suggest an implementation to emit an warnings to declarations of names and the use of text labels equal to `goto`.
21 |
22 | [discrete]
23 | [[ambiguity-minus-one]]
24 | === Ternary Minus One
25 |
26 | ----
27 | x = 1-1
28 | x = 1 -1
29 | x = 1 - 1
30 | x = 1--1
31 | x = 1- -1
32 | ----
33 |
34 | The first line could mean `1` minus `1`, or it could mean `1` and then the number `-1`. The latter is the correct interpretation. And yes, it is a syntax error.
35 |
36 | The second line has the same ambiguity and its interpretation should be the same as the first line.
37 |
38 | The third line is not ambiguous.
39 |
40 | The fourth line is ambiguous. Its actual meaning is `1` followed by the unary operator `--` and it is a syntax error.
41 |
42 | The fifth line is not ambiguous.
43 |
44 | The token stream produced by the regular lexical grammar in <> should solve this issue naturally.
45 |
46 |
--------------------------------------------------------------------------------
/core/alternators.adoc:
--------------------------------------------------------------------------------
1 | [[alternators]]
2 | == Command Selectors
3 |
4 | A _command selector_ (or _alternator_) is a kind of command which gets rewritten by the translator to another command based on the supplied argument types.
5 |
6 | A command selector consists of a name and a finite sequence of commands which are alternatives for replacement.
7 |
8 | An actual command named after a selector shall behave as if its command name is rewritten as a matching alternative before any parameter checking takes place.
9 |
10 | A _matching alternative_ is the first command in the alternative sequence to have the same amount of parameters as arguments in the actual command, and to obey the following rules for every argument and its corresponding parameter:
11 |
12 | * An integer literal argument must have a parameter of type INT.
13 | * A floating-point literal argument must have a parameter of type FLOAT.
14 | * For identifiers, the following applies (in the given order):
15 | .. If the identifier matches a global string constant, the parameter type must be INT and the argument shall behave as if rewritten as an integer literal corresponding to the string constant value.
16 | .. If the identifier references a global variable, the parameter type must be either (depending on the type of the said variable) VAR_INT, VAR_FLOAT or VAR_TEXT_LABEL.
17 | .. If the identifier references a local variable, the same rule as above applies, except by using LVAR_INT, LVAR_FLOAT and LVAR_TEXT_LABEL.
18 | .. If the identifier matches any string constant in any enumeration (except the global enumeration), the parameter type must be INPUT_INT and the argument shall behave as if rewritten as an integer literal corresponding to the string constant value.
19 | .. Otherwise, the parameter type must be TEXT_LABEL.
20 |
21 | If no matching alternative is found, the program is ill-formed.
22 |
--------------------------------------------------------------------------------
/core/structure.adoc:
--------------------------------------------------------------------------------
1 | [[structure]]
2 | == Script File Structure
3 |
4 | [[structure-main]]
5 | === Main Script Files
6 |
7 | ----
8 | main_script_file := {statement} ;
9 | ----
10 |
11 | A main script file is a sequence of zero or more statements.
12 |
13 | *Constraints*
14 |
15 | Commands in the main script file shall not refer to labels in mission script files.
16 |
17 | *Semantics*
18 |
19 | The main script starts execution at the first statement of the main script file. If there is no statement to be executed, behaviour is undefined.
20 |
21 | [[structure-main-extension]]
22 | === Main Extension Files
23 |
24 | ----
25 | main_extension_file := {statement} ;
26 | ----
27 |
28 | A main extension file is a sequence of zero or more statements.
29 |
30 | *Constraints*
31 |
32 | Commands in main extension files shall not refer to labels in mission script files.
33 |
34 | [[structure-subscript]]
35 | === Subscript Files
36 |
37 | ----
38 | subscript_file := 'MISSION_START' eol
39 | {statement}
40 | [label_prefix] 'MISSION_END' eol
41 | {statement} ;
42 | ----
43 |
44 | A subscript file is a sequence of zero or more statements within a `MISSION_START`...`MISSION_END` block. More statements can follow.
45 |
46 | *Constraints*
47 |
48 | The `MISSION_START` command shall be the very first line of the subscript file and shall not be preceded by anything but ASCII spaces (`` ``) and horizontal tabs (``\t``). Comments instead of whitespaces are disallowed.
49 |
50 | Commands in subscript files shall not refer to labels in mission script files.
51 |
52 | *Semantics*
53 |
54 | The `MISSION_END` command behaves as if by executing the `TERMINATE_THIS_SCRIPT` command.
55 |
56 | [[structure-mission]]
57 | === Mission Script Files
58 |
59 | ----
60 | mission_script_file := subscript_file ;
61 | ----
62 |
63 | A mission script file has the same structure as of a subscript file.
64 |
65 | *Constraints*
66 |
67 | Commands in mission script files shall not refer to labels in mission script files other than itself.
68 |
--------------------------------------------------------------------------------
/dma/gta3/alternator-def.adoc:
--------------------------------------------------------------------------------
1 | [[alternator-def]]
2 | == Supporting Command Selectors
3 |
4 | The following rectifies a few command selectors specified in <> to eliminate unsupported alternatives from the selection set.
5 |
6 | [[alternator-def-set]]
7 | === SET
8 |
9 | The following alternatives are not supported and thus removed:
10 |
11 | SET_VAR_INT_TO_CONSTANT VAR_INT INPUT_INT
12 | SET_LVAR_INT_TO_CONSTANT VAR_INT INPUT_INT
13 | SET_VAR_TEXT_LABEL VAR_TEXT_LABEL TEXT_LABEL
14 | SET_LVAR_TEXT_LABEL LVAR_TEXT_LABEL TEXT_LABEL
15 |
16 | [[alternator-def-is-thing-equal-to-thing]]
17 | === IS_THING_EQUAL_TO_THING
18 |
19 | The following alternatives are not supported and thus removed{blank}footnote:[This list is not wrong. Commands to compare local variables (left-hand side) to global variables (right-hand side) are not available in GTA III nor Vice City.]:
20 |
21 | IS_INT_VAR_EQUAL_TO_CONSTANT VAR_INT INPUT_INT
22 | IS_INT_LVAR_EQUAL_TO_CONSTANT LVAR_INT INPUT_INT
23 | IS_VAR_TEXT_LABEL_EQUAL_TO_TEXT_LABEL VAR_TEXT_LABEL TEXT_LABEL
24 | IS_LVAR_TEXT_LABEL_EQUAL_TO_TEXT_LABEL LVAR_TEXT_LABEL TEXT_LABEL
25 | IS_INT_LVAR_EQUAL_TO_INT_VAR LVAR_INT VAR_INT
26 | IS_FLOAT_LVAR_EQUAL_TO_FLOAT_VAR LVAR_FLOAT VAR_FLOAT
27 |
28 | [[alternator-def-is-thing-greater-than-thing]]
29 | === IS_THING_GREATER_THAN_THING
30 |
31 | The following alternatives are not supported and thus removed:
32 |
33 | IS_INT_VAR_GREATER_THAN_CONSTANT VAR_INT INPUT_INT
34 | IS_INT_LVAR_GREATER_THAN_CONSTANT LVAR_INT INPUT_INT
35 | IS_CONSTANT_GREATER_THAN_INT_VAR INPUT_INT VAR_INT
36 | IS_CONSTANT_GREATER_THAN_INT_LVAR INPUT_INT LVAR_INT
37 |
38 | [[alternator-def-is-thing-greater-or-equal-to-thing]]
39 | === IS_THING_GREATER_OR_EQUAL_TO_THING
40 |
41 | The following alternatives are not supported and thus removed:
42 |
43 | IS_INT_VAR_GREATER_OR_EQUAL_TO_CONSTANT VAR_INT INPUT_INT
44 | IS_INT_LVAR_GREATER_OR_EQUAL_TO_CONSTANT LVAR_INT INPUT_INT
45 | IS_CONSTANT_GREATER_OR_EQUAL_TO_INT_VAR INPUT_INT VAR_INT
46 | IS_CONSTANT_GREATER_OR_EQUAL_TO_INT_LVAR INPUT_INT LVAR_INT
47 |
48 |
--------------------------------------------------------------------------------
/dma/gta3/parameters.adoc:
--------------------------------------------------------------------------------
1 | [[parameters]]
2 | == Parameters
3 |
4 | [[string-constants]]
5 | === String Constants
6 |
7 | There exists an enumeration called the _default models enumeration_.footnote:[This enumeration behaves like any other enumeration. It is defined here such that section <> can refer to it.]
8 |
9 | [[parameter-used-objects]]
10 | === Used Objects
11 |
12 | An _object string constant_ is a string constant matching any string constant in the default models enumeration or any level model name (in this order).footnote:[Although it may seem like object string constants form an enumeration, they don't. Semantics are sighly different. Two examples come to mind: Variables can have the same name as level models and alternators do not take object string constants into account. All of this is unlike the in-house compiler we have, but is in accordance to what is seen in the GTA III 10th Anniversary scripts (e.g. variable and used object named `playersdoor`) as well as what is seen in GTA San Andreas to support assignment of level models to variables (i.e. not through `SET_VAR_INT_TO_CONSTANT` but `SET_VAR_INT` -- but this is an history for the GTA3script extensions for GTA San Andreas).]
13 |
14 | A parameter definition can be associated with object string constants. Further semantics for this association are defined along this specification.
15 |
16 | Any object string constant used in the multi-file is called an _used object_.
17 |
18 | [[parameter-types]]
19 | === Parameter Types
20 |
21 | [[parameter-type-input-int]]
22 | ==== INPUT_INT
23 |
24 | If the parameter is associated with object string constants, it should behave as if the parameter was associated with an enumeration containing the object string constants.
25 |
26 | [[parameter-type-var-text-label]]
27 | ==== VAR_TEXT_LABEL
28 |
29 | As text label variables are not supported, this parameter type is not supported.
30 |
31 | [[parameter-type-lvar-text-label]]
32 | ==== LVAR_TEXT_LABEL
33 |
34 | As text label variables are not supported, this parameter type is not supported.
35 |
36 | [[parameter-type-string]]
37 | ==== STRING
38 |
39 | As string literals are not supported, this parameter type is not supported.
40 |
41 | [[parameter-type-optional]]
42 | ==== Optional Parameters
43 |
44 | As text label variables are not supported, the VAR_TEXT_LABEL_OPT and LVAR_TEXT_LABEL_OPT parameter types are not supported.
45 |
--------------------------------------------------------------------------------
/core/appendix-grammar-lex.adoc:
--------------------------------------------------------------------------------
1 | [appendix]
2 | [[grammar-lex]]
3 | == Regular Lexical Grammar
4 |
5 | ----
6 | # A Regular Lexical Grammar for GTA3script (informative)
7 | sep := sep ;
8 | eol := eol ;
9 | token := token_char {token_char}
10 | | '-' (digit | '.') {token_char} ;
11 | string_literal := string_literal ;
12 | plus := '+' ;
13 | minus := '-' ;
14 | star := '*' ;
15 | slash := '/' ;
16 | plus_at := '+@' ;
17 | minus_at := '-@' ;
18 | equal := '=' ;
19 | equal_hash := '=#' ;
20 | plus_equal := '+=' ;
21 | minus_equal := '-=' ;
22 | star_equal := '*=' ;
23 | slash_equal := '/=' ;
24 | plus_equal_at := '+=@' ;
25 | minus_equal_at := '-=@' ;
26 | minus_minus := '--' ;
27 | plus_plus := '++' ;
28 | ----
29 |
30 | There are only operators, separators, unclassified tokens, and string literals.
31 |
32 | Each unclassified token requires parsing context in order to be classified.
33 |
34 | Comments are excluded from this grammar because nested block comments are context-free.
35 |
36 | This regular grammar is not capable of handling the complete set of words generated by `filename`. For instance, `file-name.sc` would not be interpreted properly. A translator should be careful to handle this case properly.
37 |
38 | The following are examples of context dependency for token classification:
39 |
40 | ----
41 | // for the sake of simplicity separation tokens are omitted.
42 |
43 | WORD: WORD: // label(WORD:) command(WORD:)
44 |
45 | WORD WORD // command(WORD) identifier(WORD)
46 |
47 | 1234 1234 // command(1234) integer(1234)
48 |
49 | X = Y // identifier(X) '=' identifier(Y)
50 | X Y // command(X) identifier(Y)
51 |
52 | X -- // identifier(X) '--'
53 | X -1 // command(X) integer(-1)
54 |
55 | LAUNCH_MISSION a.sc // command(LAUNCH_MISSION) filename(a.sc)
56 | OTHER_COMMAND a.sc // command(OTHER_COMMAND) identifier(a.sc)
57 | // NOTE: filename is not an identifier because, for instance,
58 | // filename(4x4.sc) cannot be classified as an identifier.
59 |
60 | OR // command(OR)
61 | NOT // command(NOT)
62 | IF SOMETHING //
63 | OR OR // 'OR' command(OR)
64 | OR NOT NOT // 'OR' 'NOT' command(NOT)
65 | NOP //
66 | ENDIF //
67 |
68 | // NOTE: that is a defect actually, see following example:
69 | IF SOMETHING
70 | AND var // 'AND' command(var) -- not what we want
71 | // same problem for OR.
72 | // NOT is affected by IF NOT var.
73 | ENDIF
74 | ----
75 |
76 |
--------------------------------------------------------------------------------
/core/definitions.adoc:
--------------------------------------------------------------------------------
1 | [[definitions]]
2 | == Terms and Definitions
3 |
4 | For the purposes of this document, the terms and definitions given in <> and the following apply.
5 |
6 | Terms that are used only in a small portion of this document are defined where they are used and italicized where they are defined.
7 |
8 | Because of the lack of information about the original language, some terms in this document are community defined.
9 |
10 | behaviour:: external appearance or action.
11 |
12 | behaviour, implementation-defined:: behavior specific to an implementation, where that implementation must document that behavior.
13 |
14 | behaviour, undefined:: behavior which is not guaranteed to produce any specific result.
15 |
16 | behaviour, unspecified:: behavior for which this specification provides two or more possibilities and imposes no further requirements on which is chosen in any instance.
17 |
18 | constraint:: restriction, either syntactic or semantic, on how language elements can be used.
19 |
20 | must:: describes an absolute requirement. synonymous with *shall*.
21 |
22 | must not:: describes an absolute prohibition. synonymous with *shall not*.
23 |
24 | should:: describes a recommended but not absolutely necessary requirement.
25 |
26 | should not:: describes an unrecommended but not absolutely prohibited requirement.
27 |
28 | may:: describes an optional requirement.
29 |
30 | execution environment:: the software on which the result of translation is executed on.
31 |
32 | translation environment:: the software on which the language is translated for use by an execution environment.
33 |
34 | implementation:: particular set of software, running in a particular translation environment under particular control options, that performs translation of programs for, and supports execution of commands in, a particular execution environment.
35 |
36 | well-formed program:: program constructed according to the synctatic and semantic rules as defined by this specification.
37 |
38 | ill-formed program:: program that is not well-formed.
39 |
40 | value:: precise meaning of the contents of a name when interpreted as having a specific type.
41 |
42 | argument:: a value passed to a command that is intended to map to a corresponding parameter.
43 |
44 | parameter:: the value to be received in a specific argument of a command.
45 |
46 | in-house compiler:: the translation environment used by DMA Design. this document refers more specifically to <>.
47 |
48 |
--------------------------------------------------------------------------------
/tools/asciidoctor-grammar-preprocessor.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 | """
3 | This script preprocesses an Asciidoc document, gathering all grammar
4 | productions and dumping it into a `AUTO_REPLACE_WITH_GRAMMAR` section.
5 | """
6 | import sys
7 |
8 | class GrammarPreprocessor:
9 | def __init__(self, reader, writer):
10 | self.reader = reader
11 | self.writer = writer
12 |
13 | @staticmethod
14 | def emit_error(block, error):
15 | print('invalid grammar block: ' + error, file=sys.stderr)
16 | print(block, file=sys.stderr)
17 | sys.exit(1)
18 |
19 | @staticmethod
20 | def is_grammar_block(block):
21 | first_line = block.split('\n', 1)[0]
22 | if first_line.startswith('#') and 'informative' in first_line:
23 | return False
24 | return ':=' in block
25 |
26 | def validate_grammar(self, block):
27 | expect_semicolon = False
28 | for i in range(len(block)):
29 | if block[i] == ':' and i+1 != len(block) and block[i+1] == '=':
30 | if expect_semicolon:
31 | return self.emit_error(block, 'missing semicolon')
32 | expect_semicolon = True
33 | if block[i] == ';':
34 | if not expect_semicolon:
35 | return self.emit_error(block, 'unexpected semicolon')
36 | expect_semicolon = False
37 | if expect_semicolon:
38 | return self.emit_error(block, 'missing semicolon')
39 |
40 | def read_block(self):
41 | lines = []
42 | for line in self.reader:
43 | self.writer.write(line)
44 | if line.startswith('---'):
45 | break
46 | lines.append(line)
47 | return ''.join(lines)
48 |
49 | def process(self):
50 | grammar = []
51 | for line in self.reader:
52 | if line.startswith('AUTO_REPLACE_WITH_GRAMMAR'):
53 | self.writer.write('----\n')
54 | self.writer.write('# The GTA3script Grammar (informative)\n\n')
55 | self.writer.write('\n'.join(grammar))
56 | self.writer.write('----\n')
57 | continue
58 | self.writer.write(line)
59 | if line.startswith('---'):
60 | block = self.read_block()
61 | if self.is_grammar_block(block):
62 | self.validate_grammar(block)
63 | grammar.append(block)
64 |
65 |
66 | if __name__ == '__main__':
67 | pp = GrammarPreprocessor(sys.stdin, sys.stdout)
68 | pp.process()
69 |
--------------------------------------------------------------------------------
/docinfo.html:
--------------------------------------------------------------------------------
1 |
2 |
40 |
51 |
52 |
53 |
--------------------------------------------------------------------------------
/core/general.adoc:
--------------------------------------------------------------------------------
1 | [[general]]
2 | == General Principles
3 |
4 | // TODO provide the syntax for defining commands, alternators, string constants and entity types.
5 |
6 | [[conformance]]
7 | === Implementation Conformance
8 |
9 | A conforming implementation must be able to translate and correctly execute, within its resource limits, any program which does not violate the rules in this document.
10 |
11 | A conforming implementation must produce diagnostics for violations of the syntactic and semantic rules of this document except for those resulting in undefined behaviour.
12 |
13 | A conforming implementation must document the choices made to implementation-defined portions of this specification as well as to unsupported optional features.
14 |
15 | A conforming implementation may have extensions, provided they do not alter the behaviour of any well-formed program.
16 |
17 | This specification does not impose any lower or upper bound restrictions on the resource limits of an implementation. An implementation should have reasonable limits given its problem domain, and should document them where known.
18 |
19 | [[document-structure]]
20 | === Structure of this Document
21 |
22 | Section <> through <> describes the GTA3script programming language. That description includes detailed syntactic specifications in a form detailed in <>. For convenience, <> repeats all such syntactic specifications.
23 |
24 | Sections <> and <> describes a minimal set of commands to perform computations using the language.
25 |
26 | <> describes a regular grammar suitable for scanning the language.
27 |
28 | <> describes ambiguities present in the language grammar and resolutions for them.
29 |
30 | <> lists commands that cannot happen outside of their very specific syntactical context.
31 |
32 | <> describes problematic elements in the in-house compiler that this specification choose not to follow.
33 |
34 | Along this document there are several footnotes explaining or clarifying some decisions. Often these footnotes exposes the reason for changes in the language compared to the in-house compiler. These footnotes are purely informative and are not an integral part of this document.
35 |
36 | Some changes demand more details than a footnote permits. These are marked with the footnote footnote:miss2[For consistency we have simplified this feature. Please refer to <> for details on how the in-house compiler behaves.] and further details are presented in <>.
37 |
38 | [[syntax-notation]]
39 | === Syntax Notation
40 |
41 | The syntax in this document is specified using a variation of <> (also known as _EBNF_). This variant can be self-described as follow:
42 |
43 | ----
44 | # EBNF Grammar Used In This Specification (informative)
45 |
46 | letter := 'A'..'Z' | 'a'..'z' ;
47 | digit := '0'..'9' ;
48 | character := /* printable ASCII characters */ ;
49 | identifier := letter { letter | digit | '_' } ;
50 | terminal := "'" character { character } "'"
51 | | '"' character { character } '"' ;
52 |
53 | syntax := { production } ;
54 | production := identifier ':=' [ expression ] ';' ;
55 | expression := alternative { '|' alternative } ;
56 | alternative := term { term } ;
57 | term := factor { '-' factor } ;
58 | factor := identifier | terminal [ '..' terminal ] | group | option | repetition ;
59 | group := '(' expression ')' ;
60 | option := '[' expression ']' ;
61 | repetition := '{' expression '}' ;
62 | ----
63 |
64 | The double-dot operator is an extension to EBNF. It represents the set of characters from the left to the right inclusive as alternatives.
65 |
66 | A syntax specification might refer to symbols in <> (also known as _ASCII_) through comments, avoiding the alternation of a set of well known characters.
67 |
68 |
--------------------------------------------------------------------------------
/dma/gta3/command-def.adoc:
--------------------------------------------------------------------------------
1 | [[command-def]]
2 | == Supporting Commands
3 |
4 | The GTA III implementation of the language provides an extensive list of commands to interact with the game engine. It is not of the intent of this specification to document these commands. This is left as a task for other projects in the modding community. Please see <>, <> and <> for some of these efforts.
5 |
6 | Nevertheless, there are commands that require additional support from the translation environment. These commands are specified below.
7 |
8 | [[command-def-start-new-script]]
9 | === START_NEW_SCRIPT
10 |
11 | The definition present in <> remains with the following rectification in the constraints of the command.
12 |
13 | *Constraints*
14 |
15 | The specified label location must be within a scope. Such scope can begin at the next non-empty embedded statement relative to the label location.
16 |
17 | [[command-def-player-made-progress]]
18 | === PLAYER_MADE_PROGRESS
19 |
20 | *Parameters*
21 |
22 | ----
23 | PLAYER_MADE_PROGRESS INT
24 | ----
25 |
26 | *Side effects*
27 |
28 | Adds the given amount of progress points to the game.
29 |
30 | [[command-def-set-progress-total]]
31 | === SET_PROGRESS_TOTAL
32 |
33 | *Parameters*
34 |
35 | ----
36 | SET_PROGRESS_TOTAL INT
37 | ----
38 |
39 | *Side effects*
40 |
41 | Sets the total amount of progress points that can be archieved in the game.
42 |
43 | *Constraints*
44 |
45 | The translation environment must enforce the following constraints.
46 |
47 | There shall be only a single occurrence of this command in the multi-file.
48 |
49 | The given integer value shall be equal zero. The argument must be rewritten to correspond to the sum of the arguments to all instances of <> in the multi-file.
50 |
51 | [[command-def-register-mission-passed]]
52 | === REGISTER_MISSION_PASSED
53 |
54 | *Parameters*
55 |
56 | ----
57 | REGISTER_MISSION_PASSED TEXT_LABEL
58 | ----
59 |
60 | *Side effects*
61 |
62 | Registers that the mission associated with the given text key has been passed.
63 |
64 | [[command-def-set-total-number-of-missions]]
65 | === SET_TOTAL_NUMBER_OF_MISSIONS
66 |
67 | *Parameters*
68 |
69 | ----
70 | SET_TOTAL_NUMBER_OF_MISSIONS INPUT_INT
71 | ----
72 |
73 | *Side effects*
74 |
75 | Sets the total number of missions present in the game.
76 |
77 | *Constraints*
78 |
79 | The translation environment must enforce the following constraints.
80 |
81 | There shall be only a single occurrence of this command in the multi-file.
82 |
83 | The argument must not be a variable and shall evaluate to an interger value equal zero. The argument must be rewritten to correspond to the number of times the command <> occurs in the multi-file.
84 |
85 | [[command-def-create-collectable1]]
86 | === CREATE_COLLECTABLE1
87 |
88 | *Parameters*
89 |
90 | ----
91 | CREATE_COLLECTABLE1 INPUT_FLOAT INPUT_FLOAT INPUT_FLOAT
92 | ----
93 |
94 | *Side effects*
95 |
96 | Creates a collectable at the specified X, Y and Z coordinates respectively.
97 |
98 | If the given Z coordinate is equal `-100.0`, the collectable is created at the ground of the given X, Y coordinates.
99 |
100 | [[command-def-set-collectable1-total]]
101 | === SET_COLLECTABLE1_TOTAL
102 |
103 | *Parameters*
104 |
105 | ----
106 | SET_COLLECTABLE1_TOTAL INPUT_INT
107 | ----
108 |
109 | *Side effects*
110 |
111 | Sets the total number of collectables in the game.
112 |
113 | *Constraints*
114 |
115 | The translation environment must enforce the following constraints.
116 |
117 | There shall be only a single occurrence of this command in the multi-file.
118 |
119 | The argument must not be a variable and shall evaluate to an interger value equal zero. The argument must be rewritten to correspond to the number of times the command <> occurs in the multi-file.
120 |
121 |
--------------------------------------------------------------------------------
/core/expressions.adoc:
--------------------------------------------------------------------------------
1 | [[expressions]]
2 | == Expressions
3 |
4 | *Constraints*
5 |
6 | An argument in an expression cannot be a string literal.
7 |
8 | The name of commands used to require script files (e.g. `GOSUB_FILE`) and its directive commands (i.e. `MISSION_START` and `MISSION_END`) cannot be on the left hand side of an expression.
9 |
10 | [[assignment-expressions]]
11 | === Assignment Expressions
12 |
13 | ----
14 | binop := '+' | '-' | '*' | '/' | '+@' | '-@' ;
15 | asop := '=' | '=#' | '+=' | '-=' | '*=' | '/=' | '+=@' | '-=@' ;
16 | unop := '--' | '++' ;
17 |
18 | expr_assign_abs := identifier {whitespace} '=' {whitespace} 'ABS' {whitespace} argument ;
19 | expr_assign_binary := identifier {whitespace} asop {whitespace} argument ;
20 | expr_assign_ternary := identifier {whitespace} '=' {whitespace} argument {whitespace} binop {whitespace} argument ;
21 | expr_assign_unary := (unop {whitespace} identifier)
22 | | (identifier {whitespace} unop) ;
23 |
24 | assignment_expression := expr_assign_unary
25 | | expr_assign_binary
26 | | expr_assign_ternary
27 | | expr_assign_abs ;
28 | ----
29 |
30 | The unary assignments `pass:c[++a]` and `pass:c[a++]` behaves as if `ADD_THING_TO_THING a 1` is executed.
31 |
32 | The unary assignments `--a` and `a--` behaves as if `SUB_THING_FROM_THING a 1` is executed.
33 |
34 | The binary assignment expressions behaves as if the following is executed:
35 |
36 | |===
37 | | Expression | Behaves As If
38 |
39 | | `a = b`
40 | | `SET a b`
41 |
42 | | `a =# b`
43 | | `CSET a b`
44 |
45 | | `a += b`
46 | | `ADD_THING_TO_THING a b`
47 |
48 | | `a -= b`
49 | | `SUB_THING_FROM_THING a b`
50 |
51 | | `a *= b`
52 | | `MULT_THING_BY_THING a b`
53 |
54 | | `a /= b`
55 | | `DIV_THING_BY_THING a b`
56 |
57 | | `a +=@ b`
58 | | `ADD_THING_TO_THING_TIMED a b`
59 |
60 | | `a -=@ b`
61 | | `SUB_THING_FROM_THING_TIMED a b`
62 | |===
63 |
64 | The absolute assignment `a = ABS b` behaves as if the following is executed:
65 |
66 | * `ABS a` if the name `a` is the same as the name `b`.
67 | * `SET a b` followed by `ABS a` otherwise.
68 |
69 | The ternary assignment `a = b + c` behaves as if the following is executed:
70 |
71 | * `ADD_THING_TO_THING a c` if the name `a` is the same as the name `b`.
72 | * `ADD_THING_TO_THING a b` if the name `a` is the same as the name `c`.
73 | * `SET a b` followed by `ADD_THING_TO_THING a c` otherwise.
74 |
75 | The ternary assignment `a = b - c` behaves as if the following is executed:
76 |
77 | * `SUB_THING_FROM_THING a c` if the name `a` is the same as the name `b`.
78 | * Implementation-defined if `a` is the same name as `c`.footnote:[The in-house compiler uses unsupported command selectors (`NEGATE` for substraction and `ONEOVER` for division) to perform this operation.]
79 | * `SET a b` followed by `SUB_THING_BY_THING a c` otherwise.
80 |
81 | The ternary assignment `a = b * c` behaves as if `a = b + c`, except by using `MULT_THING_BY_THING` instead of `ADD_THING_TO_THING`.
82 |
83 | The ternary assignment `a = b / c` behaves as if `a = b - c`, except by using `DIV_THING_BY_THING` instead of `SUB_THING_FROM_THING`.
84 |
85 | The ternary assignments `a = b +@ c` and `a = b -@ c` behaves as if `a = b - c`, except by using `ADD_THING_TO_THING_TIMED` and `SUB_THING_FROM_THING_TIMED`, respectively, instead of `SUB_THING_FROM_THING`.
86 |
87 | [[conditional-expressions]]
88 | === Conditional Expressions
89 |
90 | ----
91 | relop := '=' | '<' | '>' | '>=' | '<=' ;
92 | conditional_expression := argument {whitespace} relop {whitespace} argument ;
93 | ----
94 |
95 | These expressions behave as if the following is executed:
96 |
97 | |===
98 | | Expression | Behaves As If
99 |
100 | | `a = b`
101 | | `IS_THING_EQUAL_TO_THING a b`
102 |
103 | | `a > b`
104 | | `IS_THING_GREATER_THAN_THING a b`
105 |
106 | | `a >= b`
107 | | `IS_THING_GREATER_OR_EQUAL_TO_THING a b`
108 |
109 | | `a < b`
110 | | `IS_THING_GREATER_THAN_THING b a`
111 |
112 | | `+a <= b+`
113 | | `IS_THING_GREATER_OR_EQUAL_TO_THING b a`
114 | |===
115 |
--------------------------------------------------------------------------------
/core/command-def.adoc:
--------------------------------------------------------------------------------
1 | [[command-def]]
2 | == Supporting Commands
3 |
4 | In order to perform useful computation the following supporting commands may be available.
5 |
6 | [[command-def-wait]]
7 | === WAIT
8 |
9 | *Parameters*
10 |
11 | ----
12 | WAIT INPUT_INT
13 | ----
14 |
15 | *Side effects*
16 |
17 | Yields control to another script. The current script is not resumed for at least the specified number of milliseconds.
18 |
19 | [[command-def-goto]]
20 | === GOTO
21 |
22 | *Parameters*
23 |
24 | ----
25 | GOTO LABEL
26 | ----
27 |
28 | *Side effects*
29 |
30 | Performs a jump to the specified location.
31 |
32 | [[command-def-gosub]]
33 | === GOSUB
34 |
35 | *Parameters*
36 |
37 | ----
38 | GOSUB LABEL
39 | ----
40 |
41 | *Side effects*
42 |
43 | Calls the subroutine in the specified location.
44 |
45 | [[command-def-return]]
46 | === RETURN
47 |
48 | *Parameters*
49 |
50 | ----
51 | RETURN
52 | ----
53 |
54 | *Side effects*
55 |
56 | Returns from the last called subroutine.
57 |
58 | The behaviour is undefined if there is no active subroutine.
59 |
60 | [[command-def-return-true]]
61 | === RETURN_TRUE
62 |
63 | *Parameters*
64 |
65 | ----
66 | RETURN_TRUE
67 | ----
68 |
69 | *Side effects*
70 |
71 | Returns true (as in any command updating the compare flag to true).
72 |
73 | [[command-def-return-false]]
74 | === RETURN_FALSE
75 |
76 | *Parameters*
77 |
78 | ----
79 | RETURN_FALSE
80 | ----
81 |
82 | *Side effects*
83 |
84 | Returns false (as in any command updating the compare flag to false).
85 |
86 | [[command-def-script-name]]
87 | === SCRIPT_NAME
88 |
89 | *Parameters*
90 |
91 | ----
92 | SCRIPT_NAME TEXT_LABEL
93 | ----
94 |
95 | *Side effects*
96 |
97 | Associates a name to the executing script.
98 |
99 | *Constraints*
100 |
101 | The translation environment must enforce the following constraints.
102 |
103 | The name of a script must be unique across the multi-file.
104 |
105 | It is unspecified whether a name given by a text label variable is accepted.footnote:[The in-house compiler does not handle the case of text label variables in `SCRIPT_NAME`, but this does not tell much because it barely supports any text label variable feature. No compiled multi-file contains script names assigned by a variable. Thus, we refrain from defining any semantics for this case.]
106 |
107 | [[command-def-terminate-this-script]]
108 | === TERMINATE_THIS_SCRIPT
109 |
110 | *Parameters*
111 |
112 | ----
113 | TERMINATE_THIS_SCRIPT
114 | ----
115 |
116 | *Side effects*
117 |
118 | Terminates the executing script.
119 |
120 | [[command-def-start-new-script]]
121 | === START_NEW_SCRIPT
122 |
123 | *Parameters*
124 |
125 | ----
126 | START_NEW_SCRIPT LABEL INPUT_OPT...
127 | ----
128 |
129 | *Side effects*
130 |
131 | Creates a script and sets its program counter to the specified label location.
132 |
133 | The first few local variables at the scope of the target label are assigned the values of the optional input arguments. That is, the first declared local variable is set to the first optional argument, the second variable to the second optional argument, and so on.
134 |
135 | *Constraints*
136 |
137 | The translation environment must enforce the following constraints.
138 |
139 | The specified label location must be within a scope. Such scope may begin at the next non-empty embedded statement relative to the label location.footnote:[For GTA III 10th Anniversary multi-files, all target scopes are a line after its target label, which would emit an error in the in-house compiler (for GTA Vice City).]
140 |
141 | The type of a local variable and its respective input argument must match. For instance, if an input argument is an integer literal or variable of integer type, its corresponding local variable in the target scope must be of integer type.
142 |
143 | If there are not enough local variables in the target scope to accomodate the input arguments the program is ill-formed.
144 |
145 | If an input argument is a variable, the value assignment to the variable in the target scope shall obey the same constraints as specified for `SET` (<>).
146 |
--------------------------------------------------------------------------------
/core/concepts.adoc:
--------------------------------------------------------------------------------
1 | [[concepts]]
2 | == Concepts
3 |
4 | [[concept-scripts]]
5 | === Scripts
6 |
7 | A _script_ is a unit of execution which contains its own program counter, local variables and compare flag.
8 |
9 | A _program_ is a collection of scripts running concurrently in a cooperative fashion.
10 |
11 | A _variable_ is a named storage location. This location holds a value of specific type.
12 |
13 | There are global and local variables. _Global variables_ are stored in a way they are accessible from any script. _Local variables_ pertain to its particular script and is only accessible from it.
14 |
15 | The lifetime of a global variable is the same as of the execution of all scripts. The lifetime of a local variable is the same as its script and lexical scope.
16 |
17 | A _command_ is an operation to be performed by a script. Commands produce side effects which are described by their command description.
18 |
19 | A possible side effect of executing a command is the updating of the compare flag. The _compare flag_ of a command is the boolean result it produces. The _compare flag of a script_ is the compare flag of its last executed command.
20 |
21 | The _program counter_ of a script indicates its currently executing command. Unless one of the side effects of a command is to change the program counter, the counter goes from the current command to the next sequentially. An explicit change in the program counter is said to be a change in the flow of control.
22 |
23 | A command is said to perform a _jump_ if it changes the flow of control irreversibly.
24 |
25 | A command is said to call a _subroutine_ if it changes the flow of control but saves the current program counter in a stack to be restored later.
26 |
27 | A command is said to _terminate_ a script if it halts and reclaims storage of such a script.
28 |
29 | [[concept-script-files]]
30 | === Script Files
31 |
32 | A _script file_ is a source file containing a sequence of commands.
33 |
34 | The _multi-file_ is a collection of script files. Hereafter being the collection of script files being translated.
35 |
36 | The _main script file_ is the entry script file. This is where the first script (called the _main script_) starts execution.
37 |
38 | Other script files are _required_ to become part of the multi-file by the means of require statements within the main script file or main extension files. The main script file itself is required from the translation environment.
39 |
40 | A _main extension file_ (or _foreign gosub file_) is a script file required by the means of a GOSUB_FILE statement.
41 |
42 | A _subscript file_ is a script file required by the means of a LAUNCH_MISSION statement. A _subscript_ is a script started by the same statement.
43 |
44 | A _mission script file_ is a script file required by the means of a LOAD_AND_LAUNCH_MISSION statement. A _mission script_ is a script started by the same statement.
45 |
46 | An implementation may contain special features regarding the way subscripts and mission scripts are executed.
47 |
48 | The main script file is found in an unspecified manner. The other script files are found by recursively searching a directory with the same filename (excluding extension) as the main script file. This directory is in the same path as the main script file. The search for the script files shall be case-insensitive. All script files must have a `.sc` extension. If multiple script files with the same name are found, which script file is chosen is unspecified.
49 |
50 | A script type is said to come before another script type under the following total order:
51 |
52 | . Main script.
53 | . Main extension script.
54 | . Subscript.
55 | . Mission script.
56 |
57 | A script file _A_ (first required from _X_) is said to come before a script file _B_ (first required from _Y_) under the following total order:
58 |
59 | . If _A_'s script type is not the same as _B_'s, then _A_ comes before _B_ if and only if _A_'s script type comes before _B_'s script type.
60 | . Otherwise, if _X_ is not the same as _Y_, _A_ comes before _B_ if and only if _X_ comes before _Y_.
61 | . Otherwise, _A_ comes before _B_ if and only if the line on which _A_ is first required from (in _X_) comes before the line on which _B_ is first required from.
62 |
63 | A line of code _A_ in a script file _X_ is said to come before a line _B_ in a script file _Y_ different from _X_ if and only if _X_ comes before _Y_.
64 |
65 | [[concept-types]]
66 | === Types
67 |
68 | An _integer_ is a binary signed two's-complement integral number. It represents 32 bits of data and the range of values `-2147483648` through `2147483647`.
69 |
70 | A _floating-point_ is a representation of a real number. Its exact representation, precision and range of values is implementation-defined.
71 |
72 | A _label_ is a name specifying the location of a command.
73 |
74 | A _text label_ is a name whose value is only known in the execution environment.
75 |
76 | A _string_ is a sequence of zero or more characters.
77 |
78 | An _array_ is a collection of one or more elements of the same type. Each element is indexed by an integer key.
79 |
--------------------------------------------------------------------------------
/core/appendix-miss2.adoc:
--------------------------------------------------------------------------------
1 | [appendix]
2 | [[miss2]]
3 | == How to MISS2
4 | The leaked script compiler is full of bugs. It was written for in-house use, so it's meant to work and recognize at least the intended language. The problem is, the language is too inconsistent in this buggy superset. After constantly trying to make those bugs part of this specification, I strongly believe we shouldn't. For the conservative, the following is a list of known things miss2 accepts that this specification does not.
5 |
6 | Do note a regular lexical grammar (like above) cannot be built for the language recognized by miss2.
7 |
8 | *Unrestricted character set*
9 |
10 | More control codes than the specified are _accepted_ by miss2 (such as `\r` anywhere or `\v`). The compiler behaves in weird ways when those are used.
11 |
12 | You may use custom characters (c > 127), but you may clash with the characters DMA used to tokenize string literals.
13 |
14 | BLA BLA The in-house compiler recognizes all of the octets in the range 01 through FF almost indiscriminately. Some of these codes produce unexpected results, while others are used internally during translation (for e.g. escaping string literals). In practice, only the printable characters were used by designers. For simplicity we restrict source code to these characters. BLA BLA
15 |
16 | *A string literal is the same as four tokens*
17 |
18 | ----
19 | SAVE_STRING_TO_DEBUG_FILE "OO AR AZ WERTY"
20 | SAVE_STRING_TO_DEBUG_FILE FOO BAR BAZ QWERTY
21 | // both are recognized by miss2 and produce the same bytecode
22 | // this specification only accepts the string literal one
23 | ----
24 |
25 | *A string literal ends a line*
26 |
27 | As part of transforming a string literal into tokens, miss2 puts a null terminator in the line. Thus, any argument following it is kinda of ignored.
28 |
29 | ----
30 | SAVE_STRING_TO_DEBUG_FILE "this is a string" and this is ignored
31 | // this specification does not accept this
32 | ----
33 |
34 | *Accepts internal compiler commands*
35 |
36 | Remove the constraint that commands that conflict with grammar definitions cannot be used in a `command_statement` and you get atrocities like:
37 |
38 | ----
39 | IF { // does not begin a lexical scope
40 | ENDIF
41 |
42 | IF WHILE 0 // it's like an ANDOR within an ANDOR
43 | ENDIF
44 |
45 | // there is probably a lot more of these
46 | ----
47 |
48 | *WHILENOT is incomplete*
49 |
50 | WHILENOT only accepts equality comparison
51 |
52 | ----
53 | WHILENOT x = 1
54 | ENDWHILE
55 |
56 | WHILENOT x < 1 // not recognized
57 | ENDWHILE
58 |
59 | // since we accept the above, we are not a subset anymore.
60 | // to fix this (and become a subset again) only allow equality
61 | // on WHILENOT.
62 | ----
63 |
64 | *AND/OR behaves differently than IF/WHILE/expressions*
65 |
66 | ----
67 | WHILENOT x < 1 // not recognized
68 | AND x < 1 // recognized
69 | ENDWHILE
70 | // this specification accepts both
71 |
72 | WHILE WAIT 1-1 // not recognized
73 | AND WAIT 1-1 // recognized
74 | // this specification accepts neither
75 |
76 | WHILE WAIT-1 // the command WAIT with a -1 argument
77 | AND WAIT-1 // a command named WAIT-1
78 | // this specification accepts neither
79 | ----
80 |
81 | *INT tokens allow minus in the middle*
82 |
83 | ----
84 | WAIT 1-1
85 | WAIT 1-
86 | // this specification does not accept this
87 | ----
88 |
89 | *Commands may have operator characters*
90 |
91 | ----
92 | --b // recognized as '--' identifier(b)
93 | --b b // recognized as command(--b) identifier(b)
94 | // this makes the lexer context sensitive
95 | // but this spec disallow the later form based
96 | // on the belief the IF/WHILE/expressions parser
97 | // is the correct one (details above).
98 | ----
99 |
100 | *anything may follow MISSION_START*
101 |
102 | ----
103 | MISSION_START anythin"may follow" this thing
104 | MISSION_END the same "happens"with mission_end
105 | // this specification does not accept this
106 | ----
107 |
108 | *labels may contain any printable character (except quotation marks)*
109 |
110 | ----
111 | e-=1: // recognized (we don't accept this)
112 | GOTO e-=1 // not recognized
113 | LAUNCH_MISSION e/=.sc // recognized (we don't accept this)
114 | ----
115 |
116 | *label may be empty or not match identifier*
117 |
118 | The name of a label may be empty. The name of a label may contain characters that do not match the `identifier` production.
119 |
120 | ----
121 | : // recognized
122 | :::: // recognized
123 | @abc: // recognized
124 | // this specification does not accept this
125 | ----
126 |
127 | *non-identifiers on the lhs of assignment expressions*
128 |
129 | Some expressions implement this correctly in miss2, some don't.
130 |
131 | ----
132 | 1 = ABS 2 // recognized
133 | --1 // recognized for every unary expression
134 | 1 = 2 * 3 // recognized for every ternary expression
135 | 1 = 2 // recognized
136 | 1 =# 2 // recognized
137 | 1 *= 2 // not recognized for every other binary expression
138 | // this specification does not accept any of this
139 | ----
140 |
141 | *labels in AND/OR*
142 |
143 | miss2 allows labels to prefix AND/OR conditions. However, it produces weird code. As such, this specification does not accept it.
144 |
145 | ----
146 | IF x = 0
147 | lab_or: OR x = 1 // goes to the WAIT 0 after the last condition
148 | OR x = 2 // this specification does not accept this
149 | WAIT 1
150 | ELSE
151 | WAIT 2
152 | ENDIF
153 | ----
154 |
155 | *weird closing blocks*
156 |
157 | stuff like the following is recognized by miss2
158 |
159 | ----
160 | WHILE x = 0
161 | IF y = 1
162 | WAIT 0
163 | ENDWHILE
164 | ENDIF
165 | // this specification does not accept this (nor variations of this)
166 | ----
167 |
168 | this happens with scopes, IFs, REPEATs, WHILEs, `MISSION_END`, and what not.
169 |
170 | it is very interesting actually, but clearly a language bug (would not say a implementation bug though).
171 |
172 | *exclusive scripts*
173 |
174 | we don't really what are these, so we won't specify them.
175 |
176 | *entities*
177 |
178 | ----
179 | VAR_INT vcar
180 | COMMAND_INPUT_CAR_OUTPUT_CAR vcar vcar
181 | // this spec gives an error, miss2 recognizes (does not look like intended behaviour?)
182 | // [...] we are not a subset anymore because of this.
183 | ----
184 |
185 | *arrays*
186 |
187 | ----
188 | WAIT array[1]anything // recognized
189 | WAIT non_array[1] // recognized
190 | WAIT non_array[2] // not recognized
191 | // this specification does not accept this
192 | ----
193 |
--------------------------------------------------------------------------------
/core/parameters.adoc:
--------------------------------------------------------------------------------
1 | [[parameters]]
2 | == Parameters
3 |
4 | A command receives several arguments. Every argument must obey the rules of its corresponding _parameter definition_.
5 |
6 | A _parameter definition_ is a set of definitions regarding a single parameter for a specific command.
7 |
8 | A command must have the same amount of arguments as its amount of parameter definitions, unless the missing arguments correspond to optional parameters.
9 |
10 | If a variable is used in the same command both as an input and as an output, the input shall be evaluated before any output is assigned to the variable.
11 |
12 | [[string-constants]]
13 | === String Constants
14 |
15 | A _string constant_ is a name associated with an integer value. Such association is known in the translation environment.
16 |
17 | An _enumeration_ is a collection of string constants. A parameter definition can have an associated enumeration.
18 |
19 | There is a special enumeration called the _global string constants enumeration_.
20 |
21 | An identifier is said to match a string constant in certain enumeration if there exists a name in the enumeration with the same name as the identifier.
22 |
23 | Further semantics for string constants are defined along this specification.
24 |
25 | [[entities]]
26 | === Entities
27 |
28 | An _entity_ is an object of the execution environment. Each entity has an _entity type_, which defines its purposes.
29 |
30 | A parameter definition can have an associated entity type.
31 |
32 | An entity can be assigned to a variable. In such case, the variable is said to be of that specific entity type from that line of code on. Previous lines of code are not affected.
33 |
34 | If an entity type is associated with an parameter and a variable is used as argument, the variable must have the same entity type as the formal parameter.
35 |
36 | Further semantics for entities are defined along this specification.
37 |
38 | [[parameter-types]]
39 | === Parameter Types
40 |
41 | [[parameter-type-int]]
42 | ==== INT
43 |
44 | An _INT parameter_ accepts an argument only if it is an integer literal.
45 |
46 | [[parameter-type-float]]
47 | ==== FLOAT
48 |
49 | A _FLOAT parameter_ accepts an argument only if it is a floating-point literal.
50 |
51 | [[parameter-type-var-int]]
52 | ==== VAR_INT
53 |
54 | A _VAR_INT parameter_ accepts an argument only if it is an identifier referencing a global variable of integer type.
55 |
56 | [[parameter-type-var-float]]
57 | ==== VAR_FLOAT
58 |
59 | A _VAR_FLOAT parameter_ accepts an argument only if it is an identifier referencing a global variable of floating-point type.
60 |
61 | [[parameter-type-lvar-int]]
62 | ==== LVAR_INT
63 |
64 | A _LVAR_INT parameter_ accepts an argument only if it is an identifier referencing a local variable of integer type.
65 |
66 | [[parameter-type-lvar-float]]
67 | ==== LVAR_FLOAT
68 |
69 | A _LVAR_FLOAT parameter_ accepts an argument only if it is an identifier referencing a local variable of floating-point type.
70 |
71 | [[parameter-type-input-int]]
72 | ==== INPUT_INT
73 |
74 | An _INPUT_INT parameter_ accepts an argument only if it is an integer literal or an identifier either matching a string constant or referencing a variable of integer type (in this order).
75 |
76 | If the parameter has an associated enumeration, the said enumeration shall be used for matching string constants. Otherwise, the global constant enumeration shall be used.
77 |
78 | [[parameter-type-input-float]]
79 | ==== INPUT_FLOAT
80 |
81 | An _INPUT_FLOAT parameter_ accepts an argument only if it is a floating-point literal or an identifier referencing a variable of floating-point type.
82 |
83 | If the argument matches a global string constant, even if a variable of same name exists, the program is ill-formed.
84 |
85 | [[parameter-type-output-int]]
86 | ==== OUTPUT_INT
87 |
88 | An _OUTPUT_INT parameter_ accepts an argument only if it is an identifier referencing a variable of integer type.
89 |
90 | If an entity type is associated with the parameter, the variable must have the same entity type as the parameter, unless there is no entity type associated with the variable. In the latter case, the parameter's entity type is assigned to the variable.
91 |
92 | If the argument matches a global string constant, even if a variable of same name exists, the program is ill-formed.
93 |
94 | [[parameter-type-output-float]]
95 | ==== OUTPUT_FLOAT
96 |
97 | An _OUTPUT_FLOAT parameter_ accepts an argument only if it is a identifier referencing a variable of floating-point type.
98 |
99 | If the argument matches a global string constant, even if a variable of same name exists, the program is ill-formed.
100 |
101 | [[parameter-type-label]]
102 | ==== LABEL
103 |
104 | A _LABEL parameter_ accepts an argument only if it is an identifier whose name is a label in the multi-file.
105 |
106 | [[parameter-type-text-label]]
107 | ==== TEXT_LABEL
108 |
109 | A _TEXT_LABEL parameter_ accepts an argument only if it is an identifier. If the identifier begins with a dollar character, its suffix must reference a variable of text label type and such a variable is the actual argument. Otherwise, the identifier is a text label.
110 |
111 | If the identifier matches a global string constant, the program is ill-formed.
112 |
113 | [[parameter-type-var-text-label]]
114 | ==== VAR_TEXT_LABEL
115 |
116 | A _VAR_TEXT_LABEL parameter_ accepts an argument only if it is an identifier referencing a global variable of text label type.
117 |
118 | In case text label variables are not supported, this parameter type is not supported.
119 |
120 | [[parameter-type-lvar-text-label]]
121 | ==== LVAR_TEXT_LABEL
122 |
123 | A _LVAR_TEXT_LABEL parameter_ accepts an argument only if it is an identifier referencing a local variable of text label type.
124 |
125 | In case text label variables are not supported, this parameter type is not supported.
126 |
127 | [[parameter-type-string]]
128 | ==== STRING
129 |
130 | A _STRING parameter_ accepts an argument only if it is a string literal.
131 |
132 | In case string literals are not supported, this parameter type is not supported.
133 |
134 | [[parameter-type-optional]]
135 | ==== Optional Parameters
136 |
137 | Additionally, the following parameters are defined as behaving equivalently to their correspondent parameters above, except that in case an argument is absent, parameter checking stops as if there are no more parameters to be checked.
138 |
139 | * [[parameter-type-var-int-opt]] _VAR_INT_OPT_
140 | * [[parameter-type-var-float-opt]] _VAR_FLOAT_OPT_
141 | * [[parameter-type-lvar-int-opt]] _LVAR_INT_OPT_
142 | * [[parameter-type-lvar-float-opt]] _LVAR_FLOAT_OPT_
143 | * [[parameter-type-var-text-label-opt]] _VAR_TEXT_LABEL_OPT_
144 | * [[parameter-type-lvar-text-label-opt]] _LVAR_TEXT_LABEL_OPT_
145 | * _INPUT_OPT_
146 |
147 | Such parameters are always trailing parameters.
148 |
149 | [[parameter-type-input-opt]] The _INPUT_OPT parameter_ accepts an argument only if it is an integer literal, floating-point literal, or identifier matching a global string constant or referencing a variable of integer or floating-point type (in this order). A variable of text label type may be accepted by an INPUT_OPT parameter.
150 |
151 | In case text label variables are not supported, the VAR_TEXT_LABEL_OPT and LVAR_TEXT_LABEL_OPT parameter types are not supported.
152 |
--------------------------------------------------------------------------------
/core/elements.adoc:
--------------------------------------------------------------------------------
1 | [[elements]]
2 | == Elements
3 |
4 | The lexical grammar of the language is context-sensitive. As such, the lexical elements and the syntactic elements are presented together.footnote:[The in-house compiler is an ad-hoc parser, introducing a lot of contextual problems to the language.]
5 |
6 | [[element-source-code]]
7 | === Source Code
8 |
9 | _Source code_ is a stream of printable ASCII characters plus the control codes line feed (`\n`), horizontal tab (`\t`) and carriage return (`\r`).footnote:miss2[]
10 |
11 | ----
12 | ascii_char := ascii_printable | ascii_control ;
13 | ascii_printable := /* printable ASCII characters */ ;
14 | ascii_control := '\n' | '\t' | '\r' ;
15 | ----
16 |
17 | Carriage returns should appear only before a line feed.footnote:[The in-house compiler does not have such a restriction. We introduce it for simplicity.]
18 |
19 | Lowercase letters in the stream shall be interpreted as its uppercase equivalent.
20 |
21 | Space, horizontal tab, parentheses and comma are defined as _whitespace_ characters.
22 |
23 | ----
24 | whitespace := ' ' | '\t' | '(' | ')' | ',' ;
25 | ----
26 |
27 | A _line_ is a sequence of characters delimited by a newline. The start of the stream begins a line. The end of the stream finishes a line.
28 |
29 | ----
30 | newline := ['\r'] `\n` ;
31 | ----
32 |
33 | Each line should be interpreted as if there is no whitespaces in either ends of the line.footnote:simplify-whitespace[This simplifies the syntactic specification.]
34 |
35 | A _token character_ is any character capable of forming a single token.
36 |
37 | ----
38 | graph_char := ascii_printable - (whitespace | '"') ;
39 | token_char := graph_char - ('+' | '-' | '*' | '/' | '=' | '<' | '>') ;
40 | ----
41 |
42 | To simplify future definitions, the productions `eol` (end of line) and `sep` (token separator) are defined.
43 |
44 | ----
45 | sep := whitespace {whitespace} ;
46 | eol := newline | EOF ;
47 | ----
48 |
49 | [[element-comment]]
50 | === Comments
51 |
52 | _Comments_ serve as program documentation.
53 |
54 | ----
55 | comment := line_comment | block_comment ;
56 | line_comment := '//' {ascii_char} eol ;
57 | block_comment := '/*' {block_comment | ascii_char} '*/' ;
58 | ----
59 |
60 | There are two forms:
61 |
62 | * _Line comments_ starts with the character sequence `//` and stop at the end of the line.
63 | * _Block comments_ starts with the character sequence `/\*` and stop with its matching `*/`. Block comments can be nested inside each other.
64 |
65 | The contents of a comment shall be interpreted as if it is whitespaces in the source code.footnote:simplify-whitespace[] More specifically:
66 |
67 | * A line comment should be interpreted as an `eol`.
68 | * A single, nested, block comment should be interpreted as an `eol` on each line boundary it crosses. On its last line (i.e. the one it does not cross), it should be interpreted as one or more whitespace characters.
69 |
70 | Comments cannot start inside string literals.footnote:[i.e. `"This // is a string"` is a string literal, not an incomplete string.]
71 |
72 | [[element-command]]
73 | === Commands
74 |
75 | A command describes an operation for a script to perform.
76 |
77 | ----
78 | command_name := token_char {token_char} ;
79 | command := command_name { sep argument } ;
80 | ----
81 |
82 | There are several types of arguments.
83 |
84 | ----
85 | argument := integer
86 | | floating
87 | | identifier
88 | | string_literal ;
89 | ----
90 |
91 | [[element-integer-literal]]
92 | ==== Integer Literals
93 |
94 | ----
95 | digit := '0'..'9' ;
96 | integer := ['-'] digit {digit} ;
97 | ----
98 |
99 | An _integer literal_ is a sequence of digits optionally preceded by a minus sign.footnote:miss2[]
100 |
101 | If the literal begins with a minus, the number following it shall be negated.
102 |
103 | [[element-floating-point-literal]]
104 | ==== Floating-Point Literals
105 |
106 | ----
107 | floating_form1 := '.' digit { digit | '.' | 'F' } ;
108 | floating_form2 := digit { digit } ('.' | 'F') { digit | '.' | 'F' } ;
109 | floating := ['-'] (floating_form1 | floating_form2) ;
110 | ----
111 |
112 | A _floating-point literal_ is a sequence of digits which must contain at least one occurrence of the characters `.` or `F`.
113 |
114 | Once the `F` characters is found, all characters including and following it shall be ignored. The same shall happen when the character `.` is found a second time.footnote:[We have not simplified this misfeature because it is used in one of the GTA III 10th Anniversary scripts.]
115 |
116 | The literal can be preceded by a minus sign, which shall negate the floating-point number.
117 |
118 | The following are examples of valid and invalid literals:
119 |
120 | |===
121 | | Literal | Same As
122 |
123 | | 1
124 | | invalid
125 |
126 | | -1
127 | | invalid
128 |
129 | | 1f
130 | | 1.0
131 |
132 | | 1.
133 | | 1.0
134 |
135 | | .1
136 | | 0.1
137 |
138 | | .1f
139 | | 0.1
140 |
141 | | .11
142 | | 0.11
143 |
144 | | .1.9
145 | | 0.1
146 |
147 | | 1.1
148 | | 1.1
149 |
150 | | 1.f
151 | | 1.0
152 |
153 | | 1..
154 | | 1.0
155 | |===
156 |
157 | [[element-identifier]]
158 | ==== Identifiers
159 |
160 | ----
161 | identifier := ('$' | 'A'..'Z') {token_char} ;
162 | ----
163 |
164 | An _identifier_ is a sequence of token characters beginning with a dollar or alphabetic character.
165 |
166 | *Constraints*
167 |
168 | If text label variables are not supported by the implementation, the first character of an identifier shall not be a dollar.
169 |
170 | An identifier shall not end with a `:` character.
171 |
172 | [[element-string-literal]]
173 | ==== String Literals
174 |
175 | A _string literal_ holds a string delimited by quotation marks.
176 |
177 | ----
178 | string_literal := '"' { ascii_char - (newline | '"') } '"' ;
179 | ----
180 |
181 | String literals may not be supported by an implementation. In such case, a program using these literals is ill-formed.
182 |
183 | [[element-variable-reference]]
184 | ==== Variable References
185 |
186 | A _variable name_ is a identifier, except the characters `[` and `]` cannot happen. If text label variables are not supported, the first character of a variable name shall not be a dollar.
187 |
188 | ----
189 | variable_char := token_char - ('[' | ']') ;
190 | variable_name := ('$' | 'A'..'Z') {variable_char} ;
191 | ----
192 |
193 | A _variable reference_ is a variable name optionally followed by an array subscript.footnote:miss2[]
194 |
195 | ----
196 | subscript := '[' (variable_name | integer) ']' ;
197 | variable := variable_name [ subscript ] ;
198 | ----
199 |
200 | The type of a variable reference is the type of the variable name being referenced.
201 |
202 | The subscript uses an integer literal or another variable name of integer type for zero-based indexing.footnote:[The in-house compiler uses one-based indexing. Its array feature is incomplete and produces problematic bytecode when subscripting variables. Additionally, the GTA Vice City runtime (the target of the in-house compiler) does not support arrays. Thus it's believed this feature is still incomplete in V413 and was never used. Not until GTA San Andreas, which introduces arrays in the execution environment. Its runtime performs zero-based indexing on variable subscripts, but for literal subscripts we can only guess. The compiled multifile contains debug strings that suggests zero-based indexing for literals.]
203 |
204 | The program is ill-formed if the array subscript uses a negative or out of bounds value for indexing.
205 |
206 | The program is ill-formed if a variable name is followed by a subscript but the variable is not an array.footnote:miss2[]
207 |
208 | An array variable name which is not followed by a subscript behaves as if its zero-indexed element is referenced.
209 |
210 | A variable used for indexing an array must not be an array.footnote:miss2[]
211 |
212 | If array variables are not supported, subscripts are ill-formed.
213 |
--------------------------------------------------------------------------------
/core/alternator-def.adoc:
--------------------------------------------------------------------------------
1 | [[alternator-def]]
2 | == Supporting Command Selectors
3 |
4 | To further enchance the set of minimal commands for useful computation, the following command selectors and its supportive alternatives are defined.
5 |
6 | An implementation is required to support these selectors, but it may not support all of its alternatives.
7 |
8 | [[alternator-def-set]]
9 | === SET
10 |
11 | *Alternatives*
12 |
13 | SET_VAR_INT VAR_INT INT
14 | SET_VAR_FLOAT VAR_FLOAT FLOAT
15 | SET_LVAR_INT LVAR_INT INT
16 | SET_LVAR_FLOAT LVAR_FLOAT FLOAT
17 | SET_VAR_INT_TO_VAR_INT VAR_INT VAR_INT
18 | SET_LVAR_INT_TO_LVAR_INT LVAR_INT LVAR_INT
19 | SET_VAR_FLOAT_TO_VAR_FLOAT VAR_FLOAT VAR_FLOAT
20 | SET_LVAR_FLOAT_TO_LVAR_FLOAT LVAR_FLOAT LVAR_FLOAT
21 | SET_VAR_FLOAT_TO_LVAR_FLOAT VAR_FLOAT LVAR_FLOAT
22 | SET_LVAR_FLOAT_TO_VAR_FLOAT LVAR_FLOAT VAR_FLOAT
23 | SET_VAR_INT_TO_LVAR_INT VAR_INT LVAR_INT
24 | SET_LVAR_INT_TO_VAR_INT LVAR_INT VAR_INT
25 | SET_VAR_INT_TO_CONSTANT VAR_INT INPUT_INT
26 | SET_LVAR_INT_TO_CONSTANT VAR_INT INPUT_INT
27 | SET_VAR_TEXT_LABEL VAR_TEXT_LABEL TEXT_LABEL
28 | SET_LVAR_TEXT_LABEL LVAR_TEXT_LABEL TEXT_LABEL
29 |
30 | *Side-effects*
31 |
32 | Sets the variable on the left to the value on the right.
33 |
34 | *Constraints*
35 |
36 | The translation environment must enforce the following constraints.
37 |
38 | A variable cannot be assigned to another variable of different entity type. If the right variable has no entity type but the left one does, the program is ill-formed. If the left variable has no entity type, the entity type of the right variable is assigned to it.
39 |
40 | [[alternator-def-cset]]
41 | === CSET
42 |
43 | *Alternatives*
44 |
45 | CSET_VAR_INT_TO_VAR_FLOAT VAR_INT VAR_FLOAT
46 | CSET_VAR_FLOAT_TO_VAR_INT VAR_FLOAT VAR_INT
47 | CSET_LVAR_INT_TO_VAR_FLOAT LVAR_INT VAR_FLOAT
48 | CSET_LVAR_FLOAT_TO_VAR_INT LVAR_FLOAT VAR_INT
49 | CSET_VAR_INT_TO_LVAR_FLOAT VAR_INT LVAR_FLOAT
50 | CSET_VAR_FLOAT_TO_LVAR_INT VAR_FLOAT LVAR_INT
51 | CSET_LVAR_INT_TO_LVAR_FLOAT LVAR_INT LVAR_FLOAT
52 | CSET_LVAR_FLOAT_TO_LVAR_INT LVAR_FLOAT LVAR_INT
53 |
54 | *Side-effects*
55 |
56 | Sets the variable on the left to the value of the variable on the right converted to the left type.
57 |
58 | [[alternator-def-add-thing-to-thing]]
59 | === ADD_THING_TO_THING
60 |
61 | *Alternatives*
62 |
63 | ADD_VAL_TO_INT_VAR VAR_INT INT
64 | ADD_VAL_TO_FLOAT_VAR VAR_FLOAT FLOAT
65 | ADD_VAL_TO_INT_LVAR LVAR_INT INT
66 | ADD_VAL_TO_FLOAT_LVAR LVAR_FLOAT FLOAT
67 | ADD_INT_VAR_TO_INT_VAR VAR_INT VAR_INT
68 | ADD_FLOAT_VAR_TO_FLOAT_VAR VAR_FLOAT VAR_FLOAT
69 | ADD_INT_LVAR_TO_INT_LVAR LVAR_INT LVAR_INT
70 | ADD_FLOAT_LVAR_TO_FLOAT_LVAR LVAR_FLOAT LVAR_FLOAT
71 | ADD_INT_VAR_TO_INT_LVAR LVAR_INT VAR_INT
72 | ADD_FLOAT_VAR_TO_FLOAT_LVAR LVAR_FLOAT VAR_FLOAT
73 | ADD_INT_LVAR_TO_INT_VAR VAR_INT LVAR_INT
74 | ADD_FLOAT_LVAR_TO_FLOAT_VAR VAR_FLOAT LVAR_FLOAT
75 |
76 | *Side-effects*
77 |
78 | Adds the value on the right to the variable on the left.
79 |
80 | [[alternator-def-sub-thing-from-thing]]
81 | === SUB_THING_FROM_THING
82 |
83 | *Alternatives*
84 |
85 | SUB_VAL_FROM_INT_VAR VAR_INT INT
86 | SUB_VAL_FROM_FLOAT_VAR VAR_FLOAT FLOAT
87 | SUB_VAL_FROM_INT_LVAR LVAR_INT INT
88 | SUB_VAL_FROM_FLOAT_LVAR LVAR_FLOAT FLOAT
89 | SUB_INT_VAR_FROM_INT_VAR VAR_INT VAR_INT
90 | SUB_FLOAT_VAR_FROM_FLOAT_VAR VAR_FLOAT VAR_FLOAT
91 | SUB_INT_LVAR_FROM_INT_LVAR LVAR_INT LVAR_INT
92 | SUB_FLOAT_LVAR_FROM_FLOAT_LVAR LVAR_FLOAT LVAR_FLOAT
93 | SUB_INT_VAR_FROM_INT_LVAR LVAR_INT VAR_INT
94 | SUB_FLOAT_VAR_FROM_FLOAT_LVAR LVAR_FLOAT VAR_FLOAT
95 | SUB_INT_LVAR_FROM_INT_VAR VAR_INT LVAR_INT
96 | SUB_FLOAT_LVAR_FROM_FLOAT_VAR VAR_FLOAT LVAR_FLOAT
97 |
98 | *Side-effects*
99 |
100 | Substracts the value on the right from the variable on the left.
101 |
102 | [[alternator-def-mult-thing-by-thing]]
103 | === MULT_THING_BY_THING
104 |
105 | *Alternatives*
106 |
107 | MULT_INT_VAR_BY_VAL VAR_INT INT
108 | MULT_FLOAT_VAR_BY_VAL VAR_FLOAT FLOAT
109 | MULT_INT_LVAR_BY_VAL LVAR_INT INT
110 | MULT_FLOAT_LVAR_BY_VAL LVAR_FLOAT FLOAT
111 | MULT_INT_VAR_BY_INT_VAR VAR_INT VAR_INT
112 | MULT_FLOAT_VAR_BY_FLOAT_VAR VAR_FLOAT VAR_FLOAT
113 | MULT_INT_LVAR_BY_INT_LVAR LVAR_INT LVAR_INT
114 | MULT_FLOAT_LVAR_BY_FLOAT_LVAR LVAR_FLOAT LVAR_FLOAT
115 | MULT_INT_VAR_BY_INT_LVAR VAR_INT LVAR_INT
116 | MULT_FLOAT_VAR_BY_FLOAT_LVAR VAR_FLOAT LVAR_FLOAT
117 | MULT_INT_LVAR_BY_INT_VAR LVAR_INT VAR_INT
118 | MULT_FLOAT_LVAR_BY_FLOAT_VAR LVAR_FLOAT VAR_FLOAT
119 |
120 | *Side-effects*
121 |
122 | Multiplites the variable on the left by the value on the right.
123 |
124 | [[alternator-def-div-thing-by-thing]]
125 | === DIV_THING_BY_THING
126 |
127 | *Alternatives*
128 |
129 | DIV_INT_VAR_BY_VAL VAR_INT INT
130 | DIV_FLOAT_VAR_BY_VAL VAR_FLOAT FLOAT
131 | DIV_INT_LVAR_BY_VAL LVAR_INT INT
132 | DIV_FLOAT_LVAR_BY_VAL LVAR_FLOAT FLOAT
133 | DIV_INT_VAR_BY_INT_VAR VAR_INT VAR_INT
134 | DIV_FLOAT_VAR_BY_FLOAT_VAR VAR_FLOAT VAR_FLOAT
135 | DIV_INT_LVAR_BY_INT_LVAR LVAR_INT LVAR_INT
136 | DIV_FLOAT_LVAR_BY_FLOAT_LVAR LVAR_FLOAT LVAR_FLOAT
137 | DIV_INT_VAR_BY_INT_LVAR VAR_INT LVAR_INT
138 | DIV_FLOAT_VAR_BY_FLOAT_LVAR VAR_FLOAT LVAR_FLOAT
139 | DIV_INT_LVAR_BY_INT_VAR LVAR_INT VAR_INT
140 | DIV_FLOAT_LVAR_BY_FLOAT_VAR LVAR_FLOAT VAR_FLOAT
141 |
142 | *Side-effects*
143 |
144 | Divides the variable on the left by the value on the right.
145 |
146 | [[alternator-def-abs]]
147 | === ABS
148 |
149 | *Alternatives*
150 |
151 | ABS_VAR_INT VAR_INT
152 | ABS_LVAR_INT LVAR_INT
153 | ABS_VAR_FLOAT VAR_FLOAT
154 | ABS_LVAR_FLOAT LVAR_FLOAT
155 |
156 | *Side-effects*
157 |
158 | Computes the absolute value of a variable's value and store the result in the same variable.
159 |
160 | [[alternator-def-add-thing-to-thing-timed]]
161 | === ADD_THING_TO_THING_TIMED
162 |
163 | *Alternatives*
164 |
165 | ADD_TIMED_VAL_TO_FLOAT_VAR VAR_FLOAT FLOAT
166 | ADD_TIMED_VAL_TO_FLOAT_LVAR LVAR_FLOAT FLOAT
167 | ADD_TIMED_FLOAT_VAR_TO_FLOAT_VAR VAR_FLOAT VAR_FLOAT
168 | ADD_TIMED_FLOAT_LVAR_TO_FLOAT_LVAR LVAR_FLOAT LVAR_FLOAT
169 | ADD_TIMED_FLOAT_LVAR_TO_FLOAT_VAR VAR_FLOAT LVAR_FLOAT
170 | ADD_TIMED_FLOAT_VAR_TO_FLOAT_LVAR LVAR_FLOAT VAR_FLOAT
171 |
172 | *Side-effects*
173 |
174 | Adds the value on the right multipled by the frame delta time to the variable on the left.
175 |
176 | [[alternator-def-sub-thing-from-thing-timed]]
177 | === SUB_THING_FROM_THING_TIMED
178 |
179 | *Alternatives*
180 |
181 | SUB_TIMED_VAL_FROM_FLOAT_VAR VAR_FLOAT FLOAT
182 | SUB_TIMED_VAL_FROM_FLOAT_LVAR LVAR_FLOAT FLOAT
183 | SUB_TIMED_FLOAT_VAR_FROM_FLOAT_VAR VAR_FLOAT VAR_FLOAT
184 | SUB_TIMED_FLOAT_LVAR_FROM_FLOAT_LVAR LVAR_FLOAT LVAR_FLOAT
185 | SUB_TIMED_FLOAT_LVAR_FROM_FLOAT_VAR VAR_FLOAT LVAR_FLOAT
186 | SUB_TIMED_FLOAT_VAR_FROM_FLOAT_LVAR LVAR_FLOAT VAR_FLOAT
187 |
188 | *Side-effects*
189 |
190 | Substracts the value on the right multipled by the frame delta time from the variable on the left.
191 |
192 | [[alternator-def-is-thing-equal-to-thing]]
193 | === IS_THING_EQUAL_TO_THING
194 |
195 | *Alternatives*
196 |
197 | IS_INT_VAR_EQUAL_TO_NUMBER VAR_INT INT
198 | IS_INT_LVAR_EQUAL_TO_NUMBER LVAR_INT INT
199 | IS_INT_VAR_EQUAL_TO_INT_VAR VAR_INT VAR_INT
200 | IS_INT_LVAR_EQUAL_TO_INT_LVAR LVAR_INT LVAR_INT
201 | IS_INT_VAR_EQUAL_TO_INT_LVAR VAR_INT LVAR_INT
202 | IS_FLOAT_VAR_EQUAL_TO_NUMBER VAR_FLOAT FLOAT
203 | IS_FLOAT_LVAR_EQUAL_TO_NUMBER LVAR_FLOAT FLOAT
204 | IS_FLOAT_VAR_EQUAL_TO_FLOAT_VAR VAR_FLOAT VAR_FLOAT
205 | IS_FLOAT_LVAR_EQUAL_TO_FLOAT_LVAR LVAR_FLOAT LVAR_FLOAT
206 | IS_FLOAT_VAR_EQUAL_TO_FLOAT_LVAR VAR_FLOAT LVAR_FLOAT
207 | IS_INT_VAR_EQUAL_TO_CONSTANT VAR_INT INPUT_INT
208 | IS_INT_LVAR_EQUAL_TO_CONSTANT LVAR_INT INPUT_INT
209 | IS_VAR_TEXT_LABEL_EQUAL_TO_TEXT_LABEL VAR_TEXT_LABEL TEXT_LABEL
210 | IS_LVAR_TEXT_LABEL_EQUAL_TO_TEXT_LABEL LVAR_TEXT_LABEL TEXT_LABEL
211 | IS_INT_LVAR_EQUAL_TO_INT_VAR LVAR_INT VAR_INT
212 | IS_FLOAT_LVAR_EQUAL_TO_FLOAT_VAR LVAR_FLOAT VAR_FLOAT
213 |
214 | *Side-effects*
215 |
216 | Returns whether the value on the left is equal the value on the right.
217 |
218 | [[alternator-def-is-thing-greater-than-thing]]
219 | === IS_THING_GREATER_THAN_THING
220 |
221 | *Alternatives*
222 |
223 | IS_INT_VAR_GREATER_THAN_NUMBER VAR_INT INT
224 | IS_INT_LVAR_GREATER_THAN_NUMBER LVAR_INT INT
225 | IS_NUMBER_GREATER_THAN_INT_VAR INT VAR_INT
226 | IS_NUMBER_GREATER_THAN_INT_LVAR INT LVAR_INT
227 | IS_INT_VAR_GREATER_THAN_INT_VAR VAR_INT VAR_INT
228 | IS_INT_LVAR_GREATER_THAN_INT_LVAR LVAR_INT LVAR_INT
229 | IS_INT_VAR_GREATER_THAN_INT_LVAR VAR_INT LVAR_INT
230 | IS_INT_LVAR_GREATER_THAN_INT_VAR LVAR_INT VAR_INT
231 | IS_FLOAT_VAR_GREATER_THAN_NUMBER VAR_FLOAT FLOAT
232 | IS_FLOAT_LVAR_GREATER_THAN_NUMBER LVAR_FLOAT FLOAT
233 | IS_NUMBER_GREATER_THAN_FLOAT_VAR FLOAT VAR_FLOAT
234 | IS_NUMBER_GREATER_THAN_FLOAT_LVAR FLOAT LVAR_FLOAT
235 | IS_FLOAT_VAR_GREATER_THAN_FLOAT_VAR VAR_FLOAT VAR_FLOAT
236 | IS_FLOAT_LVAR_GREATER_THAN_FLOAT_LVAR LVAR_FLOAT LVAR_FLOAT
237 | IS_FLOAT_VAR_GREATER_THAN_FLOAT_LVAR VAR_FLOAT LVAR_FLOAT
238 | IS_FLOAT_LVAR_GREATER_THAN_FLOAT_VAR LVAR_FLOAT VAR_FLOAT
239 | IS_INT_VAR_GREATER_THAN_CONSTANT VAR_INT INPUT_INT
240 | IS_INT_LVAR_GREATER_THAN_CONSTANT LVAR_INT INPUT_INT
241 | IS_CONSTANT_GREATER_THAN_INT_VAR INPUT_INT VAR_INT
242 | IS_CONSTANT_GREATER_THAN_INT_LVAR INPUT_INT LVAR_INT
243 |
244 | *Side-effects*
245 |
246 | Returns whether the value on the left is greater than the value on the right.
247 |
248 | [[alternator-def-is-thing-greater-or-equal-to-thing]]
249 | === IS_THING_GREATER_OR_EQUAL_TO_THING
250 |
251 | *Alternatives*
252 |
253 | IS_INT_VAR_GREATER_OR_EQUAL_TO_NUMBER VAR_INT INT
254 | IS_INT_LVAR_GREATER_OR_EQUAL_TO_NUMBER LVAR_INT INT
255 | IS_NUMBER_GREATER_OR_EQUAL_TO_INT_VAR INT VAR_INT
256 | IS_NUMBER_GREATER_OR_EQUAL_TO_INT_LVAR INT LVAR_INT
257 | IS_INT_VAR_GREATER_OR_EQUAL_TO_INT_VAR VAR_INT VAR_INT
258 | IS_INT_LVAR_GREATER_OR_EQUAL_TO_INT_LVAR LVAR_INT LVAR_INT
259 | IS_INT_VAR_GREATER_OR_EQUAL_TO_INT_LVAR VAR_INT LVAR_INT
260 | IS_INT_LVAR_GREATER_OR_EQUAL_TO_INT_VAR LVAR_INT VAR_INT
261 | IS_FLOAT_VAR_GREATER_OR_EQUAL_TO_NUMBER VAR_FLOAT FLOAT
262 | IS_FLOAT_LVAR_GREATER_OR_EQUAL_TO_NUMBER LVAR_FLOAT FLOAT
263 | IS_NUMBER_GREATER_OR_EQUAL_TO_FLOAT_VAR FLOAT VAR_FLOAT
264 | IS_NUMBER_GREATER_OR_EQUAL_TO_FLOAT_LVAR FLOAT LVAR_FLOAT
265 | IS_FLOAT_VAR_GREATER_OR_EQUAL_TO_FLOAT_VAR VAR_FLOAT VAR_FLOAT
266 | IS_FLOAT_LVAR_GREATER_OR_EQUAL_TO_FLOAT_LVAR LVAR_FLOAT LVAR_FLOAT
267 | IS_FLOAT_VAR_GREATER_OR_EQUAL_TO_FLOAT_LVAR VAR_FLOAT LVAR_FLOAT
268 | IS_FLOAT_LVAR_GREATER_OR_EQUAL_TO_FLOAT_VAR LVAR_FLOAT VAR_FLOAT
269 | IS_INT_VAR_GREATER_OR_EQUAL_TO_CONSTANT VAR_INT INPUT_INT
270 | IS_INT_LVAR_GREATER_OR_EQUAL_TO_CONSTANT LVAR_INT INPUT_INT
271 | IS_CONSTANT_GREATER_OR_EQUAL_TO_INT_VAR INPUT_INT VAR_INT
272 | IS_CONSTANT_GREATER_OR_EQUAL_TO_INT_LVAR INPUT_INT LVAR_INT
273 |
274 | *Side-effects*
275 |
276 | Returns whether the value on the left is greater than or equal to the value on the right.
277 |
--------------------------------------------------------------------------------
/core/statements.adoc:
--------------------------------------------------------------------------------
1 | [[statements]]
2 | == Statements
3 |
4 | A statement specifies an action to be executed.
5 |
6 | ----
7 | statement := labeled_statement
8 | | embedded_statement ;
9 | ----
10 |
11 | [[statement-labeled]]
12 | === Labeled Statements
13 |
14 | Statements can be prefixed with a label.
15 |
16 | ----
17 | label_def := identifier ':' ;
18 | label_prefix := label_def sep ;
19 |
20 | labeled_statement := label_prefix embedded_statement
21 | | label_def empty_statement ;
22 | ----
23 |
24 | *Constraints*
25 |
26 | The name of a label must be unique across the multi-file.
27 |
28 | *Semantics*
29 |
30 | This declares a label named after the given identifier.
31 |
32 | The label can be referenced in certain commands to transfer (or start) control to the statement it prefixes. Labels themselves do not alter the flow of control, which continues to the statement it embodies.
33 |
34 | [[statement-empty]]
35 | === Empty Statements
36 |
37 | ----
38 | empty_statement := eol ;
39 | ----
40 |
41 | *Semantics*
42 |
43 | An empty statement does nothing.
44 |
45 | [[statement-embedded]]
46 | === Embedded Statements
47 |
48 | Embedded statements are statements not prefixed by a label.
49 |
50 | ----
51 | embedded_statement := empty_statement
52 | | command_statement
53 | | expression_statement
54 | | scope_statement
55 | | var_statement
56 | | if_statement
57 | | ifnot_statement
58 | | if_goto_statement
59 | | ifnot_goto_statement
60 | | while_statement
61 | | whilenot_statement
62 | | repeat_statement
63 | | require_statement ;
64 | ----
65 |
66 | [[statement-command]]
67 | === Command Statements
68 |
69 | ----
70 | command_statement := command eol ;
71 | ----
72 |
73 | *Constraints*
74 |
75 | The command it embodies cannot be any of the commands specified by this section (e.g. `VAR_INT`, `ELSE`, `ENDWHILE`, `{`, `GOSUB_FILE`, `MISSION_START`, etc).footnote:miss2[]
76 |
77 | [[statement-expression]]
78 | === Expression Statements
79 |
80 | ----
81 | expression_statement := assignment_expression eol
82 | | conditional_expression eol ;
83 | ----
84 |
85 | *Semantics*
86 |
87 | An expression statement executes the expression it embodies.
88 |
89 | The execution of the assignment expression `a = b` is favored over the execution of the conditional expression of the same form.
90 |
91 | [[statement-scope]]
92 | === Scope Statements
93 |
94 | ----
95 | scope_statement := '{' eol
96 | {statement}
97 | [label_prefix] '}' eol ;
98 | ----
99 |
100 | *Constraints*
101 |
102 | Lexical scopes cannot be nested.
103 |
104 | *Semantics*
105 |
106 | The command `{` activates a lexical scope where local variables can be declared.
107 |
108 | The command `}` leaves the active lexical scope.
109 |
110 | The transfer of control to any of the statements within the scope block activates it.
111 |
112 | The execution of a jump to outside the scope block leaves the lexical scope.
113 |
114 | Performing a subroutine call does not leave the active scope. The name of local variables become hidden if the subroutine is not within the scope block. The behaviour of the program is undefined if such a subroutine activates another lexical scope.
115 |
116 | Leaving a lexical scope causes the storage for the declared local variables to be reclaimed.
117 |
118 | [[statement-variable-declaration]]
119 | === Variable Declaration Statements
120 |
121 | ----
122 | command_var_name := 'VAR_INT'
123 | | 'LVAR_INT'
124 | | 'VAR_FLOAT'
125 | | 'LVAR_FLOAT'
126 | | 'VAR_TEXT_LABEL'
127 | | 'LVAR_TEXT_LABEL' ;
128 | command_var_param := sep variable ;
129 |
130 | var_statement := command_var_name command_var_param {command_var_param} eol ;
131 | ----
132 |
133 | The commands with the `VAR_` prefix declares global variables. The ones with `LVAR_` declares local variables. The `INT` suffix declares variables capable of storing integers. The `FLOAT` suffix declares floating-point ones. Finally, the `TEXT_LABEL` one declares variables capable of storing text labels.
134 |
135 | An implementation may not support variables of text label type. In such case, a program declaring a text label variable is ill-formed.
136 |
137 | An implementation may not support array variables. In such case, a program declaring a variable with dimensions is ill-formed.
138 |
139 | *Constraints*
140 |
141 | Global variable names must be unique across the multi-file.
142 |
143 | Local variables must be declared inside a lexical scope.
144 |
145 | Local variables can have identical names as long as they are in different lexical scopes.
146 |
147 | Local variables shall not have the same name as any global variable.
148 |
149 | A variable shall not have the same name as any string constant in any enumeration (except for the global constants enumeration).
150 |
151 | The array dimensions of the variable (if any) must be specified by an integer literal greater than zero.
152 |
153 | *Semantics*
154 |
155 | This command declares one or more names with the specified storage duration, type, and array dimensions.
156 |
157 | Global variable names can be seen by the entire multi-file.
158 |
159 | Local variable names can be seen by their entire lexical scope.
160 |
161 | The initial value of variables is unspecified.footnote:[In Grand Theft Auto, the memory storage of local variables is not zeroed after leaving a scope (nor while entering one). This means local variables preserve values from previous scopes. Additionally, the Stories chapters share the storage of global variables between mission scripts, having the very same implications (no in-depth research has been conduced though).]
162 |
163 | [[statement-conditional]]
164 | === Conditional Statements
165 |
166 | Conditional statements produce changes in the script compare flag.
167 |
168 | ----
169 | conditional_element := ['NOT' sep] (command | conditional_expression) ;
170 |
171 | and_conditional_stmt := 'AND' sep conditional_element eol ;
172 | or_conditional_stmt := 'OR' sep conditional_element eol ;
173 |
174 | conditional_list := conditional_element eol
175 | ({and_conditional_stmt} | {or_conditional_stmt}) ;
176 | ----
177 |
178 | *Constraints*
179 |
180 | The command it embodies cannot be any of the commands specified by this section (e.g. `VAR_INT`, `ELSE`, `ENDWHILE`, `{`, `GOSUB_FILE`, `MISSION_START`, etc).footnote:miss2[]
181 |
182 | *Semantics*
183 |
184 | A conditional element executes the command or expression it embodies. The execution of a command follows the same semantic rules of a command statement. The compare flag of the executed element is negated if the `NOT` prefix is used.
185 |
186 | A conditional list is a sequence of one or more conditional elements separated by either `AND` or `OR` tokens.
187 |
188 | The compare flag is set to true if the compare flag of all conditional elements in a `AND` list holds true. Otherwise it is set to false.
189 |
190 | The compare flag is set to true if the compare flag of at least one conditional elements in a `OR` list holds true. Otherwise it is set to false.
191 |
192 | A conditional list shall not be short-circuit evaluated. All conditional elements are executed in order.
193 |
194 | The behaviour is undefined if the command used in a conditional element does not cause side effects in the compare flag.
195 |
196 | [[statement-selection]]
197 | === Selection Statements
198 |
199 | Selection statements selects which statement to execute depending on certain conditions.
200 |
201 | [[statement-if]]
202 | ==== IF Statement
203 |
204 | ----
205 | if_statement := 'IF' sep conditional_list
206 | {statement}
207 | [[label_prefix] 'ELSE' eol
208 | {statement}]
209 | [label_prefix] 'ENDIF' eol ;
210 | ----
211 |
212 | *Semantics*
213 |
214 | This statement executes a list of conditions, grabs its compare flag and chooses between two set of statements to execute.
215 |
216 | If the compare flag is true, control is transferred to the first set of statements. Otherwise, to the second set if an `ELSE` exists. Execution of the `ELSE` or the `ENDIF` command causes control to leave the IF block.
217 |
218 | [[statement-ifnot]]
219 | ==== IFNOT Statement
220 |
221 | ----
222 | ifnot_statement := 'IFNOT' sep conditional_list
223 | {statement}
224 | [[label_prefix] 'ELSE' eol
225 | {statement}]
226 | [label_prefix] 'ENDIF' eol ;
227 | ----
228 |
229 | *Semantics*
230 |
231 | The behaviour of this is the same as of the IF statement, except the complement of the compare flag is used to test which set of statements to execute.
232 |
233 | [[statement-if-goto]]
234 | ==== IF GOTO Statement
235 |
236 | ----
237 | if_goto_statement := 'IF' sep conditional_element sep 'GOTO' sep identifier eol ;
238 | ----
239 |
240 | *Semantics*
241 |
242 | This statement performs a jump to the label specified by identifier if the compare flag of the conditional element holds true. Otherwise, the flow of control is unchanged.
243 |
244 | [[statement-ifnot-goto]]
245 | ==== IFNOT GOTO Statement
246 |
247 | ----
248 | ifnot_goto_statement := 'IFNOT' sep conditional_element sep 'GOTO' sep identifier eol ;
249 | ----
250 |
251 | *Semantics*
252 |
253 | The behaviour of this is the same as of the IF GOTO statement, except the complement of the compare flag is used to test whether to jump.
254 |
255 | [[statement-iteration]]
256 | === Iteration Statements
257 |
258 | [[statement-while]]
259 | ==== WHILE Statement
260 |
261 | ----
262 | while_statement := 'WHILE' sep conditional_list
263 | {statement}
264 | [label_prefix] 'ENDWHILE' eol ;
265 | ----
266 |
267 | *Semantics*
268 |
269 | The WHILE statement executes a set of statements while the compare flag of the conditional list holds true.
270 |
271 | The statement executes by grabbing the compare flag of the list of conditions and transferring control to after the WHILE block if it holds false. Otherwise, it executes the given set of statements. Execution of the `ENDWHILE` command causes control to be transferred to the beginning of the block, where the conditions are evaluated again.
272 |
273 | [[statement-whilenot]]
274 | ==== WHILENOT Statement
275 |
276 | ----
277 | whilenot_statement := 'WHILENOT' sep conditional_list
278 | {statement}
279 | [label_prefix] 'ENDWHILE' eol ;
280 | ----
281 |
282 | *Semantics*
283 |
284 | The behaviour of this is the same as of the WHILE statement, except the complement of the compare flag is used to test whether to continue executing the set of statements.
285 |
286 | [[statement-repeat]]
287 | ==== REPEAT Statement footnote:[Despite not being used in GTA III, REPEAT seems to be supported since then given its command id is alongside the command id for the other statements.]
288 |
289 | ----
290 | repeat_statement := 'REPEAT' sep integer sep variable eol
291 | {statement}
292 | [label_prefix] 'ENDREPEAT' eol ;
293 | ----
294 |
295 | *Constraints*
296 |
297 | The associated variable must be of integer type.footnote:[The parameter definition of `REPEAT` in the in-house compiler disallows local variables. Due to being a hardcoded command, however, the compiler ignores this parametric restriction and ends up permiting local variables (which is likely the intended behaviour).]
298 |
299 | *Semantics*
300 |
301 | The REPEAT statement executes a set of statements until a counter variable reaches a threshold.
302 |
303 | The `REPEAT` command causes the associated variable to be set to zero. Execution of the `ENDREPEAT` command causes the variable to be incremented and if it compares less than the threshold, control is transfered back to the set of statements. Otherwise, it leaves the block.
304 |
305 | The statements are always executed at least once.
306 |
307 | [[statement-require]]
308 | === Require Statements
309 |
310 | ----
311 | filename := {graph_char} '.SC' ;
312 |
313 | require_statement := command_gosub_file
314 | | command_launch_mission
315 | | command_load_and_launch_mission ;
316 | ----
317 |
318 | Require statements request script files to become part of the multi-file being translated.
319 |
320 | A file can be required more than once. In such case, if it is required using the same statement as the first request, the latter request is ignored. Otherwise, behaviour is undefined.
321 |
322 | *Constraints*
323 |
324 | Require statements shall only appear in the main script file or main extension files.
325 |
326 | [[statement-gosub-file]]
327 | ==== GOSUB_FILE Statement
328 |
329 | ----
330 | command_gosub_file := 'GOSUB_FILE' sep identifier sep filename eol ;
331 | ----
332 |
333 | *Semantics*
334 |
335 | The `GOSUB_FILE` command requires a main extension file to become part of the multi-file.
336 |
337 | It also calls the subroutine specified by label.
338 |
339 | The behaviour is undefined if the label is not part of the required file.
340 |
341 | [[statement-launch-mission]]
342 | ==== LAUNCH_MISSION Statement
343 |
344 | ----
345 | command_launch_mission := 'LAUNCH_MISSION' sep filename eol ;
346 | ----
347 |
348 | *Semantics*
349 |
350 | The `LAUNCH_MISSION` command requires a subscript file to become part of the multi-file.
351 |
352 | It also starts a new subscript with the program counter at the `MISSION_START` directive of the specified script file.
353 |
354 | [[statement-load-and-launch-mission]]
355 | ==== LOAD_AND_LAUNCH_MISSION Statement
356 |
357 | ----
358 | command_load_and_launch_mission := 'LOAD_AND_LAUNCH_MISSION' sep filename eol ;
359 | ----
360 |
361 | *Constraints*
362 |
363 | Only a single mission script can be running at once.
364 |
365 | *Semantics*
366 |
367 | The `LOAD_AND_LAUNCH_MISSION` command requires a mission script file to become part of the multi-file.
368 |
369 | It also starts a new mission script with the program counter at the `MISSION_START` directive of the specified script file.
370 |
--------------------------------------------------------------------------------