zongors-universe-machine/SPECIFICATION.MD

589 lines
13 KiB
Markdown

# *zwl* (zongors world language) Design parameters, for *zwm* (zongors world machine)
## Modern programming languages in the 21st century usually have need for the following requirements
### Data
- describing data
- numeric
- string
- logical
- complex
- point
- edge
- color
- many more
- qualitative
- sentiment analysis
- more...
- measurements
- tons of these...
### Inputing data
- stdio
- program args
- command line
- reading from other source
- gui
- input boxes
- forms
- many others
### Storing descriptions of data
- internal
- graph
- array
- list
- set
- map
- external
- database
- local
- cloud
- writing data
- stdout
- stderr
- writing to other source
- file
- tape
- socket
### Manipulating data
- algorithms
- sort
- filter
- math functions
- trigonometric
- statistics
- calculus
- many more
- Validating data
- business rules
- constraints
- formulas
### Displaying data
- objects
- 3d models
- 2d models
- graphs
- tables
- infographics
- written output
- ai generated text
### System/World Objects
- Viewing objects in nth dimensional space
- Animations
- moving the objects in space
- manipulating objects
- Interaction from user input on objects in space
- Creating
### Communication
- Sending and receiving data
- protocols
- Controlling real world objects
- embedded programs
- web programs
- mobile
- desktop
- smart devices (IOT)
- Encryption
- hashing
- keys
- more ...
### Meta
- documentation
- tutorials
- generating objects automatically like
### Data Description
- windowing system
- window
- terminal
- web browser
- form of the object (description)
- version number
- fields
- forms
- what dimensional object
- unit form / measurements
- display
- What the UI default should be
- type of display
- position in space
- user controls
- validations
- communications
- CRUD
- create
- read
- update
- delete
# *zwl* at a high level.
zwl should be thought of as more of a scripting language for virtual machine more than a programming language that is compiled.
# *zwl* Grammar and Specification
## Form
- describe storage objects "the ideal state of the object"
- atoms (invoked forms) are stored in the internal database which is why they need version numbers
- Forms can be implementations of interfaces, collsions are not important as the names of interfaces only carry what needs to be implemented a not any implemtntation itself. for people coming from OOP you can think of this similar to an abstract class.
- there are also a list of "substantial forms" which come with the language which are the building blocks for more complex forms. If you are coming from object oriented languages you can think of this as "primitive types"
- all forms derive from the root form or the "parent of all forms"
All substantial forms are "fat pointers" like in [Cello](https://www.libcello.org/). and have the following structure (here I will use a psudo C as an example):
```c
typedef enum error_e {
none, // no error
bound, // array out of bounds error
} error;
typedef enum type_e {
u8,
u16,
} type;
typedef struct type_s {
size_t sz; // size/length of the pointer
error err; // the error on the form (default is none)
void *ptr;
} frm;
```
So as you can see each type includes some extra information, its type, if it has an error, the length, and the 'real' pointer to the value.
```
frm «form_token» impls «this_form», «that_form» {
version; ! version number for auto saving to a database or whatnot
migrate; ! this is to migrate from the previous version to new, in case of interface changes, or None
dimensions; ! this returns how many dimensions it can exist in, 0th means non drawable, 2 means 2D GUI usually, 3 means 3D object, and >3 is somthing you will have to implement yourself, e.g. miegakure
unit; ! this is for the unit/measures system
display; ! some kind of UI form or None
position; ! a position in space or None
}
```
# Substantial Forms
## numeric
### bit (or unsigned units)
`u8, u16, u32, u64`
### integer (signed)
`i8, i16, i32, i64`
### real
`f32, f64`
## string
`str`
matching `''` for char
matching `""` for string
strings are always utf8, other formats will need to be done manually
## logical
`bool`
`true` / `false`
Also follows the style boolean 'c' rules of nonzero / zero, but the interpreter will make fun of you
## null values
*zwl* does not have null, because each value can have an error on it.
error is a form which describes an error that occurred, it is similar to the Go programming language and is returned as a monad like the maybe monad above and is unwrapped in a similar way, take a look at the tunnel section for an example
```
1| i32 a = 3; ! this would be similar to the follwing in Rust: `let a: Result<i32, &'static str> = Ok(3);`
2| i32 b; ! or like in Rust: `let b: Result<i32, &'static str>;`
3|
4| i32 x = a; ! this will set x to 3
5| i32 y = b; ! this will set the error part of y to an undefined error because we tried setting a undefined variable to another variable, imagine in Rust: `let y: Result<i32, &'static str> = Err("undefined");`
6| i32 z = b ? 1; ! this will check if b has an error and since it does it will set y = 1;
7|
8| print("$x $y $z\n") ! prints 3, "error: failed to unwrap a 'none' on line 5", 1
```
additionally, if a value has an error it will evaluate as "false" and Just as "true" in a boolean check, unless you are explicitly checking for an error
### panic
calling panic on a variable that has an error will halt execution of the node that is running.
```
i32 n;
i32 e = n; ! this will set e's error that we tried setting n to undefined.
err (e) { ! we can check if there is an error by using the `err` keyword in the same way as an `if`
panic(e); ! panic will halt exectution of the task and pass a message what the error was to all the other tasks listening.
}
```
## datastructures
### list
syntax
```
«form»[] «atom_token» = [item1 item2 …];
```
### set
same as list except does not allow duplicates, allows set operations
n is the starting size of the set
```
«form»{} «atom_token»();
```
sets also have the following transforms associated with them
### map
a simple form to form storage
```
«form» ~> «form» «atom_token»();
```
### tunnel
described in "tunnel" section
### uri
matching `` (backtics)
### Basic operators
The following is a list of global operators and their effect:
```
!
comment
!!
block comment (looks for another !! to close)
=
set operator
?
unwrap
?=
unwrap and set
\
lambda function
+
addition
-
subtraction
negation
*
multiplication
/
divisor
**
power
.
accessor
..
expander
(1..10) is the same as writing (1,2,3,4,5,6,7,8,9,10)
++
inline add 1
--
inline subtract 1
+=
inline add n
-=
inline subtract n
*=
inline multiply n
\=
inline divide n
**=
inline power n
```
### basic transforms
```
eq
equal to
ne
not equals to
mod
modulo
not
logical not
and
logical and
or
logical or
nor
logical nor
nand
logical nand
xor
logical xor
band
bitwise and
bor
bitwise or
bnor
bitwise nor
bxor
bitwise xor
```
## Atom
An atom is an invoked form.
For those of you coming from an object oriented language
this is similar to creating an object on the heap using "new" keyword or the like
Atoms persist in the universe until they are not needed.
Each atom has its own "process" with "socket like" i/o.
an atom can be created (in the universe) using the following syntax:
```
«form» «atom_token»(«fields», …);
```
note: if the atom name is omitted, it will make the atom unaccessible! but it is allowed, this is usually useful in the "universe" namespace
## Tunnel
Represents a path to a file, url endpoint, other process endpoint (like a socket, etc.)
Tunnels are inspired by translators in gnu/hurd, plan9 9p protocol, and unix sockets
tunnels are invoked like atoms, but have scope like control flow end scope closes the tunnel
note the form must always be of a form which is "tunnel-able" i.e. Files, sockets, etc
### transforms for tunnels
`tunnel attach(tunnel_atom)` -> open communication
`bool success = tunnel_atom.clunk()` -> close communication
`bool success = tunnel_atom.flush()` -> cancels long operation and dumps whatever is in buffer
`bool success = tunnel_atom.open(resource, mode)` -> opens a tunnel for doing operations on
`bool success = tunnel_atom.create(resource)` -> creates the object from the database graph/file from file structure
`«form» data = tunnel_atom.read(resource)` -> reads from a tunnel
`bool success = tunnel_atom.write(resource, data)` -> writes to a tunnel
`bool success = tunnel_atom.remove(resource)` -> removes the object from the database graph/file from file structure
`«form» stat_data = tunnel_atom.stat(resource)` -> returns the status of the file/resource
`«form» version = tunnel_atom.version()` -> returns the version code for the connected tunnel
`bool success = tunnel_atom.walk(path_or_endpoint)` -> moves around the filesystem or through the graph
```
«some form» data();
«tunnel-able form» endpoint(endpoint_str);
«tunnel» tunnel = endpoint.attach(user, auth);
data = tunnel.open(`\some\resource`).read()
std.write(data) ! will either write the data or if the data has an error will write the error message instead
tunnel.flush()
endpoint.clunk()
```
in "terminal mode" the default tunnel is std
in "web mode" the default tunnels are log, info, trace, warn, error, but note these are all special tunnels which only accept write commands
## Transforms
```
tf «transform_token» («form» «parameter», ...) «return_form», ... {
«instructions»
}
```
You can also create a lambda/closure form by using the syntax
```
\«form» «parameter», ... {
«instructions»
}
```
- Built in transforms
- sort
- filter
- trig functions
- calc functions
- statistical functions
## Control flow
### loops
```
for «token» in «collection», +/-/iter { «body» }
```
iterates through each object in the collection setting it to token
```
while «boolean expression» { «body» }
```
loops until the expression is false
```
loop { «body» }
```
loops infinitely until break or return
### match
```
match «token» {
'a' -> actionA
'x' -> actionX
'y'..'z' -> {
actionY
actionZ
}
someTransformOfTokensForm -> actionSomeTransform
\«token's form» t { t <= 5 and t > 0 } -> actionLambda
_ -> actionNoMatch
}
```
### exceptions
take a look at error's, but you can panic on an error like this:
```
panic(error("error message"));
panic(error(-3));
panic(«some_error_token»);
```
## Libraries and “includes”
In most languages the include or use statements get libraries which link to other files and so on. This quickly gets confusing and so requires package managers and installers, etc.
The other way to do this would be to just specifically “name” the paths using a tunnel and import it. You can even use localization tokens to create config files.
Since everything is lazily compiled jit anyways it (in theory) doesn't hurt performance much
```
import `https://raw.githubusercontent.com/some_user/some_library/some_file.zwl`;
```
```
import `./some_local_file.zwl`;
```
## Universe
All forms and complications exist within the universe.
The universe can be thought of as the "global" namespace in an object oriented language or as the kernel for the "atom processes" to exist in.
a "main" space should be created that invokes the required startup atoms of the syntax.
in kOS this actually *is* the kernel layer
## GUI
The GUI is inspired by PicoLisp and Electron, using a web browser engine to render the GUI including 3D stuff like webgl.
Most html elements have an analogous form in *zwl*: Tables, lists, links, buttons, input boxes, etc.
In kOS these are replaces by its own version of these forms.
These of course can be wrapped in your own implementations. The idea is that on *zwls* side all UI is unified by forms but also is interoperable with HTML, templating engines, or gui libraries
## Concurrency
As in elixir there are as many schedulers as there are cores for your cpu
Like in CM and real time micro architecture systems like QNX tasks are scheduled based on priority and must stay within a time limit or it will be “punished” into a lower priority
Threading in *zwl* are split up into tasks (which take input) and daemons (which take no input)
Tasks are spawned whereas daemons are summoned
Message passing can be achieved by using tunnels.
probably should take concurrency stuff from golang; its very nice
## Testing
Tests are done inside of a `test` block
```
test some_test {
someTransform() -> true
}
```
## Measurement
- forms
- time
- unit
- seconds (s)
- subforms
- date
- Default is ISO 8601
- length
- unit
- metre (m)
- subforms
- angle
- radian (rad)
- mass
- unit
- kilogram (kg)
- electric current
- unit
- ampere (a)
- temperature
- unit
- kelvin (K)
- amount of substance
- unit
- mol (mol)
- luminous intensity
- unit
- candela (candela)