README.md 22.7 KB
Newer Older
1
# ADOxx AdoScript Extension
Patrik B's avatar
Patrik B committed
2

3
The extension focuses on the static aspects of the AdoScript language, providing syntax highlighting, code snippets, comment toggling and code block folding.
4

5 6
The syntax highlighting focuses on recognizing the right concepts and displaying them according to the used theme. Additionally it tries to identify illegal code where possible and mark it accordingly, like use of variables where they aren't allowed or having lower-case characters in a procedure name.

Patrik B's avatar
Patrik B committed
7

8
## Authors / Contributors
Patrik B's avatar
Patrik B committed
9

10
* Patrik Burzynski (main author)
11
* Wilfrid Utz
Patrik B's avatar
Patrik B committed
12

13 14

## ToC
15 16 17 18 19 20 21 22 23
* [Features](#features)
* [Recommendations and Restrictions - short version](#the-short-version-of-recommendations-and-restrictions)
* [Recommendations - detailed](#recommendations)
* [Restrictions - detailed](#restrictions)
* [Requirements](#requirements)
* [Extension Settings](#extension-settings)
* [Known Issues](#known-issues)
* [Release Notes](#release-notes)
* [Used Syntax Highlighting Scopes](#used-syntax-highlighting-scopes)
24 25


Patrik B's avatar
Patrik B committed
26
## Features
Patrik B's avatar
Patrik B committed
27

28
![Code highlighting and snippets](https://git.boc-group.eu/adoxx/adoscript-vs-code-support/raw/master/images/AdoxxAdoScriptExtension1.gif)
29

Patrik B's avatar
Patrik B committed
30 31 32
* Highlighting of both AdoScript code and LEO programs, with some help for noticing errors: if something isn't highlighted properly or even marked as illegal then there's probably some syntax error, like missing closing brackets or unintentional escaping of double quotes. Note: the debug modifier is marked as illegal.deprecated so it can be quickly identified in the code.
  * Any LEO-program (e.g. GRAPHREP, ATTRREP, EXPRESSION-type attributes etc.) now has basic code highlighting as long as it doesn't deviate from the LEO grammar.
  * Additionally AdoScript specific code highlighting is provided for its additional keywords and API-commands.
33 34 35
* Code snippets for typical LEO and AdoScript patterns, like conditional or loop statements and the AdoScript message port calls. All snippets in alphabetical order:
  * AdoScript - ccacq, ccado, ccana, ccapp, ccaql, cccore, cccui, ccdb, ccdoc, ccdraw, cceval, ccexp, ccimp, ccmod, ccsim, ccuser, fornum, fortok, else, elsif, if, while
  * LEO - cond, fornum, fortok, while
36
* Support for other common features like bracket matching / autoclosing, comment toggling, folding etc.
Patrik B's avatar
Patrik B committed
37

38
[(back to ToC)](#toc)
Patrik B's avatar
Patrik B committed
39

40
-------------------------------------------------------------------------------
Patrik B's avatar
Patrik B committed
41

42

Patrik B's avatar
Patrik B committed
43
## The Short Version of Recommendations and Restrictions
44

45
Add theme customization for AdoScript specific concepts through local settings. More about how, what and some settings that can simply be copied are found under [Recommendations](#recommendations).
46

47
Four restrictions have to be considered when writing AdoScript code with this Extension (more details can be found under [Restrictions](#restrictions):
48 49
* Only use the "new" style of IF-ELSIF-ELSE with curly brackets (`IF (...) { ... } ELSE { ... }`).
* Avoid using built-in variable / function names (lower-case identifiers), keywords and API-commands (upper-case identifiers) for self defined variables, functions and procedures.
Patrik B's avatar
Patrik B committed
50
* Don't split a parameter definition / assignment (`name:type`, `type:name`, `get-str-value:fname:"firstname"`) into several lines. It's fine to put different parameter definitions / assignments in separate lines or split a bracketed LEO expressions into several lines.
51
* When using `CC "Application" EXIT` then write it in one line.
52

53
[(back to ToC)](#toc)
Patrik B's avatar
Patrik B committed
54

Patrik B's avatar
Patrik B committed
55

Patrik B's avatar
Patrik B committed
56
## Recommendations
57

58 59
The syntax highlighting assigns scopes to the different parts of the code, which are then colored and styled according to the selected theme. While the syntax highlighting mostly relies on scopes commonly found in the available themes, it is possible to further fine-tune some of the formatting to better visualize some of the special AdoScript cases.  
It is not necessary to directly edit the used themes, since own customizations can be provided through the settings JSON file (`settings.json` accessible through the command palette, F1 or CTRL+SHIFT+P on Windows). There the `editor.tokenColorCustomizations` key can be used to specify text colors and styles for the different scopes which are then applied on top of the used theme. See below for a recommended code snippet that formats built-in functions, procedures and the `debug` modifier in italics and the TODO in comments in bold.  
60
More information on what scopes are made available by the syntax highlighting and for which parts of code can be found under [Used Syntax Highlighting Scopes](#used-syntax-highlighting-scopes).
61 62

```json
63
{ // Copy into settings.json
64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88
    "editor.tokenColorCustomizations": {
        "textMateRules": [
            {
                "name": "built-in LEO functions",
                "scope": [
                    "support.function",
                    "keyword.operator.new"
                ],
                "settings": { "fontStyle": "italic" }
            }, {
                "name": "API-commands in AdoScript",
                "scope": "support.function.api-command",
                "settings": { "fontStyle": "italic" }
            }, {
                "name": "the debug modifier",
                "scope": "invalid.deprecated.debug",
                "settings": { "fontStyle": "italic" }
            }, {
                "name": "the TODO in comments",
                "scope": "comment.todo",
                "settings": { "fontStyle": "bold" }
            }
        ]
    }
}
89
```
90
While the style for `support.function` applies to both the built-in LEO functions and the API-commands, the more specific `support.function.api-command` scope is also added to allow applying a different style for API-commands.
91

92
[(back to ToC)](#toc)
Patrik B's avatar
Patrik B committed
93

94

Patrik B's avatar
Patrik B committed
95
## Restrictions
96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120

> Don't worry, there's a lot of text, but it's only just 4 easy to follow restrictions.

The syntax highlighting can't cover everything that is technically allowed as valid code in AdoScript, due to how the two systems work. However, some of the cases that can't be covered by this extension could be regarded as bad practices and should be avoided. To ensure that everything works fine please consider the following list as a set of best practices when writing AdoScript code using this extension:

* Only the new style of IF-ELSIF-ELSE using curly brackets is supported (`IF (...) { ... } ELSE { ... }`).
* Don't use any of the data type names (like `integer`, `reference`, `map` etc.) or built-in function names (`aappend`, `array`, `map`, `abs`, `cond`, `lower`, etc.) as the exact identifier for your variable or function (lower-case identifiers). Also try to avoid using variable names that are used as parameters or return values (`objid`, `objids`, `attrid`, `return`, `result` etc.). While the code might work in some or even most cases, there is the danger that your variable will be overwritten by a command (for example a `CC`). For procedures avoid any exact matches with names used by an available API-command (upper-case identifiers, `INFOBOX`, `GET_ATTR_VAL`, `EVAL_AQL_EXPRESSION` etc.). Consider using meaningful prefixes in the names / identifiers you assign. See the following good and bad examples:
    ```ado-script
    # Good examples:
    SETL int_count:(10)
    SETL map_message:({"header": {"Content-Type": "text/plain"}, "body": "..."})
    SETL i:0
    SETL str_name:"AdoScript"
    FUNCTION my_token:global src:string tok:integer return:(...)
    FUNCTION array_init_zeroes return:(...)
    PROCEDURE BEEUP_INFOBOX ...

    # Bad examples:
    SETL reference:(3)
    SETL abs:("absolutely")
    SETL type:("AB+")
    FUNCTION token:global src:string tok:integer return:(...)
    FUNCTION array return:(...)
    PROCEDURE INFOBOX ...
    ```
Patrik B's avatar
Patrik B committed
121
* Definition of or value assignment to a parameter (for procedures, functions, basic commands like `SEND` and `CALL` etc.) should not be split into several lines. Basically this means that definitions like `name:type` or `type:name` or for example the `LEO` parameters like `get-str-value:fname:"firstname"` should be in the same line. Putting different parameter definitions / assignments in separate lines or spreading a bracketed LEO expressions among several lines is however fine. Consider the following good and bad examples:
122 123 124 125 126 127 128 129 130 131 132
    ```ado-script
    # Good examples:
    PROCEDURE MY_PROCEDURE integer:int_main str_separator:string {
        ...
    }
    PROCEDURE MY_OTHER_PROCEDURE string:str_main
                                 int_from:integer
                                 int_to:integer
    {
        ...
    }
Patrik B's avatar
Patrik B committed
133 134 135
    MC_OTHER_PROCEDURE ("imagine this string " +
            "being too long for " + 
            "one line")
136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159

    # Bad examples:
    PROCEDURE MY_OTHER_PROCEDURE string:
                                    str_main
                                 int_increment:
                                    integer
    {
        ...
    }
    ```
* When using `CC "Application" EXIT` write the API-command in the same line as the `CC` if you want it to highlight properly. This is necessary, because AdoScript uses EXIT both as an API-command (exit the application) and a normal command (exit a code block / script). Putting the API-command in the same line allows to distinguish the two from one another. Consider the following good and bad examples:
    ```ado-script
    # Good examples:
    CC "Application" EXIT
    CC "Application" debug EXIT

    # Bad examples:
    CC "Application"
        EXIT
    CC
        "Application" 
        EXIT
    ```

160
[(back to ToC)](#toc)
161

Patrik B's avatar
Patrik B committed
162 163

## Requirements
Patrik B's avatar
Patrik B committed
164

Patrik B's avatar
Patrik B committed
165
> Currently there are none. AdoScript knowledge helps though.
Patrik B's avatar
Patrik B committed
166

167
[(back to ToC)](#toc)
Patrik B's avatar
Patrik B committed
168

Patrik B's avatar
Patrik B committed
169

Patrik B's avatar
Patrik B committed
170
## Extension Settings
Patrik B's avatar
Patrik B committed
171

172
> Currently there are none.
Patrik B's avatar
Patrik B committed
173

174
[(back to ToC)](#toc)
Patrik B's avatar
Patrik B committed
175

176
-------------------------------------------------------------------------------
177

178

Patrik B's avatar
Patrik B committed
179
## Known Issues
180

181
* **More complex LEO grammar:** The documentation mentions some additional parts for the "LEO grammar" for which we currently don't know any cases or are unsure about. They have been skipped for now since we don't quite know where to use them. Kindly help us understand these better or even provide some cases and examples for them. These include:
182 183
  * Function calls with more parameters beyond the normal brackets. According to the grammar they would look something like `function(para1, para2, ...) {expr1} {expr2, expr3, ...} (expr4) {expr5, ...} ...`. The parts in questions are after the first `(para1, para2, ...)` list and are basically an unrestricted amount of lists in curly or round brackets containing comma separated expressions.

184
[(back to ToC)](#toc)
Patrik B's avatar
Patrik B committed
185

186
--------------------------------------------------------------------------------
187

188

Patrik B's avatar
Patrik B committed
189
## Release Notes
Patrik B's avatar
Patrik B committed
190

Patrik B's avatar
Patrik B committed
191
### 1.0.0 (not quite there yet ...)
Patrik B's avatar
Patrik B committed
192

Patrik B's avatar
Patrik B committed
193
Initial release, providing syntax highlighting, code snippets and other basic features for both LEO programs (.leo files) and AdoScript (.asc files).
Patrik B's avatar
Patrik B committed
194

195
[(back to ToC)](#toc)
Patrik B's avatar
Patrik B committed
196

197
--------------------------------------------------------------------------------
198 199


Patrik B's avatar
Patrik B committed
200
## Used Syntax Highlighting Scopes
201

202
The following scopes are set by this extension for code highlighting and can be used for further customizing of a theme. It's easiest to think of a single scope as multiple classes in CSS. Therefore, when providing a style it is usually enough to only provide a part of the scope. For example `constant.numeric` would apply to decimals, hexadecimals, measures and time/durations unless there is a more specific style overriding it, like `constant.numeric.hex` for hexadecimals. Additionally several scopes can apply to the same part of the code, especially when it is nested. For example the `9` inside of `(sqrt(9))` has the scopes (from highest to lowest priority): constant.numeric.decimal.leo, meta.call.function.built-in.leo, meta.embedded.leo-expression.leo and source.leo assigned to it.  
203 204 205 206 207 208 209 210 211 212
(... I also might've gone a bit mental with the meta scopes ...)  
The lists are sorted in alphabetical order.

### LEO
**Note**: all of the scopes end with `.leo` which will be omitted in the following list.  
**Note**: `meta.` generally covers the entire part of a specific code structure from start to finish (e.g. entire function call including parameters).
* comment.block - a multi-line comment
* comment.line.number-sign - single line comment
* comment.todo - the TODO keyword in a comment
* constant.character.escape - the escape character used in strings
213
* constant.language.modifier.assignment - used for modifiers used in a variable assignment.
214 215 216 217 218 219
* constant.numeric.decimal - a constant decimal number (e.g. 3, 5.3)
* constant.numeric.hex - a constant hexadecimal number (e.g. $6fa)
* constant.numeric.measure - a numeric constant denoting a measure (e.g. 3cm)
* constant.numeric.time - a numeric constant denoting a time or duration (e.g. 0:002:12:30:02)
* entity.name.function - the name of a non-built-in function
* invalid.illegal - anything that looks to be something that's not allowed at the place it is
220
* keyword.control.pass-on - the one commands that pass on the control flow to a different part of code (i.e. @INCLUDE)
221 222 223
* keyword.operator.new - functions for creating more complex values (arrays(), maps(), lambdas())
* keyword.operator.arithmetic - arithmetic operators including the unary negation (e.g. +, -, *)
* keyword.operator.comparison - operators for comparison (e.g. =, <>, <)
224
* keyword.other - the keywords used in a LEO program
225 226
* meta.call.function - the entire call of a function, especially non-built-in functions
* meta.call.function.built-in - the entire call of a built-in function, including parameters etc.
227
* meta.definition.body - the body that can be part in a LEO Program
228 229 230
* meta.definition.sequence - the entire direct definition of an array or map, which uses curly brackets
* meta.embedded.leo-expression - an entire embedded "LEO sub-expression" inside of another LEO expression, generally between two round brackets 
* meta.subscription - the entire subscription for an array or map including any contained expression through square brackets
231 232
* punctuation.section.block.begin - the { at the beginning of a body block
* punctuation.section.block.end - the } at the end of a body block
233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258
* punctuation.section.comment.begin - characters indicating the start of a multi-line comment
* punctuation.section.comment.end - characters indicating the end of a multi-line comment
* punctuation.section.comment.line - character indicating the start of a line comment
* punctuation.section.expression.begin - the ( at the beginning of an embedded "LEO sub-expression"
* punctuation.section.expression.end - the ) at the end of an embedded "LEO sub-expression"
* punctuation.section.parameters.begin - the ( at the beginning of a function's parameters list
* punctuation.section.parameters.end - the ) at the end of a function's parameter list
* punctuation.section.sequence.begin - the { at the beginning of an array or map definition
* punctuation.section.sequence.end - the } at the end of an array or map definition
* punctuation.section.subscription.begin - the [ at the beginning of a subscription for an array or map
* punctuation.section.subscription.end - the ] at the end of a subscription for an array or map
* source - anything that's considered a LEO expression
* string.quoted.double - a string using double-quotes
* string.quoted.double.begin - the beginning double-quote of a string
* string.quoted.double.end - the ending double-quote of a string
* support.function.arithmetic - arithmetic functions (e.g. CEIL, FLOOR, MOD, sin(), cos(), max())
* support.function.assignment - the single function used to assign values to a variable (set())
* support.function.color - functions that deal with the manipulation of color values (e.g. byte(), hsv2rgb())
* support.function.control - functions that behave like control structures (e.g. cond(), while(), for())
* support.function.conversion - functions for conversion of values (e.g. STR, VAL, CM, toutf8(), base64encode())
* support.function.dynamic - functions for dynamically getting information about the executed code, kind of like reflection (e.g. curlineno(), eval())
* support.function.error - functions for handling errors (error(), try())
* support.function.logical - logical operators more reminiscent of functions (AND, OR, NOT)
* support.function.other - functions that didn't fit any of the other types (e.g. getTickCount(), set())
* support.function.sequence - functions that are used for "sequence" data-types, like arrays, maps and strings (e.g. aappend, merase, .length)
* support.function.string - functions specifically for strings (e.g. search, token, tokcat)
259
* variable.other - the identifier of a variable, which is used as a parameter in a function that's pretty much the only place a variable is used in a LEO expression
260
* variable.parameter.assignment - the name of a parameter that gets a value assigned and isn't directly provided by the language (e.g. assignment of parameters for a self defined procedure)
261 262 263


### AdoScript
264
**Note**: AdoScript code can contain LEO expressions at many places and thus it is possible to encounter all of the scopes used in LEO where constants, strings, expressions or comments are encountered. For example single-line comments in AdoScript get the `comment.line.number-sign.leo` scope assigned.  
265 266
**Note**: all of the scopes end with `.asc` which will be omitted in the following list.  
**Note**: `meta.` generally covers the entire part of a specific code structure from start to finish (e.g. entire function call including parameters, entire procedure definition including the body).
267 268 269 270 271
* constant.language.assignment - constants used to be assigned to specific command parameters (e.g. child, same, separate for scope of EXECUTE)
* constant.language.system - constants used as flags to modify the behavior of the SYSTEM command
* entity.name.function - the name of a non-built-in function
* entity.name.function.procedure - the name of a non-built-in procedure (under this scope because procedures behave like functions in other languages)
* invalid.deprecated.debug - used to distinguish the debug modifier from its surroundings
272
* invalid.illegal - anything that looks to be something that's not allowed at the place it is
273
* keyword.control.internal - commands that control the flow inside the code without really passing it outside of the execution scope (e.g. IF, ELSE, FOR, WHILE, NEXT, BREAK)
274
* keyword.control.pass-on - commands that pass on the control flow to a different part of code or entity (e.g. START, EXIT, CC)
275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300
* keyword.other.assignment - commands that deal with assigning values to variables (SET, SETL, SETG, LEO)
* meta.assignment - everything that is considered part of an assignment using a SET, SETL or SETG command
* meta.assignment.leo - everything that is considered part of parsing and an assignment using a LEO command
* meta.call.api-command - everything that is considered part of an API-command call, both through SEND and CC
* meta.call.dll - everything that is considered part of a CALL command
* meta.control.body.else - the body of commands in an ELSE control structure
* meta.control.body.elsif - the body of commands in an ELSIF control structure
* meta.control.body.for - the body of commands in an FOR loop
* meta.control.body.if - the body of commands in an IF control structure
* meta.control.body.while - the body of commands in an WHILE loop
* meta.control.else - everything that falls under the ELSE control structure, including the body
* meta.control.elsif - everything that falls under the ELSIF control structure, including the body
* meta.control.for - everything that falls under the FOR loop, including the body
* meta.control.if - everything that falls under the IF control structure, including the body
* meta.control.while - everything that falls under the WHILE loop, including the body
* meta.definition.body.function - the body of commands in a function definition
* meta.definition.body.procedure - the body of commands in a procedure definition
* meta.definition.function - everything that falls under the definition of a new function, including the body
* meta.definition.procedure - everything that falls under the definition of a new procedure, including the body
* meta.execute - everything that is considered part of a EXECUTE command
* meta.exit- everything that is considered part of an EXIT command
* meta.include - everything that is considered part of a @INCLUDE command
* meta.start - everything that is considered part of a START command
* meta.system - everything that is considered part of a SYSTEM command
* punctuation.section.block.begin - the { at the beginning of a command block
* punctuation.section.block.end - the } at the end of a command block
301
* source - anything that's considered AdoScript code
302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324
* storage.modifier - keywords that act as modifiers for the storage of something else (e.g. raw in a CC, reference for a functions parameter)
* storage.modifier.global - a modifier that defines a function or procedure as globally available (global)
* storage.type - the built-in types (e.g. integer, real, string, array, map, lambda)
* storage.type.function - the keyword to define a new function
* storage.type.procedure - the keyword to define a new procedure
* support.class.message-port - the message ports which can be accessed using CC and SEND (e.g. "AdoScript", "Core")
* support.function.api-command.adoscript - the API-commands made available by the AdoScript message port
* support.function.api-command.analysis - the API-commands made available by the Analysis message port
* support.function.api-command.application - the API-commands made available by the Application message port
* support.function.api-command.aql - the API-commands made available by the AQL message port
* support.function.api-command.core - the API-commands made available by the Core message port
* support.function.api-command.coreui - the API-commands made available by the CoreUI message port
* support.function.api-command.db - the API-commands made available by the DB message port
* support.function.api-command.documentation - the API-commands made available by the Documentation message port
* support.function.api-command.drawing - the API-commands made available by the Drawing message port
* support.function.api-command.evaluation - the API-commands made available by the Evaluation message port
* support.function.api-command.explorer - the API-commands made available by the Explorer message port
* support.function.api-command.importexport - the API-commands made available by the ImportExport message port
* support.function.api-command.modeling - the API-commands made available by the Modeling message port
* support.function.api-command.simulation - the API-commands made available by the Simulation message port
* support.function.api-command.usermgt - the API-commands made available by the UserMgt message port
* variable.language.assignment - the name of a parameter from a command that gets a value assigned (e.g. file, scope for EXECUTE; result for SYSTEM)
* variable.other.assignment - the name of a variable (can also be an array or map) that gets a value assigned through using SET, SETL, SETG or LEO
Patrik B's avatar
Patrik B committed
325 326
* variable.parameter.definition - the name of a parameter that is defined (e.g. in a function or procedure definition)

327
[(back to ToC)](#toc)