Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions docs/Features/Language/Operators.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ permalink: /Features/Language/Operators

# New Operators

twinBASIC introduces several new operators to enhance language capabilities.
twinBASIC introduces several new operators to enhance language capabilities. Reference pages for each individual operator live under [Reference → Operators](../../Reference/Operators).

## Bitshift Operators

Expand All @@ -17,12 +17,12 @@ twinBASIC introduces several new operators to enhance language capabilities.

### OrElse and AndAlso

With the regular `Or` and `And` statements, both sides are evaluated, even when not necessary. With a short circuit operator, if the condition is resolved by the first side, the other side is not evaluated. So if you have:
`If Condition1 OrElse Condition2 Then`, if Condition1 is `True`, then `Condition2` will not be evaluated, and any code called by it will not run.
With the regular [`Or`](../../tB/Core/Or) and [`And`](../../tB/Core/And) statements, both sides are evaluated, even when not necessary. With a short-circuit operator, if the condition is resolved by the first side, the other side is not evaluated. So if you have
`If Condition1 `[`OrElse`](../../tB/Core/OrElse)` Condition2 Then`, if `Condition1` is `True`, then `Condition2` will not be evaluated, and any code called by it will not run. The companion conjunction operator is [`AndAlso`](../../tB/Core/AndAlso).

### If() Operator

Short-circuit `If()` operator with syntax identical to the tradition `IIf`. This has the additional benefit of not converting variables into a `Variant` if they're the same type; i.e. `If(condition, Long, Long)` the `Long` variables will never become a `Variant`.
Short-circuit [`If()`](../../tB/Core/If) operator with syntax identical to the traditional [`IIf`](../../tB/Core/IIf). This has the additional benefit of not converting variables into a `Variant` if they're the same type; i.e. `If(condition, Long, Long)` the `Long` variables will never become a `Variant`.

## Assignment Operators

Expand All @@ -32,5 +32,5 @@ These are the equivalent of `var = var (operand) (var2)`. So `i += 1` is the equ

## IsNot Operator

The logical opposite of the *Is* operator for testing object equivalence. For example, instead of `If (object Is Nothing) = False` you could now write `If object IsNot Nothing Then`.
The logical opposite of the [`Is`](../../tB/Core/Is) operator for testing object equivalence. For example, instead of `If (object Is Nothing) = False` you could now write `If object `[`IsNot`](../../tB/Core/IsNot)` Nothing Then`.

2 changes: 1 addition & 1 deletion docs/Reference/Compiler Constants.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
title: Compiler Constants
parent: Reference Section
nav_order: 4
nav_order: 5
permalink: /Reference/Compiler-Constants
---

Expand Down
67 changes: 67 additions & 0 deletions docs/Reference/Core/And.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
---
title: And
parent: Operators
grand_parent: Reference Section
permalink: /tB/Core/And
---
# And operator
{: .no_toc }

Used to perform a logical conjunction on two expressions.

Syntax:
> *result* **=** *expression1* **And** *expression2*

*result*
: Any numeric variable.

*expression1*, *expression2*
: Any expressions.

If both expressions evaluate to **True**, *result* is **True**. If either expression evaluates to **False**, *result* is **False**. The following table illustrates how *result* is determined:

| If *expression1* is | And *expression2* is | The *result* is |
|:-----|:-----|:-----|
| **True** | **True** | **True** |
| **True** | **False** | **False** |
| **True** | **Null** | **Null** |
| **False** | **True** | **False** |
| **False** | **False** | **False** |
| **False** | **Null** | **False** |
| **Null** | **True** | **Null** |
| **Null** | **False** | **False** |
| **Null** | **Null** | **Null** |

The **And** operator also performs a bitwise comparison of identically positioned bits in two numeric expressions and sets the corresponding bit in *result* according to the following table:

| If bit in *expression1* is | And bit in *expression2* is | The *result* is |
|:-----:|:-----:|:-----:|
| 0 | 0 | 0 |
| 0 | 1 | 0 |
| 1 | 0 | 0 |
| 1 | 1 | 1 |

> [!NOTE]
> **And** evaluates *both* operands every time, even when *expression1* alone determines the result. Use [**AndAlso**](AndAlso) when you want short-circuit evaluation — for example, when *expression2* is expensive, has side effects, or would fail without the guard provided by *expression1*.

### Example

This example uses the **And** operator to perform a logical conjunction on two expressions.

```tb
Dim A, B, C, D, MyCheck
A = 10: B = 8: C = 6: D = Null ' Initialize variables.
MyCheck = A > B And B > C ' Returns True.
MyCheck = B > A And B > C ' Returns False.
MyCheck = A > B And B > D ' Returns Null.
MyCheck = A And B ' Returns 8 (bitwise comparison).
```

### See Also

- [**AndAlso** operator](AndAlso)
- [**Or** operator](Or)
- [**Not** operator](Not)
- [Operators](../../Reference/Operators)

{% include VBA-Attribution.md %}
52 changes: 52 additions & 0 deletions docs/Reference/Core/AndAlso.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
---
title: AndAlso
parent: Operators
grand_parent: Reference Section
permalink: /tB/Core/AndAlso
---
# AndAlso operator
{: .no_toc }

Performs a short-circuit logical conjunction of two **Boolean** expressions. If the left operand evaluates to **False**, the right operand is not evaluated.

> [!NOTE]
> **AndAlso** is a twinBASIC extension. The classic [**And**](And) operator always evaluates both operands and returns a bitwise result; **AndAlso** evaluates the right operand only when needed and always returns a **Boolean**.

Syntax:
> *result* **=** *expression1* **AndAlso** *expression2*

*result*
: A **Boolean** variable.

*expression1*, *expression2*
: Any expressions that evaluate to **Boolean** (or are coercible to **Boolean**).

If *expression1* is **False**, *result* is **False** and *expression2* is not evaluated. Otherwise *expression2* is evaluated and its **Boolean** value becomes *result*.

This is the standard "short-circuit AND". It is useful when *expression2* depends on *expression1* having succeeded — for example, a null-check guarding a property access.

### Example

Guarding a property access by first verifying the object reference:

```tb
If obj IsNot Nothing AndAlso obj.IsReady Then
' Safe to call - obj.IsReady is only evaluated when obj is non-Nothing.
obj.DoWork
End If
```

Compare with the equivalent code using **And**, which would crash if `obj` were **Nothing** because both operands are always evaluated:

```tb
' WRONG - obj.IsReady is evaluated even when obj is Nothing.
If obj IsNot Nothing And obj.IsReady Then
obj.DoWork
End If
```

### See Also

- [**OrElse** operator](OrElse)
- [**And** operator](And)
- [Operators](../../Reference/Operators)
3 changes: 2 additions & 1 deletion docs/Reference/Core/Is.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
---
title: Is
parent: Statements
parent: Operators
grand_parent: Reference Section
permalink: /tB/Core/Is
---
# Is
Expand Down
3 changes: 2 additions & 1 deletion docs/Reference/Core/IsNot.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
---
title: IsNot
parent: Statements
parent: Operators
grand_parent: Reference Section
permalink: /tB/Core/IsNot
---
# IsNot
Expand Down
47 changes: 47 additions & 0 deletions docs/Reference/Core/Mod.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
---
title: Mod
parent: Operators
grand_parent: Reference Section
permalink: /tB/Core/Mod
---
# Mod operator
{: .no_toc }

Used to divide two numbers and return only the remainder.

Syntax:
> *result* **=** *number1* **Mod** *number2*

*result*
: Any numeric variable.

*number1*, *number2*
: Any numeric expressions.

The modulus, or remainder, operator divides *number1* by *number2* (rounding floating-point numbers to integers) and returns only the remainder as *result*. For example, in the following expression, A (*result*) equals 5:

```tb
A = 19 Mod 6.7
```

Usually, the data type of *result* is **Byte**, **Byte** variant, **Integer**, **Integer** variant, **Long**, or **Variant** containing a **Long**, regardless of whether *result* is a whole number. Any fractional portion is truncated.

However, if any operand is **Null**, *result* is **Null**. Any operand that is **Empty** is treated as 0.

### Example

This example uses the **Mod** operator to divide two numbers and return only the remainder. If either number is a floating-point number, it is first rounded to an integer.

```tb
Dim MyResult
MyResult = 10 Mod 5 ' Returns 0.
MyResult = 10 Mod 3 ' Returns 1.
MyResult = 12 Mod 4.3 ' Returns 0.
MyResult = 12.6 Mod 5 ' Returns 3.
```

### See Also

- [Operators](../../Reference/Operators)

{% include VBA-Attribution.md %}
56 changes: 56 additions & 0 deletions docs/Reference/Core/Not.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
---
title: Not
parent: Operators
grand_parent: Reference Section
permalink: /tB/Core/Not
---
# Not operator
{: .no_toc }

Used to perform logical negation on an expression.

Syntax:
> *result* **=** **Not** *expression*

*result*
: Any numeric variable.

*expression*
: Any expression.

The following table illustrates how *result* is determined:

| If *expression* is | Then *result* is |
|:-----|:-----|
| **True** | **False** |
| **False** | **True** |
| **Null** | **Null** |

In addition, the **Not** operator inverts the bit values of its operand and sets the corresponding bit in *result* according to the following table:

| If bit in *expression* is | Then bit in *result* is |
|:-----:|:-----:|
| 0 | 1 |
| 1 | 0 |

### Example

This example uses the **Not** operator to perform logical negation on an expression.

```tb
Dim A, B, C, D, MyCheck
A = 10: B = 8: C = 6: D = Null ' Initialize variables.
MyCheck = Not (A > B) ' Returns False.
MyCheck = Not (B > A) ' Returns True.
MyCheck = Not (C > D) ' Returns Null.
MyCheck = Not A ' Returns -11 (bitwise comparison).
```

### See Also

- [**And** operator](And)
- [**Or** operator](Or)
- [**IsNot** operator](IsNot)
- [Operators](../../Reference/Operators)

{% include VBA-Attribution.md %}
68 changes: 68 additions & 0 deletions docs/Reference/Core/Or.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
---
title: Or
parent: Operators
grand_parent: Reference Section
permalink: /tB/Core/Or
---
# Or operator
{: .no_toc }

Used to perform a logical disjunction on two expressions.

Syntax:
> *result* **=** *expression1* **Or** *expression2*

*result*
: Any numeric variable.

*expression1*, *expression2*
: Any expressions.

If either or both expressions evaluate to **True**, *result* is **True**. The following table illustrates how *result* is determined:

| If *expression1* is | And *expression2* is | Then *result* is |
|:-----|:-----|:-----|
| **True** | **True** | **True** |
| **True** | **False** | **True** |
| **True** | **Null** | **True** |
| **False** | **True** | **True** |
| **False** | **False** | **False** |
| **False** | **Null** | **Null** |
| **Null** | **True** | **True** |
| **Null** | **False** | **Null** |
| **Null** | **Null** | **Null** |

The **Or** operator also performs a bitwise comparison of identically positioned bits in two numeric expressions and sets the corresponding bit in *result* according to the following table:

| If bit in *expression1* is | And bit in *expression2* is | Then *result* is |
|:-----:|:-----:|:-----:|
| 0 | 0 | 0 |
| 0 | 1 | 1 |
| 1 | 0 | 1 |
| 1 | 1 | 1 |

> [!NOTE]
> **Or** evaluates *both* operands every time, even when *expression1* alone determines the result. Use [**OrElse**](OrElse) when you want short-circuit evaluation — for example, when *expression2* is expensive, has side effects, or only matters when *expression1* is **False**.

### Example

This example uses the **Or** operator to perform logical disjunction on two expressions.

```tb
Dim A, B, C, D, MyCheck
A = 10: B = 8: C = 6: D = Null ' Initialize variables.
MyCheck = A > B Or B > C ' Returns True.
MyCheck = B > A Or B > C ' Returns True.
MyCheck = A > B Or B > D ' Returns True.
MyCheck = B > D Or B > A ' Returns Null.
MyCheck = A Or B ' Returns 10 (bitwise comparison).
```

### See Also

- [**OrElse** operator](OrElse)
- [**And** operator](And)
- [**Not** operator](Not)
- [Operators](../../Reference/Operators)

{% include VBA-Attribution.md %}
Loading