summaryrefslogtreecommitdiffhomepage
path: root/docs
diff options
context:
space:
mode:
authorJo-Philipp Wich <jo@mein.io>2023-07-13 12:33:28 +0200
committerJo-Philipp Wich <jo@mein.io>2023-07-13 12:34:07 +0200
commit9d5e420540d77779f32117795dd1711768b83a8f (patch)
treec66f804af98b0f5480bded0f7b44444b015552ed /docs
parent64e774b05d76753454cda01b853f2ab31d571623 (diff)
docs: add information about memory management and operator precedence
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
Diffstat (limited to 'docs')
-rw-r--r--docs/README.md148
1 files changed, 148 insertions, 0 deletions
diff --git a/docs/README.md b/docs/README.md
index 660f175..05761f9 100644
--- a/docs/README.md
+++ b/docs/README.md
@@ -657,3 +657,151 @@ operator which removes a property from an object value.
print(a); // { }
%}
```
+
+##### 5.7. Precedence
+
+Operator precedence determines the order in which operators are evaluated in an
+expression. In ucode, operators have different precedence levels, as outline
+in the table below.
+
+| Precedence | Operator type | Associativity |
+|------------|-----------------------------------|----------------|
+| 19 | Grouping `( … )` | n/a |
+| 18 | Property access `… . …` | left-to-right |
+| 18 | Optional chaining `… ?. …` | left-to-right |
+| 18 | Computed propery access `… [ … ]` | n/a |
+| 18 | Function call `… (…)` | n/a |
+| 17 | Postfix increment `… ++` | n/a |
+| 17 | Postfix decrement `… --` | n/a |
+| 16 | Logical not `! …` | n/a |
+| 16 | Bitwise not `~ …` | n/a |
+| 16 | Unary plus `+ …` | n/a |
+| 16 | Unary negation `- …` | n/a |
+| 16 | Prefix increment `++ …` | n/a |
+| 16 | Prefix decrement `-- …` | n/a |
+| 16 | Property deletion `delete …` | n/a |
+| 15 | Exponentiation `… ** …` | right-to-left |
+| 14 | Multiplication `… * …` | left-to-right |
+| 14 | Division `… / …` | left-to-right |
+| 14 | Remainder `… % …` | left-to-right |
+| 13 | Addition `… + …` | left-to-right |
+| 13 | Substraction `… - …` | left-to-right |
+| 12 | Bitwise left shift `… << …` | left-to-right |
+| 12 | Bitwise right shift `… >> …` | left-to-right |
+| 11 | Less than `… < …` | left-to-right |
+| 11 | Less than or equal `… <= …` | left-to-right |
+| 11 | Greater than `… > …` | left-to-right |
+| 11 | Greater than or equal `… >= …` | left-to-right |
+| 11 | In `… in …` | left-to-right |
+| 10 | Equality `… == …` | left-to-right |
+| 10 | Inequality `… != …` | left-to-right |
+| 10 | Strict equality `… === …` | left-to-right |
+| 10 | Strict inequality `… !== …` | left-to-right |
+| 9 | Bitwise AND `… & …` | left-to-right |
+| 8 | Bitwise XOR `… ^ …` | left-to-right |
+| 7 | Bitwise OR `… | …` | left-to-right |
+| 6 | Logical AND `… && …` | left-to-right |
+| 5 | Logical OR `… || …` | left-to-right |
+| 5 | Nullish coalescing `… ?? …` | left-to-right |
+| 4 | Assignment `… = …` | right-to-left |
+| 4 | Assignment `… += …` | right-to-left |
+| 4 | Assignment `… -= …` | right-to-left |
+| 4 | Assignment `… **= …` | right-to-left |
+| 4 | Assignment `… *= …` | right-to-left |
+| 4 | Assignment `… /= …` | right-to-left |
+| 4 | Assignment `… %= …` | right-to-left |
+| 4 | Assignment `… <<= …` | right-to-left |
+| 4 | Assignment `… >>= …` | right-to-left |
+| 4 | Assignment `… &= …` | right-to-left |
+| 4 | Assignment `… ^= …` | right-to-left |
+| 4 | Assignment `… |= …` | right-to-left |
+| 4 | Assignment `… &&= …` | right-to-left |
+| 4 | Assignment `… ||= …` | right-to-left |
+| 4 | Assignment `… ??= …` | right-to-left |
+| 3 | Ternary `… ? … : …` | right-to-left |
+| 2 | Arrow `… => …` | right-to-left |
+| 2 | Spread `... …` | n/a |
+| 1 | Sequence `… , …` | left-to-right |
+
+Operators with a higher precedence value are evaluated before operators with a
+lower precedence value. When operators have the same precedence, their
+associativity determines the order of evaluation
+(e.g., left-to-right or right-to-left).
+
+
+## Memory Management
+
+The ucode scripting language utilizes a reference count-based garbage collector
+as its primary method of memory management. When assigning an array or object
+value, the reference count is incremented. When a local variable holding a
+reference goes out of scope, the reference count is decremented. If the
+reference count reaches zero, a recursive traversal is performed to decrease the
+reference count of any nested references. Once the traversal is complete, the
+top-level array or object structure is freed.
+
+Example 1:
+```javascript
+x = [ { a: 1 }, { b: 2 }, { c: 3 } ];
+// `x` holds a reference to `[...]` (refcount 1)
+// `x[0]` holds a reference to `{ a: 1 }` (refcount 1)
+// `x[1]` holds a reference to `{ b: 2 }` (refcount 1)
+// `x[2]` holds a reference to `{ c: 3 }` (refcount 1)
+
+x = null;
+// refcount of `[...]` drops to 0; refcount decreasing cascades
+// down, `{ a: 1 }`, `{ b: 2 }` and { c: 3 }` refcounts reach
+// zero as well; `{ a: 1 }`, `{ b: 2 }`, `{ c: 3 }` and `[ ... ]`
+// are freed
+```
+
+Example 2:
+```javascript
+x = [ { a: 1 }, { b: 2 }, { c: 3 } ];
+y = x[1];
+// `x` holds a reference to `[...]` (refcount 1)
+// `x[0]` holds a reference to `{ a: 1 }` (refcount 1)
+// `x[1]` and `y` hold a reference to `{ b: 2 }` (refcount 2)
+// `x[2]` holds a reference to `{ c: 3 }` (refcount 1)
+
+x = null;
+// refcount of `[...]` drops to 0, refcount decreasing cascades
+// down, `{ a: 1 }` and `{ c: 3 }` refcounts reach zero while
+// `{ b: 2 }` refcount is down to one.
+// `{ a: 1 }`, `{ c: 3 }` and `[ ... ]` are freed
+// `{ b: 2 }` is still alive with refcount 1, pointed to by `y`
+```
+
+Although the reference count-based garbage collector efficiently manages memory,
+it cannot handle cyclic structures, leading to memory leaks.
+
+Example 1:
+```javascript
+o = { }; o.x = o;
+// `o` holds a reference to itself (refcount 1)
+
+```
+
+Example 2:
+```javascript
+a = [ ]; a[0] = a;
+// `a` holds a reference to itself (refcount 1)
+```
+
+Example 3:
+```javascript
+x = { y: { z: [ ] } }; x.y.z = x;
+// `x` holds a reference to itself through `x.y.z` (refcount 1)
+```
+
+In these examples, cyclic references are created where objects or arrays point
+back to themselves or create a circular chain. Since each element within the
+cycle maintains a reference, the reference count for each object or array never
+reaches zero, resulting in a memory leak. The reference count-based garbage
+collector cannot automatically reclaim memory in such cases.
+
+To address cyclic structures and avoid memory leaks, ucode provides a secondary
+mark-and-sweep garbage collector. This collector can be enabled by passing the
+`-g` flag to the ucode interpreter or manually triggered using the
+[`gc()`](/module-core.html#gc) function during runtime. The mark-and-sweep
+collector identifies and frees unreachable objects, including those involved in
+cyclic references.