YREA-SLS/SLS_C/src/repl.c

119 lines
3.5 KiB
C

// Kyler Olsen
// YREA SLS
// REPL
// November 2025
#include <stddef.h>
#include <stdio.h>
#include <string.h>
#include "sls/repl.h"
#include "sls/meta.h"
#include "sls/errors.h"
#include "sls/lexer.h"
#include "sls/string.h"
#include "sls/interpreter.h"
static const SlsStr REPL_FILE_NAME = SLS_STR_CONST("<STDIN>");
void print_top_of_stack(InterpreterState *interpreter_state) {
if (interpreter_state->stack == NULL) {
printf("#0: <STACK IS EMPTY>\n");
return;
}
switch (interpreter_state->stack->type) {
case STACK_IDENTIFIER:
printf("#0: ::%s\n", interpreter_state->stack->identifier.name.str);
break;
case STACK_I64:
printf("#0: %ld\n", interpreter_state->stack->i64);
break;
case STACK_I32:
printf("#0: %d:i32\n", interpreter_state->stack->i32);
break;
case STACK_I16:
printf("#0: %d:i16\n", interpreter_state->stack->i16);
break;
case STACK_I8:
printf("#0: %d:8\n", interpreter_state->stack->i8);
break;
case STACK_U64:
printf("#0: %lu:u64\n", interpreter_state->stack->u64);
break;
case STACK_U32:
printf("#0: %u:32\n", interpreter_state->stack->u32);
break;
case STACK_U16:
printf("#0: %u:16\n", interpreter_state->stack->u16);
break;
case STACK_U8:
printf("#0: %u:8\n", interpreter_state->stack->u8);
break;
case STACK_FLOAT:
printf("#0: %f:f32\n", interpreter_state->stack->f32);
break;
case STACK_DOUBLE:
printf("#0: %f\n", interpreter_state->stack->f64);
break;
case STACK_CHARACTER:
printf("#0: %c\n", interpreter_state->stack->character);
break;
case STACK_BOOLEAN:
if (interpreter_state->stack->boolean) printf("#0: TRUE\n");
else printf("#0: FALSE\n");
break;
case STACK_TOKEN_STRING:
printf("#0: <TOKEN STRING>\n");
break;
case STACK_CALLABLE:
printf("#0: <CALLABLE>\n");
break;
}
}
int repl() {
print_version();
printf("===== YREA SLS REPL =====\n");
printf("Type `#exit` to exit.\n");
fflush(stdout);
LexerInfo lexer_info;
InterpreterState *interpreter_state = interpreter_create();
if (interpreter_state == NULL) return 1;
char buf[256];
while (fgets(buf, sizeof(buf), stdin)) {
size_t len = strlen(buf);
if (len && buf[len - 1] == '\n') buf[len - 1] = '\0';
if (strncmp(buf, "#exit", 5) == 0) {
interpreter_delete(interpreter_state);
return 0;
}
SlsStr code = sls_str_malloc(buf, sizeof(buf));
init_lexer(&lexer_info, REPL_FILE_NAME, code);
LexerResult result = lexical_analysis(&lexer_info);
if (result.type == SLS_ERROR) {
printf("%s\n", result.error.message.str);
sls_str_free(&result.error.message);
} else {
LexerTokenResult *head = result.result;
while (head) {
if (head->type == SLS_ERROR) {
printf("%s\n", head->error.message.str);
break;
} else if (!execute(interpreter_state, head)) {
printf("A runtime error occurred!\n");
break;
}
head = head->next;
}
clean_token_result(result.result);
print_top_of_stack(interpreter_state);
}
sls_str_free(&code);
}
interpreter_delete(interpreter_state);
return 1;
}