zongors-universe-machine/SPECIFICATION.MD

13 KiB

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. and have the following structure (here I will use a psudo C as an example):

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 : [0, 0, 1] ! 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 : 0 ! 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

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)

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, it stole some monads from Rust, Haskell, and the like

If you are coming from haskell, a 'Just' is < some value > and a 'None' is <>, note 'None' is also an error

Like in Rust you have unwrap and unwrap_or and the like, you use ? and ??

1| i32 a = <3>; ! this can also be writen `i32 a = just(3);`
2| i32 b = <>; ! this can also be written `i32 b = none;`
3|
4| i32 x ?= a; ! this will set x to 3
5| i32 y ?= b; ! this will set y to an error
6| i32 z ?= b ?= 1; ! this will return an error from b, then unwrap the error and set y = 1;
7|
8| print("$x $y $z\n") ! prints 3, "error: failed to unwrap a 'none' on line 5", 1

additionally, a None will be evaluated as "false" and Just as "true" in a boolean check

error

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

datastructures

list

syntax

(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


}