119 lines
3.5 KiB
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;
|
|
}
|