limit arguments to not support duplicate names

This commit is contained in:
2025-07-08 04:31:01 +01:00
parent 72cc87f5b6
commit fba074a5a4
7 changed files with 85 additions and 17 deletions

2
.gitignore vendored
View File

@@ -60,6 +60,4 @@ build
*.yy.c
*.yy.h
out.arbin
rand_test.ar
__arcache__

View File

@@ -1,7 +1,7 @@
import random
myfile = open("rand_test.ar","w")
import sys
for i in range(10000000):
myfile.write("\"")
myfile.write(str(random.random())[2::])
myfile.write("\"\n")
for i in range(100000000):
sys.stdout.write("\"")
sys.stdout.write(str(random.random()))
sys.stdout.write("\"\n")

View File

@@ -1,4 +1,6 @@
#include "declaration.h"
#include "../../hashmap/hashmap.h"
#include "../../hash_data/hash_data.h"
#include "../../lexer/token.h"
#include "../../memory.h"
#include "../function/function.h"
@@ -23,7 +25,7 @@ ParsedValue *parse_declaration(char *file, DArray *tokens, size_t *index) {
darray_push(declarations, &_declaration);
ParsedSingleDeclaration *declaration =
darray_get(declarations, declarations->size - 1);
bool isFunction=false;
bool isFunction = false;
DArray parameters;
declaration->from = parse_null();
@@ -41,6 +43,7 @@ ParsedValue *parse_declaration(char *file, DArray *tokens, size_t *index) {
token = darray_get(tokens, *index);
if (token->type == TOKEN_LPAREN) {
isFunction = true;
struct hashmap *parameters_hashmap = createHashmap();
darray_init(&parameters, sizeof(char *));
(*index)++;
error_if_finished(file, tokens, index);
@@ -63,8 +66,16 @@ ParsedValue *parse_declaration(char *file, DArray *tokens, size_t *index) {
file, token->line, token->column);
exit(EXIT_FAILURE);
}
char *parameter_name = checked_malloc(strlen(token->value) + 1);
uint64_t hash = siphash64_bytes(token->value, token->length, siphash_key);
if (hashmap_lookup(parameters_hashmap, hash) != NULL) {
fprintf(stderr,
"%s:%zu:%zu error: duplicate argument '%.*s' in function definition\n",
file, token->line, token->column, (int)token->length, token->value);
exit(EXIT_FAILURE);
}
char *parameter_name = checked_malloc(token->length + 1);
strcpy(parameter_name, token->value);
hashmap_insert(parameters_hashmap, hash, parameter_name, (void*)1, 0);
darray_push(&parameters, &parameter_name);
(*index)++;
error_if_finished(file, tokens, index);

View File

@@ -41,7 +41,7 @@ void resize_hashmap_GC(struct hashmap_GC *t) {
}
}
int hashCode_GC(struct hashmap_GC *t, uint64_t hash) { return hash % t->size; }
int hashCode_GC(struct hashmap_GC *t, uint64_t hash) { return hash & (t->size - 1); }
int hashmap_remove_GC(struct hashmap_GC *t, uint64_t hash) {
int pos = hashCode_GC(t, hash);

View File

@@ -33,7 +33,6 @@ void init_types() {
init_base_field();
}
uint8_t pop_byte(Translated *translated, RuntimeState *state) {
return *((uint8_t *)darray_get(&translated->bytecode, state->head++));
}
@@ -63,8 +62,20 @@ void load_const(Translated *translated, RuntimeState *state) {
state->registers[to_register] = object;
}
void run_instruction(Translated *translated, RuntimeState *state,
struct Stack stack) {
const ArErr no_err = (ArErr){false};
ArErr create_err(char *path, int64_t line, char *type, char *message) {
return (ArErr){
false,
path,
line,
type,
message
};
}
ArErr run_instruction(Translated *translated, RuntimeState *state,
struct Stack stack) {
OperationType opcode = pop_byte(translated, state);
switch (opcode) {
case OP_LOAD_NULL:
@@ -76,7 +87,11 @@ void run_instruction(Translated *translated, RuntimeState *state,
case OP_LOAD_FUNCTION:
load_argon_function(translated, state, stack);
break;
default:
fprintf(stderr, "bytecode invalid\n");
exit(EXIT_FAILURE);
}
return no_err;
}
RuntimeState init_runtime_state(Translated translated) {
@@ -86,7 +101,7 @@ RuntimeState init_runtime_state(Translated translated) {
}
ArgonObject *runtime(Translated translated, RuntimeState state) {
struct Stack stack = {NULL,NULL};
struct Stack stack = {NULL, NULL};
state.head = 0;
while (state.head < translated.bytecode.size) {
run_instruction(&translated, &state, stack);

View File

@@ -8,16 +8,25 @@ typedef struct {
size_t head;
} RuntimeState;
typedef struct {
bool exists;
char *path;
int64_t line;
char *type;
char *message;
} ArErr;
typedef struct Stack {
ArgonObject *scope;
struct Stack *prev;
ArgonObject *scope;
struct Stack *prev;
} Stack;
void init_types();
uint64_t pop_bytecode(Translated *translated, RuntimeState *state);
void run_instruction(Translated *translated, RuntimeState *state, struct Stack stack);
ArErr run_instruction(Translated *translated, RuntimeState *state,
struct Stack stack);
RuntimeState init_runtime_state(Translated translated);

35
test.py Normal file
View File

@@ -0,0 +1,35 @@
import string
from itertools import product
import sys
def generate_names(max_width, skip_keywords=None):
if skip_keywords is None:
skip_keywords = {"if", "else", "while", "forever", "for", "break", "continue",
"return", "let", "import", "from", "do", "true", "false", "null",
"delete", "not", "try", "catch", "in"}
else:
skip_keywords = set(skip_keywords)
chars = string.ascii_lowercase
first = True
write = sys.stdout.write
for length in range(1, max_width + 1):
print(length, file=sys.stderr)
i = 0
for p in product(chars, repeat=length):
name = ''.join(p)
if name in skip_keywords:
continue
if not first:
write('\n')
write(name)
first = False
if i>10000000:
break
i+=1
# Example usage:
max_width = 15
# sys.stdout.write("let ")
generate_names(max_width)