This commit is contained in:
attilavs2 2025-03-02 22:47:04 +01:00
parent 4399f5bae9
commit a58c4064f8
3 changed files with 44 additions and 41 deletions

82
spec.md
View file

@ -1,6 +1,6 @@
# fLisp
- S-expressions:
- S-expressions:
`(<function> [arg0 ... argN])`
Will call function with optional args arg0-argN
`([*]<variable> [arg | *arg] [arg2])`
@ -20,102 +20,102 @@
C : int x = a[0];
```
For vectors and strings, it's a shallow copy (data is the same) unless a `*`
is specified before [arg]
is specified before `[arg]`
- Compiled to bytecode
In this document :
- <...> :
- `<...>` :
Mandatory argument
- [...] :
- `[...]` :
Optional argument
- | :
- `|` :
Or
## Core types
- null :
- `null`:
Represents a null value - always evaluates to false
- int :
- `int`:
32 bit signed integer, evaluates to false if zero and true otherwise
- fix :
- `fix`:
16:16 bit fixed point signed integer, same evaluation rules as ints
- float :
- `float`:
32bit IEEE floating point value, same evaluation as ints (within
`FL_ESPILOǸ̀`)
- str:
- `str`:
ASCII character string - always evaluates to false
- fn:
- `fn`:
Function, function "variables" are inherently of type fn - handle with care !
- vec :
Vectors of any type,
- `vec`:
Vectors of any type
## Core functions
- `(var[:type] <name> [size])` :
- `(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)
(if type isn't specified it is inferred)
- `(let[:type] <name>)`:
- `(let[:type] <name>)`:
Same as var, but variable is of local scope (recommended)
- `(if <cond> [expressions])`:
- `(if <cond> [expressions])`:
If cond evaluates to true, will execute optional expressions
- `(else [expressions])`:
- `(else [expressions])`:
Must follow a if, will execute if the if's cond evaluates to false
- `(while <cond> [expressions])`:
- `(while <cond> [expressions])`:
while cond evalutates to true, will execute optional expressions
- `(fn (<name> [arg0[:type] ... argN[:type]]) [expressions])` :
- `(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 name cannot be a variable
- `(import <lib0> [... libN])` :
- `(import <lib0> [... libN])` :
Import the functions and variables from lib0-libN
For the following numerical functions, values must be scalars (except + and =,
For the following numerical functions, values must be scalars (except + and =,
where they may be strings), and of the same type
- `(+ <a> <b>)`:
- `(+ <a> <b>)`:
Returns a+b, if they are both strings they will be concatenated
- `(- <a> <b>)`:
- `(- <a> <b>)`:
Returns a-b
- `(* <a> <b>)`:
- `(* <a> <b>)`:
Returns a×b
- `(/ <a> <b>)`:
- `(/ <a> <b>)`:
Returns a/b
- `(% <a> <b>)`:
- `(% <a> <b>)`:
Returns a%b
- `(< <a> <b>)`:
- `(< <a> <b>)`:
Returns 1 if a < b, else 0
- ̀`(<= <a> <b>)`:
- ̀`(<= <a> <b>)`:
Returns 1 if a <= b, else 0
- `(= <a> <b>)̀̀`:
- `(= <a> <b>)̀̀`:
Returns 1 if a == b, else 0
- `(>= <a> <b>)`:
- `(>= <a> <b>)`:
Returns 1 if a >= b, else 0
- `(> <a> <b>)`:
- `(> <a> <b>)`:
Returns 1 if a > b, else 0
## console functions
- `(input)`:
- `(input)`:
Will try to get input from the user, returns it as a string
- `(write <var>)`:
- `(write <var>)`:
Will try to cast var to string then print it to the console
- `(newline)`:
Will print a newline to the console (newline characters aren't escaped with
- `(newline)`:
Will print a newline to the console (newline characters aren't escaped with
write)
## gint functions
@ -124,9 +124,9 @@ TODO
# Bytecode
- 8 byte Value :
- 8 byte Value :
2 bytes tag, 6 bytes value itself
- 4 byte bytecode ops:
- 4 byte bytecode ops:
1 byte op, 3 byte args (named 1-3)
## Bytecode types
@ -135,7 +135,7 @@ TODO
- `T_Int` -> int
- `T_Fix` -> fix
- `T_Float` -> float
- `T_Str` -> string :
- `T_Str` -> string :
- If shorter than 4 chars (+ `\0`), is a "compact string"
- Otherwise, gets converted to a vector, inherently of chars
- `T_Fn` -> fn / function
@ -169,7 +169,7 @@ if 1:2 / 1:2:3, means stitching 1,2,3 together as a 2 or 3 byte value
- `popl` : pops the last #2 values on stack, starting from #1
- `cst0` : 2:3 -> LSW of 3
- `cst1` : 2:3 -> MSW of 3
- `iter` : Iterates on vector 1, keeping track with int value at 2, and sets
int value at 3 to 1 when done
to 1
- `iter` : Iterates on vector 1, keeping track with int value at 2, and sets
int value at 3 to 1 when done
to 1

View file

@ -2,6 +2,8 @@
#pragma once
#define FL_EPSILON (1e-6f)
enum OpTypes {
OP_add = 0,
OP_sub = 1,

View file

@ -4,6 +4,7 @@
#include <string.h>
#include "types.h"
#include "byte_defs.h"
int main(){