move stuff into docs, rewrite spec, edit readme
This commit is contained in:
parent
7ae64fb165
commit
8c9e574a5e
|
@ -6,8 +6,8 @@ It is inspired by [uxn](https://wiki.xxiivv.com/site/uxn.html), [var'aq](https:/
|
|||
|
||||
The universe machine works as a series of stack based virtual cpu's (node) and ram as a simple hashmap (hram) that each have a single stack which are able to communicate with each other using message passing.
|
||||
|
||||
The machine code of this node is a series of stack operations which act on the individal node. each node has the ability to ask the kernel to spawn an additional node or to spawn a child node off of itself which sets up a couple of communication channels automatically.
|
||||
The machine code of this node is a series of stack operations which act on the individual node. each node has the ability to ask the kernel to spawn an additional node or to spawn a child node off of itself which sets up a couple of communication channels automatically.
|
||||
|
||||
The authors main implementation of ZUM in written in C and uses the [SDL2](https://www.libsdl.org/) library to do drawing, sound, and other things.
|
||||
The authors main implementation of ZUM in written in LUA/C and uses the [SDL2](https://www.libsdl.org/) library to do drawing, sound, and other things.
|
||||
|
||||
Others
|
548
SPECIFICATION.MD
548
SPECIFICATION.MD
|
@ -1,548 +0,0 @@
|
|||
# _zwl_ (zongors world language) Design parameters
|
||||
|
||||
## What is _zwl_?
|
||||
|
||||
_zwl_ is an esoteric programming language that is trying way too hard to be a serious programming language.
|
||||
|
||||
It is inspired by both [esoteric programming languages](https://esolangs.org/wiki/Esoteric_programming_language), like [var'aq](https://web.archive.org/web/20091026213516/http://geocities.com/connorbd/varaq/), [uiua](https://www.uiua.org/), and [TIS-100 assembly](https://www.zachtronics.com/images/TIS-100P%20Reference%20Manual.pdf) and serious programming languages like C, Perl, Common Lisp, Lua, Rust, Go, Odin, Zig, Elixir, and Haskell.
|
||||
|
||||
## What are the features in _zwl_?
|
||||
|
||||
In general the paradigms are designed to be: var'aq-like, Interpreted, Distributed, Concurrent, and have an option to be JIT.
|
||||
|
||||
## What is the purpose of this language?
|
||||
|
||||
_zwl_ acts as the assembly language for the universe machine. it allows for a user to manipulate the world machine.
|
||||
|
||||
# _zwl_ Grammar and Specification
|
||||
|
||||
How do I read these operations?
|
||||
|
||||
With most of the operations below they will be in the follwing format
|
||||
|
||||
anything between « » should be read as a type of thing and not a literal
|
||||
|
||||
for any operations they will look like
|
||||
|
||||
« input arguments » `operator` « output arguments »
|
||||
|
||||
unless stated you should assume that any arguments are pushed or poped from the nodes stack, if it does not return a value I will use `-`
|
||||
|
||||
## 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"
|
||||
- the "constructor" of it is
|
||||
- string for the name of the form
|
||||
- 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
|
||||
- this is for the unit/measures system
|
||||
- some kind of procedure to draw the element in space or None
|
||||
- a position in space or None
|
||||
- the list of allowed forms that can be used as input
|
||||
- a list containing the data of that form
|
||||
|
||||
"form-name" «dimensions» «unit» «display» «position» («list» «of» «allowed» «input» «forms» …) («data» …) `frmdef` -
|
||||
|
||||
# Substantial Forms
|
||||
|
||||
## numeric
|
||||
|
||||
### bit (or unsigned units)
|
||||
|
||||
«hex number» 8 `u` u8
|
||||
|
||||
«hex number» «hex number» 16 `u` u16
|
||||
|
||||
«hex number» «hex number» «hex number» 32 `u` u32
|
||||
|
||||
«hex number» «hex number» «hex number» «hex number» 64 `u` u64
|
||||
|
||||
### integer (signed)
|
||||
|
||||
«hex number» 8 `i` u8
|
||||
|
||||
«hex number» «hex number» 16 `i` u16
|
||||
|
||||
«hex number» «hex number» «hex number» 32 `i` u32
|
||||
|
||||
«hex number» «hex number» «hex number» «hex number» 64 `i` u64
|
||||
|
||||
### real
|
||||
|
||||
«hex number» «hex number» «hex number» 32 `f` f32
|
||||
|
||||
«hex number» «hex number» «hex number» «hex number» 64 `f` f64
|
||||
|
||||
## string
|
||||
|
||||
" «utf8 encoded characters» `"` string
|
||||
|
||||
strings are always utf8, other formats will need to be done manually
|
||||
|
||||
## logical
|
||||
|
||||
### true
|
||||
|
||||
- `true` bool
|
||||
|
||||
### false
|
||||
|
||||
- `false` bool
|
||||
|
||||
### panic
|
||||
|
||||
calling panic on a variable that has an error will halt execution of the node that is running. it will broadcast the reason to the main kernel and to all other nodes listening
|
||||
|
||||
"reason" `panic` -
|
||||
|
||||
## datastructures
|
||||
|
||||
### list
|
||||
|
||||
A list will act similar to a list in LISP, it is esentially a block of memory that has an internal "length" and other operations.
|
||||
|
||||
( «item» «item2» … `)`
|
||||
|
||||
### Basic operators
|
||||
|
||||
The following is a list of global operators and their effect:
|
||||
|
||||
#### comment (looks for another ! to close)
|
||||
|
||||
! any raw text here `!` -
|
||||
|
||||
#### anonymous subtroutine
|
||||
|
||||
{ … `}` subroutine
|
||||
|
||||
#### sets a value in the node's map
|
||||
|
||||
"«name of the value [no spaces]»" «value» `set` -
|
||||
|
||||
#### delete from node's map
|
||||
|
||||
«name-of-the-item» `del`
|
||||
|
||||
#### adds the top values on the stack
|
||||
|
||||
num num `add` num (of same type)
|
||||
|
||||
#### subtracts the top values on the stack
|
||||
|
||||
num num `sub` num (of same type)
|
||||
|
||||
#### multiplys the top values on the stack
|
||||
|
||||
num num `mul` num (of same type)
|
||||
|
||||
#### divides the top values on the stack
|
||||
|
||||
num num `div` num (of same type)
|
||||
|
||||
#### does a n'th power the top values on the stack
|
||||
|
||||
num num `pow` num (of same type)
|
||||
|
||||
#### returns the divisor of the top values on the stack
|
||||
|
||||
num num `mod` num (of same type)
|
||||
|
||||
#### checks if the top values on the stack are equal
|
||||
|
||||
val val `eq` bool
|
||||
|
||||
#### checks if the top values on the stack are not equal
|
||||
|
||||
val val `ne` bool
|
||||
|
||||
#### checks if the top values on the stack are equal
|
||||
|
||||
val val `not` bool
|
||||
|
||||
#### does an and operation on the top of the stack
|
||||
|
||||
bool bool `and` bool
|
||||
|
||||
#### does an or operation on the top of the stack
|
||||
|
||||
bool bool `or` bool
|
||||
|
||||
#### does an not-or operation on the top of the stack
|
||||
|
||||
bool bool `nor` bool
|
||||
|
||||
#### does an not-and operation on the top of the stack
|
||||
|
||||
bool bool `nand` bool
|
||||
|
||||
#### does an exclusive or operation on the top of the stack
|
||||
|
||||
bool bool `xor` bool
|
||||
|
||||
#### does an bitwise and operation on the top of the stack
|
||||
|
||||
val val `band` val (of same type)
|
||||
|
||||
#### does an bitwise or operation on the top of the stack
|
||||
|
||||
val val `bor` val (of same type)
|
||||
|
||||
#### does an bitwise nor operation on the top of the stack
|
||||
|
||||
val val `bnor` val (of same type)
|
||||
|
||||
#### does an bitwise xor operation on the top of the stack
|
||||
|
||||
val val `bxor` val (of same type)
|
||||
|
||||
#### does an bitwise shift left
|
||||
|
||||
val num `sll` val (of same type)
|
||||
|
||||
#### does an bitwise shift right
|
||||
|
||||
val num `srl` val (of same type)
|
||||
|
||||
#### checks the form of the value on top of the stack
|
||||
|
||||
«value» «form» `?` bool
|
||||
|
||||
## 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 are pushed onto the stack of the node they are running in.
|
||||
|
||||
Here is an example of creating an atom and storing it as a variable in nram (the nodes map)
|
||||
|
||||
"atom name" («fields», …) `«form»` set
|
||||
|
||||
## 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
|
||||
|
||||
### subroutines for tunnels
|
||||
|
||||
#### create a new tunnel
|
||||
|
||||
«field», … `«tunnel-able form»` tunnel
|
||||
|
||||
#### open communication
|
||||
|
||||
args, … `attach` bool tunnel
|
||||
|
||||
#### close communication
|
||||
|
||||
tunnel `clunk` bool
|
||||
|
||||
#### cancels long operation and dumps whatever is in buffer
|
||||
|
||||
tunnel `flush` bool tunnel
|
||||
|
||||
#### opens a tunnel for doing operations on
|
||||
|
||||
tunnel resource mode `open` bool tunnel
|
||||
|
||||
#### creates the object from the database graph/file from file structure
|
||||
|
||||
tunnel resource `create` bool tunnel
|
||||
|
||||
#### reads from a tunnel
|
||||
|
||||
tunnel resource `read` «form» tunnel
|
||||
|
||||
#### writes to a tunnel, gets response from endpoint
|
||||
|
||||
tunnel resource data `write` bool tunnel
|
||||
|
||||
#### removes the object from the database graph/file from file structure
|
||||
|
||||
tunnel resource `remove` bool tunnel
|
||||
|
||||
#### returns the status of the file/resource
|
||||
|
||||
tunnel resource `stat` tunnel «status data»
|
||||
|
||||
#### returns the version code for the connected tunnel, returns of version info
|
||||
|
||||
tunnel `version` (list) tunnel
|
||||
|
||||
#### moves around the filesystem or through the graph
|
||||
|
||||
tunnel "path-or-endpoint" `walk` bool tunnel
|
||||
|
||||
#### example
|
||||
|
||||
```
|
||||
"echo-tunnel" "user" "auth" "http://example.com" url attach set ! create a new tunnel called "echo tunnel" and attach it to the resource !
|
||||
"hello world" "/some/rest/echo" echo-tunnel open pop write ! open the endpoint and read write the "hello world" to it !
|
||||
echo-tunnel read std write ! syncronously read in the data echoed back from the endpoint and print it to stdout !
|
||||
flush
|
||||
clunk pop
|
||||
"echo-tunnel" del
|
||||
```
|
||||
|
||||
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
|
||||
|
||||
### built in tunnleable forms
|
||||
|
||||
#### file
|
||||
|
||||
A file that exists on the local filesystem
|
||||
|
||||
#### http
|
||||
|
||||
A file or data endpoint that exists on the internet or other network using the http protocol
|
||||
|
||||
#### https
|
||||
|
||||
A file or data endpoint that exists on the internet or other network using the https protocol
|
||||
|
||||
#### 9p
|
||||
|
||||
A file or data endpoint that exists on the internet or other network using the 9p protocol
|
||||
|
||||
## subroutines
|
||||
|
||||
{ «instructions» `}`
|
||||
|
||||
- Subroutines in stdlib
|
||||
- sort
|
||||
- filter
|
||||
- trig functions
|
||||
- calc functions
|
||||
- statistical functions
|
||||
- I/O
|
||||
- networking
|
||||
- more...
|
||||
|
||||
## Control flow
|
||||
|
||||
### loops
|
||||
|
||||
runs the subroutine infinitely until it breaks or panics
|
||||
|
||||
{ «body» } `loop` ?
|
||||
|
||||
runs the subroutine a given number of times
|
||||
|
||||
«some numeric value» { «body» } `repeat` ?
|
||||
|
||||
runs the subroutine for each element on the stack
|
||||
|
||||
{ «body» } `map` ?
|
||||
|
||||
## 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.
|
||||
|
||||
The import subroutine takes in a tunnel and evaluates the contents in the node. import the same as creating a tunnel, reading the contents, and evaluating the response.
|
||||
|
||||
"«string of resource location»" «tunnel-able form» `import` -
|
||||
|
||||
For example:
|
||||
|
||||
```
|
||||
"./some_local_file.zwl" file import ! imports a local file
|
||||
"/lib/stdlib.zwl" file import ! imports the standard library
|
||||
"/some_user/some_library/some_file.zwl" "raw.githubusercontent.com" https import ! imports the contents of this url
|
||||
```
|
||||
|
||||
## 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
|
||||
|
||||
# Appendicies
|
||||
|
||||
### Data
|
||||
|
||||
- describing data
|
||||
- numeric
|
||||
- string
|
||||
- logical
|
||||
- complex
|
||||
- point
|
||||
- edge
|
||||
- color
|
||||
- many more
|
||||
- qualitative
|
||||
- sentiment analysis
|
||||
- more...
|
||||
- measurements
|
||||
- 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)
|
||||
- more...
|
||||
|
||||
### 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
|
||||
- metaprogramming
|
||||
- macros
|
||||
- generating objects automatically
|
||||
|
||||
### 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
|
|
@ -0,0 +1,479 @@
|
|||
# _ztl_ (zongors transpiler language) Design parameters
|
||||
|
||||
## What is _ztl_?
|
||||
|
||||
_ztl_ is an language transpiler with C/Zig/Rust/Lua/Fortran/Javascript/Elixir style syntax. The transpiler bootstrap is written in Lua which should make it easy to port to other systems.
|
||||
|
||||
# _ztl_ Grammar and Specification
|
||||
|
||||
## Trait
|
||||
|
||||
Describes an interface that can be applied to a type, collisions are not important as the names of traits only carry what needs to be implemented a not any implementation itself. for people coming from OOP you can think of traits similar to an abstract class.
|
||||
|
||||
```
|
||||
trait Hashable {
|
||||
fn hash(self) -> u64
|
||||
}
|
||||
|
||||
struct Vec {
|
||||
x: f32,
|
||||
y: f32,
|
||||
z: f32,
|
||||
}
|
||||
|
||||
! maybe the worst hash function ever?
|
||||
impl Hashable Vec {
|
||||
fn hash(self: Vec) -> u64 {
|
||||
return (self.x bxor (self.y sll 16) bxor (self.z sll 32) bor (self.z sll 48))
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
## Types
|
||||
|
||||
- Types can be either structs, enums, or unions.
|
||||
- struct
|
||||
- holds data
|
||||
- union
|
||||
- holds different kinds of data
|
||||
- enum
|
||||
- holds a key to integer map of data
|
||||
- there are also a list of "substantial types" which come with the language which are the building blocks for more complex types. If you are coming from object oriented languages you can think of self as "primitive types"
|
||||
|
||||
```
|
||||
struct «type_token» {
|
||||
! values
|
||||
}
|
||||
|
||||
enum «type_token» {
|
||||
! values
|
||||
}
|
||||
|
||||
union «type_token» {
|
||||
! values
|
||||
}
|
||||
```
|
||||
|
||||
# Substantial Types
|
||||
|
||||
## numeric
|
||||
|
||||
### bit (or unsigned units)
|
||||
|
||||
- `u8`
|
||||
- unsigned 8 bit integer (uint8_t)
|
||||
- `u16`
|
||||
- unsigned 16 bit integer (uint16_t)
|
||||
- `u32`
|
||||
- unsigned 32 bit integer (uint32_t)
|
||||
- `u64`
|
||||
- unsigned 64 bit integer (uint64_t)
|
||||
|
||||
### integer (signed)
|
||||
- `i8`
|
||||
- signed 8 bit integer (int8_t)
|
||||
- `i16`
|
||||
- signed 16 bit integer (int16_t)
|
||||
- `i32`
|
||||
- signed 32 bit integer (int32_t)
|
||||
- `i64`
|
||||
- signed 64 bit integer (int64_t)
|
||||
|
||||
### real
|
||||
|
||||
- `f32`
|
||||
- 32 bit floating point (float)
|
||||
- `f64`
|
||||
- 64 bit floating point (double)
|
||||
|
||||
## string
|
||||
|
||||
- `str`
|
||||
- utf8 / ascii encoded string depending on the language output
|
||||
|
||||
normal string
|
||||
|
||||
`"«utf8 encoded characters»"`
|
||||
|
||||
multiline literal string (also used for string interpolation like in JS)
|
||||
|
||||
`` `«utf8 encoded characters» {some_var}` ``
|
||||
|
||||
## logical
|
||||
|
||||
`bool`
|
||||
|
||||
`true` / `false`
|
||||
|
||||
Also follows the style boolean 'c' rules of nonzero / zero, but the compiler will make fun of you
|
||||
|
||||
## null values
|
||||
|
||||
```
|
||||
let a = 3
|
||||
let b = nil
|
||||
let c = #"nope!"
|
||||
|
||||
let x = a
|
||||
let y = b ?? 1
|
||||
|
||||
stdout.write("%d%d\n", x, y) ! outputs 3, 1
|
||||
```
|
||||
|
||||
## error
|
||||
|
||||
error is a type 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. You could also think of it as
|
||||
|
||||
```
|
||||
let error = %"something borked"
|
||||
let some_var = error ?? 0;
|
||||
let some_var = error ?? panic(error)
|
||||
```
|
||||
|
||||
## datastructure
|
||||
|
||||
Much like Lua, zwl only has tables. Lua's tables are amazing and very unique. Why have five different datastructures to do things when you can just have one that does everything?
|
||||
|
||||
### table
|
||||
|
||||
syntax (yes I was nice and kept the syntax the same as most C like langs)
|
||||
|
||||
```
|
||||
let «variable» = «type»[] ! same as a map of int->«type»
|
||||
|
||||
!or as an array
|
||||
|
||||
let «variable» = [val1, val2, ...]
|
||||
|
||||
! or as a map
|
||||
|
||||
let «variable» = {key1: val1, key2: val2, ...}
|
||||
```
|
||||
|
||||
### tunnel
|
||||
|
||||
described in "tunnel" section
|
||||
|
||||
### Basic operators
|
||||
|
||||
The following is a list of global operators and their effect:
|
||||
|
||||
- `!`
|
||||
- comment
|
||||
- `!!`
|
||||
- block comment (looks for another !! to close)
|
||||
- `=`
|
||||
- set operator
|
||||
- `??`
|
||||
- unwrap or
|
||||
- `+`
|
||||
- addition
|
||||
- `-`
|
||||
- subtraction
|
||||
- negation
|
||||
- `*`
|
||||
- multiplication
|
||||
- `/`
|
||||
- divisor
|
||||
- `**`
|
||||
- power
|
||||
- `==`
|
||||
- equals
|
||||
- `<`
|
||||
- less than
|
||||
- `>`
|
||||
- greater than
|
||||
- `>=`
|
||||
- greater than or equals
|
||||
- `<=`
|
||||
- less than or equals
|
||||
- `|>`
|
||||
- curry a function into another function (like haskell shove)
|
||||
- `.`
|
||||
- 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
|
||||
|
||||
### logical / bitwise operators
|
||||
|
||||
- `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
|
||||
- `srl`
|
||||
- bit shift right
|
||||
- `sll`
|
||||
- bit shift left
|
||||
|
||||
|
||||
### keywords
|
||||
|
||||
`is`
|
||||
|
||||
checks if a object is of that type
|
||||
```
|
||||
if («token» is i32) {
|
||||
stdout.print("hello yes self is i32?")
|
||||
}
|
||||
```
|
||||
|
||||
`as`
|
||||
|
||||
coerces a type as another type if possible
|
||||
```
|
||||
let «token» = 0
|
||||
some_functon_that_needs_a_i32(«token» as i32)
|
||||
```
|
||||
|
||||
`impls`
|
||||
|
||||
checks if a object's type, or a type impls another type
|
||||
```
|
||||
if («token» impls Tunnel) {
|
||||
stdout.print("im tunnel-able")
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
## Object
|
||||
|
||||
An object is an invoked type.
|
||||
|
||||
```
|
||||
let «variable» = «type»(«fields», …)
|
||||
```
|
||||
|
||||
## 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 objects, but have scope like control flow end scope closes the tunnel
|
||||
|
||||
note the type must always be of a type which is "tunnel-able" i.e. Files, sockets, etc
|
||||
|
||||
### transtypes for tunnels
|
||||
|
||||
`tunnel? : attach(tunnel_object)` -> open communication
|
||||
|
||||
`success? : tunnel_object.clunk()` -> close communication
|
||||
|
||||
`success? : tunnel_object.flush()` -> cancels long operation and dumps whatever is in buffer
|
||||
|
||||
`success? : tunnel_object.open(resource, mode)` -> opens a tunnel for doing operations on
|
||||
|
||||
`success? : tunnel_object.create(resource)` -> creates the object from the database graph/file from file structure
|
||||
|
||||
`data? : tunnel_object.read(resource)` -> reads from a tunnel
|
||||
|
||||
`success? : tunnel_object.write(resource, data)` -> writes to a tunnel
|
||||
|
||||
`success? : tunnel_object.remove(resource)` -> removes the object from the database graph/file from file structure
|
||||
|
||||
`stat_data? : tunnel_object.stat(resource)` -> returns the status of the file/resource
|
||||
|
||||
`version? : tunnel_object.version()` -> returns the version code for the connected tunnel
|
||||
|
||||
`success? : tunnel_object.walk(path_or_endpoint)` -> moves around the filesystem or through the graph
|
||||
|
||||
```
|
||||
let endpoint = «tunnel-able type»(endpoint_str)
|
||||
let tunnel = endpoint.attach(user, auth)
|
||||
let data = tunnel.?open("\some\resource").?read()
|
||||
stdout.write(data)
|
||||
data.flush()
|
||||
endpoint.clunk()
|
||||
```
|
||||
|
||||
in "terminal mode" the default tunnel is stdout
|
||||
|
||||
in "web mode" the default tunnels are log, info, trace, warn, error, but note these are all special tunnels which only accept write commands
|
||||
|
||||
## Functions
|
||||
|
||||
```
|
||||
fn «token» («type» «parameter», ...) -> «return_type» {
|
||||
«instructions»
|
||||
}
|
||||
```
|
||||
|
||||
- Built in transtypes
|
||||
- sort
|
||||
- filter
|
||||
- trig functions
|
||||
- calc functions
|
||||
- statistical functions
|
||||
|
||||
## Control flow
|
||||
|
||||
### loops
|
||||
|
||||
```
|
||||
for («token» in «collection») { «body» }
|
||||
|
||||
```
|
||||
iterates through each object in the collection setting it to token
|
||||
|
||||
```
|
||||
each («token» in «collection») { «body» }
|
||||
```
|
||||
iterates through each key 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
|
||||
|
||||
### branching
|
||||
|
||||
```
|
||||
match «token» {
|
||||
'a' -> actionA
|
||||
'x' -> actionX
|
||||
'y'..'z' -> {
|
||||
actionY
|
||||
actionZ
|
||||
}
|
||||
_ -> actionNoMatch
|
||||
}
|
||||
```
|
||||
### exceptions
|
||||
|
||||
take a look at error's, but you can panic on an error like self:
|
||||
|
||||
```
|
||||
panic(#"error message")
|
||||
panic(#3)
|
||||
panic(«some_error_token»)
|
||||
```
|
||||
|
||||
## Localization
|
||||
|
||||
will look up the text of «token» in the linked localization.json file
|
||||
|
||||
```
|
||||
$«token»
|
||||
```
|
||||
|
||||
```json
|
||||
{
|
||||
"some_token": [
|
||||
"localization_1": ""
|
||||
],
|
||||
"some_other_token": [
|
||||
"localization_1": "",
|
||||
"localization_2": ""
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## Libraries and “includes”
|
||||
|
||||
In most languages the include or use statements get libraries which link to other files and so on. Self quickly gets confusing and so requires package managers and installers, etc.
|
||||
The other way to do self 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 pertypeance much
|
||||
|
||||
```
|
||||
use `https://code.example.com/some_library/some_file.ztl`
|
||||
```
|
||||
|
||||
```
|
||||
use `./some_local_file.ztl`
|
||||
```
|
||||
|
||||
## Testing
|
||||
|
||||
Tests are done inside of a `test` block
|
||||
|
||||
```
|
||||
test some_test {
|
||||
someFunction() => true
|
||||
|
||||
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
### assertion
|
||||
|
||||
```
|
||||
assert(«expression», «expected output») ! returns «error or none»
|
||||
```
|
||||
|
||||
## Measurements
|
||||
|
||||
- types
|
||||
- time
|
||||
- unit
|
||||
- seconds (s)
|
||||
- subtypes
|
||||
- date
|
||||
- Default is ISO 8601
|
||||
- length
|
||||
- unit
|
||||
- metre (m)
|
||||
- subtypes
|
||||
- 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)
|
|
@ -8,8 +8,8 @@
|
|||
~ username set
|
||||
~ password set
|
||||
|
||||
(username (0.0 1.0 2.0) purple) ~ me set
|
||||
(password) me login cons ~ players set
|
||||
() username cons (0.0 1.0 2.0) cons purple cons ~ me set
|
||||
() password cons me login cons ~ players set
|
||||
|
||||
() () me shatter pop exch pop shatter cons
|
||||
10.0 add cons
|
|
@ -36,13 +36,13 @@
|
|||
username 0.0 f32 1.0 f32 2.0 f32 vec purple :me player
|
||||
password me login :players set
|
||||
|
||||
() me.pos.x push
|
||||
me.pos.y 10.0 add push
|
||||
me.pos.z 10.0 add push (* Camera pos *)
|
||||
me.pos (* Camera looking at point *)
|
||||
0.0 1.0 0.0 vec (* Camera up vector(rotation towards target) *)
|
||||
45.0 f32 (* Camera field - of - view Y *)
|
||||
:CAMERA_PERSPECTIVE (* Camera projection type *)
|
||||
me.pos.x
|
||||
me.pos.y 10.0 add
|
||||
me.pos.z 10.0 add vec (* Camera pos *)
|
||||
me.pos (* Camera looking at point *)
|
||||
0.0 1.0 0.0 vec (* Camera up vector(rotation towards target) *)
|
||||
45.0 f32 (* Camera field - of - view Y *)
|
||||
:CAMERA_PERSPECTIVE (* Camera projection type *)
|
||||
:camera Camera3D
|
||||
|
||||
screen_width screen_height "zwl client : raylib" init_window
|
|
@ -22,7 +22,7 @@ void login(Player p, str password) {
|
|||
/* do the login here */
|
||||
}
|
||||
|
||||
Color purple(255, 255, 0);
|
||||
Color purple(255, 0, 255);
|
||||
|
||||
void main(int argc, str[] argv) {
|
||||
i32 screen_width = 800;
|
|
@ -1,25 +1,33 @@
|
|||
void build(ProjectConfig c) {
|
||||
c.name("MMO Project");
|
||||
|
||||
c.client({
|
||||
"javascript":{
|
||||
c.client("src/", {
|
||||
"c":{
|
||||
"ffi": [
|
||||
{
|
||||
"name":"raylib",
|
||||
"library":"$RAYLIB_PATH/libraylib.a",
|
||||
"path":"",
|
||||
"build": "make build",
|
||||
}
|
||||
],
|
||||
"out": "client/"
|
||||
}
|
||||
})
|
||||
|
||||
c.server({
|
||||
"c":{
|
||||
c.server("src/",{
|
||||
"javascript":{
|
||||
"out":"server/"
|
||||
}
|
||||
});
|
||||
|
||||
c.database({
|
||||
c.database("src/",{
|
||||
"sqlite":{
|
||||
"out":"db/"
|
||||
}
|
||||
});
|
||||
|
||||
c.common({
|
||||
c.common("src/",{
|
||||
"c":{
|
||||
"out":"server/"
|
||||
},
|
|
@ -1,7 +1,8 @@
|
|||
use "common.zl"
|
||||
use "common.ztl"
|
||||
|
||||
Player[] login(Server s, Player p, str password) {
|
||||
/* do the login here */
|
||||
Player[] login(tunnel s, Player p, str password) {
|
||||
s.auth(p.username, password);
|
||||
s.
|
||||
}
|
||||
|
||||
void main(int argc, str[] argv) {
|
|
@ -1,6 +1,8 @@
|
|||
use "common.ztl"
|
||||
|
||||
void main(int argc, str[] argv) {
|
||||
tunnel s();
|
||||
s.host("localhost:25565",
|
||||
s.host("0.0.0.0:25565",
|
||||
version,
|
||||
auth,
|
||||
error,
|
|
@ -0,0 +1,43 @@
|
|||
fn build(c: ProjectConfig) {
|
||||
c.name("MMO Project");
|
||||
|
||||
c.client("src/", {
|
||||
"c":{
|
||||
"ffi": [
|
||||
{
|
||||
"name":"raylib",
|
||||
"library":"$RAYLIB_PATH/libraylib.a",
|
||||
"path":"",
|
||||
"build": "make build",
|
||||
}
|
||||
],
|
||||
"out": "client/"
|
||||
}
|
||||
})
|
||||
|
||||
c.server("src/",{
|
||||
"javascript":{
|
||||
"out":"server/"
|
||||
}
|
||||
});
|
||||
|
||||
c.database("src/",{
|
||||
"sqlite":{
|
||||
"out":"db/"
|
||||
}
|
||||
});
|
||||
|
||||
c.common("src/",{
|
||||
"c":{
|
||||
"out":"server/"
|
||||
},
|
||||
"javascript":{
|
||||
"out":"client/"
|
||||
},
|
||||
"sqlite":{
|
||||
"out":"db/"
|
||||
}
|
||||
});
|
||||
|
||||
c.build();
|
||||
}
|
|
@ -0,0 +1,93 @@
|
|||
use "common.ztl"
|
||||
|
||||
fn login(s: tunnel, p: Player, password: str)->Player[] {
|
||||
s.auth(p.username, password);
|
||||
return s.read("players")
|
||||
}
|
||||
|
||||
fn main(argc: int, argv: str[]) {
|
||||
const screen_width: i32 = 800;
|
||||
const screen_height: i32 = 450;
|
||||
|
||||
let username = argv[0];
|
||||
let password = argv[1];
|
||||
|
||||
let s = tunnel();
|
||||
s.attach("localhost:25565");
|
||||
|
||||
let me = Player(
|
||||
username,
|
||||
Vec(0.0, 1.0, 2.0),
|
||||
purple
|
||||
);
|
||||
let players = login(s, me, password);
|
||||
|
||||
let camera = Camera3D(
|
||||
Vec(0.0, 1.0, 0.0),
|
||||
45.0,
|
||||
:CAMERA_PERSPECTIVE,
|
||||
Vec(
|
||||
me.pos.x + 10.0,
|
||||
me.pos.y + 10.0,
|
||||
me.pos.z
|
||||
),
|
||||
me.pos
|
||||
);
|
||||
|
||||
init_window("zwl client : raylib", screen_width, screen_height);
|
||||
set_target_fps(60)
|
||||
|
||||
(* Main game loop *)
|
||||
while ( not window_should_close() ) {
|
||||
let player_updated = false
|
||||
|
||||
if (is_key_down(:KEY_RIGHT)) {
|
||||
me.pos.x = me.pos.x + 0.2;
|
||||
player_updated = true;
|
||||
}
|
||||
|
||||
if (is_key_down(:KEY_LEFT)) {
|
||||
me.pos.x = me.pos.x - 0.2;
|
||||
player_updated = true;
|
||||
}
|
||||
|
||||
if (is_key_down(:KEY_DOWN)) {
|
||||
me.pos.z = me.pos.z + 0.2;
|
||||
player_updated = true;
|
||||
}
|
||||
|
||||
if (is_key_down(:KEY_UP)) {
|
||||
me.pos.z = me.pos.z - 0.2;
|
||||
player_updated = true;
|
||||
}
|
||||
|
||||
sync_camera(s, me, camera);
|
||||
|
||||
if (player_updated) {
|
||||
players = move(s, me);
|
||||
} else {
|
||||
players = ping(s, me);
|
||||
}
|
||||
|
||||
begin_drawing();
|
||||
clear_background(:RAYWHITE);
|
||||
|
||||
begin_mode_3d(camera);
|
||||
|
||||
(* Draw floor *)
|
||||
draw_grid(30, 1.0);
|
||||
|
||||
draw_cube(me.pos, 0.5, 0.5, 0.5, me.apperance);
|
||||
|
||||
for (player in players) {
|
||||
draw_cube(player.pos, 0.5, 0.5, 0.5, player.apperance);
|
||||
}
|
||||
|
||||
end_mode_3d();
|
||||
|
||||
end_drawing();
|
||||
}
|
||||
|
||||
logout(me);
|
||||
close_window(); (* Close window and OpenGL context *)
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
type Vec {
|
||||
x: f32,
|
||||
y: f32,
|
||||
z: f32,
|
||||
}
|
||||
|
||||
type Color {
|
||||
r: i8,
|
||||
g: i8,
|
||||
b: i8,
|
||||
}
|
||||
|
||||
type Player {
|
||||
username: str,
|
||||
pos: Vec,
|
||||
color: Color,
|
||||
}
|
||||
|
||||
const purple = Color(255, 255, 0);
|
|
@ -0,0 +1,59 @@
|
|||
use "common.ztl"
|
||||
|
||||
fn main(argc, argv) {
|
||||
tunnel s();
|
||||
s.host("0.0.0.0:25565",
|
||||
version,
|
||||
auth,
|
||||
error,
|
||||
flush,
|
||||
attach,
|
||||
walk,
|
||||
open,
|
||||
create,
|
||||
read,
|
||||
write,
|
||||
clunk,
|
||||
remove,
|
||||
stat);
|
||||
}
|
||||
|
||||
fn version(m) {
|
||||
|
||||
}
|
||||
fn auth(m) {
|
||||
|
||||
}
|
||||
fn error(m) {
|
||||
|
||||
}
|
||||
fn flush(m) {
|
||||
|
||||
}
|
||||
fn attach(m) {
|
||||
|
||||
}
|
||||
fn walk(m) {
|
||||
|
||||
}
|
||||
fn open(m) {
|
||||
|
||||
}
|
||||
fn create(m) {
|
||||
|
||||
}
|
||||
fn read(m) {
|
||||
|
||||
}
|
||||
fn write(m) {
|
||||
|
||||
}
|
||||
fn clunk(m) {
|
||||
|
||||
}
|
||||
fn remove(m) {
|
||||
|
||||
}
|
||||
fn stat(m) {
|
||||
|
||||
}
|
Loading…
Reference in New Issue