From e23bd09454241337eb24f2d4cd873fc66d9b10ca Mon Sep 17 00:00:00 2001 From: zongor Date: Tue, 2 Jun 2026 20:57:53 -0700 Subject: [PATCH] Add language spec, update readme to link spec and move some notes --- docs/SPECIFICATION.org | 411 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 411 insertions(+) create mode 100644 docs/SPECIFICATION.org diff --git a/docs/SPECIFICATION.org b/docs/SPECIFICATION.org new file mode 100644 index 0000000..8cc31db --- /dev/null +++ b/docs/SPECIFICATION.org @@ -0,0 +1,411 @@ +* /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 container for primitive types. +- Not a class: no inheritance, no vtables +- Methods are functions with implicit =this= argument + +#+begin_src ul +plex «token» { + init() { + // values + } +} + +// example +plex Vec3 { + init(real x, real y, real z) { + this.x = x; + this.y = z; + this.y = z; + } +} +#+end_src ul + +*** Substantial Plexs +:PROPERTIES: +:CUSTOM_ID: substantial-plexs +:END: + +| Type | Description | +|------+-----------------------------------| +| =byte= | Character (architecture specific) | +| =u8= | exactly 8-bit unsigned int | +| =i8= | exactly 8-bit signed int | +| =u16= | exactly 16-bit unsigned int | +| =i16= | exactly 16-bit signed int | +| =u32= | exactly 32-bit unsigned integer | +| =i32= | exactly 32-bit signed integer | +| =int= | 1 word signed number | +| =nat= | 1 word unsigned number | +| =real= | Q16.16 fixed-point real number | +| =str= | string | +| =bool= | true/false | + +** Basic operators +:PROPERTIES: +:CUSTOM_ID: basic-operators +:END: +The following is a list of global operators and their effect: + +- // + - comment +- //* */ + - block comment +- ! + - not +- + + - addition +- - + - subtraction + - negation +- * + - multiplication +- / + - divisor +- == + - equals +- < + - less than +- > + - greater than +- >= + - greater than or equals +- <= + - less than or equals +- . + - accessor + +*** logical / bitwise operators +:PROPERTIES: +:CUSTOM_ID: logical-bitwise-operators +:END: +- =mod= + - modulo +- =and= + - logical and +- =or= + - logical or +- =xor= + - logical xor +- =srl= + - bit shift right +- =sll= + - bit shift left + +** keywords +:PROPERTIES: +:CUSTOM_ID: keywords +:END: + +=is= + +checks if a atom is of that plex + +#+begin_src ul +if («token» is real) { + print("self is a real"); +} +#+end_src ul + +also used for letting constants + +=as= + +coerces a plex as another plex if possible + +#+begin_src ul +nat «token» = 0; +some_functon(«token» as real); // needs a real +#+end_src ul + +=in= + +checks if a atom's plex contains the fields inside of a trait + +#+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 + +** 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 +for («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) + +#+begin_src ul +while («boolean expression») { «body» } +#+end_src ul + +loops until the expression is false + +*** branching +:PROPERTIES: +:CUSTOM_ID: branching +:END: +=if= + +#+begin_src ul +if («boolean expression») { + +} else if («boolean expression») { + +} else { + +} +#+end_src ul + +=switch= (WIP) + +#+begin_src ul +switch (value) { + case A: + case B: + case C: + default: +} +#+end_src ul + +* Memory Management + +All memory used by the program exists in one big bump allocator. + +When a function gets called, it creates a new arena in memory starting at the end of the previous frame. (or at the beginning of memory if no function has been called) + +Variables allocated in the frame's arena are owned by default by the frame they are allocated in. + +When variables get modified within the current frame they will get updated in that frame in their current location in the arena. + +All complex types (Plex, arrays, strings) use fat pointers where they have a header of the length of that block and a "next" ptr that refers to the next allocated block for that value + +If the size of the variable changes (like adding a value to the end of a array), a link is added to the internal list that points to a new block is allocated at the end of the arena of the size of that value, so they are variable sized blocks + +When a variable is passed to a child function primitive types are pass by value, complex types (Arrays, Plexes, Strings) are pass by reference. + +Variables passed as arguments to the child follow the same rules except when the size of a complex type changes, then a new value is added as a link from the parent to the child and the new value is allocated at the end of the childs arena (but the owner is still the parent). + +When a function "returns" the frame is deallocated and all values allocated by it is freed; thus freeing memory deterministically. + +Only a single variable may be returned from a function. When a variable is returned if it is primitive it is just passed back to the parent. If it is complex the value is coalesced into a single contiguous values and the link in the parent is updated to point at the "new" end of the arena. If the parents block is at the end the entire block is coalesced into a single contiguous block. + +This allows for the low resource usage of a C but the convenience of a garbage collected language like C# or Go but without the GC pauses. + +** 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 :WIP: +:PROPERTIES: +:CUSTOM_ID: tunnel-1 +:END: +Represents a path to a file, url endpoint, other process endpoint (like +a socket, file, etc.) + +Tunnels are inspired by translators in gnu/hurd, plan9 9p protocol, and +unix sockets + +A plex must implement the tunnel trait + +*** tunnels +:PROPERTIES: +:CUSTOM_ID: 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 +Client endpoint("tcp://path/to/source"); +Tunnel tunnel = endpoint.attach(user, auth); +str data = tunnel.open("/some/resource").read(); +std.write(data); +data.flush(); +endpoint.clunk(); + +// server +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 +function «token» («parameter» «plex», ...) «return_plex» { + «body» +} +#+end_src ul + +- Built in stdlib + - sort + - filter + - trig functions + - calc functions + - statistical functions + +** 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.ul" +#+end_src ul + +** Testing +:PROPERTIES: +:CUSTOM_ID: testing +:END: +*** assertion +:PROPERTIES: +:CUSTOM_ID: assertion +:END: +#+begin_src ul +assert(«expression», «expected output») +#+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)