# OneScript Overview

This provides a basic overview of the OneScript language and how it relates to the Macro Virtual Machine.

In reverence to all other languages OneScript offers the same capabilities as many other languages:

```csharp
using OneScript.Core;
Console.Write("Hello World");
```

## General Terms

These general terms refer to all elements of OneScript

* `ident` - refers to an identifier (for a variable or constant) that can contain almost any character, including Unicode characters. Identifiers can’t contain whitespace characters, mathematical symbols, arrows, private-use Unicode scalar values, or line- and box-drawing characters. Nor can they begin with a number, although numbers may be included elsewhere within the name.

  For example, 😺🙈, ⿅⿇⿌ and `init`.
* `literal` - a literal can refer to a value of numeric, string, boolean, date or set value.
* `numeric` - numeric values can be integers or floating point values.
* `string` - string values.
* `date` - date and/or time values.
* `set` - sets are a special collection of values that can be used with the categorical or multiple choice type questions in a survey.
* `enum` - a value type defined by a set of named constants of the underlying integral numeric type.

### Numeric Constants

Numerical constants can be in decimal, hexadecimal, binary, octal or float point. These can take the following forms:

| Type                   | Example                   |
| ---------------------- | ------------------------- |
| `decimal-value`        | 1, 2, -3                  |
| `hexadecimal-value`    | 0x12F                     |
| `binary-value`         | 0b10111                   |
| `octal-value`          | 0o1234567                 |
| `floating-point-value` | 0.23, -.12, -123.45, 0f23 |

### Date Constants

Because OneScript is a researchers programming language dates and times are handled in a specific manner.

A basic date can be defined&#x20;

```
0t2021-02-01
```

For information on dates [check here.](/onescript-overview/dates-and-times.md)

### Set Constants

Set constants can be an alpha optionally followed by an alphanumeric separated by a comma and surrounded by braces. For example:

* `{a}`
* `{_1,_2}`
* `{a1}`
* `{a,b1}`
* `{abc}`

For more information on Sets [check here](/onescript-overview/sets.md).

### Enum Constants

Enum constants are a way to using an identifier to reference a constant value rather that placing the constant value everywhere in the code. For example:

```csharp
enum Fluid {
    Water,
    Coke,
    Milk,
    Tea,
    Coffee
}
```

### Whitespace

OneScript programs are defined through the OneScript language which is case sensitive. It supports each keyword and associated operator can be separated with whitespace. The following can be considered to be whitespace:

* `Space`
* `Tab`
* `//` followed by a comment
* `/*` with a comment `*/`

### Keywords

The following keywords are reserved and may not be used as identifiers:

```
assert         async audio   await
base           bool           break
byte           case         catch       
class          continue     control 
date           default      define
do             else         enum
false          fields       fix
float          for
get
global         goto         helpers
if             in           int
initial        is           new
nocasedata
null           media        object
page           picture      precision
private        public       ref
return         scale        set
string         state
struct         switch       this
throw
time           true         try
typeof         using        while    
validation     video        void
```

### Basic Data Types

The following basic data types are built into OneScript

| Type     | Description                                                                       |
| -------- | --------------------------------------------------------------------------------- |
| `bool`   | a boolean value that be either true or false.                                     |
| `byte`   | an unsigned byte value                                                            |
| `int`    | a signed integer value                                                            |
| `float`  | a floating point value                                                            |
| `date`   | a date value                                                                      |
| `string` | a string value                                                                    |
| `enum`   | an enum numeric value.                                                            |
| `Set`    | a sets value                                                                      |
| `object` | an object                                                                         |
| `void`   | used to define the absence of a value (for example a method with no return value) |

### Objects

`object` refer to instances of classes that cannot be defined by the base types (bool, int, float, date, enum and string).

### Void

`void` refers to a 'no value' and is used to explain what is returned in a method.

### Null

`null` refers to a reference that has no value. This can be used to detect whether a value has been instantiated or not. If an object has not yet been instantiated then it is automatically set to null.

### String Constants

String constants are delimited with a double quote `"`. String constants are Unicode with the ability to add encoded values from the following list:

* `\n` - new line
* `\r` - return&#x20;
* `\t` - tab
* `\\` - back slash
* `\"` - double quote
* `""` - double quote

## Program Structure

OneScript is a "Light Object Orientated Language". This means it does not support inheritance within its own language, but does support it through the objects it can create from libraries.

Basic statements and declarations in a OneScript program are added to a "Main" static class if they are not declared explicitly within a class. The "Main" class is always used as the entry point to a Macro Virtual Machine program.

### Declarations

Basic declarations take the following form:

```csharp
int a = 0;
string b;
bool c, d;
float f = 0.2;
string 😺🙈 = "catmonkey";
```

### Collections

OneScript supports the concept of collections in a number of different ways. This section covers them.

#### Arrays

Declare arrays using brackets (`[]`), and create the array using the `new` statement.

```csharp
int[] a = new int[3];
```

Array values can also be initialised as part of the declaration.

```csharp
int[] a = {1,2,3};
```

Access the array elements using brackets:

```csharp
a[0] = 2;
```

> Currently only one dimensional arrays are supported. Multi dimensional arrays can be supported by creating nested arrays.

#### Ranges

Ranges are used to refer to set of values to reference. For example:

```csharp
[4..6]
```

The above statement declares a range of integers from 4 to 6 inclusive of the 4 and 6. Ranges can include any basic types. For example:

```csharp
[0t2021-08-01..0t2021-08-08]
[2.3..4.5]
```

Ranges can be used in the place of `for` statements:

```csharp
string animals = new string[6];
animals[3..5] = {”cat”, ”dog”, ”fish”};
```

The above statements create an array and set values 3 to 6 to specific values.

### Statements

Statements are used to control the flow of a program and manipulate data defined in declarations. The following demonstrates a simple OneScript program:

```csharp
string hw = "Hello Word";
Console.PrintLine(hw);
```

### Blocks

Statements can be grouped into blocks by using the `{` and `}` braces. This allows statements to refer to a group of statements rather just one. For example:

```csharp
if (a == 1) {
    a = 2;
    a = a + 1;
}
```

In some instances the a single statement can be used in place of a block. For example:

```csharp
if (a == 1)
    a = 2;
```

### Flow Control

OneScript contains the following program flow controls.

#### **If Statements**

A basic `if` statement requires a condition and a block referring to a statement that is executed if the statement results in a boolean value of `true`. For example:

```csharp
bool b = true;
if (b) {
    // Perform this block.
}
```

A more extensive `if` statement includes the `else` statement. For example:

```csharp
int b = 2;
if (b == 1) {
    // Perform this block
}
else {
    // Perform this block
}
```

It is possible to chain if statements together by using the `else if` phrasing:

```csharp
int b = 2;
if (b == 1) {
    // Perform this block
}
else if (b == 2) {
    // Perform this block
}
else {
    // Perform this block
}
```

#### **Immediate If Statements**

To save coding time it is possible to place an if statement within a statement:

```csharp
int a = 0;
Console.WriteLine(a == 0 ? "0" : "1");
```

If the condition is true then the first part of the immediate if phrase is performed otherwise the second phrase. In the case above, `a` equals `0` so the `"0"` will be chosen.

#### **Do..While Statements**

Do while statements follow the flow of performing a statement or block while an expression is true. For example:

```csharp
int a = 0;
do {
    a++;
} while (a < 30)
```

#### **While Statements**

While statements will perform the following statement or block whilst an expression is true. For example:

```csharp
int a = 0;
while (a < 20) {
    a++;
}
```

#### **For Statements**

For statements consist of a set of statements that control a loop. 1. A declaration initializer 2. A test 3. A changer

The simplest form of this is:

```csharp
for (int i = 0; i < 5; i++) {
    Console.Write(i);
}
```

In this example the `int i = 0` is the declaration initializer, the `i < 5` is the test and the `i++` is the changer.

#### **Iterator For Statements**

Iterator for statements are based on an iterator being implemented by the object be assessed. OneScript has a standard set of properties and methods that allow the iterator `for` statement to be to used.

```csharp
for (IQuestion question in questions) {
    question.Ask();
}
```

#### Range For Statements

Range for statements take the following form:

```csharp
int total = 0;
for (int number in [4..6]) {
    total += number;
}
```

In the above example the `total` will equal 15.

#### Array For Statements

Array for statements take the following form:

```csharp
string animals[] = {“cat”, ”dog”, ”camal”};
for (string animal in animals) {
    Console.WriteLine(animal);
}
```

In the above example the array of animals are wirtten to the console.

#### Break and Continue

The `break` statement will force the for loop to finish and move onto the next statement. The `continue` statement will force the process to jump to the next changer, if present, statement continuing the loop.

> Iterator capability will be opened up to user created OneScript objects in [future releases](/onescript-overview/future-features.md).

#### **Implied For Statements**

Implied range for statements use range specifications:

```csharp
int[] numbers = new int[5];
numbers[..] = 5;
```

In the above example all values in the array are set to value 5. The `..` is a special range specifier that refers to all elements.

#### **Switch Statements**

Switch statements supports any kind of data type and is designed to support testing for for equality of a value against other values:

```csharp
switch (question.QuestionName) {
    case "fred":
        question.Ask();
        break;
    case otherQuestion.QuestionName:
        otherQuestion.Ask();
        break;
    default:
        break;
}
```

Like many other languages the break statement will route the logic to the next statement outside of the switch block. Without the break statement the flow will continue to the next case statement.

#### **Goto Statements**

Goto statements rely on a label. They are basic representation of branching to a new statement. The following is an example:

```csharp
    b = 0;
start:
    if (b == 10) {
        goto exit;
    }

    b = b + 1;
    goto start;
exit:
    ...
```

### **Methods**

Methods are declared by using parentheses and a block of statements. For example:

```csharp
string greet(string person, string day) {
    return "Hello" + person + " today is " + day;
}
```

A method will automatically return after the last statement in the block or when a return statement (or throw statement) is performed.

```csharp
void greet(string person, string day) {
    Console.WriteLine("Hello" + person + " today is " + day);
}
```

> It is important the return value matches the declaration of the method itself.

#### **Return Statements**

Return statements are used to exit methods and return to the call include method. When the end of the statements are reached in a method an automatic return is carried out.

```csharp
void CheckStatus(int status) {
    if (status == 1) {
        return;
    }

    question.Ask();
}
```

### Error Handling

Error handling automatically handled by the Macro Virtual Machine. By default, when the application generates an error it will fail with unpredicted results and the user of the application must deal with it.

To take control of any errors it will be necessary to implement a `try..catch` coding control. For example:

```csharp
try {
    if (a == 1) {
        ...
    }
}
catch(Exception e) {
    ...
}
```

It is possible to provide a set of catch clauses for different errors. For example:

```csharp
try {
    if (a == 1) {
        ...
    }
}
catch(NullParameterException ne) {

}
catch(Exception e) {
    ...
}
```

Ultimately if the errors are not met then the error falls through to the next error handler in the stack. The catch statement can optional declare a variable that is store at the private method block level.

It is possible to force an error with the `throw` statement. for example:

```csharp
if (a == 0) {
    throw new Exception("There is a problem with a");
}
```

### Assertions

Assertions are checks that happen at runtime. They are used to make sure an essential condition is satisfied before executing any further code.

```csharp
int a = 3;
assert a == 2;
```

In the above example, the assertion will fail and cause an exception, which if not handled will force the program to stop.

### Snapshots

Snapshots are a unique feature of OneScript to support the ability to move back and forth in an application by defining a `snapshot` of the application to jump back to later.

```csharp
save snapshot "intro";
q1.Ask();
q2.Ask();
if (q2.Response.Value == null) {
    restore snapshot "intro";
}
```

A snapshot will hold information about the virtual machine position in the code and the restoration of a snapshot will automatically jump the flow of the application back to the statement directly after the save snapshot statement with the equivalent name.

> Note: The snapshots are automatically generated for questions in the Interview Model and named after the questions full name in the [Interview Model.](/standard-libraries/interview-model.md)

### State Management

Unlike many other languages OneScript passes data between its environment and the code using [state management](/onescript-overview/state-management.md). Other languages will pass a simple parameter and only at the beginning of running the program. OneScript can handle more complex data structures with state management and can share changes during the running of the program, not just at the entry point.

For full access to state management the OneScript Software Development is available. For general access we have built a set of environments that support the running of a survey.

## Operators and Expressions

OneScript supports a number of operators that can be split into the following groups:

### Arithmetic Operators

Arithmetic operators can be applied to `byte`, `int` and `float`. All types are signed.

### **Unary Operators**

Unary operators can be applied as prefixes or suffixes.

| Name | Description                                                                                                                                                  |
| ---- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `++` | Increment operator. Applied as a prefix the value is incremented by 1 before it is used. Applied as a suffix it is incremented by 1after the value is used.  |
| `--` | Decrement operator. Applied as a prefix the value is decremented by 1 before it is used. Applied as a suffix it is decremented by 1 after the value is used. |

### **Binary Operators**

| Name | Description                                                                                                                  |
| ---- | ---------------------------------------------------------------------------------------------------------------------------- |
| `+`  | Addition operator can be used to add integers or floating point number. It can also be used to concatenate strings and sets. |
| `-`  | Subtraction operator can be used to subtract integers, floating point numbers and sets.                                      |
| `/`  | Division                                                                                                                     |
| `*`  | Multiplication                                                                                                               |
| `%`  | Modulus                                                                                                                      |

### **Bitwise Operators**

Logical operators can be applied to `byte` and `int`.

| Name | Description          |
| ---- | -------------------- |
| `&`  | Bitwise and          |
| `\|` | Bitwise or           |
| `^`  | Bitwise exclusive or |

### **Conditional Operators**

Condition operators can be applied to ...

| Name | Description              |
| ---- | ------------------------ |
| `==` | Equal to                 |
| `!=` | Not equal to             |
| `>`  | Greater than             |
| `>=` | Greater than or equal to |
| `<`  | Less than                |
| `<=` | Less than or equal to    |

It is also possible to compare a value to `null`

### **is Operator**

The `is` operator can be used to check the type of an object and returns a boolean value to indicate a match:

```csharp
if (question is IQuestion) {
    question.Ask();
}
```

### **?? Operator**

The `??` operator (also known as the null coalescing operator) can be used to check whether a value is `null` and if provide another value to use as the expression result:

```csharp
if (question.Response.Value ?? "" == "") {
    question.Ask();
}
```

If the question.Response.Value is equal to `null` then use an empty string as the result.

### **Operator Precedence**

The following table shows the operator precedence. This can be overridden with the use of brackets around those parts of the expression that should take precedence.

| Name           | Description                       |
| -------------- | --------------------------------- |
| -- ++ ! (type) | unary operators                   |
| `*` / %        | Multiplication, division, modulus |
| `-` +          | Subtraction, addition             |
| is             | is operator                       |
| < > <= >=      | Comparison operators              |
| == !=          | Comparison operators              |
| & \| ^         | Bitwise operators                 |
| &&             | Logical And                       |
| \|\|           | Logical Or                        |
| ??             | Null coalescing                   |
| ?              | Immediate if                      |

## Fields

To make OneScript a researchers language it supports the definition of fields that hold the definitions of questions to be asked and results to be stored for analysis. Fields are declared in a field block:

```csharp
fields {
    catGRCOptIn { ENU:"<b>Do you have a <u>Genting Rewards Card</u>?</b>", 
                  ZHA:"您是否持有<u>云尊卡</u>？" } 
        categorical [1..1] {
            r01 { ENU:"Yes" , ZHA:"是" } factor (1),
            r02 { ENU:"No" , ZHA:"否" } factor (2), 
            - "No Answer" NA factor (99)
        };
}
```

A field can describe the options, language and controls to be used in the asking of a question, but is also accessible through the object interfaces (IInterview, IQuestion, ICategory, etc.) automatically generated for OneScript.

```csharp
catGRCOptIn.MustAnswer = false;
CatGRCOptIn.Ask();
```

When the `Ask` method of a question is used a Snapshot is automatically generated to support the ability to move back and forth through questions. A feature that is supported by DIY Surveys.

For more information on Field please refer to the [Fields Reference](/onescript-overview/fields.md)

## Classes

Classes are a way of encapsulating methods and properties together. Unlike other languages OneScript classes only have basic capabilities and cannot be inherited or used in polymorphisms.

```csharp
class Shape {
    public int numberOfSides = 0;
    public string SimpleDescription() {
        return "A shape with " + numberOfSides + " sides";
    }
}
```

An instance of a class can be created in the following way:

```csharp
Shape shape = new Shape();
shape.numberOfSides = 3;
shape.SimpleDescription();
```

## Structures

Structures are similar to classes in that they can contain methods and properties.

```csharp
structure Animal {
    public string Name;
}
```

Structures are not instantiated in the same way as a class:

```csharp
Animal cow;
cow.Name = “Ermintrude”;
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://www.onescript.org/onescript-overview.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
