├── .gitignore ├── BUG.md ├── GENERIC.md ├── IDEAS.md ├── LICENSE ├── Logo.png ├── Makefile ├── QUICKSTART.md ├── README.md ├── STDLIB.md ├── TODO.md ├── docs ├── build-tool │ ├── makefile.md │ └── mlpx.md ├── language │ └── rethinking macros.md └── stdlib │ ├── alloc.md │ ├── cdef.md │ ├── convert.md │ ├── cstdarg.md │ ├── cstdlib.md │ ├── debug.md │ ├── examples.md │ ├── file.md │ ├── for.md │ ├── macro.md │ ├── print.md │ ├── read.md │ └── string.md ├── include └── stdlib │ ├── alloc │ └── backend.ml │ ├── builtin.ml │ ├── builtin │ ├── alloc.ml │ └── for.ml │ ├── c │ ├── cdef.ml │ ├── cstdarg.ml │ └── cstdlib.ml │ ├── convert.ml │ ├── debug.ml │ ├── io │ ├── file.ml │ ├── print.ml │ └── read.ml │ ├── legacy │ └── va_utils.ml │ ├── macro.ml │ ├── str_build.ml │ ├── str_list.ml │ ├── string.ml │ └── string │ └── backend.ml ├── minilang-highlighter ├── CHANGELOG.md ├── README.md ├── language-configuration.json ├── minilang-highlighter-0.0.1.vsix ├── package.json ├── support-function.txt ├── syntaxes │ └── minilang.tmLanguage.json └── vsc-extension-quickstart.md ├── mlpx ├── samples ├── calc │ ├── in.txt │ └── src │ │ ├── def.ml │ │ ├── lex.ml │ │ └── main.ml ├── fib │ └── src │ │ └── main.ml ├── fizzbuzz │ └── src │ │ └── main.ml ├── fractal │ ├── mandelbrot.txt │ └── src │ │ ├── clui.ml │ │ ├── cluidefs.ml │ │ ├── fractal.ml │ │ └── main.ml ├── helloworld │ └── src │ │ └── main.ml ├── io │ ├── in.txt │ ├── out.txt │ └── src │ │ └── main.ml ├── max │ └── src │ │ └── main.ml ├── printf │ └── src │ │ ├── main.ml │ │ ├── number.ml │ │ └── printf.ml ├── str-ufcs │ └── src │ │ └── main.ml └── task-mgr │ └── src │ ├── main.ml │ └── task.ml ├── skel ├── Makefile ├── include │ ├── gc-LICENSE │ ├── gc.c │ ├── gc.h │ ├── log.c │ ├── log.h │ ├── mlalloc.c │ ├── mlalloc.h │ ├── sds-LICENSE │ ├── sds.c │ ├── sds.h │ └── sdsalloc.h └── src │ └── main.ml ├── src ├── Def.py ├── Gen.py ├── GenStr.py ├── Lexer.py ├── Main.py ├── Parser.py ├── Snippet.py └── backend │ ├── Walker.py │ ├── c │ ├── CDef.py │ └── CWalker.py │ └── ml │ ├── MLDef.py │ └── MLWalker.py └── tests ├── alloc-test └── src │ ├── alloc.ml │ ├── alloc_backend.ml │ └── main.ml ├── aoc-2022 ├── day-1 │ ├── Makefile │ ├── include │ │ ├── gc-LICENSE │ │ ├── gc.c │ │ ├── gc.h │ │ ├── log.c │ │ ├── log.h │ │ ├── mlalloc.c │ │ ├── mlalloc.h │ │ ├── sds-LICENSE │ │ ├── sds.c │ │ ├── sds.h │ │ └── sdsalloc.h │ ├── input.txt │ └── src │ │ └── main.ml └── day-2 │ ├── Makefile │ ├── include │ ├── gc-LICENSE │ ├── gc.c │ ├── gc.h │ ├── log.c │ ├── log.h │ ├── mlalloc.c │ ├── mlalloc.h │ ├── sds-LICENSE │ ├── sds.c │ ├── sds.h │ └── sdsalloc.h │ ├── input.txt │ └── src │ └── main.ml ├── array ├── loop-test │ ├── Makefile │ └── src │ │ └── main.ml ├── ptr-test │ ├── Makefile │ └── src │ │ └── main.ml └── test │ ├── Makefile │ └── src │ └── main.ml ├── bool └── src │ └── main.ml ├── builtins └── main.ml ├── convert-test └── src │ ├── convert.ml │ └── main.ml ├── defer └── src │ └── main.ml ├── for-test └── src │ └── main.ml ├── gen-test └── src │ └── main.ml ├── io-test ├── out.txt ├── src │ ├── io │ │ ├── fio.ml │ │ ├── io.ml │ │ ├── print.ml │ │ └── read.ml │ └── main.ml ├── test-num.txt └── test.txt ├── macro-lang └── src │ └── main.ml ├── macro └── src │ └── main.ml ├── print-test └── src │ └── main.ml ├── raii-test ├── mlpx └── src │ └── main.ml ├── re-test └── src │ ├── main.ml │ └── re.ml ├── ref └── src │ └── main.ml ├── regex-test └── src │ ├── main.ml │ └── regex.ml ├── stdarg-test └── src │ ├── cstdarg.ml │ └── main.ml ├── str-buildtest ├── main.c ├── mlpx └── src │ ├── main.ml │ └── str_build.ml ├── string-test ├── input.txt └── src │ └── main.ml ├── string ├── heredoc.ml ├── loop.ml ├── strcat.ml └── strcpy.ml └── test ├── input.txt ├── src ├── main.ml ├── primes.ml ├── sig.ml ├── str_list.ml └── task.ml └── test.c /.gitignore: -------------------------------------------------------------------------------- 1 | .vscode 2 | __pycache__ 3 | src/__pycache__ -------------------------------------------------------------------------------- /BUG.md: -------------------------------------------------------------------------------- 1 | # Bugs 2 | 3 | Solved: 26/33 4 | 5 | - [ ] GC alloc with RAII. (free after alloc_stop) 6 | - [ ] Signature inside struct. 7 | - [ ] Variadic macro expansion nestsing. 8 | - [ ] Macros cause buggy behaviour with UFCS. 9 | - [ ] Make that control structures create blocks. 10 | - [ ] Function declarations do not work inside macros (fails signature check). 11 | - [ ] Div/Mod bug for asm backend (Doesn't check `in_reg` == `rax`) (**DEPRECATED BACKEND**) 12 | - [X] No type checking for array access idx. 13 | - [X] No type checking when passing sig to fun. 14 | - [X] Bug with functions returning refs. 15 | - [X] `Parser.ref` does not implicit cast-to-ref (add `try_cast_ref`) 16 | - [X] Functions like `input` are predeferred. 17 | - [X] Using an iterator `i` in a for loop does not compile correctly. 18 | - [X] Nested UFCS expressions (s.equals("Hello".str)) 19 | - [X] The type of an overloaded function with a diff type than the first takes the type of the first overloaded function 20 | - [X] Pointer to struct displayed as "long long*". (no name field in elem_ckind) 21 | - [X] Struct elements pollute the global scope with non-existent variables. 22 | - [X] Cannot call function as struct method with only one arg. 23 | - [X] Macro-related bug (check `expand_macro`). 24 | - [X] `ma_cnt` builtin is no longer working. 25 | - [X] Implicit cast arr-ptr/ref doesn't work (Def.type_compatible). 26 | - [X] Passing arguments from variadic macro to fun doesn't work. 27 | - [X] Assignment/At-related bug (also in macros) (`"15" = 5`/`"15" at (12 + 1)`). 28 | - [X] Cannot call function as a function param. 29 | - [X] No type checking for reference and dereference (`*bool = int64`). 30 | - [X] Faulty load before an assignment (div). 31 | - [X] Assignment of array rvalue to ptr type 32 | - [X] `nr % 10 + '0'` fails due to widen. 33 | - [X] No non-int64 ptrs/arrays due to arr_type and ptr_type. 34 | - [X] Save registers before calling a function. 35 | - [X] *cstr results in a int64, not int8. 36 | - [X] Add declared variables to fun's offset. 37 | - [X] References aren't working. 38 | -------------------------------------------------------------------------------- /GENERIC.md: -------------------------------------------------------------------------------- 1 | # Generic plan of action 2 | 3 | 1. Change lexer to interpret "\[.*\]" as pack. 4 | 2. Then in post-process it's expanded based on the previous token. 5 | * var[...] => Array access 6 | * fun[...] => Generic specialization 7 | * [...] => Array literal 8 | -------------------------------------------------------------------------------- /IDEAS.md: -------------------------------------------------------------------------------- 1 | # Ideas 2 | 3 | Implemented: 17/25 4 | 5 | - [ ] Unions 6 | - [ ] Enums 7 | - [ ] Generics 8 | - [ ] Operator overloading 9 | - [ ] `when` and `symbol` construct 10 | - [ ] Add stdlib.safe: A library that disables c bindings and makes the language safer 11 | - [ ] Function overloading (by return) 12 | - [ ] Rethink assembly interface (regs as variables, ...) 13 | - [X] RAII 14 | - [X] Structs 15 | - [X] Access operator (`.`) 16 | - [X] Function overloading (by args) 17 | - [X] Deprecate `ma_cnt` (`count` builtin) 18 | - [X] Add `literal` builtin (pass arg directly to backend) 19 | - [X] Deprecate `off_of` (cannot be reproduced in c) 20 | - [X] type_of builtin -> str literal. 21 | - [X] Check for circular imports. 22 | - [X] Type inference. 23 | - [X] Type definitions. 24 | - [X] Namespaces. 25 | - [X] Ruby-like heredocs. 26 | - [X] Non-integer boolean type. 27 | - [X] `file` & `line` builtins. 28 | - [X] References. 29 | - [X] Cast builtin. 30 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright © 2023-2024 Nicolae Petri, 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the “Software”), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE.. 22 | -------------------------------------------------------------------------------- /Logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NICUP14/MiniLang/df58259c6cd8592e879982c32bfae78e42bffd49/Logo.png -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # Project structure 2 | RECIPE ?= 3 | BUILD_DIR ?= bin 4 | SOURCE_DIR ?= src 5 | 6 | # Project parameters 7 | PROJECT = main 8 | SOURCES = $(wildcard $(SOURCE_DIR)/main.ml) 9 | OBJECTS = $(patsubst $(SOURCE_DIR)/%.ml, $(BUILD_DIR)/%.c, $(SOURCES)) 10 | ASM_OBJECTS = $(patsubst $(SOURCE_DIR)/%.ml, $(BUILD_DIR)/%.S, $(SOURCES)) 11 | 12 | # C compiler parameters 13 | CC = gcc 14 | CFLAGS ?= 15 | CFLAGS += -g 16 | 17 | # Compiler parameters 18 | ML = python ../../src/Main.py 19 | MLLIB ?= "../../include" 20 | MLFLAGS ?= 21 | MLFLAGS += -C 22 | 23 | # Recipes 24 | default: clean def 25 | c: clean _c 26 | ml: clean _ml 27 | debug: clean _mldebug 28 | cdebug: clean _cdebug 29 | assemble: $(ASM_OBJECTS) 30 | compile: $(PROJECT) 31 | 32 | # Shortcuts 33 | def: c 34 | dbg: debug 35 | cdbg: cdebug 36 | asm: assemble 37 | 38 | _c: $(SOURCES) 39 | @mkdir -p $(BUILD_DIR) 40 | $(ML) $(MLFLAGS) -I $(MLLIB) -I src $(SOURCES) > $(BUILD_DIR)/$(PROJECT).c 41 | $(CC) $(CFLAGS) -I include include/*.c $(BUILD_DIR)/$(PROJECT).c -o $(BUILD_DIR)/$(PROJECT) 42 | 43 | _cdebug: $(SOURCES) 44 | $(ML) $(MLFLAGS) -I $(MLLIB) -I src $(SOURCES) 45 | 46 | _ml: 47 | @mkdir -p $(BUILD_DIR) 48 | $(ML) $(MLFLAGS) -d -I $(MLLIB) -I src $(SOURCES) -o $(BUILD_DIR)/$(PROJECT).ml 49 | 50 | _mldebug: $(SOURCES) 51 | $(ML) $(MLFLAGS) -d -I $(MLLIB) -I src $(SOURCES) 52 | 53 | $(PROJECT) : $(OBJECTS) 54 | $(CC) $(CFLAGS) $(CXX) $^ -o $(BUILD_DIR)/$@ 55 | 56 | $(BUILD_DIR)/%.o: $(BUILD_DIR)/%.S 57 | @mkdir -p $(BUILD_DIR) 58 | $(CC) $(CFLAGS) $^ -o $@ 59 | 60 | $(BUILD_DIR)/%.S: $(SOURCE_DIR)/%.ml 61 | @mkdir -p $(BUILD_DIR) 62 | $(ML) $(MLFLAGS) -I $(MLLIB) -I src $< -o $@ 63 | 64 | clean: 65 | @rm -vrf $(BUILD_DIR) -------------------------------------------------------------------------------- /STDLIB.md: -------------------------------------------------------------------------------- 1 | # Standard library 2 | 3 | An overview of the ML standard library. 4 | 5 | ## Dependencies 6 | 7 | Dependency | Required by 8 | ------------------------------------------------------|------------ 9 | [tiny-regex-c](https://github.com/kokke/tiny-regex-c) | `stdlib/re` (*Coming soon...*) 10 | [sds](https://github.com/antirez/sds) | `stdlib/string` 11 | [gc](https://github.com/mkirchner/gc) | `stdlib/builtin/alloc` 12 | 13 | ## Motivation 14 | 15 | > [!IMPORTANT] 16 | > Ported functions from the c library are regarded as unsafe in terms of type and memory safety, unlike their ML counterparts. Using c bindings should be avoided where safer ML libraries are available. 17 | 18 | The standard library permits the use of both unsafe c standard library functions (for embedded systems and nostalgic c programmers) and their safe ML counterparts, plus some other useful modern libraries, like `string` and `convert`. 19 | 20 | ## Modules 21 | 22 | > [!TIP] 23 | > Click on a module to display its documentation. 24 | 25 | Module | Parent dir. | Description 26 | ----------------------------------|---------------|------------ 27 | [for](docs/stdlib/for.md) | builtin | Convenient for-based constructs and looping utilities 28 | [alloc](docs/stdlib/alloc.md) | builtin | Customizable memory allocation utilities 29 | [cdefs](docs/stdlib/cdef.md) | c | Commonly used c type definitions 30 | [cstdlib](docs/stdlib/cstdlib.md) | c | Bindings for ported functions of the c standard library 31 | [cstarg](docs/stdlib/cstdarg.md) | c | Bindings for the `stdarg.h` c library 32 | [print](docs/stdlib/print.md) | io | Extendable and safe frontend for `printf`/`fprintf` 33 | [read](docs/stdlib/read.md) | io | Extendable and safe frontend for `scanf`/`fscanf` 34 | [file](docs/stdlib/file.md) | io | A frontend for c file-related functions 35 | [convert](docs/stdlib/convert.md) | - | Type conversion library 36 | [debug](docs/stdlib/debug.ml) | - | Customizable rust-like assertables and panic macros 37 | [string](docs/stdlib/string.md) | - | Functional-like string library 38 | [macro](docs/stdlib/macro.md) | - | Stand-alone convenience macros 39 | backend | alloc | Bindings for the `gc.h` c library (Garbage collector) 40 | backend | string | Bindings for the `sds.h` c library (Simple Dynamic Strings) 41 | va_utils | legacy | Simplistic `stdarg.h`-like implementation for the assembly backend (deprecated) 42 | -------------------------------------------------------------------------------- /TODO.md: -------------------------------------------------------------------------------- 1 | # TODO 2 | 3 | Solved: 30/39 4 | 5 | - [ ] Global arrays. 6 | - [ ] Add block section to README. 7 | - [ ] Improve safety and memory safety! 8 | - [ ] Add roadmap to README. 9 | - [ ] Add function sigs to README 10 | - [ ] Add generic functions to QUICKSTART. 11 | - [ ] Suggestive errors for non-existent members. 12 | - [ ] Add const, unsigned and floating point types. 13 | - [ ] Add multi-lever pointers/refs (vtype: List[ckind]). 14 | - [X] Function pointer (`^my_fun`). 15 | - [X] Create `inject_ref` to replace `inject_copy` for `Parser._fun_call`. 16 | - [X] Document `mlpx` in `MLPX.md` and add it to README. 17 | - [X] Fix references causing errors in c backend (`&fun(...)`). 18 | - [X] Separate macro (`delimit(" " , args)`). 19 | - [X] Add for-loop & RAII documentation to QUICKSTART. 20 | - [X] Simplify compiling process (`mlpx.py`) 21 | - [X] Add namespace section to README. 22 | - [X] Replace "minimal" by "easy to learn", "gentle curve" in README. 23 | - [X] Add section at the start of README about lang-specific features. 24 | - [X] `end` no longed needed at bottom of module. 25 | - [X] C generator backend (CWalker.py). 26 | - [X] ML generator backend (GenStr.py -> MLWalker.py). 27 | - [X] Fix type system. 28 | - [X] Widen during parsing. 29 | - [X] Static type analysis. 30 | - [X] Check args in function call. 31 | - [X] Include section in README regarding miscellaneous features (references, fixed-len pointers, namespaces). 32 | - [X] Update README (#1) (new builtins, elif, ufcs, alias). 33 | - [X] Update README (#2) (new operators, function overloading, structs). 34 | - [X] Fix array access. 35 | - [X] Fix array variable offset. 36 | - [X] Implement stack alignment (align by 16-bytes). 37 | - [X] Define operator token types (binary, unary). 38 | - [X] Implement right-assoc. 39 | - [X] Implement lazy loading (gen). 40 | - [X] Add an output file parameter to the Gen module. 41 | - [X] Improve Def.rev_type_of. 42 | - [X] Defer. 43 | - [X] Import. 44 | -------------------------------------------------------------------------------- /docs/build-tool/makefile.md: -------------------------------------------------------------------------------- 1 | # Makefile 2 | 3 | Managing `MiniLang` project using the `GNU make` build tool. 4 | 5 | ## Project skeleton structure 6 | 7 | ```txt 8 | skel/ 9 | ├── include 10 | │ ├── gc.c 11 | │ ├── gc.h 12 | │ ├── gc-LICENSE 13 | │ ├── log.c 14 | │ ├── log.h 15 | │ ├── sds.c 16 | │ ├── sds.h 17 | │ ├── sdsalloc.h 18 | │ └── sds-LICENSE 19 | ├── Makefile 20 | └── src 21 | └── main.ml 22 | ``` 23 | 24 | ## Recipes 25 | 26 | Recipe | Alias | Backend 27 | ---------|--------|-------- 28 | default | def, c | c 29 | cdebug | cdbg | c 30 | debug | dbg | ml 31 | assemble | asm | asm 32 | 33 | ## Parameters 34 | 35 | > [!WARNING] 36 | > For new ML projects, makefile parameters `ML`, `MLLIB` need to be adjusted if they are specified by a relative path. 37 | 38 | Parameter | Description 39 | ----------|------------------------------ 40 | CC | Path to c compiler 41 | ML | Path to ML compiler 42 | MLLIB | Path to ML standard library 43 | CFLAGS | Options passed to c compiler 44 | MLFLAGS | Options passed to ML compiler 45 | -------------------------------------------------------------------------------- /docs/build-tool/mlpx.md: -------------------------------------------------------------------------------- 1 | # MiniLang Project Extension 2 | 3 | A convenient tool for managing `MiniLang` projects. 4 | 5 | ## Project skeleton structure 6 | 7 | ```txt 8 | skel/ 9 | ├── mlpx 10 | └── src 11 | └── main.ml 12 | ``` 13 | 14 | ## Examples 15 | 16 | ### Creating a project 17 | 18 | ```txt 19 | $ python mlpx init tests/newproj 20 | Initializing project tests/newproj 21 | mkdir -p tests/newproj 22 | cp -vr ./skel/src tests/newproj 23 | './skel/src' -> 'tests/newproj/src' 24 | './skel/src/main.ml' -> 'tests/newproj/src/main.ml' 25 | ``` 26 | 27 | ### Cleaning a project 28 | 29 | ```txt 30 | $ python mlpx -C tests/test/ clean 31 | Cleaning tests/test/bin 32 | rm -vrf tests/test/bin 33 | removed 'tests/test/bin/main.c' 34 | removed 'tests/test/bin/main.exe' 35 | removed directory 'tests/test/bin' 36 | Done! 37 | ``` 38 | 39 | ### Running a project 40 | 41 | ```txt 42 | $ python mlpx -C tests/test/ run 43 | > Running tests/test/bin/main 44 | tests/test/bin/main 45 |