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)
 |