# Langatator A very basic interpreted programming language. ## Background The goal of this project is to create a simple implementation of a BASIC-like language just to learn a few things along the way and practice my C programming skills. No need to do complex thing, just to create a simple interpreted language that can be used to do some arithmetics and create for example a number guessing game. I didn't really study how others languages works beforehand, I'm just guessing how I'm implementing things so that I can make mistakes to learn from. ## Progress - 2022-04-29 : Implementation of a basic evaluator engine to evaluate arithmetic expressions and call functions ToDo List: - [X] pow operator - [X] binary operators - [X] implement basic math functions - [X] implement random_int(min, max) - [X] implement print_number(message) - [X] add unit tests - [X] allow to set variables - [X] read line comments - [ ] add modulus operator '%' - [ ] implement input_number() - [ ] base of the CLI - [ ] evaluate expression from stdin - [ ] read a file - [ ] if statements - [ ] while statements (with break) - [ ] add functions support - [ ] add config header file - [ ] ability to modify keywords and customize the lang - [ ] add strings support - [ ] add list support ## The language You would be able to use the lang directly via CLI, via a REPL or by writing in a file (file ext `.ltor`). To begin with and order to simplify things we would only have numbers as datatypes (so an abstraction with int or float under the hood). One instruction set per line. ### Comments Can only use single line comments with `#` ``` # this is a comment ``` ### Expression evaluation can only operate on integer function calls: func(arg_a, arg_b) operators: +, *, /, ^ ### Set a variable ``` set {VARNAME} to {EXPRESSION} ``` ### Eval an expression without using the result ``` eval print_number(42) ``` ### function definition ``` function {NAME} begin ... end ``` ### Conditional structure ``` if {EXPRESSION} then begin ... end ``` ### Conditional loop ``` while {EXPRESSION} do begin ... end ``` ### Unconditional loop ``` repeat {EXPRESSION THAT EVALUATE TO INT} begin end ``` ### std functions ``` abs(nb) sqrt,sin,cos,exp,ln,log etc. print_number(data) input_number() random_int(min, max) ``` # Evaluator (draft) EDIT: that's not actually quite how I implemented the evaluator. Map componentList: bytes steam first byte is a uint8 representing the type of the component then depending on the type of the component there is 0 or N bytes components types: - name: integer size: 4 bytes (for int) - name: open parenthesis size: 0 bytes - name: close parenthesis size: 0 bytes - name: float size: 32 bytes (IEEE 754) - name: operator size: 1 byte (255 operators are possible) - name: function designator desc: id of a function size: 2 bytes (65536 functions are possibles) Example map of `9+(5*(8+6))` lexed stream -TYPE:NUMERAL VALUE:9 -TYPE:OPERATOR VALUE:PLUS -TYPE:OPEN_PARENTHESIS VALUE:NULL -TYPE:NUMERAL VALUE:5 -TYPE:OPERATOR VALUE:TIMES -TYPE:OPEN_PARENTHESIS VALUE:NULL -TYPE:NUMERAL VALUE:8 -TYPE:OPERATOR VALUE:PLUS -TYPE:NUMERAL VALUE:6 -TYPE:CLOSE_P VALUE:NULL -TYPE:CLOSE_P VALUE:NULL scan the whole lexed stream So there will be a kind of time line with reference, a list of reference in the begining we allocate two lists, one for the component type, one for the component values ## Dynamics lists we allocate N bytes (uint_8 list[2048]) methods: list_length() list_assign_int(int index, int value) list_assign_float(int index, float value) list_assign_uint_8(int index, uint_8 value) list_get_int(int index) etc...