Started Implementing a BASIC interpriter
This commit is contained in:
parent
e82fb49c04
commit
3eee0f8269
22
.vscode/c_cpp_properties.json
vendored
Normal file
22
.vscode/c_cpp_properties.json
vendored
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
{
|
||||||
|
"configurations": [
|
||||||
|
{
|
||||||
|
"name": "Win32",
|
||||||
|
"includePath": [
|
||||||
|
"${default}",
|
||||||
|
"${workspaceFolder}/**"
|
||||||
|
],
|
||||||
|
"defines": [
|
||||||
|
"_DEBUG",
|
||||||
|
"UNICODE",
|
||||||
|
"_UNICODE"
|
||||||
|
],
|
||||||
|
"windowsSdkVersion": "10.0.22621.0",
|
||||||
|
"compilerPath": "C:/msys64/mingw64/bin/gcc.exe",
|
||||||
|
"cStandard": "c17",
|
||||||
|
"cppStandard": "c++17",
|
||||||
|
"intelliSenseMode": "linux-gcc-x64"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"version": 4
|
||||||
|
}
|
Binary file not shown.
Binary file not shown.
BIN
EYOSx86-main/dist/x86_64/kernel.bin
vendored
BIN
EYOSx86-main/dist/x86_64/kernel.bin
vendored
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
build/x86_64/basic.o
Normal file
BIN
build/x86_64/basic.o
Normal file
Binary file not shown.
Binary file not shown.
BIN
build/x86_64/strings.o
Normal file
BIN
build/x86_64/strings.o
Normal file
Binary file not shown.
Binary file not shown.
BIN
dist/x86_64/kernel.bin
vendored
Normal file
BIN
dist/x86_64/kernel.bin
vendored
Normal file
Binary file not shown.
Binary file not shown.
@ -10,11 +10,9 @@
|
|||||||
#include "window.h"
|
#include "window.h"
|
||||||
#include "fs.h"
|
#include "fs.h"
|
||||||
#include "fat12.h"
|
#include "fat12.h"
|
||||||
|
#include "basic.h"
|
||||||
|
|
||||||
|
#define COMMAND_BUFFER_SIZE 256 // Increase buffer size to handle longer commands
|
||||||
|
|
||||||
|
|
||||||
#define COMMAND_BUFFER_SIZE 256 // Increase buffer size to handle longer commands
|
|
||||||
#define BACKSPACE_KEY 8
|
#define BACKSPACE_KEY 8
|
||||||
#define HISTORY_SIZE 10
|
#define HISTORY_SIZE 10
|
||||||
#define COMMAND_BUFFER_SIZE 256
|
#define COMMAND_BUFFER_SIZE 256
|
||||||
@ -22,29 +20,31 @@
|
|||||||
|
|
||||||
extern void kpanic(int error_code);
|
extern void kpanic(int error_code);
|
||||||
|
|
||||||
|
void shutdown_system()
|
||||||
void shutdown_system() {
|
{
|
||||||
__asm__ (
|
__asm__(
|
||||||
"movl $1, %eax\n" // syscall number for sys_reboot (1 in this case)
|
"movl $1, %eax\n" // syscall number for sys_reboot (1 in this case)
|
||||||
"movl $0, %ebx\n" // reboot flags
|
"movl $0, %ebx\n" // reboot flags
|
||||||
"movl $0, %ecx\n" // no additional arguments
|
"movl $0, %ecx\n" // no additional arguments
|
||||||
"movl $0, %edx\n" // no additional arguments
|
"movl $0, %edx\n" // no additional arguments
|
||||||
"int $0x80\n" // interrupt to invoke syscall
|
"int $0x80\n" // interrupt to invoke syscall
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
char commandHistory[HISTORY_SIZE][COMMAND_BUFFER_SIZE];
|
char commandHistory[HISTORY_SIZE][COMMAND_BUFFER_SIZE];
|
||||||
int currentHistoryIndex = 0;
|
int currentHistoryIndex = 0;
|
||||||
int historyCount = 0;
|
int historyCount = 0;
|
||||||
|
|
||||||
void add_to_history(const char* command) {
|
void add_to_history(const char *command)
|
||||||
if (historyCount < HISTORY_SIZE) {
|
{
|
||||||
|
if (historyCount < HISTORY_SIZE)
|
||||||
|
{
|
||||||
historyCount++;
|
historyCount++;
|
||||||
} else {
|
}
|
||||||
for (int i = 1; i < HISTORY_SIZE; i++) {
|
else
|
||||||
|
{
|
||||||
|
for (int i = 1; i < HISTORY_SIZE; i++)
|
||||||
|
{
|
||||||
strcpy(commandHistory[i - 1], commandHistory[i]);
|
strcpy(commandHistory[i - 1], commandHistory[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -52,23 +52,26 @@ void add_to_history(const char* command) {
|
|||||||
currentHistoryIndex = historyCount;
|
currentHistoryIndex = historyCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* get_previous_command() {
|
const char *get_previous_command()
|
||||||
if (currentHistoryIndex > 0) {
|
{
|
||||||
|
if (currentHistoryIndex > 0)
|
||||||
|
{
|
||||||
currentHistoryIndex--;
|
currentHistoryIndex--;
|
||||||
return commandHistory[currentHistoryIndex];
|
return commandHistory[currentHistoryIndex];
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* get_next_command() {
|
const char *get_next_command()
|
||||||
if (currentHistoryIndex < historyCount - 1) {
|
{
|
||||||
|
if (currentHistoryIndex < historyCount - 1)
|
||||||
|
{
|
||||||
currentHistoryIndex++;
|
currentHistoryIndex++;
|
||||||
return commandHistory[currentHistoryIndex];
|
return commandHistory[currentHistoryIndex];
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const void clear()
|
const void clear()
|
||||||
{
|
{
|
||||||
print_set_color(PRINT_COLOR_WHITE, PRINT_COLOR_BLACK); // Set text color
|
print_set_color(PRINT_COLOR_WHITE, PRINT_COLOR_BLACK); // Set text color
|
||||||
@ -79,113 +82,127 @@ const void clear()
|
|||||||
print_setup_prompt();
|
print_setup_prompt();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void halt()
|
||||||
|
{
|
||||||
|
|
||||||
void halt(){
|
|
||||||
print_str("[ WARN ] HALT\n");
|
print_str("[ WARN ] HALT\n");
|
||||||
while (1) {}
|
while (1)
|
||||||
|
{
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void commandHandler(char* command) {
|
void commandHandler(char *command)
|
||||||
|
{
|
||||||
printf("\n");
|
printf("\n");
|
||||||
|
|
||||||
if (strcmp(command, "cls") == 0) {
|
if (strcmp(command, "cls") == 0)
|
||||||
|
{
|
||||||
clear();
|
clear();
|
||||||
} else if (strcmp(command, "knp") == 0) {
|
}
|
||||||
|
else if (strcmp(command, "knp") == 0)
|
||||||
|
{
|
||||||
kpanic(1);
|
kpanic(1);
|
||||||
} else if (int_strncmp(command, "echo ", 5) == 0) {
|
}
|
||||||
char* message = command + 5; // Skip the "echo " part
|
else if (int_strncmp(command, "echo ", 5) == 0)
|
||||||
|
{
|
||||||
|
char *message = command + 5; // Skip the "echo " part
|
||||||
print_str("\n");
|
print_str("\n");
|
||||||
print_str(message);
|
print_str(message);
|
||||||
print_str("\n");
|
print_str("\n");
|
||||||
} else if (int_strncmp(command, "cwin", 4) == 0) {
|
}
|
||||||
|
else if (int_strncmp(command, "cwin", 4) == 0)
|
||||||
|
{
|
||||||
// Define window properties
|
// Define window properties
|
||||||
Window myWindow;
|
Window myWindow;
|
||||||
int x = 8; // X position of the window
|
int x = 8; // X position of the window
|
||||||
int y = 4; // Y position of the window
|
int y = 4; // Y position of the window
|
||||||
int width = 30; // Width of the window
|
int width = 30; // Width of the window
|
||||||
int height = 10; // Height of the window
|
int height = 10; // Height of the window
|
||||||
uint8_t borderColor = PRINT_COLOR_RED; // Border color
|
uint8_t borderColor = PRINT_COLOR_RED; // Border color
|
||||||
uint8_t backgroundColor = PRINT_COLOR_BLUE; // Background color
|
uint8_t backgroundColor = PRINT_COLOR_BLUE; // Background color
|
||||||
|
|
||||||
// Create and display the window
|
// Create and display the window
|
||||||
create_window(&myWindow, x, y, width, height, borderColor, backgroundColor, "Main Window");
|
create_window(&myWindow, x, y, width, height, borderColor, backgroundColor, "Main Window");
|
||||||
|
|
||||||
// Print text inside the window
|
// Print text inside the window
|
||||||
print_set_color(PRINT_COLOR_WHITE, PRINT_COLOR_BLUE); // Set text color
|
print_set_color(PRINT_COLOR_WHITE, PRINT_COLOR_BLUE); // Set text color
|
||||||
print_text_in_window(&myWindow, 2, 2, "Window Manager is a ");
|
print_text_in_window(&myWindow, 2, 2, "Window Manager is a ");
|
||||||
print_text_in_window(&myWindow, 2, 3, "Work in progress, Sorry :("); // Print text inside the window
|
print_text_in_window(&myWindow, 2, 3, "Work in progress, Sorry :("); // Print text inside the window
|
||||||
print_text_in_window(&myWindow, 2, 4, "do [ cls ] to clear"); // Print text inside the window
|
print_text_in_window(&myWindow, 2, 4, "do [ cls ] to clear"); // Print text inside the window
|
||||||
|
}
|
||||||
|
else if (int_strncmp(command, "exit", 4) == 0)
|
||||||
|
{
|
||||||
} else if (int_strncmp(command, "exit", 4) == 0) {
|
|
||||||
printf("Driver Call [ shutdown_system(); ] \n");
|
printf("Driver Call [ shutdown_system(); ] \n");
|
||||||
shutdown_system();
|
shutdown_system();
|
||||||
|
}
|
||||||
|
else if (int_strncmp(command, "panic_test", 10) == 0)
|
||||||
} else if (int_strncmp(command, "panic_test", 10) == 0) {
|
{
|
||||||
int _y = 1/0;
|
int _y = 1 / 0;
|
||||||
printf("Output %d\n", _y);
|
printf("Output %d\n", _y);
|
||||||
|
}
|
||||||
} else if (int_strncmp(command, "test", 4) == 0) {
|
else if (int_strncmp(command, "test", 4) == 0)
|
||||||
|
{
|
||||||
|
|
||||||
//// Test custom malloc and free
|
//// Test custom malloc and free
|
||||||
//void* block1 = malloc(32);
|
// void* block1 = malloc(32);
|
||||||
//void* block2 = malloc(64);
|
// void* block2 = malloc(64);
|
||||||
//void* block3 = malloc(128);
|
// void* block3 = malloc(128);
|
||||||
//
|
//
|
||||||
//// List used blocks
|
//// List used blocks
|
||||||
//list_used_blocks();
|
// list_used_blocks();
|
||||||
//
|
//
|
||||||
//// Free a block and check again
|
//// Free a block and check again
|
||||||
//free(block2);
|
// free(block2);
|
||||||
//printf("\nAfter freeing block2:\n");
|
// printf("\nAfter freeing block2:\n");
|
||||||
//list_used_blocks();
|
// list_used_blocks();
|
||||||
//
|
//
|
||||||
//void* block4 = malloc(64);
|
// void* block4 = malloc(64);
|
||||||
//
|
//
|
||||||
//list_used_blocks();
|
// list_used_blocks();
|
||||||
|
|
||||||
|
|
||||||
create_game();
|
create_game();
|
||||||
|
}
|
||||||
} else if (int_strncmp(command, "split", 5) == 0) {
|
else if (int_strncmp(command, "split", 5) == 0)
|
||||||
|
{
|
||||||
printf("Kernel Call [ split_string(); ]\n");
|
printf("Kernel Call [ split_string(); ]\n");
|
||||||
|
|
||||||
// Check the length of the command string and use it properly
|
// Check the length of the command string and use it properly
|
||||||
char** new_command = split_string(command, ",", strlen(command));
|
char **new_command = split_string(command, ",", strlen(command));
|
||||||
|
|
||||||
//char** new_command = {{NULL, NULL, NULL, NULL}};
|
// char** new_command = {{NULL, NULL, NULL, NULL}};
|
||||||
|
|
||||||
if (new_command) {
|
if (new_command)
|
||||||
|
{
|
||||||
// Add a loop to print all the elements in the new_command array for debugging
|
// Add a loop to print all the elements in the new_command array for debugging
|
||||||
for (int i = 0; new_command[i] != NULL; i++) {
|
for (int i = 0; new_command[i] != NULL; i++)
|
||||||
|
{
|
||||||
printf("new_command[%d]: %s\n", i, new_command[i]);
|
printf("new_command[%d]: %s\n", i, new_command[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
//halt(); // Debug halt
|
// halt(); // Debug halt
|
||||||
|
|
||||||
// Ensure that new_command[1] exists before accessing it
|
// Ensure that new_command[1] exists before accessing it
|
||||||
if (new_command[1] != NULL) {
|
if (new_command[1] != NULL)
|
||||||
|
{
|
||||||
printf("%s\n", new_command[1]);
|
printf("%s\n", new_command[1]);
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
printf("Error: new_command[1] is NULL\n");
|
printf("Error: new_command[1] is NULL\n");
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
printf("Error: split_string returned NULL\n");
|
else
|
||||||
|
{
|
||||||
|
printf("Error: split_string returned NULL\n");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
} else {
|
|
||||||
printf("Unknown command: %s\n", command);
|
printf("Unknown command: %s\n", command);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void print_setup_prompt()
|
||||||
|
{
|
||||||
void print_setup_prompt() {
|
|
||||||
move_cursor(0, 0);
|
move_cursor(0, 0);
|
||||||
print_set_color(PRINT_COLOR_LIGHT_RED, PRINT_COLOR_BLACK);
|
print_set_color(PRINT_COLOR_LIGHT_RED, PRINT_COLOR_BLACK);
|
||||||
print_str("-------------------- ");
|
print_str("-------------------- ");
|
||||||
@ -197,34 +214,58 @@ void print_setup_prompt() {
|
|||||||
print_str("V 1.5.01\n");
|
print_str("V 1.5.01\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int test_basic()
|
||||||
|
{
|
||||||
|
InterpreterState state;
|
||||||
|
init_state(&state);
|
||||||
|
|
||||||
|
const char *program[] = {
|
||||||
|
"LET A = 10",
|
||||||
|
"LET B = 20",
|
||||||
|
"PRINT A + B",
|
||||||
|
"LET A = \"Hello\"",
|
||||||
|
"LET B = \" World\"",
|
||||||
|
"PRINT A + B",
|
||||||
|
"END",
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
for (size_t i = 0; i < sizeof(program) / sizeof(program[0]); i++)
|
||||||
|
{
|
||||||
|
execute_line(&state, program[i]);
|
||||||
|
if (!state.running)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void kernel_main()
|
||||||
|
{
|
||||||
|
|
||||||
void kernel_main() {
|
|
||||||
|
|
||||||
init_keyboard_driver();
|
init_keyboard_driver();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
idt_install();
|
idt_install();
|
||||||
|
|
||||||
|
|
||||||
print_str("[ WARN ] Skipping File System Initialization...\n[ INFO ] Do [ fsinit ] to initalize the filesystem\n");
|
print_str("[ WARN ] Skipping File System Initialization...\n[ INFO ] Do [ fsinit ] to initalize the filesystem\n");
|
||||||
|
|
||||||
if (fat12_init() == 0) {
|
if (fat12_init() == 0)
|
||||||
|
{
|
||||||
printf("Filesystem mounted\n");
|
printf("Filesystem mounted\n");
|
||||||
|
|
||||||
fat12_read_root_directory();
|
fat12_read_root_directory();
|
||||||
|
|
||||||
fat12_dir_entry_t entry;
|
fat12_dir_entry_t entry;
|
||||||
if (fat12_find_file("HELLOTXT", &entry)) {
|
if (fat12_find_file("HELLOTXT", &entry))
|
||||||
|
{
|
||||||
printf("File found: HELLO.TXT\n");
|
printf("File found: HELLO.TXT\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
clear();
|
||||||
|
|
||||||
print_setup_prompt();
|
|
||||||
|
|
||||||
|
test_basic();
|
||||||
|
|
||||||
|
print_setup_prompt();
|
||||||
|
|
||||||
print_str(" > ");
|
print_str(" > ");
|
||||||
|
|
||||||
@ -232,57 +273,64 @@ void kernel_main() {
|
|||||||
char key;
|
char key;
|
||||||
bool keydown = false;
|
bool keydown = false;
|
||||||
char commandBuffer[COMMAND_BUFFER_SIZE];
|
char commandBuffer[COMMAND_BUFFER_SIZE];
|
||||||
size_t commandLength = 0; // To track the length of the current command
|
size_t commandLength = 0; // To track the length of the current command
|
||||||
|
|
||||||
|
while (1)
|
||||||
while (1) {
|
{
|
||||||
key = read_key();
|
key = read_key();
|
||||||
|
|
||||||
if (key != 0) {
|
if (key != 0)
|
||||||
if (!keydown) {
|
{
|
||||||
|
if (!keydown)
|
||||||
|
{
|
||||||
CursorPosition pos = get_print_cursor_pos();
|
CursorPosition pos = get_print_cursor_pos();
|
||||||
move_cursor(pos.x,pos.y);
|
move_cursor(pos.x, pos.y);
|
||||||
if (key == 10) { // Enter key
|
if (key == 10)
|
||||||
commandBuffer[commandLength] = '\0'; // Null-terminate the command
|
{ // Enter key
|
||||||
|
commandBuffer[commandLength] = '\0'; // Null-terminate the command
|
||||||
commandHandler(commandBuffer);
|
commandHandler(commandBuffer);
|
||||||
|
|
||||||
// Reset command buffer for the next input
|
// Reset command buffer for the next input
|
||||||
commandLength = 0;
|
commandLength = 0;
|
||||||
print_str(" > ");
|
print_str(" > ");
|
||||||
|
}
|
||||||
} else if (key == BACKSPACE_KEY) { // Backspace key
|
else if (key == BACKSPACE_KEY)
|
||||||
if (commandLength > 0) {
|
{ // Backspace key
|
||||||
|
if (commandLength > 0)
|
||||||
|
{
|
||||||
// Remove the last character from the buffer
|
// Remove the last character from the buffer
|
||||||
commandLength--;
|
commandLength--;
|
||||||
commandBuffer[commandLength] = '0'; // Null-terminate after removal
|
commandBuffer[commandLength] = '0'; // Null-terminate after removal
|
||||||
|
|
||||||
// Clear the character from the screen (overwrite with space)
|
// Clear the character from the screen (overwrite with space)
|
||||||
// Move cursor back one position
|
// Move cursor back one position
|
||||||
offset_print_cursor(-1,0);
|
offset_print_cursor(-1, 0);
|
||||||
print_char(' '); // Overwrite the character
|
print_char(' '); // Overwrite the character
|
||||||
offset_print_cursor(-1,0); // Move cursor back one position(because its moved left one by the rpintf)
|
offset_print_cursor(-1, 0); // Move cursor back one position(because its moved left one by the rpintf)
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} else {
|
else
|
||||||
if (key >= 32 && key <= 126) { // Check if the key is a printable character
|
{
|
||||||
if (commandLength < COMMAND_BUFFER_SIZE - 1) {
|
if (key >= 32 && key <= 126)
|
||||||
commandBuffer[commandLength++] = key; // Append character to buffer
|
{ // Check if the key is a printable character
|
||||||
|
if (commandLength < COMMAND_BUFFER_SIZE - 1)
|
||||||
|
{
|
||||||
|
commandBuffer[commandLength++] = key; // Append character to buffer
|
||||||
commandBuffer[commandLength] = '\0'; // Null-terminate the buffer
|
commandBuffer[commandLength] = '\0'; // Null-terminate the buffer
|
||||||
print_char(key); // Print key to the screen
|
print_char(key); // Print key to the screen
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
keydown = true;
|
keydown = true;
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
keydown = false;
|
keydown = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// int x = 100/0;
|
// int x = 100/0;
|
||||||
}
|
}
|
||||||
|
|
||||||
kpanic(2);
|
kpanic(2);
|
||||||
|
|
||||||
}
|
}
|
184
src/impl/x86_64/basic.c
Normal file
184
src/impl/x86_64/basic.c
Normal file
@ -0,0 +1,184 @@
|
|||||||
|
#include "memory.h"
|
||||||
|
#include "print.h"
|
||||||
|
#include "strings.h"
|
||||||
|
#include "stdint.h"
|
||||||
|
#include "stddef.h"
|
||||||
|
#include "basic.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Utility: Find or create a variable by name
|
||||||
|
Variable* get_variable(InterpreterState* state, const char* name) {
|
||||||
|
for (size_t i = 0; i < state->variable_count; i++) {
|
||||||
|
if (strcmp(state->variables[i].name, name) == 0) {
|
||||||
|
return &state->variables[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (state->variable_count < MAX_VARIABLES) {
|
||||||
|
Variable* var = &state->variables[state->variable_count++];
|
||||||
|
strncpy(var->name, name, sizeof(var->name) - 1);
|
||||||
|
var->name[sizeof(var->name) - 1] = '\0';
|
||||||
|
var->value = 0;
|
||||||
|
var->str_value = NULL;
|
||||||
|
return var;
|
||||||
|
}
|
||||||
|
return NULL; // No space for more variables
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse an integer from a string, skipping leading whitespace
|
||||||
|
int parse_int(const char* str) {
|
||||||
|
while (*str == ' ') str++; // Skip leading spaces
|
||||||
|
int result = 0;
|
||||||
|
int sign = 1;
|
||||||
|
if (*str == '-') {
|
||||||
|
sign = -1;
|
||||||
|
str++;
|
||||||
|
}
|
||||||
|
while (*str >= '0' && *str <= '9') {
|
||||||
|
result = result * 10 + (*str - '0');
|
||||||
|
str++;
|
||||||
|
}
|
||||||
|
return result * sign;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const char* evaluate_expression(InterpreterState* state, const char* expr) {
|
||||||
|
char buffer[64];
|
||||||
|
strncpy(buffer, expr, sizeof(buffer) - 1);
|
||||||
|
buffer[sizeof(buffer) - 1] = '\0';
|
||||||
|
|
||||||
|
char* plus = strrchr(buffer, '+');
|
||||||
|
if (plus) {
|
||||||
|
*plus = '\0';
|
||||||
|
|
||||||
|
// Evaluate the left and right sides only once
|
||||||
|
const char* left = evaluate_expression(state, buffer);
|
||||||
|
const char* right = evaluate_expression(state, plus + 1);
|
||||||
|
|
||||||
|
// Debug output
|
||||||
|
printf("DEBUG: Left operand: %s\n", left);
|
||||||
|
printf("DEBUG: Right operand: %s\n", right);
|
||||||
|
|
||||||
|
// Check if both sides are numeric
|
||||||
|
int left_is_number = (left[0] >= '0' && left[0] <= '9') || (left[0] == '-' && left[1] >= '0' && left[1] <= '9');
|
||||||
|
int right_is_number = (right[0] >= '0' && right[0] <= '9') || (right[0] == '-' && right[1] >= '0' && right[1] <= '9');
|
||||||
|
|
||||||
|
static char result[128];
|
||||||
|
|
||||||
|
if (left_is_number && right_is_number) {
|
||||||
|
// Parse the left and right operands
|
||||||
|
int left_value = parse_int(left);
|
||||||
|
int right_value = parse_int(right);
|
||||||
|
|
||||||
|
// Correct addition logic
|
||||||
|
int sum = left_value + right_value;
|
||||||
|
|
||||||
|
// Debug addition
|
||||||
|
printf("DEBUG: Adding %d + %d = %d\n", left_value, right_value, sum);
|
||||||
|
|
||||||
|
// Format the result as a string
|
||||||
|
snprintf(result, sizeof(result), "%d", sum);
|
||||||
|
} else {
|
||||||
|
// Concatenate strings
|
||||||
|
snprintf(result, sizeof(result), "%s%s", left, right);
|
||||||
|
|
||||||
|
// Debug string concatenation
|
||||||
|
printf("DEBUG: Concatenating strings: %s + %s = %s\n", left, right, result);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Trim leading and trailing spaces
|
||||||
|
const char* start = buffer;
|
||||||
|
while (*start == ' ') start++;
|
||||||
|
|
||||||
|
char* end = buffer + strlen(buffer) - 1;
|
||||||
|
while (end > start && *end == ' ') *end-- = '\0';
|
||||||
|
|
||||||
|
if (start[0] >= 'A' && start[0] <= 'Z') {
|
||||||
|
Variable* var = get_variable(state, start);
|
||||||
|
if (var) {
|
||||||
|
static char var_result[64];
|
||||||
|
if (var->str_value) {
|
||||||
|
strncpy(var_result, var->str_value, sizeof(var_result) - 1);
|
||||||
|
var_result[sizeof(var_result) - 1] = '\0';
|
||||||
|
return var_result;
|
||||||
|
} else {
|
||||||
|
snprintf(var_result, sizeof(var_result), "%d", var->value);
|
||||||
|
return var_result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (start[0] == '"') {
|
||||||
|
// String literal
|
||||||
|
size_t len = strlen(start);
|
||||||
|
if (start[len - 1] == '"') {
|
||||||
|
static char str_result[64];
|
||||||
|
strncpy(str_result, start + 1, len - 2);
|
||||||
|
str_result[len - 2] = '\0';
|
||||||
|
return str_result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static char int_result[16];
|
||||||
|
snprintf(int_result, sizeof(int_result), "%d", parse_int(start));
|
||||||
|
return int_result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Interpret a single line of code
|
||||||
|
void interpret_line(InterpreterState* state, const char* line) {
|
||||||
|
if (strncmp(line, "LET", 3) == 0) {
|
||||||
|
const char* rest = line + 3;
|
||||||
|
while (*rest == ' ') rest++;
|
||||||
|
const char* equals = strchr(rest, '=');
|
||||||
|
if (!equals) return;
|
||||||
|
|
||||||
|
char var_name[16];
|
||||||
|
strncpy(var_name, rest, equals - rest);
|
||||||
|
var_name[equals - rest] = '\0';
|
||||||
|
|
||||||
|
// Trim trailing spaces from var_name
|
||||||
|
size_t len = strlen(var_name);
|
||||||
|
while (len > 0 && var_name[len - 1] == ' ') {
|
||||||
|
var_name[--len] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
Variable* var = get_variable(state, var_name);
|
||||||
|
if (var) {
|
||||||
|
const char* value = evaluate_expression(state, equals + 1);
|
||||||
|
if (value[0] >= '0' && value[0] <= '9') {
|
||||||
|
var->value = parse_int(value);
|
||||||
|
var->str_value = NULL;
|
||||||
|
} else {
|
||||||
|
var->str_value = malloc(strlen(value) + 1);
|
||||||
|
strcpy(var->str_value, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (strncmp(line, "PRINT", 5) == 0) {
|
||||||
|
const char* rest = line + 5;
|
||||||
|
while (*rest == ' ') rest++;
|
||||||
|
const char* value = evaluate_expression(state, rest);
|
||||||
|
printf("%s\n", value);
|
||||||
|
} else if (strncmp(line, "END", 3) == 0) {
|
||||||
|
printf("Program terminated.\n");
|
||||||
|
state->running = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize interpreter state
|
||||||
|
void init_state(InterpreterState* state) {
|
||||||
|
state->variable_count = 0;
|
||||||
|
state->running = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Execute a single line in the context of a state
|
||||||
|
void execute_line(InterpreterState* state, const char* line) {
|
||||||
|
printf("Executing line: %s\n", line); // Debugging
|
||||||
|
interpret_line(state, line);
|
||||||
|
}
|
||||||
|
|
@ -1,139 +1,139 @@
|
|||||||
; isr.asm - ISR assembly stubs
|
; isr.asm - ISR assembly stubs
|
||||||
|
|
||||||
global isr0, isr1, isr2, isr3, isr4, isr5, isr6, isr7, isr8, isr9, isr10, isr11, isr12, isr13, isr14, isr15
|
global isr0, isr1, isr2, isr3, isr4, isr5, isr6, isr7, isr8, isr9, isr10, isr11, isr12, isr13, isr14, isr15
|
||||||
global isr16, isr17, isr18, isr19, isr20, isr21, isr22, isr23, isr24, isr25, isr26, isr27, isr28, isr29, isr30, isr31
|
global isr16, isr17, isr18, isr19, isr20, isr21, isr22, isr23, isr24, isr25, isr26, isr27, isr28, isr29, isr30, isr31
|
||||||
extern isr_common_handler
|
extern isr_common_handler
|
||||||
|
|
||||||
section .text
|
section .text
|
||||||
|
|
||||||
; ISRs 0 to 13 (no error code pushed by CPU)
|
; ISRs 0 to 13 (no error code pushed by CPU)
|
||||||
isr0:
|
isr0:
|
||||||
cli
|
cli
|
||||||
push 0 ; Push error code (none for isr0)
|
push 0 ; Push error code (none for isr0)
|
||||||
push 0 ; Push interrupt number
|
push 0 ; Push interrupt number
|
||||||
jmp isr_common_handler
|
jmp isr_common_handler
|
||||||
|
|
||||||
isr1:
|
isr1:
|
||||||
cli
|
cli
|
||||||
push 0
|
push 0
|
||||||
push 1
|
push 1
|
||||||
jmp isr_common_handler
|
jmp isr_common_handler
|
||||||
|
|
||||||
isr2:
|
isr2:
|
||||||
cli
|
cli
|
||||||
push 0
|
push 0
|
||||||
push 2
|
push 2
|
||||||
jmp isr_common_handler
|
jmp isr_common_handler
|
||||||
|
|
||||||
isr3:
|
isr3:
|
||||||
cli
|
cli
|
||||||
push 0
|
push 0
|
||||||
push 3
|
push 3
|
||||||
jmp isr_common_handler
|
jmp isr_common_handler
|
||||||
|
|
||||||
isr4:
|
isr4:
|
||||||
cli
|
cli
|
||||||
push 0
|
push 0
|
||||||
push 4
|
push 4
|
||||||
jmp isr_common_handler
|
jmp isr_common_handler
|
||||||
|
|
||||||
isr5:
|
isr5:
|
||||||
cli
|
cli
|
||||||
push 0
|
push 0
|
||||||
push 5
|
push 5
|
||||||
jmp isr_common_handler
|
jmp isr_common_handler
|
||||||
|
|
||||||
isr6:
|
isr6:
|
||||||
cli
|
cli
|
||||||
push 0
|
push 0
|
||||||
push 6
|
push 6
|
||||||
jmp isr_common_handler
|
jmp isr_common_handler
|
||||||
|
|
||||||
isr7:
|
isr7:
|
||||||
cli
|
cli
|
||||||
push 0
|
push 0
|
||||||
push 7
|
push 7
|
||||||
jmp isr_common_handler
|
jmp isr_common_handler
|
||||||
|
|
||||||
isr8:
|
isr8:
|
||||||
cli
|
cli
|
||||||
push 0
|
push 0
|
||||||
push 8
|
push 8
|
||||||
jmp isr_common_handler
|
jmp isr_common_handler
|
||||||
|
|
||||||
isr9:
|
isr9:
|
||||||
cli
|
cli
|
||||||
push 0
|
push 0
|
||||||
push 9
|
push 9
|
||||||
jmp isr_common_handler
|
jmp isr_common_handler
|
||||||
|
|
||||||
isr10:
|
isr10:
|
||||||
cli
|
cli
|
||||||
push 0
|
push 0
|
||||||
push 10
|
push 10
|
||||||
jmp isr_common_handler
|
jmp isr_common_handler
|
||||||
|
|
||||||
isr11:
|
isr11:
|
||||||
cli
|
cli
|
||||||
push 0
|
push 0
|
||||||
push 11
|
push 11
|
||||||
jmp isr_common_handler
|
jmp isr_common_handler
|
||||||
|
|
||||||
isr12:
|
isr12:
|
||||||
cli
|
cli
|
||||||
push 0
|
push 0
|
||||||
push 12
|
push 12
|
||||||
jmp isr_common_handler
|
jmp isr_common_handler
|
||||||
|
|
||||||
isr13:
|
isr13:
|
||||||
cli
|
cli
|
||||||
push 0
|
push 0
|
||||||
push 13
|
push 13
|
||||||
jmp isr_common_handler
|
jmp isr_common_handler
|
||||||
|
|
||||||
; ISR 14 (Page Fault) requires error code pushed by CPU
|
; ISR 14 (Page Fault) requires error code pushed by CPU
|
||||||
isr14:
|
isr14:
|
||||||
cli
|
cli
|
||||||
push 14 ; Push interrupt number
|
push 14 ; Push interrupt number
|
||||||
jmp isr_common_handler
|
jmp isr_common_handler
|
||||||
|
|
||||||
; ISRs 15 to 31 (no error code pushed by CPU)
|
; ISRs 15 to 31 (no error code pushed by CPU)
|
||||||
isr15:
|
isr15:
|
||||||
cli
|
cli
|
||||||
push 0
|
push 0
|
||||||
push 15
|
push 15
|
||||||
jmp isr_common_handler
|
jmp isr_common_handler
|
||||||
|
|
||||||
isr16:
|
isr16:
|
||||||
cli
|
cli
|
||||||
push 0
|
push 0
|
||||||
push 16
|
push 16
|
||||||
jmp isr_common_handler
|
jmp isr_common_handler
|
||||||
|
|
||||||
isr17:
|
isr17:
|
||||||
cli
|
cli
|
||||||
push 0
|
push 0
|
||||||
push 17
|
push 17
|
||||||
jmp isr_common_handler
|
jmp isr_common_handler
|
||||||
|
|
||||||
isr18:
|
isr18:
|
||||||
cli
|
cli
|
||||||
push 0
|
push 0
|
||||||
push 18
|
push 18
|
||||||
jmp isr_common_handler
|
jmp isr_common_handler
|
||||||
|
|
||||||
isr19:
|
isr19:
|
||||||
cli
|
cli
|
||||||
push 0
|
push 0
|
||||||
push 19
|
push 19
|
||||||
jmp isr_common_handler
|
jmp isr_common_handler
|
||||||
|
|
||||||
isr20:
|
isr20:
|
||||||
cli
|
cli
|
||||||
push 0
|
push 0
|
||||||
push 20
|
push 20
|
||||||
jmp isr_common_handler
|
jmp isr_common_handler
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1,43 +1,43 @@
|
|||||||
// disk_io.c
|
// disk_io.c
|
||||||
|
|
||||||
#include "disk_io.h"
|
#include "disk_io.h"
|
||||||
#include "print.h" // Assuming you have a function for kernel printing
|
#include "print.h" // Assuming you have a function for kernel printing
|
||||||
|
|
||||||
#define SECTOR_SIZE 512
|
#define SECTOR_SIZE 512
|
||||||
|
|
||||||
// Function to read sectors from disk
|
// Function to read sectors from disk
|
||||||
int disk_read(uint32_t lba, void *buffer, uint32_t size) {
|
int disk_read(uint32_t lba, void *buffer, uint32_t size) {
|
||||||
// lba: logical block address
|
// lba: logical block address
|
||||||
// buffer: where to store the read data
|
// buffer: where to store the read data
|
||||||
// size: number of bytes to read
|
// size: number of bytes to read
|
||||||
|
|
||||||
if (size % SECTOR_SIZE != 0) {
|
if (size % SECTOR_SIZE != 0) {
|
||||||
printf("Read size must be a multiple of 512 bytes\n");
|
printf("Read size must be a multiple of 512 bytes\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (uint32_t i = 0; i < size / SECTOR_SIZE; i++) {
|
for (uint32_t i = 0; i < size / SECTOR_SIZE; i++) {
|
||||||
// Placeholder for actual disk sector read. Replace with proper implementation
|
// Placeholder for actual disk sector read. Replace with proper implementation
|
||||||
if (!bios_read_sector(lba + i, buffer + (i * SECTOR_SIZE))) {
|
if (!bios_read_sector(lba + i, buffer + (i * SECTOR_SIZE))) {
|
||||||
printf("Error reading sector from disk\n");
|
printf("Error reading sector from disk\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Placeholder function to simulate reading sectors from the disk
|
// Placeholder function to simulate reading sectors from the disk
|
||||||
// Replace this with actual disk reading logic depending on the platform
|
// Replace this with actual disk reading logic depending on the platform
|
||||||
int bios_read_sector(uint32_t lba, void *buffer) {
|
int bios_read_sector(uint32_t lba, void *buffer) {
|
||||||
// Simulate disk sector read
|
// Simulate disk sector read
|
||||||
// In an actual kernel, you'd use interrupts or other mechanisms to read from disk
|
// In an actual kernel, you'd use interrupts or other mechanisms to read from disk
|
||||||
|
|
||||||
// For now, just zero out the buffer to simulate
|
// For now, just zero out the buffer to simulate
|
||||||
for (int i = 0; i < SECTOR_SIZE; i++) {
|
for (int i = 0; i < SECTOR_SIZE; i++) {
|
||||||
((uint8_t*)buffer)[i] = 0; // Fill buffer with zeros
|
((uint8_t*)buffer)[i] = 0; // Fill buffer with zeros
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1; // Success
|
return 1; // Success
|
||||||
}
|
}
|
||||||
|
|
@ -334,6 +334,48 @@ int my_sscanf(const char *input, const char *format, char *output) {
|
|||||||
return match_count;
|
return match_count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
snprintf(char* buffer, size_t size, const char* format, ...) {
|
||||||
|
va_list args;
|
||||||
|
va_start(args, format);
|
||||||
|
|
||||||
|
const char* traverse = format;
|
||||||
|
size_t written = 0;
|
||||||
|
|
||||||
|
while (*traverse && written < size - 1) {
|
||||||
|
if (*traverse == '%' && *(traverse + 1)) {
|
||||||
|
traverse++;
|
||||||
|
if (*traverse == 's') {
|
||||||
|
const char* str = va_arg(args, const char*);
|
||||||
|
while (*str && written < size - 1) {
|
||||||
|
buffer[written++] = *str++;
|
||||||
|
}
|
||||||
|
} else if (*traverse == 'd') {
|
||||||
|
int num = va_arg(args, int);
|
||||||
|
char num_buffer[16];
|
||||||
|
int num_len = 0;
|
||||||
|
if (num < 0) {
|
||||||
|
if (written < size - 1) buffer[written++] = '-';
|
||||||
|
num = -num;
|
||||||
|
}
|
||||||
|
do {
|
||||||
|
num_buffer[num_len++] = '0' + (num % 10);
|
||||||
|
num /= 10;
|
||||||
|
} while (num > 0);
|
||||||
|
while (num_len > 0 && written < size - 1) {
|
||||||
|
buffer[written++] = num_buffer[--num_len];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
buffer[written++] = *traverse;
|
||||||
|
}
|
||||||
|
traverse++;
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer[written] = '\0';
|
||||||
|
va_end(args);
|
||||||
|
return written;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void printf(const char* format, ...) {
|
void printf(const char* format, ...) {
|
||||||
va_list args;
|
va_list args;
|
@ -1,80 +1,80 @@
|
|||||||
#include "vector.h"
|
#include "vector.h"
|
||||||
|
|
||||||
// Initial capacity for a new vector
|
// Initial capacity for a new vector
|
||||||
#define VECTOR_INITIAL_CAPACITY 4
|
#define VECTOR_INITIAL_CAPACITY 4
|
||||||
|
|
||||||
// Create a new vector
|
// Create a new vector
|
||||||
vector* vector_create() {
|
vector* vector_create() {
|
||||||
vector* v = (vector*)malloc(sizeof(vector));
|
vector* v = (vector*)malloc(sizeof(vector));
|
||||||
if (!v) return NULL; // Return NULL if allocation fails
|
if (!v) return NULL; // Return NULL if allocation fails
|
||||||
|
|
||||||
v->capacity = VECTOR_INITIAL_CAPACITY;
|
v->capacity = VECTOR_INITIAL_CAPACITY;
|
||||||
v->size = 0;
|
v->size = 0;
|
||||||
v->items = (void**)malloc(sizeof(void*) * v->capacity);
|
v->items = (void**)malloc(sizeof(void*) * v->capacity);
|
||||||
if (!v->items) {
|
if (!v->items) {
|
||||||
free(v); // Free the vector if item allocation fails
|
free(v); // Free the vector if item allocation fails
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Destroy the vector and free allocated memory
|
// Destroy the vector and free allocated memory
|
||||||
void vector_destroy(vector* v) {
|
void vector_destroy(vector* v) {
|
||||||
if (v) {
|
if (v) {
|
||||||
free(v->items);
|
free(v->items);
|
||||||
free(v);
|
free(v);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Push an item to the back of the vector
|
// Push an item to the back of the vector
|
||||||
int vector_push_back(vector* v, void* item) {
|
int vector_push_back(vector* v, void* item) {
|
||||||
// Resize the vector if it's full
|
// Resize the vector if it's full
|
||||||
if (v->size == v->capacity) {
|
if (v->size == v->capacity) {
|
||||||
if (vector_resize(v, v->capacity * 2) != 0) {
|
if (vector_resize(v, v->capacity * 2) != 0) {
|
||||||
return -1; // Return -1 on failure to resize
|
return -1; // Return -1 on failure to resize
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
v->items[v->size++] = item; // Add the new item
|
v->items[v->size++] = item; // Add the new item
|
||||||
return 0; // Success
|
return 0; // Success
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the item at a specific index
|
// Get the item at a specific index
|
||||||
void* vector_get(vector* v, size_t index) {
|
void* vector_get(vector* v, size_t index) {
|
||||||
if (index >= v->size) return NULL; // Return NULL if index is out of bounds
|
if (index >= v->size) return NULL; // Return NULL if index is out of bounds
|
||||||
return v->items[index];
|
return v->items[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set an item at a specific index
|
// Set an item at a specific index
|
||||||
int vector_set(vector* v, size_t index, void* item) {
|
int vector_set(vector* v, size_t index, void* item) {
|
||||||
if (index >= v->size) return -1; // Return -1 if index is out of bounds
|
if (index >= v->size) return -1; // Return -1 if index is out of bounds
|
||||||
v->items[index] = item;
|
v->items[index] = item;
|
||||||
return 0; // Success
|
return 0; // Success
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the size of the vector
|
// Get the size of the vector
|
||||||
size_t vector_size(vector* v) {
|
size_t vector_size(vector* v) {
|
||||||
return v->size;
|
return v->size;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Resize the vector's internal array
|
// Resize the vector's internal array
|
||||||
int vector_resize(vector* v, size_t new_capacity) {
|
int vector_resize(vector* v, size_t new_capacity) {
|
||||||
// Allocate new memory for the resized array
|
// Allocate new memory for the resized array
|
||||||
void** new_items = (void**)malloc(sizeof(void*) * new_capacity);
|
void** new_items = (void**)malloc(sizeof(void*) * new_capacity);
|
||||||
if (!new_items) return -1; // Return -1 on failure
|
if (!new_items) return -1; // Return -1 on failure
|
||||||
|
|
||||||
// Copy the old items into the new array
|
// Copy the old items into the new array
|
||||||
for (size_t i = 0; i < v->size; i++) {
|
for (size_t i = 0; i < v->size; i++) {
|
||||||
new_items[i] = v->items[i];
|
new_items[i] = v->items[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Free the old memory
|
// Free the old memory
|
||||||
free(v->items);
|
free(v->items);
|
||||||
|
|
||||||
// Update the vector's internal state
|
// Update the vector's internal state
|
||||||
v->items = new_items;
|
v->items = new_items;
|
||||||
v->capacity = new_capacity;
|
v->capacity = new_capacity;
|
||||||
|
|
||||||
return 0; // Success
|
return 0; // Success
|
||||||
}
|
}
|
@ -1,185 +1,185 @@
|
|||||||
#include "game.h"
|
#include "game.h"
|
||||||
#include "print.h"
|
#include "print.h"
|
||||||
#include "keydriver.h"
|
#include "keydriver.h"
|
||||||
#include "strings.h"
|
#include "strings.h"
|
||||||
#include "stdint.h"
|
#include "stdint.h"
|
||||||
|
|
||||||
// Define constants for the game
|
// Define constants for the game
|
||||||
#define ROOM_COUNT 5
|
#define ROOM_COUNT 5
|
||||||
#define INVENTORY_SIZE 5
|
#define INVENTORY_SIZE 5
|
||||||
|
|
||||||
// Global variable to hold the game state
|
// Global variable to hold the game state
|
||||||
static GameState game_state;
|
static GameState game_state;
|
||||||
|
|
||||||
// Room descriptions and connected rooms
|
// Room descriptions and connected rooms
|
||||||
typedef struct {
|
typedef struct {
|
||||||
const char* description;
|
const char* description;
|
||||||
int north;
|
int north;
|
||||||
int south;
|
int south;
|
||||||
int east;
|
int east;
|
||||||
int west;
|
int west;
|
||||||
} Room;
|
} Room;
|
||||||
|
|
||||||
static const Room rooms[ROOM_COUNT] = {
|
static const Room rooms[ROOM_COUNT] = {
|
||||||
{ "You are in a dark forest. There are paths to the north and east.", 1, -1, 2, -1 },
|
{ "You are in a dark forest. There are paths to the north and east.", 1, -1, 2, -1 },
|
||||||
{ "You are on a beach. There is a cave to the west.", -1, 0, -1, 3 },
|
{ "You are on a beach. There is a cave to the west.", -1, 0, -1, 3 },
|
||||||
{ "You are inside a cave. It’s damp and dark.", -1, -1, -1, 0 },
|
{ "You are inside a cave. It’s damp and dark.", -1, -1, -1, 0 },
|
||||||
{ "You are in a small village. There's a shop to the north and a forest to the east.", 4, -1, -1, -1 },
|
{ "You are in a small village. There's a shop to the north and a forest to the east.", 4, -1, -1, -1 },
|
||||||
{ "You are in a shop filled with various items. The village is to the south.", -1, 3, -1, -1 }
|
{ "You are in a shop filled with various items. The village is to the south.", -1, 3, -1, -1 }
|
||||||
};
|
};
|
||||||
|
|
||||||
// Player's inventory
|
// Player's inventory
|
||||||
static const char* inventory[INVENTORY_SIZE];
|
static const char* inventory[INVENTORY_SIZE];
|
||||||
static int inventory_count = 0;
|
static int inventory_count = 0;
|
||||||
|
|
||||||
// Command buffer
|
// Command buffer
|
||||||
static char commandBuffer[MAX_COMMAND_LENGTH];
|
static char commandBuffer[MAX_COMMAND_LENGTH];
|
||||||
static size_t commandLength = 0;
|
static size_t commandLength = 0;
|
||||||
|
|
||||||
bool keydown = false;
|
bool keydown = false;
|
||||||
|
|
||||||
// Function to handle user input commands
|
// Function to handle user input commands
|
||||||
void handle_command(const char* command) {
|
void handle_command(const char* command) {
|
||||||
|
|
||||||
|
|
||||||
game_clear();
|
game_clear();
|
||||||
|
|
||||||
|
|
||||||
if (strcmp(command, "look") == 0) {
|
if (strcmp(command, "look") == 0) {
|
||||||
printf(rooms[game_state.current_room].description);
|
printf(rooms[game_state.current_room].description);
|
||||||
printf("\n");
|
printf("\n");
|
||||||
} else if (strcmp(command, "north") == 0) {
|
} else if (strcmp(command, "north") == 0) {
|
||||||
if (rooms[game_state.current_room].north != -1) {
|
if (rooms[game_state.current_room].north != -1) {
|
||||||
game_state.current_room = rooms[game_state.current_room].north;
|
game_state.current_room = rooms[game_state.current_room].north;
|
||||||
printf("You walk north.\n");
|
printf("You walk north.\n");
|
||||||
printf("%s\n", rooms[game_state.current_room].description);
|
printf("%s\n", rooms[game_state.current_room].description);
|
||||||
} else {
|
} else {
|
||||||
printf("You can't go that way.\n");
|
printf("You can't go that way.\n");
|
||||||
}
|
}
|
||||||
} else if (strcmp(command, "south") == 0) {
|
} else if (strcmp(command, "south") == 0) {
|
||||||
if (rooms[game_state.current_room].south != -1) {
|
if (rooms[game_state.current_room].south != -1) {
|
||||||
game_state.current_room = rooms[game_state.current_room].south;
|
game_state.current_room = rooms[game_state.current_room].south;
|
||||||
printf("You walk south.\n");
|
printf("You walk south.\n");
|
||||||
printf("%s\n", rooms[game_state.current_room].description);
|
printf("%s\n", rooms[game_state.current_room].description);
|
||||||
} else {
|
} else {
|
||||||
printf("You can't go that way.\n");
|
printf("You can't go that way.\n");
|
||||||
}
|
}
|
||||||
} else if (strcmp(command, "east") == 0) {
|
} else if (strcmp(command, "east") == 0) {
|
||||||
if (rooms[game_state.current_room].east != -1) {
|
if (rooms[game_state.current_room].east != -1) {
|
||||||
game_state.current_room = rooms[game_state.current_room].east;
|
game_state.current_room = rooms[game_state.current_room].east;
|
||||||
printf("You walk east.\n");
|
printf("You walk east.\n");
|
||||||
printf("%s\n", rooms[game_state.current_room].description);
|
printf("%s\n", rooms[game_state.current_room].description);
|
||||||
} else {
|
} else {
|
||||||
printf("You can't go that way.\n");
|
printf("You can't go that way.\n");
|
||||||
}
|
}
|
||||||
} else if (strcmp(command, "west") == 0) {
|
} else if (strcmp(command, "west") == 0) {
|
||||||
if (rooms[game_state.current_room].west != -1) {
|
if (rooms[game_state.current_room].west != -1) {
|
||||||
game_state.current_room = rooms[game_state.current_room].west;
|
game_state.current_room = rooms[game_state.current_room].west;
|
||||||
printf("You walk west.\n");
|
printf("You walk west.\n");
|
||||||
printf("%s\n", rooms[game_state.current_room].description);
|
printf("%s\n", rooms[game_state.current_room].description);
|
||||||
} else {
|
} else {
|
||||||
printf("You can't go that way.\n");
|
printf("You can't go that way.\n");
|
||||||
}
|
}
|
||||||
} else if (strcmp(command, "inventory") == 0) {
|
} else if (strcmp(command, "inventory") == 0) {
|
||||||
printf("You are carrying:\n");
|
printf("You are carrying:\n");
|
||||||
for (int i = 0; i < inventory_count; ++i) {
|
for (int i = 0; i < inventory_count; ++i) {
|
||||||
printf("- %s\n", inventory[i]);
|
printf("- %s\n", inventory[i]);
|
||||||
}
|
}
|
||||||
if (inventory_count == 0) {
|
if (inventory_count == 0) {
|
||||||
printf("Nothing.\n");
|
printf("Nothing.\n");
|
||||||
}
|
}
|
||||||
} else if (strcmp(command, "take key") == 0) {
|
} else if (strcmp(command, "take key") == 0) {
|
||||||
if (game_state.current_room == 1) {
|
if (game_state.current_room == 1) {
|
||||||
if (inventory_count < INVENTORY_SIZE) {
|
if (inventory_count < INVENTORY_SIZE) {
|
||||||
inventory[inventory_count++] = "key";
|
inventory[inventory_count++] = "key";
|
||||||
printf("You picked up a key.\n");
|
printf("You picked up a key.\n");
|
||||||
} else {
|
} else {
|
||||||
printf("Your inventory is full.\n");
|
printf("Your inventory is full.\n");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
printf("There is no key here.\n");
|
printf("There is no key here.\n");
|
||||||
}
|
}
|
||||||
} else if (strcmp(command, "use key") == 0) {
|
} else if (strcmp(command, "use key") == 0) {
|
||||||
bool has_key = false;
|
bool has_key = false;
|
||||||
for (int i = 0; i < inventory_count; ++i) {
|
for (int i = 0; i < inventory_count; ++i) {
|
||||||
if (strcmp(inventory[i], "key") == 0) {
|
if (strcmp(inventory[i], "key") == 0) {
|
||||||
has_key = true;
|
has_key = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (has_key && game_state.current_room == 2) {
|
if (has_key && game_state.current_room == 2) {
|
||||||
printf("You unlock the door in the cave and find a treasure!\n");
|
printf("You unlock the door in the cave and find a treasure!\n");
|
||||||
game_state.game_active = false; // End the game
|
game_state.game_active = false; // End the game
|
||||||
} else {
|
} else {
|
||||||
printf("You can't use the key here.\n");
|
printf("You can't use the key here.\n");
|
||||||
}
|
}
|
||||||
} else if (strcmp(command, "quit") == 0) {
|
} else if (strcmp(command, "quit") == 0) {
|
||||||
printf("You quit the game.\n");
|
printf("You quit the game.\n");
|
||||||
game_state.game_active = false;
|
game_state.game_active = false;
|
||||||
} else {
|
} else {
|
||||||
printf("Unknown command.\n");
|
printf("Unknown command.\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Function to print the prompt for the player
|
// Function to print the prompt for the player
|
||||||
void print_prompt() {
|
void print_prompt() {
|
||||||
printf(" > ");
|
printf(" > ");
|
||||||
}
|
}
|
||||||
|
|
||||||
const void game_clear()
|
const void game_clear()
|
||||||
{
|
{
|
||||||
print_set_color(PRINT_COLOR_WHITE, PRINT_COLOR_BLACK); // Set text color
|
print_set_color(PRINT_COLOR_WHITE, PRINT_COLOR_BLACK); // Set text color
|
||||||
|
|
||||||
move_print_cursor(0, 0);
|
move_print_cursor(0, 0);
|
||||||
move_cursor(0, 0);
|
move_cursor(0, 0);
|
||||||
print_clear();
|
print_clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Function to initialize and run the game
|
// Function to initialize and run the game
|
||||||
void create_game() {
|
void create_game() {
|
||||||
// Initialize the game state
|
// Initialize the game state
|
||||||
game_state.current_room = 0;
|
game_state.current_room = 0;
|
||||||
game_state.game_active = true;
|
game_state.game_active = true;
|
||||||
|
|
||||||
printf("Welcome to the text adventure game!\n");
|
printf("Welcome to the text adventure game!\n");
|
||||||
printf("Type 'look' to see where you are, 'north', 'south', 'east', 'west' to move, or 'quit' to exit.\n");
|
printf("Type 'look' to see where you are, 'north', 'south', 'east', 'west' to move, or 'quit' to exit.\n");
|
||||||
printf("You can 'take key' or 'use key' in the appropriate places.\n");
|
printf("You can 'take key' or 'use key' in the appropriate places.\n");
|
||||||
|
|
||||||
print_prompt();
|
print_prompt();
|
||||||
|
|
||||||
// Main game loop
|
// Main game loop
|
||||||
while (game_state.game_active) {
|
while (game_state.game_active) {
|
||||||
char key = read_key(); // Get key input
|
char key = read_key(); // Get key input
|
||||||
|
|
||||||
if (key != 0) {
|
if (key != 0) {
|
||||||
if (!keydown) {
|
if (!keydown) {
|
||||||
if (key == 10) { // Enter key
|
if (key == 10) { // Enter key
|
||||||
printf("\n");
|
printf("\n");
|
||||||
commandBuffer[commandLength] = '\0'; // Null-terminate the command
|
commandBuffer[commandLength] = '\0'; // Null-terminate the command
|
||||||
handle_command(commandBuffer); // Process the command
|
handle_command(commandBuffer); // Process the command
|
||||||
commandLength = 0; // Reset command buffer
|
commandLength = 0; // Reset command buffer
|
||||||
if (game_state.game_active) {
|
if (game_state.game_active) {
|
||||||
print_prompt(); // Print prompt for the next command
|
print_prompt(); // Print prompt for the next command
|
||||||
}
|
}
|
||||||
} else if (key == 8) { // Backspace key
|
} else if (key == 8) { // Backspace key
|
||||||
if (commandLength > 0) {
|
if (commandLength > 0) {
|
||||||
commandLength--;
|
commandLength--;
|
||||||
offset_print_cursor(-1, 0);
|
offset_print_cursor(-1, 0);
|
||||||
print_char(' '); // Overwrite the character
|
print_char(' '); // Overwrite the character
|
||||||
offset_print_cursor(-1, 0);
|
offset_print_cursor(-1, 0);
|
||||||
}
|
}
|
||||||
} else if (key >= 32 && key <= 126) { // Printable characters
|
} else if (key >= 32 && key <= 126) { // Printable characters
|
||||||
if (commandLength < MAX_COMMAND_LENGTH - 1) {
|
if (commandLength < MAX_COMMAND_LENGTH - 1) {
|
||||||
commandBuffer[commandLength++] = key;
|
commandBuffer[commandLength++] = key;
|
||||||
print_char(key); // Display the key on the screen
|
print_char(key); // Display the key on the screen
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
keydown = true;
|
keydown = true;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
keydown = false;
|
keydown = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("Thanks for playing!\n");
|
printf("Thanks for playing!\n");
|
||||||
}
|
}
|
@ -89,4 +89,14 @@ int strncmp(const char *s1, const char *s2, size_t n) {
|
|||||||
} else {
|
} else {
|
||||||
return (*(unsigned char *)s1 - *(unsigned char *)s2);
|
return (*(unsigned char *)s1 - *(unsigned char *)s2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char* strchr(const char* str, int ch) {
|
||||||
|
while (*str) {
|
||||||
|
if (*str == (char)ch) {
|
||||||
|
return (char*)str;
|
||||||
|
}
|
||||||
|
str++;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
32
src/intf/basic.h
Normal file
32
src/intf/basic.h
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
#ifndef BASIC_INTERPRETER_H
|
||||||
|
#define BASIC_INTERPRETER_H
|
||||||
|
|
||||||
|
#include "stdint.h"
|
||||||
|
#include "stddef.h"
|
||||||
|
|
||||||
|
#define MAX_LINE_LENGTH 128
|
||||||
|
#define MAX_VARIABLES 32
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
char name[16];
|
||||||
|
int value;
|
||||||
|
char* str_value;
|
||||||
|
} Variable;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
Variable variables[MAX_VARIABLES];
|
||||||
|
size_t variable_count;
|
||||||
|
int running;
|
||||||
|
} InterpreterState;
|
||||||
|
|
||||||
|
// Initialize the interpreter state
|
||||||
|
void init_state(InterpreterState* state);
|
||||||
|
|
||||||
|
// Execute a single line of code in the context of a state
|
||||||
|
void execute_line(InterpreterState* state, const char* line);
|
||||||
|
|
||||||
|
// Utility to evaluate an expression (exposed for potential reuse)
|
||||||
|
const char* evaluate_expression(InterpreterState* state, const char* expr);
|
||||||
|
|
||||||
|
|
||||||
|
#endif // BASIC_INTERPRETER_H
|
@ -1,17 +1,17 @@
|
|||||||
// disk_io.h
|
// disk_io.h
|
||||||
|
|
||||||
#ifndef DISK_IO_H
|
#ifndef DISK_IO_H
|
||||||
#define DISK_IO_H
|
#define DISK_IO_H
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
// Read sectors from the disk
|
// Read sectors from the disk
|
||||||
int disk_read(uint32_t lba, void *buffer, uint32_t size);
|
int disk_read(uint32_t lba, void *buffer, uint32_t size);
|
||||||
|
|
||||||
// Optional: Write sectors to the disk (not implemented)
|
// Optional: Write sectors to the disk (not implemented)
|
||||||
int disk_write(uint32_t lba, const void *buffer, uint32_t size);
|
int disk_write(uint32_t lba, const void *buffer, uint32_t size);
|
||||||
|
|
||||||
|
|
||||||
int bios_read_sector(uint32_t lba, void *buffer);
|
int bios_read_sector(uint32_t lba, void *buffer);
|
||||||
|
|
||||||
#endif // DISK_IO_H
|
#endif // DISK_IO_H
|
@ -1,25 +1,25 @@
|
|||||||
#ifndef GAME_H
|
#ifndef GAME_H
|
||||||
#define GAME_H
|
#define GAME_H
|
||||||
|
|
||||||
#include "stdint.h"
|
#include "stdint.h"
|
||||||
|
|
||||||
|
|
||||||
// Define the maximum length of a command
|
// Define the maximum length of a command
|
||||||
#define MAX_COMMAND_LENGTH 128
|
#define MAX_COMMAND_LENGTH 128
|
||||||
|
|
||||||
// Game state structure
|
// Game state structure
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int current_room;
|
int current_room;
|
||||||
bool game_active;
|
bool game_active;
|
||||||
} GameState;
|
} GameState;
|
||||||
|
|
||||||
// Function to initialize and run the game
|
// Function to initialize and run the game
|
||||||
void create_game();
|
void create_game();
|
||||||
|
|
||||||
// Function to handle the command input by the player
|
// Function to handle the command input by the player
|
||||||
void handle_command(const char* command);
|
void handle_command(const char* command);
|
||||||
|
|
||||||
// Function to print the current prompt
|
// Function to print the current prompt
|
||||||
void print_prompt();
|
void print_prompt();
|
||||||
|
|
||||||
#endif
|
#endif
|
@ -29,6 +29,7 @@ enum {
|
|||||||
};
|
};
|
||||||
|
|
||||||
void sscanf(const char *str, const char *format, char *filename, char *content);
|
void sscanf(const char *str, const char *format, char *filename, char *content);
|
||||||
|
snprintf(char* buffer, size_t size, const char* format, ...);
|
||||||
int my_sscanf(const char *input, const char *format, char *output);
|
int my_sscanf(const char *input, const char *format, char *output);
|
||||||
void print_clear();
|
void print_clear();
|
||||||
void print_char(char character);
|
void print_char(char character);
|
@ -5,8 +5,9 @@
|
|||||||
int strcmp(const char *str1, const char *str2);
|
int strcmp(const char *str1, const char *str2);
|
||||||
size_t strlen(const char *str);
|
size_t strlen(const char *str);
|
||||||
char *strncpy(char *dest, const char *src, size_t n);
|
char *strncpy(char *dest, const char *src, size_t n);
|
||||||
int int_strncmp(const char* s1, const char* s2, size_t n);
|
int int_strncmp(const char *s1, const char *s2, size_t n);
|
||||||
void strcpy(char *dest, const char *src);
|
void strcpy(char *dest, const char *src);
|
||||||
char* strrchr(const char* str, char ch);
|
char *strrchr(const char *str, char ch);
|
||||||
|
|
||||||
int strncmp(const char *s1, const char *s2, size_t n);
|
int strncmp(const char *s1, const char *s2, size_t n);
|
||||||
|
char *strchr(const char *str, int ch);
|
@ -1,22 +1,22 @@
|
|||||||
#ifndef VECTOR_H
|
#ifndef VECTOR_H
|
||||||
#define VECTOR_H
|
#define VECTOR_H
|
||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
// Define the vector structure
|
// Define the vector structure
|
||||||
typedef struct {
|
typedef struct {
|
||||||
void** items; // Pointer to the array of items
|
void** items; // Pointer to the array of items
|
||||||
size_t capacity; // Maximum number of items the vector can hold
|
size_t capacity; // Maximum number of items the vector can hold
|
||||||
size_t size; // Current number of items in the vector
|
size_t size; // Current number of items in the vector
|
||||||
} vector;
|
} vector;
|
||||||
|
|
||||||
// Function prototypes
|
// Function prototypes
|
||||||
vector* vector_create();
|
vector* vector_create();
|
||||||
void vector_destroy(vector* v);
|
void vector_destroy(vector* v);
|
||||||
int vector_push_back(vector* v, void* item);
|
int vector_push_back(vector* v, void* item);
|
||||||
void* vector_get(vector* v, size_t index);
|
void* vector_get(vector* v, size_t index);
|
||||||
int vector_set(vector* v, size_t index, void* item);
|
int vector_set(vector* v, size_t index, void* item);
|
||||||
size_t vector_size(vector* v);
|
size_t vector_size(vector* v);
|
||||||
int vector_resize(vector* v, size_t new_capacity);
|
int vector_resize(vector* v, size_t new_capacity);
|
||||||
|
|
||||||
#endif
|
#endif
|
BIN
targets/x86_64/iso/boot/kernel.bin
Normal file
BIN
targets/x86_64/iso/boot/kernel.bin
Normal file
Binary file not shown.
Loading…
Reference in New Issue
Block a user