Compare commits
4 Commits
prerelease
...
prerelease
| Author | SHA1 | Date | |
|---|---|---|---|
| 72cc87f5b6 | |||
| 5c0ced5e45 | |||
| 886599c9c5 | |||
| cbebe4812b |
2
.github/workflows/release.yml
vendored
2
.github/workflows/release.yml
vendored
@@ -12,6 +12,8 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v3
|
||||||
|
with:
|
||||||
|
submodules: recursive
|
||||||
|
|
||||||
- name: Setup Python (needed for Conan)
|
- name: Setup Python (needed for Conan)
|
||||||
uses: actions/setup-python@v4
|
uses: actions/setup-python@v4
|
||||||
|
|||||||
3
.gitmodules
vendored
3
.gitmodules
vendored
@@ -1,3 +1,6 @@
|
|||||||
[submodule "external/xxhash"]
|
[submodule "external/xxhash"]
|
||||||
path = external/xxhash
|
path = external/xxhash
|
||||||
url = https://github.com/Cyan4973/xxHash.git
|
url = https://github.com/Cyan4973/xxHash.git
|
||||||
|
[submodule "external/cwalk"]
|
||||||
|
path = external/cwalk
|
||||||
|
url = https://github.com/likle/cwalk.git
|
||||||
|
|||||||
@@ -30,7 +30,9 @@ add_custom_command(
|
|||||||
add_custom_target(GenerateLexer DEPENDS ${LEXER_C} ${LEXER_H})
|
add_custom_target(GenerateLexer DEPENDS ${LEXER_C} ${LEXER_H})
|
||||||
|
|
||||||
# Step 3: Add executable
|
# Step 3: Add executable
|
||||||
add_executable(argon ${CFILES} ${LEXER_C})
|
add_executable(argon external/xxhash/xxhash.c external/cwalk/src/cwalk.c ${CFILES} ${LEXER_C})
|
||||||
|
set(CMAKE_INTERPROCEDURAL_OPTIMIZATION TRUE)
|
||||||
|
target_include_directories(argon PRIVATE ${CMAKE_SOURCE_DIR}/external/cwalk/include)
|
||||||
|
|
||||||
# Step 4: Build order
|
# Step 4: Build order
|
||||||
add_dependencies(argon GenerateLexer)
|
add_dependencies(argon GenerateLexer)
|
||||||
@@ -56,3 +58,5 @@ target_link_libraries(argon PRIVATE
|
|||||||
target_include_directories(argon PRIVATE
|
target_include_directories(argon PRIVATE
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/src/lexer
|
${CMAKE_CURRENT_SOURCE_DIR}/src/lexer
|
||||||
)
|
)
|
||||||
|
|
||||||
|
add_custom_command(TARGET argon POST_BUILD COMMAND ${CMAKE_STRIP} $<TARGET_FILE:argon>)
|
||||||
8
Makefile
8
Makefile
@@ -2,8 +2,8 @@ LEXER_SRC = src/lexer/lex.l
|
|||||||
LEXER_C = src/lexer/lex.yy.c
|
LEXER_C = src/lexer/lex.yy.c
|
||||||
LEXER_H = src/lexer/lex.yy.h
|
LEXER_H = src/lexer/lex.yy.h
|
||||||
|
|
||||||
CFILES = external/xxhash/xxhash.c $(shell find src -name '*.c')
|
CFILES = external/xxhash/xxhash.c external/cwalk/src/cwalk.c $(shell find src -name '*.c')
|
||||||
CFLAGS = $(ARCHFLAGS) -lm -lgc -lgmp -Wall -Wextra -Wno-unused-function
|
CFLAGS = $(ARCHFLAGS) -lm -lgc -lgmp -Wall -Wextra -Wno-unused-function -Iexternal/cwalk/include
|
||||||
BINARY = bin/argon
|
BINARY = bin/argon
|
||||||
|
|
||||||
all: $(BINARY)
|
all: $(BINARY)
|
||||||
@@ -15,6 +15,10 @@ $(BINARY): $(CFILES) $(LEXER_C) $(LEXER_H)
|
|||||||
mkdir -p bin
|
mkdir -p bin
|
||||||
gcc -O3 -o $(BINARY) $(CFILES) $(CFLAGS) -s
|
gcc -O3 -o $(BINARY) $(CFILES) $(CFLAGS) -s
|
||||||
|
|
||||||
|
native: $(CFILES) $(LEXER_C) $(LEXER_H)
|
||||||
|
mkdir -p bin
|
||||||
|
gcc -O3 -march=native -o $(BINARY) $(CFILES) $(CFLAGS)
|
||||||
|
|
||||||
debug: $(CFILES) $(LEXER_C) $(LEXER_H)
|
debug: $(CFILES) $(LEXER_C) $(LEXER_H)
|
||||||
mkdir -p bin
|
mkdir -p bin
|
||||||
gcc -g -O0 -o $(BINARY) $(CFILES) $(CFLAGS)
|
gcc -g -O0 -o $(BINARY) $(CFILES) $(CFLAGS)
|
||||||
|
|||||||
1
external/cwalk
vendored
Submodule
1
external/cwalk
vendored
Submodule
Submodule external/cwalk added at e98d23f688
@@ -6,8 +6,6 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
|
|
||||||
struct hashmap *createHashmap() {
|
struct hashmap *createHashmap() {
|
||||||
size_t size = 8;
|
size_t size = 8;
|
||||||
@@ -20,7 +18,8 @@ struct hashmap *createHashmap() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void hashmap_free(struct hashmap *t, free_val_func free_val) {
|
void hashmap_free(struct hashmap *t, free_val_func free_val) {
|
||||||
if (!t) return;
|
if (!t)
|
||||||
|
return;
|
||||||
|
|
||||||
for (size_t i = 0; i < t->size; i++) {
|
for (size_t i = 0; i < t->size; i++) {
|
||||||
struct node *current = t->list[i];
|
struct node *current = t->list[i];
|
||||||
@@ -56,13 +55,15 @@ void resize_hashmap(struct hashmap *t) {
|
|||||||
while (temp) {
|
while (temp) {
|
||||||
hashmap_insert(t, temp->hash, temp->key, temp->val,
|
hashmap_insert(t, temp->hash, temp->key, temp->val,
|
||||||
temp->order); // Will increment count
|
temp->order); // Will increment count
|
||||||
|
struct node *temp_temp = temp;
|
||||||
temp = temp->next;
|
temp = temp->next;
|
||||||
|
free(temp_temp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
free(old_list);
|
free(old_list);
|
||||||
}
|
}
|
||||||
|
|
||||||
int hashCode(struct hashmap *t, uint64_t hash) { return hash % t->size; }
|
int hashCode(struct hashmap *t, uint64_t hash) { return hash & (t->size - 1); }
|
||||||
|
|
||||||
int hashmap_remove(struct hashmap *t, uint64_t hash) {
|
int hashmap_remove(struct hashmap *t, uint64_t hash) {
|
||||||
int pos = hashCode(t, hash);
|
int pos = hashCode(t, hash);
|
||||||
@@ -86,8 +87,8 @@ int hashmap_remove(struct hashmap *t, uint64_t hash) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void hashmap_insert(struct hashmap *t, uint64_t hash, void *key,
|
void hashmap_insert(struct hashmap *t, uint64_t hash, void *key, void *val,
|
||||||
void *val, size_t order) {
|
size_t order) {
|
||||||
if (!order) {
|
if (!order) {
|
||||||
order = t->order++;
|
order = t->order++;
|
||||||
}
|
}
|
||||||
|
|||||||
227
src/main.c
227
src/main.c
@@ -26,8 +26,44 @@
|
|||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#endif
|
#endif
|
||||||
|
#include "../external/cwalk/include/cwalk.h"
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
#include <windows.h>
|
||||||
|
#else
|
||||||
|
#include <limits.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
char *get_current_directory() {
|
||||||
|
char *buffer = NULL;
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
DWORD size = GetCurrentDirectoryA(0, NULL);
|
||||||
|
buffer = malloc(size);
|
||||||
|
if (buffer == NULL)
|
||||||
|
return NULL;
|
||||||
|
if (GetCurrentDirectoryA(size, buffer) == 0) {
|
||||||
|
free(buffer);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
long size = pathconf(".", _PC_PATH_MAX);
|
||||||
|
if (size == -1)
|
||||||
|
size = 4096; // fallback
|
||||||
|
buffer = malloc(size);
|
||||||
|
if (buffer == NULL)
|
||||||
|
return NULL;
|
||||||
|
if (getcwd(buffer, size) == NULL) {
|
||||||
|
free(buffer);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
int ensure_dir_exists(const char *path) {
|
int ensure_dir_exists(const char *path) {
|
||||||
struct stat st = {0};
|
struct stat st = {0};
|
||||||
|
|
||||||
@@ -41,126 +77,22 @@ int ensure_dir_exists(const char *path) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *normalize_path(char *path) {
|
|
||||||
#ifdef _WIN32
|
|
||||||
for (char *p = path; *p; p++) {
|
|
||||||
if (*p == '/') {
|
|
||||||
*p = '\\';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
return path;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Join two paths using '/' as separator, no platform checks here.
|
|
||||||
int path_join(char *dest, size_t dest_size, const char *path1,
|
|
||||||
const char *path2) {
|
|
||||||
size_t len1 = strlen(path1);
|
|
||||||
size_t len2 = strlen(path2);
|
|
||||||
|
|
||||||
// Check if buffer is large enough (extra 2 for '/' and '\0')
|
|
||||||
if (len1 + len2 + 2 > dest_size)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
strcpy(dest, path1);
|
|
||||||
|
|
||||||
// Add '/' if needed
|
|
||||||
if (len1 > 0 && dest[len1 - 1] != '/') {
|
|
||||||
dest[len1] = '/';
|
|
||||||
dest[len1 + 1] = '\0';
|
|
||||||
len1++;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Skip leading '/' in path2 to avoid double separator
|
|
||||||
if (len2 > 0 && path2[0] == '/') {
|
|
||||||
path2++;
|
|
||||||
len2--;
|
|
||||||
}
|
|
||||||
|
|
||||||
strcat(dest, path2);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char CACHE_FOLDER[] = "__arcache__";
|
const char CACHE_FOLDER[] = "__arcache__";
|
||||||
const char FILE_IDENTIFIER[5] = "ARBI";
|
const char FILE_IDENTIFIER[5] = "ARBI";
|
||||||
const char BYTECODE_EXTENTION[] = "arbin";
|
const char BYTECODE_EXTENTION[] = "arbin";
|
||||||
const uint32_t version_number = 0;
|
const uint32_t version_number = 0;
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
#define PATH_SEP '\\'
|
|
||||||
#else
|
|
||||||
#define PATH_SEP '/'
|
|
||||||
#endif
|
|
||||||
|
|
||||||
char *replace_extension(const char *path, const char *new_ext) {
|
|
||||||
// Defensive: if new_ext doesn't start with '.', add it
|
|
||||||
int need_dot = (new_ext[0] != '.');
|
|
||||||
|
|
||||||
// Find last path separator to avoid changing dots in folder names
|
|
||||||
const char *last_sep = strrchr(path, PATH_SEP);
|
|
||||||
#ifdef _WIN32
|
|
||||||
// Windows can have '/' too as separator in practice, check it
|
|
||||||
const char *last_alt_sep = strrchr(path, '/');
|
|
||||||
if (last_alt_sep && (!last_sep || last_alt_sep > last_sep)) {
|
|
||||||
last_sep = last_alt_sep;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Find last '.' after last_sep (if any)
|
|
||||||
const char *last_dot = strrchr(path, '.');
|
|
||||||
if (last_dot && (!last_sep || last_dot > last_sep)) {
|
|
||||||
// Extension found: copy path up to last_dot, then append new_ext
|
|
||||||
size_t base_len = last_dot - path;
|
|
||||||
size_t ext_len = strlen(new_ext) + (need_dot ? 1 : 0);
|
|
||||||
size_t new_len = base_len + ext_len + 1;
|
|
||||||
|
|
||||||
char *result = malloc(new_len);
|
|
||||||
if (!result)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
memcpy(result, path, base_len);
|
|
||||||
|
|
||||||
if (need_dot)
|
|
||||||
result[base_len] = '.';
|
|
||||||
|
|
||||||
strcpy(result + base_len + (need_dot ? 1 : 0), new_ext);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
} else {
|
|
||||||
// No extension found: append '.' + new_ext (if needed)
|
|
||||||
size_t path_len = strlen(path);
|
|
||||||
size_t ext_len = strlen(new_ext) + (need_dot ? 1 : 0);
|
|
||||||
size_t new_len = path_len + ext_len + 1;
|
|
||||||
|
|
||||||
char *result = malloc(new_len);
|
|
||||||
if (!result)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
strcpy(result, path);
|
|
||||||
|
|
||||||
if (need_dot)
|
|
||||||
strcat(result, ".");
|
|
||||||
|
|
||||||
strcat(result, new_ext);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int load_cache(Translated *translated_dest, char *joined_paths, uint64_t hash) {
|
int load_cache(Translated *translated_dest, char *joined_paths, uint64_t hash) {
|
||||||
FILE *bytecode_file = fopen(joined_paths, "rb");
|
FILE *bytecode_file = fopen(joined_paths, "rb");
|
||||||
if (!bytecode_file)
|
if (!bytecode_file)
|
||||||
return 1;
|
return 1;
|
||||||
char file_identifier_from_cache[sizeof(FILE_IDENTIFIER)];
|
char file_identifier_from_cache[sizeof(FILE_IDENTIFIER)] = {0};
|
||||||
file_identifier_from_cache[strlen(FILE_IDENTIFIER)] = '\0';
|
|
||||||
if (fread(&file_identifier_from_cache, 1,
|
if (fread(&file_identifier_from_cache, 1,
|
||||||
sizeof(file_identifier_from_cache) - 1,
|
sizeof(file_identifier_from_cache) - 1,
|
||||||
bytecode_file) != sizeof(file_identifier_from_cache) - 1 ||
|
bytecode_file) != sizeof(file_identifier_from_cache) - 1 ||
|
||||||
memcmp(file_identifier_from_cache, FILE_IDENTIFIER,
|
memcmp(file_identifier_from_cache, FILE_IDENTIFIER,
|
||||||
sizeof(file_identifier_from_cache)) != 0) {
|
sizeof(file_identifier_from_cache)) != 0) {
|
||||||
fclose(bytecode_file);
|
goto FAILED;
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t read_version;
|
uint32_t read_version;
|
||||||
@@ -228,19 +160,36 @@ FAILED:
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
ArgonObject *execute(char*absolute_path) {
|
||||||
generate_siphash_key(siphash_key);
|
|
||||||
clock_t start, end;
|
clock_t start, end;
|
||||||
double time_spent, total_time_spent = 0;
|
double time_spent, total_time_spent = 0;
|
||||||
setlocale(LC_ALL, "");
|
|
||||||
if (argc <= 1)
|
|
||||||
return -1;
|
|
||||||
ar_memory_init();
|
|
||||||
char *path = argv[1];
|
|
||||||
|
|
||||||
FILE *file = fopen(path, "r");
|
const char *basename_ptr;
|
||||||
|
size_t basename_length;
|
||||||
|
cwk_path_get_basename(absolute_path, &basename_ptr, &basename_length);
|
||||||
|
|
||||||
|
if (!basename_ptr) return NULL;
|
||||||
|
|
||||||
|
char basename[FILENAME_MAX];
|
||||||
|
memcpy(basename, basename_ptr, basename_length);
|
||||||
|
|
||||||
|
size_t parent_directory_length;
|
||||||
|
cwk_path_get_dirname(absolute_path, &parent_directory_length);
|
||||||
|
|
||||||
|
char parent_directory[FILENAME_MAX];
|
||||||
|
memcpy(parent_directory, absolute_path, parent_directory_length);
|
||||||
|
parent_directory[parent_directory_length] = '\0';
|
||||||
|
|
||||||
|
char cache_folder_path[FILENAME_MAX];
|
||||||
|
cwk_path_join(parent_directory, CACHE_FOLDER, cache_folder_path, sizeof(cache_folder_path));
|
||||||
|
|
||||||
|
char cache_file_path[FILENAME_MAX];
|
||||||
|
cwk_path_join(cache_folder_path, basename, cache_file_path, sizeof(cache_file_path));
|
||||||
|
cwk_path_change_extension(cache_file_path, BYTECODE_EXTENTION, cache_file_path, sizeof(cache_file_path));
|
||||||
|
|
||||||
|
FILE *file = fopen(absolute_path, "r");
|
||||||
if (!file) {
|
if (!file) {
|
||||||
return -1;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
XXH3_state_t *hash_state = XXH3_createState();
|
XXH3_state_t *hash_state = XXH3_createState();
|
||||||
@@ -255,28 +204,16 @@ int main(int argc, char *argv[]) {
|
|||||||
uint64_t hash = XXH3_64bits_digest(hash_state);
|
uint64_t hash = XXH3_64bits_digest(hash_state);
|
||||||
XXH3_freeState(hash_state);
|
XXH3_freeState(hash_state);
|
||||||
|
|
||||||
char *filename_without_extention =
|
|
||||||
replace_extension(path, BYTECODE_EXTENTION);
|
|
||||||
|
|
||||||
size_t joined_paths_length =
|
|
||||||
strlen(CACHE_FOLDER) + strlen(filename_without_extention) + 2;
|
|
||||||
char *joined_paths = checked_malloc(joined_paths_length);
|
|
||||||
|
|
||||||
path_join(joined_paths, joined_paths_length, CACHE_FOLDER,
|
|
||||||
filename_without_extention);
|
|
||||||
free(filename_without_extention);
|
|
||||||
filename_without_extention = NULL;
|
|
||||||
|
|
||||||
Translated translated = init_translator();
|
Translated translated = init_translator();
|
||||||
|
|
||||||
if (load_cache(&translated, joined_paths, hash) != 0) {
|
if (load_cache(&translated, cache_file_path, hash) != 0) {
|
||||||
free_translator(&translated);
|
free_translator(&translated);
|
||||||
translated = init_translator();
|
translated = init_translator();
|
||||||
|
|
||||||
DArray tokens;
|
DArray tokens;
|
||||||
darray_init(&tokens, sizeof(Token));
|
darray_init(&tokens, sizeof(Token));
|
||||||
|
|
||||||
LexerState state = {path, file, 0, 0, &tokens};
|
LexerState state = {absolute_path, file, 0, 0, &tokens};
|
||||||
start = clock();
|
start = clock();
|
||||||
lexer(state);
|
lexer(state);
|
||||||
end = clock();
|
end = clock();
|
||||||
@@ -290,7 +227,7 @@ int main(int argc, char *argv[]) {
|
|||||||
darray_init(&ast, sizeof(ParsedValue));
|
darray_init(&ast, sizeof(ParsedValue));
|
||||||
|
|
||||||
start = clock();
|
start = clock();
|
||||||
parser(path, &ast, &tokens, false);
|
parser(absolute_path, &ast, &tokens, false);
|
||||||
end = clock();
|
end = clock();
|
||||||
time_spent = (double)(end - start) / CLOCKS_PER_SEC;
|
time_spent = (double)(end - start) / CLOCKS_PER_SEC;
|
||||||
total_time_spent += time_spent;
|
total_time_spent += time_spent;
|
||||||
@@ -305,9 +242,9 @@ int main(int argc, char *argv[]) {
|
|||||||
printf("Translation time taken: %f seconds\n", time_spent);
|
printf("Translation time taken: %f seconds\n", time_spent);
|
||||||
|
|
||||||
darray_free(&ast, free_parsed);
|
darray_free(&ast, free_parsed);
|
||||||
ensure_dir_exists(CACHE_FOLDER);
|
ensure_dir_exists(cache_folder_path);
|
||||||
|
|
||||||
file = fopen(joined_paths, "wb");
|
file = fopen(cache_file_path, "wb");
|
||||||
|
|
||||||
uint64_t constantsSize = (uint64_t)translated.constants.size;
|
uint64_t constantsSize = (uint64_t)translated.constants.size;
|
||||||
uint64_t bytecodeSize = (uint64_t)translated.bytecode.size;
|
uint64_t bytecodeSize = (uint64_t)translated.bytecode.size;
|
||||||
@@ -330,10 +267,9 @@ int main(int argc, char *argv[]) {
|
|||||||
fclose(file);
|
fclose(file);
|
||||||
}
|
}
|
||||||
|
|
||||||
init_types();
|
|
||||||
|
|
||||||
start = clock();
|
start = clock();
|
||||||
runtime(translated);
|
RuntimeState state = init_runtime_state(translated);
|
||||||
|
ArgonObject *resp = runtime(translated,state);
|
||||||
|
|
||||||
end = clock();
|
end = clock();
|
||||||
time_spent = (double)(end - start) / CLOCKS_PER_SEC;
|
time_spent = (double)(end - start) / CLOCKS_PER_SEC;
|
||||||
@@ -342,6 +278,23 @@ int main(int argc, char *argv[]) {
|
|||||||
printf("total time taken: %f seconds\n", total_time_spent);
|
printf("total time taken: %f seconds\n", total_time_spent);
|
||||||
|
|
||||||
free_translator(&translated);
|
free_translator(&translated);
|
||||||
free(joined_paths);
|
return resp;
|
||||||
return 0;
|
}
|
||||||
|
|
||||||
|
int main(int argc, char *argv[]) {
|
||||||
|
setlocale(LC_ALL, "");
|
||||||
|
ar_memory_init();
|
||||||
|
generate_siphash_key(siphash_key);
|
||||||
|
init_types();
|
||||||
|
char *CWD = get_current_directory();
|
||||||
|
if (argc <= 1)
|
||||||
|
return -1;
|
||||||
|
char *path_non_absolute = argv[1];
|
||||||
|
char path[FILENAME_MAX];
|
||||||
|
cwk_path_get_absolute(CWD, path_non_absolute, path,
|
||||||
|
sizeof(path));
|
||||||
|
free(CWD);
|
||||||
|
ArgonObject *resp = execute(path);
|
||||||
|
if (resp) return 0;
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -22,7 +22,9 @@ ParsedValue *parse_access(char *file, DArray *tokens, size_t *index,
|
|||||||
ParsedValue *parsedString = parse_string(token, false);
|
ParsedValue *parsedString = parse_string(token, false);
|
||||||
darray_push(&parsedAccess->access, parsedString);
|
darray_push(&parsedAccess->access, parsedString);
|
||||||
free(parsedString);
|
free(parsedString);
|
||||||
|
parsedAccess->access_fields = true;
|
||||||
} else {
|
} else {
|
||||||
|
parsedAccess->access_fields = false;
|
||||||
while (true) {
|
while (true) {
|
||||||
skip_newlines_and_indents(tokens, index);
|
skip_newlines_and_indents(tokens, index);
|
||||||
error_if_finished(file, tokens, index);
|
error_if_finished(file, tokens, index);
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
ParsedValue to_access;
|
ParsedValue to_access;
|
||||||
|
bool access_fields;
|
||||||
DArray access;
|
DArray access;
|
||||||
} ParsedAccess;
|
} ParsedAccess;
|
||||||
|
|
||||||
|
|||||||
@@ -79,13 +79,18 @@ void run_instruction(Translated *translated, RuntimeState *state,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void runtime(Translated translated) {
|
RuntimeState init_runtime_state(Translated translated) {
|
||||||
RuntimeState state = {
|
RuntimeState state = {
|
||||||
checked_malloc(translated.registerCount * sizeof(ArgonObject *)), 0};
|
checked_malloc(translated.registerCount * sizeof(ArgonObject *)), 0};
|
||||||
struct Stack stack = {};
|
return state;
|
||||||
|
}
|
||||||
|
|
||||||
|
ArgonObject *runtime(Translated translated, RuntimeState state) {
|
||||||
|
struct Stack stack = {NULL,NULL};
|
||||||
state.head = 0;
|
state.head = 0;
|
||||||
while (state.head < translated.bytecode.size) {
|
while (state.head < translated.bytecode.size) {
|
||||||
run_instruction(&translated, &state, stack);
|
run_instruction(&translated, &state, stack);
|
||||||
}
|
}
|
||||||
free(state.registers);
|
free(state.registers);
|
||||||
|
return stack.scope;
|
||||||
}
|
}
|
||||||
@@ -19,6 +19,8 @@ uint64_t pop_bytecode(Translated *translated, RuntimeState *state);
|
|||||||
|
|
||||||
void run_instruction(Translated *translated, RuntimeState *state, struct Stack stack);
|
void run_instruction(Translated *translated, RuntimeState *state, struct Stack stack);
|
||||||
|
|
||||||
void runtime(Translated translated);
|
RuntimeState init_runtime_state(Translated translated);
|
||||||
|
|
||||||
|
ArgonObject *runtime(Translated translated, RuntimeState state);
|
||||||
|
|
||||||
#endif // RUNTIME_H
|
#endif // RUNTIME_H
|
||||||
15
src/translator/identifier/identifier.c
Normal file
15
src/translator/identifier/identifier.c
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
#include "../translator.h"
|
||||||
|
#include "identifier.h"
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
size_t translate_parsed_identifier(Translated *translated, char* identifier) {
|
||||||
|
size_t length = strlen(identifier);
|
||||||
|
size_t identifier_pos = arena_push(&translated->constants, identifier, length);
|
||||||
|
set_registers(translated, 1);
|
||||||
|
size_t start = push_instruction_byte(translated, OP_IDENTIFIER);
|
||||||
|
push_instruction_code(translated,length);
|
||||||
|
push_instruction_code(translated, identifier_pos);
|
||||||
|
return start;
|
||||||
|
}
|
||||||
8
src/translator/identifier/identifier.h
Normal file
8
src/translator/identifier/identifier.h
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
#ifndef BYTECODE_IDENTIFIER_H
|
||||||
|
#define BYTECODE_IDENTIFIER_H
|
||||||
|
#include "../translator.h"
|
||||||
|
#include "../../parser/assignable/identifier/identifier.h"
|
||||||
|
|
||||||
|
size_t translate_parsed_identifier(Translated *translated, char* identifier);
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -3,6 +3,7 @@
|
|||||||
#include "../hashmap/hashmap.h"
|
#include "../hashmap/hashmap.h"
|
||||||
#include "declaration/declaration.h"
|
#include "declaration/declaration.h"
|
||||||
#include "function/function.h"
|
#include "function/function.h"
|
||||||
|
#include "identifier/identifier.h"
|
||||||
#include "number/number.h"
|
#include "number/number.h"
|
||||||
#include "string/string.h"
|
#include "string/string.h"
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
@@ -122,6 +123,8 @@ size_t translate_parsed(Translated *translated, ParsedValue *parsedValue) {
|
|||||||
case AST_FUNCTION:
|
case AST_FUNCTION:
|
||||||
return translate_parsed_function(translated,
|
return translate_parsed_function(translated,
|
||||||
(ParsedFunction *)parsedValue->data);
|
(ParsedFunction *)parsedValue->data);
|
||||||
|
case AST_IDENTIFIER:
|
||||||
|
return translate_parsed_identifier(translated, (char *)parsedValue->data);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
typedef enum { OP_LOAD_CONST, OP_DECLARE, OP_LOAD_NULL, OP_LOAD_FUNCTION } OperationType;
|
typedef enum { OP_LOAD_CONST, OP_DECLARE, OP_LOAD_NULL, OP_LOAD_FUNCTION, OP_IDENTIFIER } OperationType;
|
||||||
typedef enum { TYPE_OP_STRING, TYPE_OP_NUMBER } types;
|
typedef enum { TYPE_OP_STRING, TYPE_OP_NUMBER } types;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
|||||||
Reference in New Issue
Block a user