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", "type": "cppdbg",
"request": "launch", "request": "launch",
"program": "${workspaceFolder}/bin/argon", "program": "${workspaceFolder}/bin/argon",
"args": ["test.ar"], "args": ["testing.ar"],
"stopAtEntry": true, "stopAtEntry": true,
"cwd": "${workspaceFolder}", "cwd": "${workspaceFolder}",
"environment": [], "environment": [],

View File

@@ -5,7 +5,7 @@
import random import random
import sys import sys
for i in range(100000000): for i in range(10000):
sys.stdout.write("\"") sys.stdout.write("\"")
sys.stdout.write(str(random.random())) sys.stdout.write(str(random.random()))
sys.stdout.write("\"\n") sys.stdout.write("\"\n")

View File

@@ -15,6 +15,51 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.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}; const ArErr no_err = (ArErr){false};
ArErr create_err(int64_t line, int64_t column, int length, char *path, 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) { while ((len = getline(&buffer, &size, file)) != -1) {
if (current_line == err.line) { if (current_line == err.line) {
printf("bruh\n");
break; break;
} }
current_line++; current_line++;
@@ -99,20 +143,24 @@ void output_err(ArErr err) {
char *line_starts = buffer; char *line_starts = buffer;
size_t skipped_chars = 0; 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++; line_starts++;
err.column--; err.column--;
skipped_chars++; skipped_chars++;
} }
fprintf(stderr, " %zu | ", err.line); fprintf(stderr, " %zu | ", err.line);
if (err.length) { 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); dyefg(stderr, DYE_RED);
dye_style(stderr, DYE_STYLE_BOLD); dye_style(stderr, DYE_STYLE_BOLD);
fprintf(stderr, "%.*s", err.length, line_starts + err.column - 1); fprintf(stderr, "%.*s", err.length, line_starts + err.column - 1);
dye_style(stderr, DYE_STYLE_RESET); dye_style(stderr, DYE_STYLE_RESET);
dyefg(stderr, DYE_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++) { for (int64_t i = 0; i < err.column - 1; i++) {
fprintf(stderr, " "); fprintf(stderr, " ");
} }

View File

@@ -4,10 +4,15 @@
* SPDX-License-Identifier: GPL-3.0-or-later * SPDX-License-Identifier: GPL-3.0-or-later
*/ */
#ifdef _WIN32
#include <windows.h>
#include <bcrypt.h>
#else
#include <fcntl.h> #include <fcntl.h>
#include <unistd.h>
#endif
#include <stdint.h> #include <stdint.h>
#include <stdio.h> #include <stdio.h>
#include <unistd.h>
#include "siphash/siphash.h" #include "siphash/siphash.h"
#include "hash_data.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}; 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]; uint8_t empty_siphash_key[16];
void generate_siphash_key(uint8_t hash_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); int fd = open("/dev/urandom", O_RDONLY);
if (fd < 0 || read(fd, hash_key, 16) != 16) { if (fd < 0 || read(fd, hash_key, 16) != 16) {
// Fallback or abort // Fallback or abort
} }
close(fd); close(fd);
#endif
} }
uint64_t siphash64_bytes(const void *data, size_t len,const uint8_t hash_key[16]) { 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_COLON,
TOKEN_EXCLAMATION, TOKEN_EXCLAMATION,
TOKEN_INVALID, TOKEN_INVALID,
} TokenType; } ArTokenType;
typedef struct { typedef struct {
TokenType type; ArTokenType type;
size_t line; size_t line;
size_t column; size_t column;
size_t length; size_t length;

View File

@@ -14,8 +14,6 @@
#include "../external/xxhash/xxhash.h" #include "../external/xxhash/xxhash.h"
#include "hash_data/hash_data.h" #include "hash_data/hash_data.h"
#include <arpa/inet.h>
#include <endian.h>
#include <locale.h> #include <locale.h>
#include <stdbool.h> #include <stdbool.h>
#include <stddef.h> #include <stddef.h>
@@ -26,11 +24,13 @@
#include <time.h> #include <time.h>
#include <unistd.h> #include <unistd.h>
#ifdef _WIN32 #ifdef _WIN32
#include <direct.h> #include <windows.h>
#define mkdir(path, mode) _mkdir(path) #include <direct.h> // for _mkdir
#include <sys/stat.h> // for _stat
#else #else
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/types.h> #include <sys/types.h>
#include <unistd.h>
#endif #endif
#include "../external/cwalk/include/cwalk.h" #include "../external/cwalk/include/cwalk.h"
#include <string.h> #include <string.h>
@@ -43,6 +43,28 @@
#endif #endif
#include "err.h" #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 *get_current_directory() {
char *buffer = NULL; char *buffer = NULL;
@@ -72,15 +94,31 @@ char *get_current_directory() {
} }
int ensure_dir_exists(const char *path) { int ensure_dir_exists(const char *path) {
struct stat st = {0}; #ifdef _WIN32
struct _stat st;
if (stat(path, &st) == -1) { 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;
}
#else
struct stat st;
if (stat(path, &st) != 0) {
// Directory does not exist, create it // Directory does not exist, create it
if (mkdir(path, 0755) != 0) { if (mkdir(path, 0755) != 0) {
perror("mkdir failed"); perror("mkdir failed");
return -1; return -1;
} }
} else if (!S_ISDIR(st.st_mode)) {
fprintf(stderr, "Path exists but is not a directory\n");
return -1;
} }
#endif
return 0; return 0;
} }

View File

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

View File

@@ -49,59 +49,57 @@ ParsedValueReturn parse_dowrap(char *file, DArray *tokens, size_t *index) {
NULL}; NULL};
} }
size_t indent_depth = 0; size_t indent_depth = 0;
bool temp_indent_depth_toggle = false; bool has_body_started = false;
size_t temp_indent_depth = 0; bool inside_body = false;
bool pass = false; bool pass = false;
DArray dowrap_tokens; DArray dowrap_tokens;
darray_init(&dowrap_tokens, sizeof(Token)); darray_init(&dowrap_tokens, sizeof(Token));
DArray to_free; DArray to_free;
darray_init(&to_free, sizeof(char *)); 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) { while (!pass && ++dowrap_index < tokens->size) {
token = darray_get(tokens, *index); token = darray_get(tokens, dowrap_index);
switch (token->type) { 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: case TOKEN_NEW_LINE:
temp_indent_depth = 0;
temp_indent_depth_toggle = true;
darray_push(&dowrap_tokens, token); darray_push(&dowrap_tokens, token);
temp_index_count++; inside_body = false;
break; break;
default: case TOKEN_INDENT:
if (temp_indent_depth < indent_depth && temp_indent_depth_toggle) { if (!inside_body && !has_body_started) {
pass = true; indent_depth = token->length;
break; inside_body = true;
} } else if (indent_depth < token->length) {
if (temp_indent_depth > indent_depth) { size_t indent_amount = token->length - indent_depth;
size_t indent_amount = temp_indent_depth - indent_depth;
Token indent_token; Token indent_token;
indent_token.line = token->line; indent_token.line = token->line;
indent_token.column = token->column; indent_token.column = token->column;
indent_token.length = indent_amount;
indent_token.type = TOKEN_INDENT; indent_token.type = TOKEN_INDENT;
indent_token.value = repeat_space(indent_amount); indent_token.value = repeat_space(indent_amount);
darray_push(&dowrap_tokens, &indent_token); darray_push(&dowrap_tokens, &indent_token);
darray_push(&to_free, &indent_token.value); 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; break;
temp_indent_depth = 0; default:
temp_index_count = 0; if (!inside_body) {
pass = true;
break;
}
last_normal_token = dowrap_index;
has_body_started = true;
darray_push(&dowrap_tokens, token); darray_push(&dowrap_tokens, token);
} }
} }
(*index) -= temp_index_count; *index = last_normal_token + 1;
for (size_t i = 0; i < temp_index_count; i++) {
darray_pop(&dowrap_tokens, NULL);
}
ArErr err = parser(file, dowrap_parsed, &dowrap_tokens, false); ArErr err = parser(file, dowrap_parsed, &dowrap_tokens, false);
darray_free(&dowrap_tokens, NULL); 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) { if (to_operate_on->size == 1) {
return *((ParsedValue *)darray_get(to_operate_on, 0)); return *((ParsedValue *)darray_get(to_operate_on, 0));
} }
TokenType operation = 0; ArTokenType operation = 0;
DArray positions; DArray positions;
for (size_t i = 0; i < operations->size; i++) { 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 < *current_operation) {
if (operation != 0) { if (operation != 0) {
darray_free(&positions, NULL); darray_free(&positions, NULL);
@@ -68,7 +68,7 @@ ParsedValueReturn parse_operations(char *file, DArray *tokens, size_t *index,
free(first_parsed_value); free(first_parsed_value);
DArray operations; DArray operations;
darray_init(&operations, sizeof(TokenType)); darray_init(&operations, sizeof(ArTokenType));
while (tokens->size > *index) { while (tokens->size > *index) {
bool to_break = false; bool to_break = false;

View File

@@ -10,7 +10,7 @@
#include "../../lexer/token.h" // for Token #include "../../lexer/token.h" // for Token
typedef struct { typedef struct {
TokenType operation; ArTokenType operation;
DArray to_operate_on; // ParsedValue[] DArray to_operate_on; // ParsedValue[]
} ParsedOperation; } 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 "../hash_data/hash_data.h"
#include "../hashmap/hashmap.h" #include "../hashmap/hashmap.h"
#include "declaration/declaration.h" #include "declaration/declaration.h"
#include "dowrap/dowrap.h"
#include "function/function.h" #include "function/function.h"
#include "identifier/identifier.h" #include "identifier/identifier.h"
#include "if/if.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 init_translator() {
Translated translated; Translated translated;
translated.registerCount = 0; translated.registerCount = 1;
translated.return_jumps=NULL;
darray_init(&translated.bytecode, sizeof(uint8_t)); darray_init(&translated.bytecode, sizeof(uint8_t));
darray_init(&translated.source_locations, sizeof(SourceLocation)); darray_init(&translated.source_locations, sizeof(SourceLocation));
arena_init(&translated.constants); arena_init(&translated.constants);
@@ -144,6 +146,8 @@ size_t translate_parsed(Translated *translated, ParsedValue *parsedValue) {
(ParsedIdentifier *)parsedValue->data); (ParsedIdentifier *)parsedValue->data);
case AST_IF: case AST_IF:
return translate_parsed_if(translated, (DArray *)parsedValue->data); return translate_parsed_if(translated, (DArray *)parsedValue->data);
case AST_DOWRAP:
return translate_parsed_dowrap(translated, (DArray *)parsedValue->data);
} }
return 0; return 0;
} }

View File

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

View File

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