Merge branch 'main' into 119-fix-ast-memory-leak
This commit is contained in:
commit
a639b988ed
|
@ -0,0 +1,20 @@
|
||||||
|
name: MSYS2
|
||||||
|
on: [push, pull_request]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
msys2-mingw64:
|
||||||
|
runs-on: windows-latest
|
||||||
|
defaults:
|
||||||
|
run:
|
||||||
|
shell: msys2 {0}
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
- uses: msys2/setup-msys2@v2
|
||||||
|
with:
|
||||||
|
msystem: MINGW64
|
||||||
|
update: true
|
||||||
|
install: mingw-w64-x86_64-gcc mingw-w64-x86_64-glib2 bison flex mingw-w64-x86_64-llvm cmake git make
|
||||||
|
- name: CI-Build
|
||||||
|
run: |
|
||||||
|
echo 'Running in MSYS2!'
|
||||||
|
./ci-build.sh
|
30
README.md
30
README.md
|
@ -1,17 +1,31 @@
|
||||||
# Gemstone
|
|
||||||
|
|
||||||
Gemstone is a programming language compiler written in C with lex and yacc.
|
<div align="center">
|
||||||
|
<picture>
|
||||||
|
<img alt="gemstone logo" src="https://github.com/Servostar/gemstone/assets/72654954/fdb37c1b-81ca-4e6a-a9e9-c46effb12dae" width="75%">
|
||||||
|
</picture>
|
||||||
|
</div>
|
||||||
|
<br>
|
||||||
|
|
||||||
|
## Gemstone
|
||||||
|
|
||||||
|
Gemstone is a programming language compiler (short: GSC) written in C based on flex and GNU bison.
|
||||||
|
It uses LLVM to produce optimized native binaries for many platforms and uses its own builtin build system for more complex project management.
|
||||||
|
|
||||||
## Dependencies (build)
|
## Dependencies (build)
|
||||||
|
|
||||||
### Windows 11
|
### Windows 11
|
||||||
|
|
||||||
For setup instruction see issue #30
|
#### MSYS2
|
||||||
|
|
||||||
Requires:
|
|
||||||
- Microsoft Build Tools 2022 (includes: CMake, MSVC)
|
|
||||||
- WinFlexBison [find it here](https://github.com/lexxmark/winflexbison) (needs to be in PATH)
|
|
||||||
|
|
||||||
|
Install MSYS2 under Windows 11. Open the MingGW64 environment.
|
||||||
|
Install the following packages:
|
||||||
|
```
|
||||||
|
pacman -S mingw-w64-x86_64-gcc mingw-w64-x86_64-glib2 bison flex mingw-w64-x86_64-llvm cmake git make
|
||||||
|
```
|
||||||
|
Clone the repository and build the gemstone compiler:
|
||||||
|
```
|
||||||
|
cmake . && make release
|
||||||
|
```
|
||||||
### GNU/Linux
|
### GNU/Linux
|
||||||
|
|
||||||
Requires:
|
Requires:
|
||||||
|
@ -20,6 +34,8 @@ Requires:
|
||||||
- Make
|
- Make
|
||||||
- bison
|
- bison
|
||||||
- flex
|
- flex
|
||||||
|
- LLVM
|
||||||
|
- Glib 2.0
|
||||||
|
|
||||||
## Writing Tests
|
## Writing Tests
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
cmake .
|
||||||
|
make release
|
|
@ -215,6 +215,7 @@ void AST_delete_node(struct AST_Node_t *node) {
|
||||||
DEBUG("Deleting AST node: %p", node);
|
DEBUG("Deleting AST node: %p", node);
|
||||||
|
|
||||||
if (node->parent != NULL) {
|
if (node->parent != NULL) {
|
||||||
|
[[maybe_unused]]
|
||||||
const struct AST_Node_t* child = AST_detach_child(node->parent, node);
|
const struct AST_Node_t* child = AST_detach_child(node->parent, node);
|
||||||
assert(child == node);
|
assert(child == node);
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,9 +14,15 @@
|
||||||
|
|
||||||
#define MAX_PATH_BYTES PATH_MAX
|
#define MAX_PATH_BYTES PATH_MAX
|
||||||
|
|
||||||
|
#define min(a, b) ((a) > (b) ? (b) : (a))
|
||||||
|
|
||||||
#elif defined(_WIN32) || defined(WIN32)
|
#elif defined(_WIN32) || defined(WIN32)
|
||||||
|
|
||||||
#include <Windows.h>
|
#include <Windows.h>
|
||||||
|
// for _fullpath
|
||||||
|
#include <stdlib.h>
|
||||||
|
// for _mkdir
|
||||||
|
#include <direct.h>
|
||||||
|
|
||||||
#define MAX_PATH_BYTES _MAX_PATH
|
#define MAX_PATH_BYTES _MAX_PATH
|
||||||
|
|
||||||
|
@ -66,10 +72,6 @@ void delete_files(ModuleFileStack *stack) {
|
||||||
// seeking the current line in print_diagnostic()
|
// seeking the current line in print_diagnostic()
|
||||||
#define SEEK_BUF_BYTES 256
|
#define SEEK_BUF_BYTES 256
|
||||||
|
|
||||||
static inline unsigned long int min(unsigned long int a, unsigned long int b) {
|
|
||||||
return a > b ? b : a;
|
|
||||||
}
|
|
||||||
|
|
||||||
// behaves like fgets except that it has defined behavior when n == 1
|
// behaves like fgets except that it has defined behavior when n == 1
|
||||||
static void custom_fgets(char *buffer, size_t n, FILE *stream) {
|
static void custom_fgets(char *buffer, size_t n, FILE *stream) {
|
||||||
if (n == 1) {
|
if (n == 1) {
|
||||||
|
@ -123,15 +125,15 @@ void print_diagnostic(ModuleFile *file, TokenLocation *location, Message kind, c
|
||||||
|
|
||||||
mem_free((void *) absolute_path);
|
mem_free((void *) absolute_path);
|
||||||
|
|
||||||
const size_t lines = location->line_end - location->line_start + 1;
|
const unsigned long int lines = location->line_end - location->line_start + 1;
|
||||||
|
|
||||||
for (size_t l = 0; l < lines; l++) {
|
for (unsigned long int l = 0; l < lines; l++) {
|
||||||
printf(" %4ld | ", location->line_start + l);
|
printf(" %4ld | ", location->line_start + l);
|
||||||
|
|
||||||
size_t chars = 0;
|
unsigned long int chars = 0;
|
||||||
|
|
||||||
// print line before token group start
|
// print line before token group start
|
||||||
size_t limit = min(location->col_start, SEEK_BUF_BYTES);
|
unsigned long int limit = min(location->col_start, SEEK_BUF_BYTES);
|
||||||
while (limit > 1) {
|
while (limit > 1) {
|
||||||
custom_fgets(buffer, (int) limit, file->handle);
|
custom_fgets(buffer, (int) limit, file->handle);
|
||||||
chars += printf("%s", buffer);
|
chars += printf("%s", buffer);
|
||||||
|
@ -169,13 +171,13 @@ void print_diagnostic(ModuleFile *file, TokenLocation *location, Message kind, c
|
||||||
}
|
}
|
||||||
|
|
||||||
printf(" | ");
|
printf(" | ");
|
||||||
for (size_t i = 1; i < location->col_start; i++) {
|
for (unsigned long int i = 1; i < location->col_start; i++) {
|
||||||
printf(" ");
|
printf(" ");
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("%s", accent_color);
|
printf("%s", accent_color);
|
||||||
printf("^");
|
printf("^");
|
||||||
for (size_t i = 0; i < location->col_end - location->col_start; i++) {
|
for (unsigned long int i = 0; i < location->col_end - location->col_start; i++) {
|
||||||
printf("~");
|
printf("~");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -321,7 +323,7 @@ const char *get_absolute_path(const char *path) {
|
||||||
#elif defined(_WIN32) || defined(WIN32)
|
#elif defined(_WIN32) || defined(WIN32)
|
||||||
// use Windows CRT specific function
|
// use Windows CRT specific function
|
||||||
char absolute_path[MAX_PATH_BYTES];
|
char absolute_path[MAX_PATH_BYTES];
|
||||||
_fullpath(path, absolute_path, _MAX_PATH);
|
_fullpath((char*) path, absolute_path, _MAX_PATH);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return mem_strdup(MemoryNamespaceIo, absolute_path);
|
return mem_strdup(MemoryNamespaceIo, absolute_path);
|
||||||
|
|
|
@ -15,9 +15,9 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef struct FileDiagnosticStatistics_t {
|
typedef struct FileDiagnosticStatistics_t {
|
||||||
size_t error_count;
|
unsigned long int error_count;
|
||||||
size_t warning_count;
|
unsigned long int warning_count;
|
||||||
size_t info_count;
|
unsigned long int info_count;
|
||||||
} FileDiagnosticStatistics;
|
} FileDiagnosticStatistics;
|
||||||
|
|
||||||
typedef struct ModuleFile_t {
|
typedef struct ModuleFile_t {
|
||||||
|
|
|
@ -71,8 +71,7 @@ int stdout_supports_ansi_esc() {
|
||||||
HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
|
HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||||
|
|
||||||
if (!GetConsoleMode(hConsole, &mode)) {
|
if (!GetConsoleMode(hConsole, &mode)) {
|
||||||
ERROR("failed to get console mode");
|
return ASNI_DISABLED;
|
||||||
return ANSI_ENABLED;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((mode & ENABLE_VIRTUAL_TERMINAL_INPUT) |
|
if ((mode & ENABLE_VIRTUAL_TERMINAL_INPUT) |
|
||||||
|
|
Loading…
Reference in New Issue