start adding error message support
This commit is contained in:
2
.gitmodules
vendored
2
.gitmodules
vendored
@@ -6,4 +6,4 @@
|
||||
url = https://github.com/likle/cwalk.git
|
||||
[submodule "external/libdye"]
|
||||
path = external/libdye
|
||||
url = https://github.com/kuzalekon/libdye.git
|
||||
url = https://github.com/Ugric/libdye.git
|
||||
|
||||
@@ -30,9 +30,10 @@ add_custom_command(
|
||||
add_custom_target(GenerateLexer DEPENDS ${LEXER_C} ${LEXER_H})
|
||||
|
||||
# Step 3: Add executable
|
||||
add_executable(argon external/xxhash/xxhash.c external/cwalk/src/cwalk.c ${CFILES} ${LEXER_C})
|
||||
add_executable(argon external/xxhash/xxhash.c external/cwalk/src/cwalk.c external/libdye/src/dye.c ${CFILES} ${LEXER_C})
|
||||
set(CMAKE_INTERPROCEDURAL_OPTIMIZATION TRUE)
|
||||
target_include_directories(argon PRIVATE ${CMAKE_SOURCE_DIR}/external/cwalk/include)
|
||||
target_include_directories(argon PRIVATE ${CMAKE_SOURCE_DIR}/external/libdye/include)
|
||||
|
||||
# Step 4: Build order
|
||||
add_dependencies(argon GenerateLexer)
|
||||
|
||||
4
Makefile
4
Makefile
@@ -2,8 +2,8 @@ LEXER_SRC = src/lexer/lex.l
|
||||
LEXER_C = src/lexer/lex.yy.c
|
||||
LEXER_H = src/lexer/lex.yy.h
|
||||
|
||||
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 -Iexternal/cwalk/include
|
||||
CFILES = external/xxhash/xxhash.c external/cwalk/src/cwalk.c external/libdye/src/dye.c $(shell find src -name '*.c')
|
||||
CFLAGS = $(ARCHFLAGS) -lm -lgc -lgmp -Wall -Wextra -Wno-unused-function -Iexternal/cwalk/include -Iexternal/libdye/include
|
||||
BINARY = bin/argon
|
||||
|
||||
all: $(BINARY)
|
||||
|
||||
2
external/libdye
vendored
2
external/libdye
vendored
Submodule external/libdye updated: da48196fff...c3fa048e65
52
src/arobject.h
Normal file
52
src/arobject.h
Normal file
@@ -0,0 +1,52 @@
|
||||
#ifndef AROBJECT_H
|
||||
#define AROBJECT_H
|
||||
|
||||
#include <gmp.h>
|
||||
#include "runtime/internals/dynamic_array_armem/darray_armem.h"
|
||||
|
||||
typedef struct ArgonObject ArgonObject; // forward declaration
|
||||
|
||||
typedef enum ArgonType {
|
||||
TYPE_NULL,
|
||||
TYPE_BOOL,
|
||||
TYPE_NUMBER,
|
||||
TYPE_STRING,
|
||||
TYPE_FUNCTION,
|
||||
TYPE_NATIVE_FUNCTION,
|
||||
TYPE_OBJECT,
|
||||
} ArgonType;
|
||||
|
||||
struct string_struct {
|
||||
char *data;
|
||||
size_t length;
|
||||
};
|
||||
|
||||
typedef struct Stack {
|
||||
ArgonObject *scope;
|
||||
struct Stack *prev;
|
||||
} Stack;
|
||||
|
||||
struct argon_function_struct {
|
||||
darray_armem bytecode;
|
||||
Stack stack;
|
||||
size_t number_of_parameters;
|
||||
char **parameters;
|
||||
};
|
||||
|
||||
// full definition of ArgonObject (no typedef again!)
|
||||
struct ArgonObject {
|
||||
ArgonType type;
|
||||
char *name;
|
||||
ArgonObject *self;
|
||||
ArgonObject *baseObject;
|
||||
struct hashmap_GC *fields;
|
||||
union {
|
||||
mpq_t as_number;
|
||||
bool as_bool;
|
||||
struct string_struct as_str;
|
||||
void *native_fn;
|
||||
struct argon_function_struct argon_fn;
|
||||
} value;
|
||||
};
|
||||
|
||||
#endif // AROBJECT_H
|
||||
134
src/err.c
Normal file
134
src/err.c
Normal file
@@ -0,0 +1,134 @@
|
||||
#include "err.h"
|
||||
#include "../external/libdye/include/dye.h"
|
||||
#include <ctype.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
const ArErr no_err = (ArErr){false};
|
||||
|
||||
ArErr create_err(int64_t line, int64_t column, int length, char *path,
|
||||
const char *type, const char *fmt, ...) {
|
||||
ArErr err;
|
||||
err.exists = true;
|
||||
err.path = path;
|
||||
err.line = line;
|
||||
err.column = column;
|
||||
err.length = length;
|
||||
|
||||
// Copy error type safely
|
||||
strncpy(err.type, type, sizeof(err.type) - 1);
|
||||
err.type[sizeof(err.type) - 1] = '\0';
|
||||
|
||||
// Format error message
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
vsnprintf(err.message, sizeof(err.message), fmt, args);
|
||||
va_end(args);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
void output_err(ArErr err) {
|
||||
if (!err.exists)
|
||||
return;
|
||||
dye(stderr, DYE_WHITE, DYE_RED);
|
||||
fprintf(stderr, "ERROR!");
|
||||
dye(stderr, DYE_RESET, DYE_RESET);
|
||||
fprintf(stderr, " ");
|
||||
dyefg(stderr, DYE_RED);
|
||||
dye_style(stderr, DYE_STYLE_BOLD);
|
||||
fprintf(stderr, "%s", err.type);
|
||||
dye_style(stderr, DYE_STYLE_RESET);
|
||||
dyefg(stderr, DYE_RESET);
|
||||
fprintf(stderr, ": ");
|
||||
dyefg(stderr, DYE_RED);
|
||||
fprintf(stderr, "%s", err.message);
|
||||
dye_style(stderr, DYE_STYLE_RESET);
|
||||
dyefg(stderr, DYE_RESET);
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
if (err.path && err.line) {
|
||||
dyefg(stderr, DYE_GRAY);
|
||||
fprintf(stderr, " --> ");
|
||||
dyefg(stderr, DYE_CYAN);
|
||||
fprintf(stderr, "%s", err.path);
|
||||
dyefg(stderr, DYE_GRAY);
|
||||
fprintf(stderr, ":");
|
||||
dyefg(stderr, DYE_YELLOW);
|
||||
fprintf(stderr, "%zu", err.line);
|
||||
dyefg(stderr, DYE_GRAY);
|
||||
fprintf(stderr, ":");
|
||||
dyefg(stderr, DYE_YELLOW);
|
||||
fprintf(stderr, "%zu", err.column);
|
||||
dye_style(stderr, DYE_STYLE_RESET);
|
||||
dyefg(stderr, DYE_RESET);
|
||||
fprintf(stderr, "\n");
|
||||
FILE *file = fopen(err.path, "r");
|
||||
if (file) {
|
||||
dye_style(stderr, DYE_STYLE_RESET);
|
||||
dyefg(stderr, DYE_RESET);
|
||||
int line_number_width = snprintf(NULL, 0, "%zu", err.line);
|
||||
char *buffer = NULL;
|
||||
size_t size = 0;
|
||||
int current_line = 1;
|
||||
ssize_t len;
|
||||
|
||||
while ((len = getline(&buffer, &size, file)) != -1) {
|
||||
if (current_line == err.line) {
|
||||
break;
|
||||
}
|
||||
current_line++;
|
||||
}
|
||||
fprintf(stderr, " ");
|
||||
for (int i = 0; i < line_number_width; i++) {
|
||||
fprintf(stderr, " ");
|
||||
}
|
||||
fprintf(stderr, "|\n");
|
||||
getline(&buffer, &size, file);
|
||||
|
||||
char *line_starts = buffer;
|
||||
while (*line_starts && isspace((unsigned char)*line_starts)) {
|
||||
line_starts++;
|
||||
err.column--;
|
||||
}
|
||||
fprintf(stderr, " %zu | ", err.line);
|
||||
if (err.length) {
|
||||
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", line_starts + (int)err.column + err.length - 1);
|
||||
for (int64_t i = 0; i < err.column - 1; i++) {
|
||||
fprintf(stderr, " ");
|
||||
}
|
||||
} else {
|
||||
fprintf(stderr, "%s", line_starts);
|
||||
}
|
||||
free(buffer);
|
||||
fprintf(stderr, "\n ");
|
||||
for (int i = 0; i < line_number_width; i++) {
|
||||
fprintf(stderr, " ");
|
||||
}
|
||||
fprintf(stderr, "| ");
|
||||
|
||||
for (int i = 1; i < err.column; i++) {
|
||||
fprintf(stderr, " ");
|
||||
}
|
||||
dyefg(stderr, DYE_RED);
|
||||
dye_style(stderr, DYE_STYLE_BOLD);
|
||||
for (int i = 0; i < err.length; i++) {
|
||||
fprintf(stderr, "^");
|
||||
}
|
||||
dye_style(stderr, DYE_STYLE_RESET);
|
||||
dyefg(stderr, DYE_RESET);
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
7
src/err.h
Normal file
7
src/err.h
Normal file
@@ -0,0 +1,7 @@
|
||||
#include "returnTypes.h"
|
||||
|
||||
extern const ArErr no_err;
|
||||
|
||||
ArErr create_err(int64_t line, int64_t column, int length, char *path, const char *type,
|
||||
const char *fmt, ...);
|
||||
void output_err(ArErr err);
|
||||
@@ -3,8 +3,6 @@
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
typedef struct ArgonObject ArgonObject;
|
||||
|
||||
typedef void (*free_val_func)(void *val);
|
||||
|
||||
struct node {
|
||||
|
||||
@@ -108,8 +108,6 @@ int yywrap(void * unused_param) {
|
||||
#[^\n]* { /* skip comment */ }
|
||||
|
||||
. {
|
||||
GET_STATE
|
||||
fprintf(stderr, "%s:%zu:%zu error: unexpected character '%s'\n", state->path, state->current_line+1, COLUMN_NO+1, yytext);
|
||||
exit(1);
|
||||
return TOKEN_INVALID;
|
||||
}
|
||||
%%
|
||||
@@ -1,8 +1,8 @@
|
||||
#include "lexer.h"
|
||||
#include "lex.yy.h"
|
||||
#include "../string/string.h"
|
||||
#include "lex.yy.h"
|
||||
|
||||
void lexer(LexerState state) {
|
||||
ArErr lexer(LexerState state) {
|
||||
size_t line = 1;
|
||||
size_t column = 1;
|
||||
int ch;
|
||||
@@ -32,13 +32,16 @@ void lexer(LexerState state) {
|
||||
|
||||
int token;
|
||||
while ((token = yylex(scanner)) != 0) {
|
||||
Token token_struct = (Token){
|
||||
token,
|
||||
state.current_line+1,
|
||||
state.current_column+1,
|
||||
yyget_leng(scanner),
|
||||
cloneString(yyget_text(scanner))
|
||||
};
|
||||
if (token == TOKEN_INVALID) {
|
||||
ArErr err = create_err(state.current_line + 1, state.current_column + 1,
|
||||
yyget_leng(scanner), state.path, "Syntax Error",
|
||||
"Invalid Token '%s'", yyget_text(scanner));
|
||||
yylex_destroy(scanner);
|
||||
return err;
|
||||
}
|
||||
Token token_struct =
|
||||
(Token){token, state.current_line + 1, state.current_column + 1,
|
||||
yyget_leng(scanner), cloneString(yyget_text(scanner))};
|
||||
darray_push(state.tokens, &token_struct);
|
||||
if (token == TOKEN_NEW_LINE) {
|
||||
state.current_line += 1;
|
||||
@@ -48,4 +51,5 @@ void lexer(LexerState state) {
|
||||
}
|
||||
}
|
||||
yylex_destroy(scanner);
|
||||
return no_err;
|
||||
}
|
||||
@@ -4,9 +4,10 @@
|
||||
#include "../dynamic_array/darray.h"
|
||||
#include "token.h"
|
||||
#include <stdio.h>
|
||||
#include "../err.h"
|
||||
|
||||
typedef struct {
|
||||
const char *path;
|
||||
char *path;
|
||||
FILE *file;
|
||||
size_t current_line;
|
||||
size_t current_column;
|
||||
@@ -14,6 +15,6 @@ typedef struct {
|
||||
// add more fields as needed
|
||||
} LexerState;
|
||||
|
||||
void lexer(LexerState state);
|
||||
ArErr lexer(LexerState state);
|
||||
|
||||
#endif // LEXER_H
|
||||
@@ -72,6 +72,7 @@ typedef enum {
|
||||
TOKEN_COMMA,
|
||||
TOKEN_COLON,
|
||||
TOKEN_EXCLAMATION,
|
||||
TOKEN_INVALID,
|
||||
} TokenType;
|
||||
|
||||
typedef struct {
|
||||
|
||||
46
src/main.c
46
src/main.c
@@ -35,6 +35,7 @@
|
||||
#include <limits.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#include "err.h"
|
||||
|
||||
char *get_current_directory() {
|
||||
char *buffer = NULL;
|
||||
@@ -160,7 +161,7 @@ FAILED:
|
||||
return 1;
|
||||
}
|
||||
|
||||
ArgonObject *execute(char*absolute_path) {
|
||||
Execution execute(char *absolute_path) {
|
||||
clock_t start, end;
|
||||
double time_spent, total_time_spent = 0;
|
||||
|
||||
@@ -168,7 +169,10 @@ ArgonObject *execute(char*absolute_path) {
|
||||
size_t basename_length;
|
||||
cwk_path_get_basename(absolute_path, &basename_ptr, &basename_length);
|
||||
|
||||
if (!basename_ptr) return NULL;
|
||||
if (!basename_ptr)
|
||||
return (Execution){create_err(0, 0 ,0 , NULL, "Path Error",
|
||||
"path has no basename '%s'", absolute_path),
|
||||
(Stack){NULL, NULL}};
|
||||
|
||||
char basename[FILENAME_MAX];
|
||||
memcpy(basename, basename_ptr, basename_length);
|
||||
@@ -181,15 +185,20 @@ ArgonObject *execute(char*absolute_path) {
|
||||
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));
|
||||
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));
|
||||
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) {
|
||||
return NULL;
|
||||
return (Execution){create_err(0, 0, 0, NULL, "File Error", "Unable to open file '%s'",
|
||||
absolute_path),
|
||||
(Stack){NULL, NULL}};
|
||||
}
|
||||
|
||||
XXH3_state_t *hash_state = XXH3_createState();
|
||||
@@ -215,7 +224,13 @@ ArgonObject *execute(char*absolute_path) {
|
||||
|
||||
LexerState state = {absolute_path, file, 0, 0, &tokens};
|
||||
start = clock();
|
||||
lexer(state);
|
||||
ArErr err = lexer(state);
|
||||
if (err.exists) {
|
||||
free_translator(&translated);
|
||||
darray_free(&tokens, free_token);
|
||||
return (Execution){err,
|
||||
(Stack){NULL, NULL}};
|
||||
}
|
||||
end = clock();
|
||||
time_spent = (double)(end - start) / CLOCKS_PER_SEC;
|
||||
total_time_spent += time_spent;
|
||||
@@ -269,7 +284,8 @@ ArgonObject *execute(char*absolute_path) {
|
||||
|
||||
start = clock();
|
||||
RuntimeState state = init_runtime_state(translated);
|
||||
ArgonObject *resp = runtime(translated,state);
|
||||
Stack main_scope = create_scope(NULL);
|
||||
ArErr err = runtime(translated, state, main_scope);
|
||||
|
||||
end = clock();
|
||||
time_spent = (double)(end - start) / CLOCKS_PER_SEC;
|
||||
@@ -278,7 +294,7 @@ ArgonObject *execute(char*absolute_path) {
|
||||
printf("total time taken: %f seconds\n", total_time_spent);
|
||||
|
||||
free_translator(&translated);
|
||||
return resp;
|
||||
return (Execution){err, main_scope};
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
@@ -291,10 +307,12 @@ int main(int argc, char *argv[]) {
|
||||
return -1;
|
||||
char *path_non_absolute = argv[1];
|
||||
char path[FILENAME_MAX];
|
||||
cwk_path_get_absolute(CWD, path_non_absolute, path,
|
||||
sizeof(path));
|
||||
cwk_path_get_absolute(CWD, path_non_absolute, path, sizeof(path));
|
||||
free(CWD);
|
||||
ArgonObject *resp = execute(path);
|
||||
if (resp) return 0;
|
||||
return -1;
|
||||
Execution resp = execute(path);
|
||||
if (resp.err.exists){
|
||||
output_err(resp.err);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
22
src/returnTypes.h
Normal file
22
src/returnTypes.h
Normal file
@@ -0,0 +1,22 @@
|
||||
#ifndef RETURN_TYPES_H
|
||||
#define RETURN_TYPES_H
|
||||
#include <stdint.h>
|
||||
#include "arobject.h"
|
||||
|
||||
#define ERR_MSG_MAX_LEN 256
|
||||
|
||||
typedef struct ArErr {
|
||||
bool exists;
|
||||
char *path;
|
||||
int64_t line;
|
||||
int64_t column;
|
||||
int length;
|
||||
char type[32];
|
||||
char message[ERR_MSG_MAX_LEN];
|
||||
} ArErr;
|
||||
|
||||
typedef struct Execution {
|
||||
ArErr err;
|
||||
Stack stack;
|
||||
} Execution;
|
||||
#endif // RETURN_TYPES_
|
||||
@@ -3,8 +3,6 @@
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
typedef struct ArgonObject ArgonObject;
|
||||
|
||||
struct node_GC {
|
||||
uint64_t hash;
|
||||
void *key;
|
||||
|
||||
@@ -1,53 +1,15 @@
|
||||
#ifndef OBJECT_H
|
||||
#define OBJECT_H
|
||||
#include "../internals/hashmap/hashmap.h"
|
||||
#include "../internals/dynamic_array_armem/darray_armem.h"
|
||||
#include <gmp.h>
|
||||
#include <stdbool.h>
|
||||
#include "../runtime.h"
|
||||
#include <stdbool.h>
|
||||
|
||||
extern ArgonObject *BASE_CLASS;
|
||||
|
||||
struct string_struct {
|
||||
char *data;
|
||||
size_t length;
|
||||
};
|
||||
struct argon_function_struct {
|
||||
darray_armem bytecode;
|
||||
struct Stack stack;
|
||||
size_t number_of_parameters;
|
||||
char** parameters;
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
TYPE_NULL,
|
||||
TYPE_BOOL,
|
||||
TYPE_NUMBER,
|
||||
TYPE_STRING,
|
||||
TYPE_FUNCTION,
|
||||
TYPE_NATIVE_FUNCTION,
|
||||
TYPE_OBJECT, // generic user object
|
||||
} ArgonType;
|
||||
|
||||
struct ArgonObject {
|
||||
ArgonType type;
|
||||
char* name;
|
||||
ArgonObject *self;
|
||||
ArgonObject *baseObject;
|
||||
struct hashmap_GC *fields; // dynamic fields/methods
|
||||
union {
|
||||
mpq_t as_number;
|
||||
bool as_bool;
|
||||
struct string_struct as_str;
|
||||
void *native_fn;
|
||||
struct argon_function_struct argon_fn;
|
||||
// others as needed
|
||||
} value;
|
||||
};
|
||||
typedef struct ArgonObject ArgonObject;
|
||||
void init_base_field();
|
||||
ArgonObject* init_child_argon_object(ArgonObject *cls);
|
||||
ArgonObject* init_argon_class(char*name);
|
||||
ArgonObject *init_child_argon_object(ArgonObject *cls);
|
||||
ArgonObject *init_argon_class(char *name);
|
||||
|
||||
void add_field(ArgonObject*target, char* name, ArgonObject *object);
|
||||
void add_field(ArgonObject *target, char *name, ArgonObject *object);
|
||||
#endif // OBJECT_H
|
||||
@@ -1,4 +1,5 @@
|
||||
#include "runtime.h"
|
||||
#include "../err.h"
|
||||
#include "../translator/translator.h"
|
||||
#include "objects/functions/functions.h"
|
||||
#include "objects/null/null.h"
|
||||
@@ -62,20 +63,8 @@ void load_const(Translated *translated, RuntimeState *state) {
|
||||
state->registers[to_register] = object;
|
||||
}
|
||||
|
||||
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) {
|
||||
ArErr run_instruction(Translated *translated, RuntimeState *state,
|
||||
struct Stack stack) {
|
||||
OperationType opcode = pop_byte(translated, state);
|
||||
switch (opcode) {
|
||||
case OP_LOAD_NULL:
|
||||
@@ -88,24 +77,26 @@ ArErr create_err(char *path, int64_t line, char *type, char *message) {
|
||||
load_argon_function(translated, state, stack);
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "bytecode invalid\n");
|
||||
exit(EXIT_FAILURE);
|
||||
return create_err(0, 0, 0, NULL, "Runtime Error", "Invalid Opcode %#x", opcode);
|
||||
}
|
||||
return no_err;
|
||||
}
|
||||
|
||||
RuntimeState init_runtime_state(Translated translated) {
|
||||
RuntimeState state = {
|
||||
return (RuntimeState){
|
||||
checked_malloc(translated.registerCount * sizeof(ArgonObject *)), 0};
|
||||
return state;
|
||||
}
|
||||
|
||||
ArgonObject *runtime(Translated translated, RuntimeState state) {
|
||||
struct Stack stack = {NULL, NULL};
|
||||
Stack create_scope(Stack *prev) { return (Stack){NULL, prev}; }
|
||||
|
||||
ArErr runtime(Translated translated, RuntimeState state, Stack stack) {
|
||||
state.head = 0;
|
||||
while (state.head < translated.bytecode.size) {
|
||||
run_instruction(&translated, &state, stack);
|
||||
ArErr err = run_instruction(&translated, &state, stack);
|
||||
if (err.exists) {
|
||||
return err;
|
||||
}
|
||||
}
|
||||
free(state.registers);
|
||||
return stack.scope;
|
||||
return no_err;
|
||||
}
|
||||
@@ -2,25 +2,13 @@
|
||||
#define RUNTIME_H
|
||||
#include "../translator/translator.h"
|
||||
#include "internals/hashmap/hashmap.h"
|
||||
#include "../returnTypes.h"
|
||||
|
||||
typedef struct {
|
||||
ArgonObject **registers;
|
||||
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;
|
||||
} Stack;
|
||||
|
||||
void init_types();
|
||||
|
||||
uint64_t pop_bytecode(Translated *translated, RuntimeState *state);
|
||||
@@ -30,6 +18,8 @@ ArErr run_instruction(Translated *translated, RuntimeState *state,
|
||||
|
||||
RuntimeState init_runtime_state(Translated translated);
|
||||
|
||||
ArgonObject *runtime(Translated translated, RuntimeState state);
|
||||
Stack create_scope(Stack *prev);
|
||||
|
||||
ArErr runtime(Translated translated, RuntimeState state, Stack stack);
|
||||
|
||||
#endif // RUNTIME_H
|
||||
1
testing.ar
Normal file
1
testing.ar
Normal file
@@ -0,0 +1 @@
|
||||
10~10
|
||||
Reference in New Issue
Block a user