translate and execute do wraps
This commit is contained in:
2
.vscode/launch.json
vendored
2
.vscode/launch.json
vendored
@@ -9,7 +9,7 @@
|
||||
"type": "cppdbg",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/bin/argon",
|
||||
"args": ["test.ar"],
|
||||
"args": ["testing.ar"],
|
||||
"stopAtEntry": true,
|
||||
"cwd": "${workspaceFolder}",
|
||||
"environment": [],
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
import random
|
||||
import sys
|
||||
|
||||
for i in range(100000000):
|
||||
for i in range(10000):
|
||||
sys.stdout.write("\"")
|
||||
sys.stdout.write(str(random.random()))
|
||||
sys.stdout.write("\"\n")
|
||||
|
||||
56
src/err.c
56
src/err.c
@@ -15,6 +15,51 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
ssize_t getline(char **lineptr, size_t *n, FILE *stream) {
|
||||
if (lineptr == NULL || n == NULL || stream == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
size_t pos = 0;
|
||||
int c;
|
||||
|
||||
if (*lineptr == NULL || *n == 0) {
|
||||
*n = 128; // initial buffer size
|
||||
*lineptr = malloc(*n);
|
||||
if (*lineptr == NULL) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
while ((c = fgetc(stream)) != EOF) {
|
||||
// Resize buffer if needed
|
||||
if (pos + 1 >= *n) {
|
||||
size_t new_size = *n * 2;
|
||||
char *new_ptr = realloc(*lineptr, new_size);
|
||||
if (new_ptr == NULL) {
|
||||
return -1;
|
||||
}
|
||||
*lineptr = new_ptr;
|
||||
*n = new_size;
|
||||
}
|
||||
|
||||
(*lineptr)[pos++] = (char)c;
|
||||
|
||||
if (c == '\n') {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (pos == 0 && c == EOF) {
|
||||
return -1; // EOF and no data read
|
||||
}
|
||||
|
||||
(*lineptr)[pos] = '\0';
|
||||
return (ssize_t)pos;
|
||||
}
|
||||
#endif
|
||||
|
||||
const ArErr no_err = (ArErr){false};
|
||||
|
||||
ArErr create_err(int64_t line, int64_t column, int length, char *path,
|
||||
@@ -86,7 +131,6 @@ void output_err(ArErr err) {
|
||||
|
||||
while ((len = getline(&buffer, &size, file)) != -1) {
|
||||
if (current_line == err.line) {
|
||||
printf("bruh\n");
|
||||
break;
|
||||
}
|
||||
current_line++;
|
||||
@@ -99,20 +143,24 @@ void output_err(ArErr err) {
|
||||
|
||||
char *line_starts = buffer;
|
||||
size_t skipped_chars = 0;
|
||||
while (*line_starts && isspace((unsigned char)*line_starts) && line_starts-buffer < err.column-1) {
|
||||
while (*line_starts && isspace((unsigned char)*line_starts) &&
|
||||
line_starts - buffer < err.column - 1) {
|
||||
line_starts++;
|
||||
err.column--;
|
||||
skipped_chars++;
|
||||
}
|
||||
fprintf(stderr, " %zu | ", err.line);
|
||||
if (err.length) {
|
||||
fprintf(stderr, "%.*s", (int)err.column-1, line_starts);
|
||||
fprintf(stderr, "%.*s", (int)err.column - 1, line_starts);
|
||||
dyefg(stderr, DYE_RED);
|
||||
dye_style(stderr, DYE_STYLE_BOLD);
|
||||
fprintf(stderr, "%.*s", err.length, line_starts + err.column - 1);
|
||||
dye_style(stderr, DYE_STYLE_RESET);
|
||||
dyefg(stderr, DYE_RESET);
|
||||
fprintf(stderr, "%.*s", (int)len - (int)skipped_chars-(int)err.column-(int)err.length, line_starts + (int)err.column + err.length - 1);
|
||||
fprintf(stderr, "%.*s",
|
||||
(int)len - (int)skipped_chars - (int)err.column -
|
||||
(int)err.length,
|
||||
line_starts + (int)err.column + err.length - 1);
|
||||
for (int64_t i = 0; i < err.column - 1; i++) {
|
||||
fprintf(stderr, " ");
|
||||
}
|
||||
|
||||
@@ -4,10 +4,15 @@
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#include <bcrypt.h>
|
||||
#else
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include "siphash/siphash.h"
|
||||
#include "hash_data.h"
|
||||
|
||||
@@ -15,12 +20,19 @@ uint8_t siphash_key[16];
|
||||
const uint8_t siphash_key_fixed_for_translator[16] = {218, 19, 245, 136, 128, 160, 122, 81, 249, 147, 111, 230, 174, 145, 125 ,218};
|
||||
uint8_t empty_siphash_key[16];
|
||||
|
||||
|
||||
void generate_siphash_key(uint8_t hash_key[16]) {
|
||||
#ifdef _WIN32
|
||||
if (BCryptGenRandom(NULL, hash_key, 16, BCRYPT_USE_SYSTEM_PREFERRED_RNG) != 0) {
|
||||
// Fallback or abort
|
||||
}
|
||||
#else
|
||||
int fd = open("/dev/urandom", O_RDONLY);
|
||||
if (fd < 0 || read(fd, hash_key, 16) != 16) {
|
||||
// Fallback or abort
|
||||
}
|
||||
close(fd);
|
||||
#endif
|
||||
}
|
||||
|
||||
uint64_t siphash64_bytes(const void *data, size_t len,const uint8_t hash_key[16]) {
|
||||
|
||||
@@ -79,10 +79,10 @@ typedef enum {
|
||||
TOKEN_COLON,
|
||||
TOKEN_EXCLAMATION,
|
||||
TOKEN_INVALID,
|
||||
} TokenType;
|
||||
} ArTokenType;
|
||||
|
||||
typedef struct {
|
||||
TokenType type;
|
||||
ArTokenType type;
|
||||
size_t line;
|
||||
size_t column;
|
||||
size_t length;
|
||||
|
||||
68
src/main.c
68
src/main.c
@@ -14,8 +14,6 @@
|
||||
|
||||
#include "../external/xxhash/xxhash.h"
|
||||
#include "hash_data/hash_data.h"
|
||||
#include <arpa/inet.h>
|
||||
#include <endian.h>
|
||||
#include <locale.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
@@ -26,11 +24,13 @@
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
#ifdef _WIN32
|
||||
#include <direct.h>
|
||||
#define mkdir(path, mode) _mkdir(path)
|
||||
#include <windows.h>
|
||||
#include <direct.h> // for _mkdir
|
||||
#include <sys/stat.h> // for _stat
|
||||
#else
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#include "../external/cwalk/include/cwalk.h"
|
||||
#include <string.h>
|
||||
@@ -43,6 +43,28 @@
|
||||
#endif
|
||||
#include "err.h"
|
||||
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
|
||||
// Windows / MinGW usually uses little-endian, so these can be no-ops
|
||||
// But define them explicitly to avoid implicit declaration warnings
|
||||
|
||||
static inline uint32_t le32toh(uint32_t x) {
|
||||
return x;
|
||||
}
|
||||
static inline uint64_t le64toh(uint64_t x) {
|
||||
return x;
|
||||
}
|
||||
static inline uint32_t htole32(uint32_t x) {
|
||||
return x;
|
||||
}
|
||||
static inline uint64_t htole64(uint64_t x) {
|
||||
return x;
|
||||
}
|
||||
|
||||
#else
|
||||
#include <endian.h> // On Linux/BSD
|
||||
#endif
|
||||
|
||||
char *get_current_directory() {
|
||||
char *buffer = NULL;
|
||||
|
||||
@@ -72,16 +94,32 @@ char *get_current_directory() {
|
||||
}
|
||||
|
||||
int ensure_dir_exists(const char *path) {
|
||||
struct stat st = {0};
|
||||
|
||||
if (stat(path, &st) == -1) {
|
||||
// Directory does not exist, create it
|
||||
if (mkdir(path, 0755) != 0) {
|
||||
perror("mkdir failed");
|
||||
return -1;
|
||||
#ifdef _WIN32
|
||||
struct _stat st;
|
||||
if (_stat(path, &st) != 0) {
|
||||
// Directory does not exist, create it
|
||||
if (_mkdir(path) != 0) {
|
||||
perror("_mkdir failed");
|
||||
return -1;
|
||||
}
|
||||
} else if (!(st.st_mode & _S_IFDIR)) {
|
||||
fprintf(stderr, "Path exists but is not a directory\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
#else
|
||||
struct stat st;
|
||||
if (stat(path, &st) != 0) {
|
||||
// Directory does not exist, create it
|
||||
if (mkdir(path, 0755) != 0) {
|
||||
perror("mkdir failed");
|
||||
return -1;
|
||||
}
|
||||
} else if (!S_ISDIR(st.st_mode)) {
|
||||
fprintf(stderr, "Path exists but is not a directory\n");
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char CACHE_FOLDER[] = "__arcache__";
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
typedef struct {
|
||||
ParsedValue * to;
|
||||
TokenType type;
|
||||
ArTokenType type;
|
||||
ParsedValue * from;
|
||||
} ParsedAssign;
|
||||
|
||||
|
||||
@@ -49,59 +49,57 @@ ParsedValueReturn parse_dowrap(char *file, DArray *tokens, size_t *index) {
|
||||
NULL};
|
||||
}
|
||||
size_t indent_depth = 0;
|
||||
bool temp_indent_depth_toggle = false;
|
||||
size_t temp_indent_depth = 0;
|
||||
bool has_body_started = false;
|
||||
bool inside_body = false;
|
||||
bool pass = false;
|
||||
|
||||
DArray dowrap_tokens;
|
||||
darray_init(&dowrap_tokens, sizeof(Token));
|
||||
DArray to_free;
|
||||
darray_init(&to_free, sizeof(char *));
|
||||
|
||||
size_t temp_index_count = 0;
|
||||
size_t dowrap_index = *index;
|
||||
size_t last_normal_token = dowrap_index-1;
|
||||
|
||||
while (!pass && ++(*index) < tokens->size) {
|
||||
token = darray_get(tokens, *index);
|
||||
while (!pass && ++dowrap_index < tokens->size) {
|
||||
token = darray_get(tokens, dowrap_index);
|
||||
switch (token->type) {
|
||||
case TOKEN_INDENT:
|
||||
temp_indent_depth_toggle = true;
|
||||
if (dowrap_tokens.size == 0) {
|
||||
indent_depth = strlen(token->value);
|
||||
temp_indent_depth = indent_depth;
|
||||
} else {
|
||||
temp_indent_depth = strlen(token->value);
|
||||
}
|
||||
break;
|
||||
case TOKEN_NEW_LINE:
|
||||
temp_indent_depth = 0;
|
||||
temp_indent_depth_toggle = true;
|
||||
darray_push(&dowrap_tokens, token);
|
||||
temp_index_count++;
|
||||
inside_body = false;
|
||||
break;
|
||||
default:
|
||||
if (temp_indent_depth < indent_depth && temp_indent_depth_toggle) {
|
||||
pass = true;
|
||||
break;
|
||||
}
|
||||
if (temp_indent_depth > indent_depth) {
|
||||
size_t indent_amount = temp_indent_depth - indent_depth;
|
||||
case TOKEN_INDENT:
|
||||
if (!inside_body && !has_body_started) {
|
||||
indent_depth = token->length;
|
||||
inside_body = true;
|
||||
} else if (indent_depth < token->length) {
|
||||
size_t indent_amount = token->length - indent_depth;
|
||||
Token indent_token;
|
||||
indent_token.line = token->line;
|
||||
indent_token.column = token->column;
|
||||
indent_token.length = indent_amount;
|
||||
indent_token.type = TOKEN_INDENT;
|
||||
indent_token.value = repeat_space(indent_amount);
|
||||
darray_push(&dowrap_tokens, &indent_token);
|
||||
darray_push(&to_free, &indent_token.value);
|
||||
inside_body = true;
|
||||
} else if (indent_depth == token->length) {
|
||||
inside_body = true;
|
||||
} else if (indent_depth > token->length) {
|
||||
inside_body = false;
|
||||
}
|
||||
temp_indent_depth_toggle = false;
|
||||
temp_indent_depth = 0;
|
||||
temp_index_count = 0;
|
||||
break;
|
||||
default:
|
||||
if (!inside_body) {
|
||||
pass = true;
|
||||
break;
|
||||
}
|
||||
last_normal_token = dowrap_index;
|
||||
has_body_started = true;
|
||||
darray_push(&dowrap_tokens, token);
|
||||
}
|
||||
}
|
||||
(*index) -= temp_index_count;
|
||||
for (size_t i = 0; i < temp_index_count; i++) {
|
||||
darray_pop(&dowrap_tokens, NULL);
|
||||
}
|
||||
*index = last_normal_token + 1;
|
||||
ArErr err = parser(file, dowrap_parsed, &dowrap_tokens, false);
|
||||
|
||||
darray_free(&dowrap_tokens, NULL);
|
||||
|
||||
@@ -16,10 +16,10 @@ ParsedValue convert_to_operation(DArray *to_operate_on, DArray *operations) {
|
||||
if (to_operate_on->size == 1) {
|
||||
return *((ParsedValue *)darray_get(to_operate_on, 0));
|
||||
}
|
||||
TokenType operation = 0;
|
||||
ArTokenType operation = 0;
|
||||
DArray positions;
|
||||
for (size_t i = 0; i < operations->size; i++) {
|
||||
TokenType *current_operation = darray_get(operations, i);
|
||||
ArTokenType *current_operation = darray_get(operations, i);
|
||||
if (operation < *current_operation) {
|
||||
if (operation != 0) {
|
||||
darray_free(&positions, NULL);
|
||||
@@ -68,7 +68,7 @@ ParsedValueReturn parse_operations(char *file, DArray *tokens, size_t *index,
|
||||
free(first_parsed_value);
|
||||
|
||||
DArray operations;
|
||||
darray_init(&operations, sizeof(TokenType));
|
||||
darray_init(&operations, sizeof(ArTokenType));
|
||||
|
||||
while (tokens->size > *index) {
|
||||
bool to_break = false;
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
#include "../../lexer/token.h" // for Token
|
||||
|
||||
typedef struct {
|
||||
TokenType operation;
|
||||
ArTokenType operation;
|
||||
DArray to_operate_on; // ParsedValue[]
|
||||
} ParsedOperation;
|
||||
|
||||
|
||||
48
src/translator/dowrap/dowrap.c
Normal file
48
src/translator/dowrap/dowrap.c
Normal file
@@ -0,0 +1,48 @@
|
||||
#include "dowrap.h"
|
||||
#include <stddef.h>
|
||||
|
||||
size_t translate_parsed_dowrap(Translated *translated, DArray *parsedDowrap) {
|
||||
set_registers(translated, 1);
|
||||
|
||||
size_t first = translated->bytecode.size;
|
||||
|
||||
if (parsedDowrap->size) {
|
||||
DArray return_jumps;
|
||||
push_instruction_byte(translated, OP_NEW_SCOPE);
|
||||
darray_init(&return_jumps, sizeof(size_t));
|
||||
DArray *old_return_jumps = translated->return_jumps;
|
||||
translated->return_jumps = &return_jumps;
|
||||
for (size_t i = 0; i < parsedDowrap->size; i++) {
|
||||
ParsedValue *parsedValue = darray_get(parsedDowrap, i);
|
||||
translate_parsed(translated, parsedValue);
|
||||
}
|
||||
push_instruction_byte(translated, OP_LOAD_NULL);
|
||||
push_instruction_byte(translated, 0);
|
||||
if (!old_return_jumps) {
|
||||
size_t return_jump_to = push_instruction_byte(translated, OP_POP_SCOPE);
|
||||
for (size_t i = 0; i < return_jumps.size; i++) {
|
||||
size_t *index = darray_get(&return_jumps, i);
|
||||
set_instruction_code(translated, *index, return_jump_to);
|
||||
}
|
||||
} else {
|
||||
push_instruction_byte(translated, OP_POP_SCOPE);
|
||||
push_instruction_byte(translated, OP_JUMP);
|
||||
size_t not_return_jump = push_instruction_code(translated, 0);
|
||||
size_t return_jump_to = push_instruction_byte(translated, OP_POP_SCOPE);
|
||||
push_instruction_byte(translated, OP_JUMP);
|
||||
size_t return_up = push_instruction_code(translated, 0);
|
||||
darray_push(old_return_jumps, &return_up);
|
||||
for (size_t i = 0; i < return_jumps.size; i++) {
|
||||
size_t *index = darray_get(&return_jumps, i);
|
||||
set_instruction_code(translated, *index, return_jump_to);
|
||||
}
|
||||
set_instruction_code(translated, not_return_jump, translated->bytecode.size);
|
||||
}
|
||||
darray_free(&return_jumps, NULL);
|
||||
translated->return_jumps = old_return_jumps;
|
||||
} else {
|
||||
push_instruction_byte(translated, OP_LOAD_NULL);
|
||||
push_instruction_byte(translated, 0);
|
||||
}
|
||||
return first;
|
||||
}
|
||||
14
src/translator/dowrap/dowrap.h
Normal file
14
src/translator/dowrap/dowrap.h
Normal file
@@ -0,0 +1,14 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2025 William Bell
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
#ifndef TRANSLATE_DO_WRAP_H
|
||||
#define TRANSLATE_DO_WRAP_H
|
||||
#include "../translator.h"
|
||||
|
||||
|
||||
size_t translate_parsed_dowrap(Translated *translated, DArray *parsedDowrap);
|
||||
|
||||
#endif // TRANSLATE_DO_WRAP_H
|
||||
@@ -8,6 +8,7 @@
|
||||
#include "../hash_data/hash_data.h"
|
||||
#include "../hashmap/hashmap.h"
|
||||
#include "declaration/declaration.h"
|
||||
#include "dowrap/dowrap.h"
|
||||
#include "function/function.h"
|
||||
#include "identifier/identifier.h"
|
||||
#include "if/if.h"
|
||||
@@ -85,7 +86,8 @@ size_t arena_push(ConstantArena *arena, const void *data, size_t length) {
|
||||
|
||||
Translated init_translator() {
|
||||
Translated translated;
|
||||
translated.registerCount = 0;
|
||||
translated.registerCount = 1;
|
||||
translated.return_jumps=NULL;
|
||||
darray_init(&translated.bytecode, sizeof(uint8_t));
|
||||
darray_init(&translated.source_locations, sizeof(SourceLocation));
|
||||
arena_init(&translated.constants);
|
||||
@@ -144,6 +146,8 @@ size_t translate_parsed(Translated *translated, ParsedValue *parsedValue) {
|
||||
(ParsedIdentifier *)parsedValue->data);
|
||||
case AST_IF:
|
||||
return translate_parsed_if(translated, (DArray *)parsedValue->data);
|
||||
case AST_DOWRAP:
|
||||
return translate_parsed_dowrap(translated, (DArray *)parsedValue->data);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@ typedef struct {
|
||||
|
||||
typedef struct {
|
||||
uint8_t registerCount;
|
||||
DArray *return_jumps;
|
||||
DArray bytecode;
|
||||
DArray source_locations;
|
||||
ConstantArena constants;
|
||||
|
||||
@@ -5,4 +5,5 @@
|
||||
let y = 1
|
||||
let term = y
|
||||
if (let x = let z = y) do
|
||||
else x
|
||||
do
|
||||
x
|
||||
Reference in New Issue
Block a user