diff --git a/docs/SPECIFICATION.org b/docs/SPECIFICATION.org index 7dd9d56..451d5d5 100644 --- a/docs/SPECIFICATION.org +++ b/docs/SPECIFICATION.org @@ -23,12 +23,24 @@ systems. are coming from object oriented languages you can think of self as "primitive types" +- Note that these look like classes but act like structs + the methods actually have a implied struct as their first argument + #+begin_src zre type «token» { init() { // values } } + +/* example */ +type Vec3 { + init(x real, y real, z real) { + this.x = x; + this.y = z; + this.y = z; + } +} #+end_src zre * Basic Types @@ -40,13 +52,13 @@ type «token» { :CUSTOM_ID: numeric :END: - =real= - - 64 bit floating point (Double) by default for modern CPUs that have a FPU - - 32 bit 16.16 for microcontrollers/hardware without a FPU like a raspberry pi pico, retro hardware like a Mac 68k - - 16 bit 12.4 for older retro hardware like PS1 or UXN. - - Is it slow and takes up a lot of space? yeah, kinda, maybe, - the nice part of a unified numeric type is that makes it so that you do not have to worry about type casting which actually ends up speeding up processing - This is also how Lua, Lox, and Wren programming language handles numbers. Also because ZRE is intended to be used for Games, floats are used more for - 3D graphics than other numeric types. + - 32 bit Q16.16 fixed point by default. + - self casts to a 64 bit floating point (Double) by default for modern CPUs that have a FPU + for 3D math for performance reasons +- =int= + - 32 bit integer +- =nat= + - 32 bit unsigned integer (for loop counting and indexing) ** string :PROPERTIES: @@ -77,48 +89,34 @@ string interpolation - =bool= - =true= / =false= -** error -:PROPERTIES: -:CUSTOM_ID: error -:END: -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 every variable being able to have "the type" and also "error" as a -possible value. - -#+begin_src zre -let rr = err("something borked"); -let var = rr ?? 0; // value is 0 -let other_var = rr ?? panic(rr); // will panic -#+end_src zre - ** datastructure :PROPERTIES: :CUSTOM_ID: datastructure :END: -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? -Types that can be indexes are numbers and strings (no objects); - -*** table +*** Array :PROPERTIES: -:CUSTOM_ID: table +:CUSTOM_ID: array :END: -syntax (yes I was nice and kept the syntax the same as most C like -langs) + +Array of a specific type #+begin_src zre -/* array same as a map of int to «type» */ let «variable» = [val1, val2, ...]; +#+end_src zre -/* or as a map */ +*** Map +:PROPERTIES: +:CUSTOM_ID: map +:END: + +Hashmap + +#+begin_src zre let «variable» = {key1: val1, key2: val2, ...}; #+end_src zre -*** tunnel +*** Tunnel :PROPERTIES: :CUSTOM_ID: tunnel :END: @@ -178,6 +176,8 @@ The following is a list of global operators and their effect: :END: - =mod= - modulo +- =not= + - logical not - =and= - logical and - =or= @@ -309,15 +309,15 @@ filesystem or through the graph #+begin_src zre /* client */ -let endpoint = `protocol://path/to/source`; +let endpoint = Client("tcp://path/to/source"); let tunnel = endpoint.attach(user, auth); let data = tunnel.open("/some/resource").read(); -std.write(data); //print(data); +std.write(data); data.flush(); endpoint.clunk(); /* server */ -let server = `protocol://ip`; +let server = Server("tcp://0.0.0.0:25565"); s.bind("/some/resource", fn () str { return "hello world"; }) @@ -367,16 +367,10 @@ while («boolean expression») { «body» } loops until the expression is false #+begin_src zre -loop { «body» } +do (let «variable» = initial_value, end_value, increment) { «body» } #+end_src zre -loops infinitely until break or return - -#+begin_src zre -do («variable» = initial_value, end_value, increment) { «body» } -#+end_src zre - -loops from initial value to end value by increment value +loops from initial value to end value by increment value (like a for loop in other languages) *** branching :PROPERTIES: @@ -392,16 +386,31 @@ if («boolean expression») { } #+end_src zre -*** exceptions +#+begin_src zre +switch (value) { + case A: + case B: + case C: + default: +} +#+end_src zre + +** Error handling :PROPERTIES: -:CUSTOM_ID: exceptions +:CUSTOM_ID: error :END: -take a look at error's, but you can panic on an error like self: + +Error handling is much like in C/C++ where a try catch can be used. #+begin_src zre -panic(err("error message")); -panic(err(3)); -panic(«some_error_token»); +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 zre ** Localization @@ -431,19 +440,10 @@ will look up the text of «token» in the linked localization.json file :CUSTOM_ID: libraries-and-includes :END: 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 +to other files and so on. #+begin_src zre -use `https://example.com/some_library/some_file.zre` -#+end_src zre - -#+begin_src zre -use `./some_local_file.zre` +use "./some_local_file.zre" #+end_src zre ** Testing