hugo website for pit
This commit is contained in:
311
docs/language.md
Normal file
311
docs/language.md
Normal file
@@ -0,0 +1,311 @@
|
||||
---
|
||||
title: "ƿit Language"
|
||||
description: "Syntax, types, operators, and built-in functions"
|
||||
weight: 10
|
||||
type: "docs"
|
||||
---
|
||||
|
||||
ƿit is a scripting language for actor-based programming. It combines a familiar syntax with a prototype-based object system and strict immutability semantics.
|
||||
|
||||
## Basics
|
||||
|
||||
### Variables and Constants
|
||||
|
||||
```javascript
|
||||
var x = 10 // mutable variable (block-scoped like let)
|
||||
def PI = 3.14159 // constant (cannot be reassigned)
|
||||
```
|
||||
|
||||
### Data Types
|
||||
|
||||
ƿit has six fundamental types:
|
||||
|
||||
- **number** — DEC64 decimal floating point (no rounding errors)
|
||||
- **text** — Unicode strings
|
||||
- **logical** — `true` or `false`
|
||||
- **null** — the absence of a value (no `undefined`)
|
||||
- **array** — ordered, numerically-indexed sequences
|
||||
- **object** — key-value records with prototype inheritance
|
||||
- **blob** — binary data (bits, not bytes)
|
||||
- **function** — first-class callable values
|
||||
|
||||
### Literals
|
||||
|
||||
```javascript
|
||||
// Numbers
|
||||
42
|
||||
3.14
|
||||
1_000_000 // underscores for readability
|
||||
|
||||
// Text
|
||||
"hello"
|
||||
'world'
|
||||
`template ${x}` // string interpolation
|
||||
|
||||
// Logical
|
||||
true
|
||||
false
|
||||
|
||||
// Null
|
||||
null
|
||||
|
||||
// Arrays
|
||||
[1, 2, 3]
|
||||
["a", "b", "c"]
|
||||
|
||||
// Objects
|
||||
{name: "pit", version: 1}
|
||||
{x: 10, y: 20}
|
||||
```
|
||||
|
||||
### Operators
|
||||
|
||||
```javascript
|
||||
// Arithmetic
|
||||
+ - * / %
|
||||
** // exponentiation
|
||||
|
||||
// Comparison (always strict)
|
||||
== // equals (like === in JS)
|
||||
!= // not equals (like !== in JS)
|
||||
< > <= >=
|
||||
|
||||
// Logical
|
||||
&& || !
|
||||
|
||||
// Assignment
|
||||
= += -= *= /=
|
||||
```
|
||||
|
||||
### Control Flow
|
||||
|
||||
```javascript
|
||||
// Conditionals
|
||||
if (x > 0) {
|
||||
log.console("positive")
|
||||
} else if (x < 0) {
|
||||
log.console("negative")
|
||||
} else {
|
||||
log.console("zero")
|
||||
}
|
||||
|
||||
// Ternary
|
||||
var sign = x > 0 ? 1 : -1
|
||||
|
||||
// Loops
|
||||
for (var i = 0; i < 10; i++) {
|
||||
log.console(i)
|
||||
}
|
||||
|
||||
for (var item of items) {
|
||||
log.console(item)
|
||||
}
|
||||
|
||||
for (var key in obj) {
|
||||
log.console(key, obj[key])
|
||||
}
|
||||
|
||||
while (condition) {
|
||||
// body
|
||||
}
|
||||
|
||||
// Control
|
||||
break
|
||||
continue
|
||||
return value
|
||||
disrupt
|
||||
```
|
||||
|
||||
### Functions
|
||||
|
||||
```javascript
|
||||
// Named function
|
||||
function add(a, b) {
|
||||
return a + b
|
||||
}
|
||||
|
||||
// Anonymous function
|
||||
var multiply = function(a, b) {
|
||||
return a * b
|
||||
}
|
||||
|
||||
// Arrow function
|
||||
var square = x => x * x
|
||||
var sum = (a, b) => a + b
|
||||
|
||||
// Rest parameters
|
||||
function log_all(...args) {
|
||||
for (var arg of args) log.console(arg)
|
||||
}
|
||||
|
||||
// Default parameters
|
||||
function greet(name, greeting = "Hello") {
|
||||
return `${greeting}, ${name}!`
|
||||
}
|
||||
```
|
||||
|
||||
All closures capture `this` (like arrow functions in JavaScript).
|
||||
|
||||
## Arrays
|
||||
|
||||
Arrays are **distinct from objects**. They are ordered, numerically-indexed sequences. You cannot add arbitrary string keys to an array.
|
||||
|
||||
```javascript
|
||||
var arr = [1, 2, 3]
|
||||
arr[0] // 1
|
||||
arr[2] = 10 // [1, 2, 10]
|
||||
length(arr) // 3
|
||||
|
||||
// Array spread
|
||||
var more = [...arr, 4, 5] // [1, 2, 10, 4, 5]
|
||||
```
|
||||
|
||||
## Objects
|
||||
|
||||
Objects are key-value records with prototype-based inheritance.
|
||||
|
||||
```javascript
|
||||
var point = {x: 10, y: 20}
|
||||
point.x // 10
|
||||
point["y"] // 20
|
||||
|
||||
// Object spread
|
||||
var point3d = {...point, z: 30}
|
||||
|
||||
// Prototype inheritance
|
||||
var colored_point = {__proto__: point, color: "red"}
|
||||
colored_point.x // 10 (inherited)
|
||||
```
|
||||
|
||||
### Prototypes
|
||||
|
||||
```javascript
|
||||
// Create object with prototype
|
||||
var child = meme(parent)
|
||||
|
||||
// Get prototype
|
||||
var p = proto(child)
|
||||
|
||||
// Check prototype chain
|
||||
isa(child, parent) // true
|
||||
```
|
||||
|
||||
## Immutability with Stone
|
||||
|
||||
The `stone()` function makes values permanently immutable.
|
||||
|
||||
```javascript
|
||||
var config = stone({
|
||||
debug: true,
|
||||
maxRetries: 3
|
||||
})
|
||||
|
||||
config.debug = false // Error! Stone objects cannot be modified
|
||||
```
|
||||
|
||||
Stone is **deep** — all nested objects and arrays are also frozen. This cannot be reversed.
|
||||
|
||||
```javascript
|
||||
stone.p(value) // returns true if value is stone
|
||||
```
|
||||
|
||||
## Built-in Functions
|
||||
|
||||
### length(value)
|
||||
|
||||
Returns the length of arrays (elements), text (codepoints), blobs (bits), or functions (arity).
|
||||
|
||||
```javascript
|
||||
length([1, 2, 3]) // 3
|
||||
length("hello") // 5
|
||||
length(function(a,b){}) // 2
|
||||
```
|
||||
|
||||
### use(path)
|
||||
|
||||
Import a module. Returns the cached, stone value.
|
||||
|
||||
```javascript
|
||||
var math = use('math/radians')
|
||||
var json = use('json')
|
||||
```
|
||||
|
||||
### isa(value, type)
|
||||
|
||||
Check type or prototype chain.
|
||||
|
||||
```javascript
|
||||
is_number(42) // true
|
||||
is_text("hi") // true
|
||||
is_array([1,2]) // true
|
||||
is_object({}) // true
|
||||
isa(child, parent) // true if parent is in prototype chain
|
||||
```
|
||||
|
||||
### reverse(array)
|
||||
|
||||
Returns a new array with elements in reverse order.
|
||||
|
||||
```javascript
|
||||
reverse([1, 2, 3]) // [3, 2, 1]
|
||||
```
|
||||
|
||||
### logical(value)
|
||||
|
||||
Convert to boolean.
|
||||
|
||||
```javascript
|
||||
logical(0) // false
|
||||
logical(1) // true
|
||||
logical("true") // true
|
||||
logical("false") // false
|
||||
logical(null) // false
|
||||
```
|
||||
|
||||
## Logging
|
||||
|
||||
```javascript
|
||||
log.console("message") // standard output
|
||||
log.error("problem") // error output
|
||||
```
|
||||
|
||||
## Pattern Matching
|
||||
|
||||
ƿit supports regex patterns in string functions, but not standalone regex objects.
|
||||
|
||||
```javascript
|
||||
text.search("hello world", /world/)
|
||||
replace("hello", /l/g, "L")
|
||||
```
|
||||
|
||||
## Error Handling
|
||||
|
||||
ƿit uses `disrupt` and `disruption` for error handling. A `disrupt` signals that something went wrong. The `disruption` block attached to a function catches it.
|
||||
|
||||
```javascript
|
||||
var safe_divide = function(a, b) {
|
||||
if (b == 0) disrupt
|
||||
return a / b
|
||||
} disruption {
|
||||
log.error("something went wrong")
|
||||
}
|
||||
```
|
||||
|
||||
`disrupt` is a bare keyword — it does not carry a value. The `disruption` block knows that something went wrong, but not what.
|
||||
|
||||
To test whether an operation disrupts:
|
||||
|
||||
```javascript
|
||||
var should_disrupt = function(fn) {
|
||||
var caught = false
|
||||
var wrapper = function() {
|
||||
fn()
|
||||
} disruption {
|
||||
caught = true
|
||||
}
|
||||
wrapper()
|
||||
return caught
|
||||
}
|
||||
```
|
||||
|
||||
If an actor has an unhandled disruption, it crashes.
|
||||
Reference in New Issue
Block a user