The CaseMaster Script Language
reviewed: 14 February 2025
(From hereon I refer to CaseMaster Script simply as cms).
Cms is the scripting language of CaseMaster and is an interpreted procedural language (3GL) combined with a number of concepts from Object Oriented languages.
Cms is a small language that is mainly concerned with flow control. The actual functionality is provided by function handlers.
Building Blocks
Each .cms file will consist of one of the following building blocks:
| Building Block | Usage |
|---|---|
| Comments | Comments are considere white space |
| Directives | Directives are instructions that appear before anything else (with exception of optional comments) and are instructions that apply to the entire script |
| Functions | Functions are blocks of statements and are executable entry points of a script |
| Conditions | Conditions are very specific functions used for filtering (where clauses) and business object state tests |
| Resources | Resource contain property bags and are non-executable |
| Statements | Statements form the executable code and can only appear inside functions or conditions |
Lexical Rules
- Cms is case-insensitive
- Spaces, tabs, newlines and comments are all considered white space (unless within quotes)
- Identifiers consist of letters, digits, underscores, hyphens and dots. The first character should not be a digit
- Statements can span multiple lines
- Cms supports double quotes ("), single quotes (') and back-ticks (`) as a string enclosure
- Cms uses the point (.) as decimal separator regardless of the locale setting of the server
- Cms does not accept thousand seperators in numbers
- Cms does not accept scientific notation of double precision numbers
- The backslash (\) escapes the next character of its' special meaning
Cms supports the following literals:
| Token | Use | Examples |
|---|---|---|
| String | Can start with ', " or `; must end with same quote as start-quote. Use backslash (\) to escape next character | 'Hello world' |
| "Hello World" | ||
| "That's all" | ||
| 'That\s all' | ||
| Integer | Digits | 1 |
| 12 | ||
| 06 | ||
| -8 | ||
| Decimal | Digits, '.' as decimal separator, no thousand seperator, no scientific notation | 18.8876 |
| 18.8876 | ||
| -6.3 | ||
| Date | Starts and ends with '#' | #1/1/2025# |
| #2024/12/6# | ||
| #6jan2024# | ||
| Time | String with hh:mm and optionally :ss | '12:10' |
| '18:06:45' | ||
| Boolean | 1 or 0, 't' or 'f', 'y' or 'n' (or true() or false()) | true |
| 't' | ||
| '0' | ||
| 'n' | ||
| 'N' | ||
| Property bag | Cms equivalent of JSON | < initials: 'B' surname: 'Dispa' > |
The Back-tick String
Cms supports three types of string enclosures; the single quote, the double quote and the back-tick.
'Hello world'
"Hello world"
'It\'s a boy'
"It's a boy"
`It's a boy`
`
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Sed ut magna ut tortor aliquam ultrices pretium ac odio.
Praesent gravida augue diam, ac hendrerit urna ultrices nec.
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
`
The back-tick has a special function when the string spans multiple lines (as in the last example).
Each line break is part of the string but the leading white-space on each subsequent line is not part of the string. This is convenient to keep a neat layout of your code.
The following two strings are thus exactly the same:
`
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Sed ut magna ut tortor aliquam ultrices pretium ac odio.
Praesent gravida augue diam, ac hendrerit urna ultrices nec.
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
`
`
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Sed ut magna ut tortor aliquam ultrices pretium ac odio.
Praesent gravida augue diam, ac hendrerit urna ultrices nec.
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
`
Comments
Cms knows two types of comments:
- Rest of line comments
- Block comments
A rest-of-line comment is indicated by //.
// Copyright (c) 9 Knots Business Solutions Ltd. All rights reserved.
A block-comment starts with /* and ends with */. All text in between is considered a comment.
summary: 'Defines an applications caching polices',
items: <
/*
<@qualifier/schema/item
name: 'script',
summary: 'The script caching policy'
qualifier: '@configuration/caching/policy',
defaultValue: qualifier.get('./defaultValues', 'policy')
>
*/
>
>
Directives
Before anything else in a .cms file (with the exception of optional comments), you can have directives. These are instructions to the CaseMaster runtime that apply to the entire script file.
The following directives are supported:
| Directive | Usage |
|---|---|
| inherits | Indicates that this script inherits from another script |
| trace | Activate tracing for all functions in this specific script |
| cache | Highly specialist directive; can be used to override standard caching behavior for this specific script |
Inheritance and tracing are covered in other documents.
Variables
Variables in cms do not have to be defined before use and the type is defined by the value it is assigned to them. A variable will change type when a value of another type is assigned to it.
You can refer to a variable by enclosing the variable name square brackets ([ and ]).
set( 'variable', 1 ) // Variable is now a long
set( 'variable', '1' ) // Variable is now a string
set( 'otherVariable', [variable] ) // Referring to a variable
Functions
A function is defined by the function and end-function keywords. The function keyword is followed by a valid identifier which is the name of the function. The name must be unique within the .cms file.
function someFunction()
// Statements here
end-function
The function name is followed by the parameter list. When a function does not have any parameters, the parenthesis are still required.
Parameters are separated by comma's. Parameters are mandatory unless a parameter has a default value set.
// Variables a, b and c where c is an optional parameter
function someFunctionWithParameters( a, b, c:null() )
// Statements here
end-function
When a function is called, you can pass parameters named or unnamed. If you explicitly name parameters the sequence is not relevant.
function someFunctionWithParameters( a, b, c:null() )
// Statements here
end-function
function otherFunction()
// Call with all 3 parameters
script.call( './someFunctionWithParameters', 1, 2, 3 )
// Call with all mandatory parameters
script.call( './someFunctionWithParameters', 1, 2)
// Call with named parameters
script.call( './someFunctionWithParameters', a:1, b:2 )
// Call with named parameters in different sequence
script.call( './someFunctionWithParameters', b:2, c:3, a:1 )
// Incorrect: cannot have unamed parameters follow a named parameter
script.call( './someFunctionWithParameters', b:2, c:3, 1 )
end-function
Returning a value from a function is optional. Use the keyword return to return a value.
function surface( length, width )
return mul( [length], [width] )
end-function
You can exit a function prematurely using the exit-function keyword.
function main()
// For security we hide access to this page when not in DEVL group
if not( ingroup( 'DEVL' ) )
page.call( 'error/404' )
exit-function
end-if
// More code here
A function can have an access modifier. This defines how the function is accessible. The following modifiers are supported.
| Modifier | Usage | Notes |
|---|---|---|
| Public | No restrictions on access to this function | Default value so can be left out |
| Private | This function is only accessible to code in the same script | |
| Protected | This function is only accessible to code in the same script or a script that inherits from this script | |
| Internal | This function is not a public end-point | Only relevant for page scripts 1) |
| Static | This function can not be invoked on business objects, only on entities | Only relevant for BO scripts 2) |
- See chapter on Pages in Details
- See chapter on Business Objects in Details
Conditions
Conditions are highly specific function that have a function in where clauses as well as testing. Conditions are only relevant for BO scripts.
condition isActive()
return 'status=1'
end-condition
It is beyond the scope of this document to explain conditions in detail. See here for more information.
A condition can take parameters just like functions.
Only the access modifiers public, private and protected apply to conditions.
Resources
A resource is a named place where you can store a property bag.
The concept of property bags and resources is explained in the document on Property Bags, Qualifiers and Resources.
The access modifiers public, static (BO's only) and internal (pages only) apply to conditions.
<End of document>