// Kyler Olsen // YREA SLS // Pico Main File // December 2025 #include #include #include #include "pico/stdlib.h" #include "pico/stdio_usb.h" #include "hardware/uart.h" #include "hardware/gpio.h" #include "sls/meta.h" #include "sls/bool.h" #include "sls/string.h" #include "sls/errors.h" #include "sls/lexer.h" #include "sls/interpreter.h" // Pico onboard LED #define LED_PIN 25 static const SlsStr PICO_REPL_NAME = SLS_STR_CONST(""); void print_top_of_stack(InterpreterState *interpreter_state) { if (interpreter_state->stack == NULL) { printf("#0: \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: %lld:i64\n", interpreter_state->stack->i64); break; case STACK_I32: printf("#0: %ld\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:i8\n", interpreter_state->stack->i8); break; case STACK_U64: printf("#0: %llu:u64\n", interpreter_state->stack->u64); break; case STACK_U32: printf("#0: %lu:u32\n", interpreter_state->stack->u32); break; case STACK_U16: printf("#0: %u:u16\n", interpreter_state->stack->u16); break; case STACK_U8: printf("#0: %u:u8\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: \n"); break; case STACK_CALLABLE: printf("#0: \n"); break; } } void led_blink(int count) { for (int i = 0; i < count; i++) { gpio_put(LED_PIN, 1); sleep_ms(100); gpio_put(LED_PIN, 0); sleep_ms(100); } } int pico_repl() { // Initialize LED gpio_init(LED_PIN); gpio_set_dir(LED_PIN, GPIO_OUT); // Blink to show we're ready led_blink(3); // Wait for a key press to start the repl while (true) { int c = getchar_timeout_us(100000); if (c == PICO_ERROR_TIMEOUT) { continue; } else if (c == '\r' || c == '\n' || c == 8 || (c >= 32 && c < 128)) { printf("\n"); break; } } led_blink(1); print_version(); printf("===== YREA SLS PICO REPL =====\n"); printf("Type `#exit` to exit.\n"); fflush(stdout); LexerInfo lexer_info; InterpreterState *interpreter_state = interpreter_create(); if (interpreter_state == NULL) { printf("ERROR: Failed to create interpreter!\n"); return 1; } char buf[256]; int buf_pos = 0; while (true) { // Read character by character for better embedded behavior int c = getchar_timeout_us(100000); // 100ms timeout if (c == PICO_ERROR_TIMEOUT) { continue; } if (c == '\r' || c == '\n') { if (buf_pos == 0) continue; // Empty line buf[buf_pos] = '\0'; printf("\n"); // Echo newline if (strncmp(buf, "#exit", 5) == 0) { printf("Exiting REPL...\n"); interpreter_delete(interpreter_state); led_blink(2); return 0; } SlsStr code = sls_str_malloc(buf, buf_pos); init_lexer(&lexer_info, PICO_REPL_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); buf_pos = 0; } else if (c == 127 || c == 8) { // Backspace or DEL if (buf_pos > 0) { buf_pos--; printf("\b \b"); // Erase character from terminal fflush(stdout); } } else if (c >= 32 && c < 127 && buf_pos < 255) { // Printable character buf[buf_pos++] = (char)c; putchar(c); // Echo character fflush(stdout); } } interpreter_delete(interpreter_state); return 1; } int main() { // Initialize USB/UART stdio stdio_init_all(); // Wait a bit for USB to enumerate sleep_ms(5000); printf("\n\n=============================\n"); printf("YREA SLS on Raspberry Pi Pico\n"); printf("=============================\n\n"); printf("Press any key to begin...\n"); return pico_repl(); }