483 lines
		
	
	
		
			9.1 KiB
		
	
	
	
		
			Org Mode
		
	
	
	
			
		
		
	
	
			483 lines
		
	
	
		
			9.1 KiB
		
	
	
	
		
			Org Mode
		
	
	
	
* /Undar/ (Reality Engine Language) Design parameters
 | 
						||
:PROPERTIES:
 | 
						||
:CUSTOM_ID: Undar-zongors-reality-engine-language-design-parameters
 | 
						||
:END:
 | 
						||
** What is /Undar/?
 | 
						||
:PROPERTIES:
 | 
						||
:CUSTOM_ID: what-is-undar
 | 
						||
:END:
 | 
						||
/Undar/ is an permacomputing oriented programming language for 3D games with C style syntax.
 | 
						||
The compiler is written in C which should make it easy to port to other
 | 
						||
systems. 
 | 
						||
 | 
						||
It is short for "Undarsċieppan" The name comes from the Proto-West-Germanic word [[https://en.wiktionary.org/wiki/Reconstruction:Proto-Germanic/under][Undar]], which means "under" and [[https://en.wiktionary.org/wiki/scieppan][Sċieppan]] meaning "to create". It inspired by the idea of "Sub-creation" from Tolkien and C.S. Lewis, that the developer is sub-creating a reality for their users, whether it be a video game, office software, a website, or a embedded driver.
 | 
						||
 | 
						||
* /Undar/ Grammar and Specification
 | 
						||
:PROPERTIES:
 | 
						||
:CUSTOM_ID: undar-grammar-and-specification
 | 
						||
:END:
 | 
						||
** Plexs
 | 
						||
:PROPERTIES:
 | 
						||
:CUSTOM_ID: plexs
 | 
						||
:END:
 | 
						||
- A =plex= is a **Platonic form** - a structured definition of a kind of being in your program.
 | 
						||
- Not a class: no inheritance, no vtables
 | 
						||
- Methods are functions with implicit =this= argument
 | 
						||
- Instances are **atoms** - persistent, versioned, serializable
 | 
						||
- Stored in the internal graph
 | 
						||
- "A plex defines what a thing is. An atom is its instance in that reality."
 | 
						||
- there are also a list of "substantial plexs" which come with the
 | 
						||
  language which are the building blocks for more complex types called "Plexes". If you are coming from object oriented languages you can think of self as "primitive types"
 | 
						||
 | 
						||
#+begin_src ul
 | 
						||
plex «token» {
 | 
						||
  init() {
 | 
						||
    // values
 | 
						||
  }
 | 
						||
}
 | 
						||
 | 
						||
! example
 | 
						||
plex Vec3 {
 | 
						||
  init(x real, y real, z real) {
 | 
						||
     this.x = x;
 | 
						||
     this.y = z;
 | 
						||
     this.y = z;
 | 
						||
  }
 | 
						||
}
 | 
						||
#+end_src ul
 | 
						||
 | 
						||
* Substantial Plexs
 | 
						||
:PROPERTIES:
 | 
						||
:CUSTOM_ID: substantial-plexs
 | 
						||
:END:
 | 
						||
** numeric
 | 
						||
:PROPERTIES:
 | 
						||
:CUSTOM_ID: numeric
 | 
						||
:END:
 | 
						||
- =real=
 | 
						||
  - 32 bit floats
 | 
						||
- =int=
 | 
						||
  - 32 bit integer
 | 
						||
- =nat=
 | 
						||
  - 32 bit unsigned integer (for loop counting and indexing)
 | 
						||
 | 
						||
** string
 | 
						||
:PROPERTIES:
 | 
						||
:CUSTOM_ID: string
 | 
						||
:END:
 | 
						||
- =str=
 | 
						||
  - utf8 / ascii encoded string depending on the language output
 | 
						||
 | 
						||
normal string
 | 
						||
 | 
						||
="«utf8 encoded characters»"=
 | 
						||
 | 
						||
string interpolation
 | 
						||
 | 
						||
="«utf8 encoded characters» ${some_var}"=
 | 
						||
 | 
						||
** binary
 | 
						||
:PROPERTIES:
 | 
						||
:CUSTOM_ID: binary 
 | 
						||
:END:
 | 
						||
- =byte=
 | 
						||
  - same as uint8 or c char, also used for interop
 | 
						||
 | 
						||
** logical
 | 
						||
:PROPERTIES:
 | 
						||
:CUSTOM_ID: logical
 | 
						||
:END:
 | 
						||
- =bool=
 | 
						||
   - =true= / =false=
 | 
						||
 | 
						||
** datastructure
 | 
						||
:PROPERTIES:
 | 
						||
:CUSTOM_ID: datastructure
 | 
						||
:END:
 | 
						||
 | 
						||
*** Array
 | 
						||
:PROPERTIES:
 | 
						||
:CUSTOM_ID: array
 | 
						||
:END:
 | 
						||
 | 
						||
Array of a specific plex
 | 
						||
 | 
						||
#+begin_src ul
 | 
						||
«plex»[«length»] «variable» = [val1, val2, ...];
 | 
						||
#+end_src ul
 | 
						||
 | 
						||
*** Tunnel
 | 
						||
:PROPERTIES:
 | 
						||
:CUSTOM_ID: tunnel
 | 
						||
:END:
 | 
						||
described in "tunnel" section
 | 
						||
 | 
						||
*** Basic operators
 | 
						||
:PROPERTIES:
 | 
						||
:CUSTOM_ID: basic-operators
 | 
						||
:END:
 | 
						||
The following is a list of global operators and their effect:
 | 
						||
 | 
						||
- !
 | 
						||
  - comment
 | 
						||
- ??
 | 
						||
  - unwrap or
 | 
						||
- .?
 | 
						||
  - null check or return error
 | 
						||
- +
 | 
						||
  - addition
 | 
						||
- -
 | 
						||
  - subtraction
 | 
						||
  - negation
 | 
						||
- *
 | 
						||
  - multiplication
 | 
						||
- /
 | 
						||
  - divisor
 | 
						||
- ^
 | 
						||
  - power
 | 
						||
- ==
 | 
						||
  - equals
 | 
						||
- <
 | 
						||
  - less than
 | 
						||
- >
 | 
						||
  - greater than
 | 
						||
- >=
 | 
						||
  - greater than or equals
 | 
						||
- <=
 | 
						||
  - less than or equals
 | 
						||
- .
 | 
						||
  - accessor
 | 
						||
- ++
 | 
						||
  - inline add 1
 | 
						||
- --
 | 
						||
  - inline subtract 1
 | 
						||
- +=
 | 
						||
  - inline add n
 | 
						||
- -=
 | 
						||
  - inline subtract n
 | 
						||
- *=
 | 
						||
  - inline multiply n
 | 
						||
- \=
 | 
						||
  - inline divide n
 | 
						||
 | 
						||
*** logical / bitwise operators
 | 
						||
:PROPERTIES:
 | 
						||
:CUSTOM_ID: logical-bitwise-operators
 | 
						||
:END:
 | 
						||
- =mod=
 | 
						||
  - modulo
 | 
						||
- =not=
 | 
						||
  - logical not
 | 
						||
- =and=
 | 
						||
  - logical and
 | 
						||
- =or=
 | 
						||
  - logical or
 | 
						||
- =xor=
 | 
						||
  - logical xor
 | 
						||
- =band=
 | 
						||
  - bitwise and
 | 
						||
- =bor=
 | 
						||
  - bitwise or
 | 
						||
- =bxor=
 | 
						||
  - bitwise xor
 | 
						||
- =srl=
 | 
						||
  - bit shift right
 | 
						||
- =sll=
 | 
						||
  - bit shift left
 | 
						||
 | 
						||
*** keywords
 | 
						||
:PROPERTIES:
 | 
						||
:CUSTOM_ID: keywords
 | 
						||
:END:
 | 
						||
 | 
						||
=let=
 | 
						||
 | 
						||
let operator
 | 
						||
 | 
						||
#+begin_src ul
 | 
						||
let «token» = true;
 | 
						||
#+end_src ul
 | 
						||
 | 
						||
=is=
 | 
						||
 | 
						||
checks if a atom is of that plex
 | 
						||
 | 
						||
#+begin_src ul
 | 
						||
if («token» is real) {
 | 
						||
  print("hello yes self is a real?");
 | 
						||
}
 | 
						||
#+end_src ul
 | 
						||
 | 
						||
also used for letting constants
 | 
						||
 | 
						||
=as=
 | 
						||
 | 
						||
coerces a plex as another plex if possible
 | 
						||
 | 
						||
#+begin_src ul
 | 
						||
let «token» = 0; ! default is int
 | 
						||
some_functon(«token» as real); ! needs a real
 | 
						||
#+end_src ul
 | 
						||
 | 
						||
=in=
 | 
						||
 | 
						||
checks if a atom's plex, or a plex implements a contract
 | 
						||
 | 
						||
#+begin_src ul
 | 
						||
if («token» in Tunnel, Drawable) {
 | 
						||
  print("im tunnel-able and draw-able");
 | 
						||
}
 | 
						||
#+end_src ul
 | 
						||
 | 
						||
also used inside of the for loops
 | 
						||
 | 
						||
#+begin_src ul
 | 
						||
for («token» in «collection») { «body» }
 | 
						||
#+end_src ul
 | 
						||
 | 
						||
** Atom
 | 
						||
:PROPERTIES:
 | 
						||
:CUSTOM_ID: atom
 | 
						||
:END:
 | 
						||
An atom is an invoked plex.
 | 
						||
 | 
						||
#+begin_src ul
 | 
						||
let «variable» = «plex»(«fields», …);
 | 
						||
#+end_src ul
 | 
						||
 | 
						||
** Tunnel
 | 
						||
:PROPERTIES:
 | 
						||
:CUSTOM_ID: tunnel-1
 | 
						||
:END:
 | 
						||
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 plex must always be of a plex which is "tunnel-able"
 | 
						||
i.e. Files, sockets, etc
 | 
						||
 | 
						||
Tunnels have almost the same interface as 9p since they are closely
 | 
						||
based on 9p.
 | 
						||
 | 
						||
*** transplexs for tunnels
 | 
						||
:PROPERTIES:
 | 
						||
:CUSTOM_ID: transplexs-for-tunnels
 | 
						||
:END:
 | 
						||
=tunnel? : attach(tunnel_atom)= -> open communication
 | 
						||
 | 
						||
=success? : tunnel_atom.clunk()= -> close communication
 | 
						||
 | 
						||
=success? : tunnel_atom.flush()= -> cancels long operation and dumps
 | 
						||
whatever is in buffer
 | 
						||
 | 
						||
=success? : tunnel_atom.open(resource, mode)= -> opens a tunnel for
 | 
						||
doing operations on
 | 
						||
 | 
						||
=success? : tunnel_atom.create(resource)= -> creates the atom from
 | 
						||
the database graph/file from file structure
 | 
						||
 | 
						||
=data? : tunnel_atom.read(resource)= -> reads from a tunnel
 | 
						||
 | 
						||
=success? : tunnel_atom.write(resource, data)= -> writes to a tunnel
 | 
						||
 | 
						||
=success? : tunnel_atom.remove(resource)= -> removes the atom from
 | 
						||
the database graph/file from file structure
 | 
						||
 | 
						||
=stat_data? : tunnel_atom.stat(resource)= -> returns the status of the
 | 
						||
file/resource
 | 
						||
 | 
						||
=version? : tunnel_atom.version()= -> returns the version code for the
 | 
						||
connected tunnel
 | 
						||
 | 
						||
=success? : tunnel_atom.walk(path_or_endpoint)= -> moves around the
 | 
						||
filesystem or through the graph
 | 
						||
 | 
						||
#+begin_src ul
 | 
						||
! client 
 | 
						||
let endpoint = Client("tcp://path/to/source");
 | 
						||
let tunnel = endpoint.attach(user, auth);
 | 
						||
let data = tunnel.open("/some/resource").read();
 | 
						||
std.write(data);
 | 
						||
data.flush();
 | 
						||
endpoint.clunk();
 | 
						||
 | 
						||
! server
 | 
						||
let server = Server("tcp://0.0.0.0:25565");
 | 
						||
s.bind("/some/resource", fn () str {
 | 
						||
   return "hello world";
 | 
						||
})
 | 
						||
server.start();
 | 
						||
#+end_src ul
 | 
						||
 | 
						||
** Functions
 | 
						||
:PROPERTIES:
 | 
						||
:CUSTOM_ID: functions
 | 
						||
:END:
 | 
						||
Functions are all typechecked statically at compile time. Since we
 | 
						||
always have a "default plex" for all constant values or a developer can
 | 
						||
use the =as= keyword we do not have to define all values like in C,
 | 
						||
while keeping the same plex safety as a more strongly typed language.
 | 
						||
 | 
						||
#+begin_src ul
 | 
						||
fn «token» («parameter» «plex», ...) «return_plex» {
 | 
						||
  «body»
 | 
						||
}
 | 
						||
#+end_src ul
 | 
						||
 | 
						||
- Built in transplexs
 | 
						||
  - sort
 | 
						||
  - filter
 | 
						||
  - trig functions
 | 
						||
  - calc functions
 | 
						||
  - statistical functions
 | 
						||
 | 
						||
** Control flow
 | 
						||
:PROPERTIES:
 | 
						||
:CUSTOM_ID: control-flow
 | 
						||
:END:
 | 
						||
*** loops
 | 
						||
:PROPERTIES:
 | 
						||
:CUSTOM_ID: loops
 | 
						||
:END:
 | 
						||
#+begin_src ul
 | 
						||
for («variable» in «collection») { «body» }
 | 
						||
#+end_src ul
 | 
						||
 | 
						||
iterates through each atom in the collection setting it to variable
 | 
						||
 | 
						||
#+begin_src ul
 | 
						||
while («boolean expression») { «body» }
 | 
						||
#+end_src ul
 | 
						||
 | 
						||
loops until the expression is false
 | 
						||
 | 
						||
#+begin_src ul
 | 
						||
do («variable» = initial_value, end_value, increment) { «body» }
 | 
						||
#+end_src ul
 | 
						||
 | 
						||
loops from initial value to end value by increment value (like a for loop in other languages)
 | 
						||
 | 
						||
*** branching
 | 
						||
:PROPERTIES:
 | 
						||
:CUSTOM_ID: branching
 | 
						||
:END:
 | 
						||
#+begin_src ul
 | 
						||
if («boolean expression») {
 | 
						||
 | 
						||
} else if («boolean expression») {
 | 
						||
 | 
						||
} else {
 | 
						||
 | 
						||
}
 | 
						||
#+end_src ul
 | 
						||
 | 
						||
#+begin_src ul
 | 
						||
switch (value) {
 | 
						||
  case A:
 | 
						||
  case B:
 | 
						||
  case C:
 | 
						||
  default:
 | 
						||
}
 | 
						||
#+end_src ul
 | 
						||
 | 
						||
** Error handling
 | 
						||
:PROPERTIES:
 | 
						||
:CUSTOM_ID: error
 | 
						||
:END:
 | 
						||
 | 
						||
Error handling is much like in C/C++ where a try catch can be used.
 | 
						||
 | 
						||
#+begin_src ul
 | 
						||
let rr = nil;
 | 
						||
let var = rr ?? 0; ! value is 0
 | 
						||
try {
 | 
						||
   let other_var = 1 / rr; ! will panic
 | 
						||
 | 
						||
} catch (e) {
 | 
						||
   print("Caught error ${e}");
 | 
						||
}
 | 
						||
#+end_src ul
 | 
						||
 | 
						||
** Localization
 | 
						||
:PROPERTIES:
 | 
						||
:CUSTOM_ID: localization
 | 
						||
:END:
 | 
						||
will look up the text of «token» in the linked localization.json file
 | 
						||
 | 
						||
#+begin_src ul
 | 
						||
#«token»
 | 
						||
#+end_src ul
 | 
						||
 | 
						||
#+begin_src json
 | 
						||
{
 | 
						||
  "some_token": [
 | 
						||
    "localization_1": ""
 | 
						||
  ],
 | 
						||
  "some_other_token": [
 | 
						||
    "localization_1": "",
 | 
						||
    "localization_2": ""
 | 
						||
  ]
 | 
						||
}
 | 
						||
#+end_src
 | 
						||
 | 
						||
** Libraries and "includes"
 | 
						||
:PROPERTIES:
 | 
						||
:CUSTOM_ID: libraries-and-includes
 | 
						||
:END:
 | 
						||
In most languages the include or use statements get libraries which link
 | 
						||
to other files and so on. 
 | 
						||
 | 
						||
#+begin_src ul
 | 
						||
use "./some_local_file.Undar"
 | 
						||
#+end_src ul
 | 
						||
 | 
						||
** Testing
 | 
						||
:PROPERTIES:
 | 
						||
:CUSTOM_ID: testing
 | 
						||
:END:
 | 
						||
*** assertion
 | 
						||
:PROPERTIES:
 | 
						||
:CUSTOM_ID: assertion
 | 
						||
:END:
 | 
						||
#+begin_src ul
 | 
						||
assert(«expression», «expected output») ! returns «error or none»
 | 
						||
#+end_src ul
 | 
						||
 | 
						||
** Measurements
 | 
						||
:PROPERTIES:
 | 
						||
:CUSTOM_ID: measurements
 | 
						||
:END:
 | 
						||
- 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)
 |