translate and execute do wraps

This commit is contained in:
2025-07-14 04:51:00 +01:00
parent 217e4047d3
commit 1bdc792705
15 changed files with 226 additions and 62 deletions

2
.vscode/launch.json vendored
View File

@@ -9,7 +9,7 @@
"type": "cppdbg",
"request": "launch",
"program": "${workspaceFolder}/bin/argon",
"args": ["test.ar"],
"args": ["testing.ar"],
"stopAtEntry": true,
"cwd": "${workspaceFolder}",
"environment": [],

View File

@@ -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")

View File

@@ -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, " ");
}

View File

@@ -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]) {

View File

@@ -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;

View File

@@ -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__";

View File

@@ -11,7 +11,7 @@
typedef struct {
ParsedValue * to;
TokenType type;
ArTokenType type;
ParsedValue * from;
} ParsedAssign;

View File

@@ -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);

View File

@@ -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;

View File

@@ -10,7 +10,7 @@
#include "../../lexer/token.h" // for Token
typedef struct {
TokenType operation;
ArTokenType operation;
DArray to_operate_on; // ParsedValue[]
} ParsedOperation;

View 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;
}

View 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

View File

@@ -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;
}

View File

@@ -26,6 +26,7 @@ typedef struct {
typedef struct {
uint8_t registerCount;
DArray *return_jumps;
DArray bytecode;
DArray source_locations;
ConstantArena constants;

View File

@@ -5,4 +5,5 @@
let y = 1
let term = y
if (let x = let z = y) do
else x
do
x