diff --git a/spec.md b/spec.md index e42fba8..5e99c10 100644 --- a/spec.md +++ b/spec.md @@ -6,7 +6,11 @@ `([*]<variable> [arg | *arg] [arg2])` If arg is given, it will assign arg to variable, then return variable If assigning to a vector or string : - - If `*` is specified before variable, it will replace the vector + - if variable is a string, arg may be a string literal. In this case, + variable becomes the string literal with or without `*` specified + - In the same way, if variable is a vector, arg may be a vector literal, + and the same rules apply + - If `*` is specified before variable, arg will replace the vector - Otherwise, if only arg is given, it will return the element at position arg of variable. If arg2 is given, it will set the element at position arg of variable to arg2. @@ -14,14 +18,32 @@ ``` fLisp : (let:vec:int a 5) C : int a[5]; + fLisp : (a 0 69) C : a[0] = 69; - fLisp : (let:int x)(x (a 0)) + + fLisp : (let:int x) + (x (a 0)) C : int x = a[0]; + + fLisp : (let:str hello) + (hello "Hello !") + (*hello "Hello !") # equivalent + C : char *hello = "Hello !"; ``` For vectors and strings, it's a shallow copy (data is the same) unless a `*` is specified before `[arg]` - +- Literals: + Literals are of the following form: + - `1234`: int literal + - `12.34`: float literal + - `"abcd"`: string literal + - `(1,2,3,4)`: vector literal. All values must be of the same type + Null and fix literals do not exist. "Fix" type constants may exist by + assigning to a fix typed variable, such as `(let:fix x 0.5)`, where x will + be of value 0.5 in fixed point +- Comments are indicated by `#`. The whole rest of the line is ignored by the + parser - Compiled to bytecode In this document : @@ -54,7 +76,7 @@ In this document : - `(var[:type] <name> [size])`: Declares a global variable of optional type type and name name if type is of format `:vec:<type>`, the variable will be a vector - of type type, and optional size size (otherwise size 0) + of type type, and optional size size (otherwise size 0) (if type isn't specified it is inferred) - `(let[:type] <name>)`: @@ -69,9 +91,25 @@ In this document : - `(while <cond> [expressions])`: while cond evalutates to true, will execute optional expressions +- `(for (<vec> <var>) [expressions])` + Will initialize a local scope variable var with the type of the vector vec, + and execute expressions for every element of vec. var will be set to the + element of vec interated on + Example: + ``` + (let:vec:int a (1,2,3)) + (for (a i) + (write i) + (write " ") + ) + ``` + will display `1 2 3 ` + - `(fn (<name> [arg0[:type] ... argN[:type]]) [expressions])` : Declares a function of name name, optional args arg0-argN with optional types (recommended to explicit them), that executes optional expressions + The function will return the value of the last expression + Passed vectors and strings are shallow copied The name cannot be a variable - `(import <lib0> [... libN])` : @@ -109,11 +147,36 @@ where they may be strings), and of the same type - `(> <a> <b>)`: Returns 1 if a > b, else 0 -## console functions +- `(! <a>)`: + If a evaluates to false, returns true, and false otherwise + +- `(and <a> <b>)`: + Logical and on a and b + +- `(or <a> <b>)`: + Logical or on a and b + +- `(is<:type> <arg>)`: + Returns 1 if arg is of type type + +- `(<:type> <arg>)`: + Will attempt to convert arg to type, returns it on success, and returns + null on failure. + +- `(len <vec>)` : + Returns the length of vector vec. + +- `(push <vec> <arg>)`: + Adds item arg to the end of vec, increasing the size of vec + +- `(pop <vec> <arg>)`: + Deletes item at pos arg from vec, and returns it + +## console functions (`(import console)`) - `(input)`: Will try to get input from the user, returns it as a string - `(write <var>)`: - Will try to cast var to string then print it to the console + Will try to convert var to a string then print it to the console - `(newline)`: Will print a newline to the console (newline characters aren't escaped with write) @@ -172,4 +235,7 @@ if 1:2 / 1:2:3, means stitching 1,2,3 together as a 2 or 3 byte value - `iter` : Iterates on vector 1, keeping track with int value at 2, and sets int value at 3 to 1 when done to 1 +- `not` : !1 -> stack +- `and` : 1 && 2 -> stack +- `or` : 1 || 2 -> stack diff --git a/src/byte_defs.h b/src/byte_defs.h index c5cf7fc..2072f24 100644 --- a/src/byte_defs.h +++ b/src/byte_defs.h @@ -29,7 +29,10 @@ enum OpTypes { OP_popl = 21, OP_cst0 = 22, OP_cst1 = 23, - OP_iter = 24 + OP_iter = 24, + OP_not = 25, + OP_and = 26, + OP_or = 27 }; typedef struct {