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 "fs.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 HISTORY_SIZE 10
|
||||
#define COMMAND_BUFFER_SIZE 256
|
||||
@ -22,29 +20,31 @@
|
||||
|
||||
extern void kpanic(int error_code);
|
||||
|
||||
|
||||
void shutdown_system() {
|
||||
__asm__ (
|
||||
"movl $1, %eax\n" // syscall number for sys_reboot (1 in this case)
|
||||
"movl $0, %ebx\n" // reboot flags
|
||||
"movl $0, %ecx\n" // no additional arguments
|
||||
"movl $0, %edx\n" // no additional arguments
|
||||
"int $0x80\n" // interrupt to invoke syscall
|
||||
void shutdown_system()
|
||||
{
|
||||
__asm__(
|
||||
"movl $1, %eax\n" // syscall number for sys_reboot (1 in this case)
|
||||
"movl $0, %ebx\n" // reboot flags
|
||||
"movl $0, %ecx\n" // no additional arguments
|
||||
"movl $0, %edx\n" // no additional arguments
|
||||
"int $0x80\n" // interrupt to invoke syscall
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
char commandHistory[HISTORY_SIZE][COMMAND_BUFFER_SIZE];
|
||||
int currentHistoryIndex = 0;
|
||||
int historyCount = 0;
|
||||
|
||||
void add_to_history(const char* command) {
|
||||
if (historyCount < HISTORY_SIZE) {
|
||||
void add_to_history(const char *command)
|
||||
{
|
||||
if (historyCount < HISTORY_SIZE)
|
||||
{
|
||||
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]);
|
||||
}
|
||||
}
|
||||
@ -52,23 +52,26 @@ void add_to_history(const char* command) {
|
||||
currentHistoryIndex = historyCount;
|
||||
}
|
||||
|
||||
const char* get_previous_command() {
|
||||
if (currentHistoryIndex > 0) {
|
||||
const char *get_previous_command()
|
||||
{
|
||||
if (currentHistoryIndex > 0)
|
||||
{
|
||||
currentHistoryIndex--;
|
||||
return commandHistory[currentHistoryIndex];
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const char* get_next_command() {
|
||||
if (currentHistoryIndex < historyCount - 1) {
|
||||
const char *get_next_command()
|
||||
{
|
||||
if (currentHistoryIndex < historyCount - 1)
|
||||
{
|
||||
currentHistoryIndex++;
|
||||
return commandHistory[currentHistoryIndex];
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
const void clear()
|
||||
{
|
||||
print_set_color(PRINT_COLOR_WHITE, PRINT_COLOR_BLACK); // Set text color
|
||||
@ -79,113 +82,127 @@ const void clear()
|
||||
print_setup_prompt();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void halt(){
|
||||
void halt()
|
||||
{
|
||||
print_str("[ WARN ] HALT\n");
|
||||
while (1) {}
|
||||
while (1)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
void commandHandler(char* command) {
|
||||
void commandHandler(char *command)
|
||||
{
|
||||
printf("\n");
|
||||
|
||||
if (strcmp(command, "cls") == 0) {
|
||||
if (strcmp(command, "cls") == 0)
|
||||
{
|
||||
clear();
|
||||
} else if (strcmp(command, "knp") == 0) {
|
||||
}
|
||||
else if (strcmp(command, "knp") == 0)
|
||||
{
|
||||
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(message);
|
||||
print_str("\n");
|
||||
} else if (int_strncmp(command, "cwin", 4) == 0) {
|
||||
}
|
||||
else if (int_strncmp(command, "cwin", 4) == 0)
|
||||
{
|
||||
// Define window properties
|
||||
Window myWindow;
|
||||
int x = 8; // X position of the window
|
||||
int y = 4; // Y position of the window
|
||||
int width = 30; // Width of the window
|
||||
int height = 10; // Height of the window
|
||||
uint8_t borderColor = PRINT_COLOR_RED; // Border color
|
||||
int x = 8; // X position of the window
|
||||
int y = 4; // Y position of the window
|
||||
int width = 30; // Width of the window
|
||||
int height = 10; // Height of the window
|
||||
uint8_t borderColor = PRINT_COLOR_RED; // Border color
|
||||
uint8_t backgroundColor = PRINT_COLOR_BLUE; // Background color
|
||||
|
||||
|
||||
// Create and display the window
|
||||
create_window(&myWindow, x, y, width, height, borderColor, backgroundColor, "Main Window");
|
||||
|
||||
|
||||
// Print text inside the window
|
||||
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, 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
|
||||
|
||||
|
||||
|
||||
} else if (int_strncmp(command, "exit", 4) == 0) {
|
||||
print_text_in_window(&myWindow, 2, 4, "do [ cls ] to clear"); // Print text inside the window
|
||||
}
|
||||
else if (int_strncmp(command, "exit", 4) == 0)
|
||||
{
|
||||
printf("Driver Call [ shutdown_system(); ] \n");
|
||||
shutdown_system();
|
||||
|
||||
|
||||
} else if (int_strncmp(command, "panic_test", 10) == 0) {
|
||||
int _y = 1/0;
|
||||
}
|
||||
else if (int_strncmp(command, "panic_test", 10) == 0)
|
||||
{
|
||||
int _y = 1 / 0;
|
||||
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
|
||||
//void* block1 = malloc(32);
|
||||
//void* block2 = malloc(64);
|
||||
//void* block3 = malloc(128);
|
||||
//
|
||||
// void* block1 = malloc(32);
|
||||
// void* block2 = malloc(64);
|
||||
// void* block3 = malloc(128);
|
||||
//
|
||||
//// List used blocks
|
||||
//list_used_blocks();
|
||||
//
|
||||
// list_used_blocks();
|
||||
//
|
||||
//// Free a block and check again
|
||||
//free(block2);
|
||||
//printf("\nAfter freeing block2:\n");
|
||||
//list_used_blocks();
|
||||
// free(block2);
|
||||
// printf("\nAfter freeing block2:\n");
|
||||
// list_used_blocks();
|
||||
//
|
||||
//void* block4 = malloc(64);
|
||||
// void* block4 = malloc(64);
|
||||
//
|
||||
//list_used_blocks();
|
||||
|
||||
|
||||
// list_used_blocks();
|
||||
|
||||
create_game();
|
||||
|
||||
} else if (int_strncmp(command, "split", 5) == 0) {
|
||||
}
|
||||
else if (int_strncmp(command, "split", 5) == 0)
|
||||
{
|
||||
printf("Kernel Call [ split_string(); ]\n");
|
||||
|
||||
|
||||
// Check the length of the command string and use it properly
|
||||
char** new_command = split_string(command, ",", strlen(command));
|
||||
|
||||
//char** new_command = {{NULL, NULL, NULL, NULL}};
|
||||
|
||||
if (new_command) {
|
||||
char **new_command = split_string(command, ",", strlen(command));
|
||||
|
||||
// char** new_command = {{NULL, NULL, NULL, NULL}};
|
||||
|
||||
if (new_command)
|
||||
{
|
||||
// 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]);
|
||||
}
|
||||
|
||||
//halt(); // Debug halt
|
||||
|
||||
|
||||
// halt(); // Debug halt
|
||||
|
||||
// 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]);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void print_setup_prompt() {
|
||||
void print_setup_prompt()
|
||||
{
|
||||
move_cursor(0, 0);
|
||||
print_set_color(PRINT_COLOR_LIGHT_RED, PRINT_COLOR_BLACK);
|
||||
print_str("-------------------- ");
|
||||
@ -197,34 +214,58 @@ void print_setup_prompt() {
|
||||
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();
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
idt_install();
|
||||
|
||||
|
||||
|
||||
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");
|
||||
|
||||
fat12_read_root_directory();
|
||||
|
||||
|
||||
fat12_dir_entry_t entry;
|
||||
if (fat12_find_file("HELLOTXT", &entry)) {
|
||||
if (fat12_find_file("HELLOTXT", &entry))
|
||||
{
|
||||
printf("File found: HELLO.TXT\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
print_setup_prompt();
|
||||
clear();
|
||||
|
||||
test_basic();
|
||||
|
||||
print_setup_prompt();
|
||||
|
||||
print_str(" > ");
|
||||
|
||||
@ -232,57 +273,64 @@ void kernel_main() {
|
||||
char key;
|
||||
bool keydown = false;
|
||||
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();
|
||||
|
||||
if (key != 0) {
|
||||
if (!keydown) {
|
||||
if (key != 0)
|
||||
{
|
||||
if (!keydown)
|
||||
{
|
||||
CursorPosition pos = get_print_cursor_pos();
|
||||
move_cursor(pos.x,pos.y);
|
||||
if (key == 10) { // Enter key
|
||||
commandBuffer[commandLength] = '\0'; // Null-terminate the command
|
||||
move_cursor(pos.x, pos.y);
|
||||
if (key == 10)
|
||||
{ // Enter key
|
||||
commandBuffer[commandLength] = '\0'; // Null-terminate the command
|
||||
commandHandler(commandBuffer);
|
||||
|
||||
// Reset command buffer for the next input
|
||||
commandLength = 0;
|
||||
print_str(" > ");
|
||||
|
||||
} else if (key == BACKSPACE_KEY) { // Backspace key
|
||||
if (commandLength > 0) {
|
||||
}
|
||||
else if (key == BACKSPACE_KEY)
|
||||
{ // Backspace key
|
||||
if (commandLength > 0)
|
||||
{
|
||||
// Remove the last character from the buffer
|
||||
commandLength--;
|
||||
commandBuffer[commandLength] = '0'; // Null-terminate after removal
|
||||
commandBuffer[commandLength] = '0'; // Null-terminate after removal
|
||||
|
||||
// Clear the character from the screen (overwrite with space)
|
||||
// Move cursor back one position
|
||||
offset_print_cursor(-1,0);
|
||||
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);
|
||||
print_char(' '); // Overwrite the character
|
||||
offset_print_cursor(-1, 0); // Move cursor back one position(because its moved left one by the rpintf)
|
||||
}
|
||||
|
||||
} else {
|
||||
if (key >= 32 && key <= 126) { // Check if the key is a printable character
|
||||
if (commandLength < COMMAND_BUFFER_SIZE - 1) {
|
||||
commandBuffer[commandLength++] = key; // Append character to buffer
|
||||
}
|
||||
else
|
||||
{
|
||||
if (key >= 32 && key <= 126)
|
||||
{ // 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
|
||||
print_char(key); // Print key to the screen
|
||||
print_char(key); // Print key to the screen
|
||||
}
|
||||
}
|
||||
}
|
||||
keydown = true;
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
keydown = false;
|
||||
}
|
||||
|
||||
|
||||
// int x = 100/0;
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
extern isr_common_handler
|
||||
|
||||
section .text
|
||||
|
||||
; ISRs 0 to 13 (no error code pushed by CPU)
|
||||
isr0:
|
||||
cli
|
||||
push 0 ; Push error code (none for isr0)
|
||||
push 0 ; Push interrupt number
|
||||
jmp isr_common_handler
|
||||
|
||||
isr1:
|
||||
cli
|
||||
push 0
|
||||
push 1
|
||||
jmp isr_common_handler
|
||||
|
||||
isr2:
|
||||
cli
|
||||
push 0
|
||||
push 2
|
||||
jmp isr_common_handler
|
||||
|
||||
isr3:
|
||||
cli
|
||||
push 0
|
||||
push 3
|
||||
jmp isr_common_handler
|
||||
|
||||
isr4:
|
||||
cli
|
||||
push 0
|
||||
push 4
|
||||
jmp isr_common_handler
|
||||
|
||||
isr5:
|
||||
cli
|
||||
push 0
|
||||
push 5
|
||||
jmp isr_common_handler
|
||||
|
||||
isr6:
|
||||
cli
|
||||
push 0
|
||||
push 6
|
||||
jmp isr_common_handler
|
||||
|
||||
isr7:
|
||||
cli
|
||||
push 0
|
||||
push 7
|
||||
jmp isr_common_handler
|
||||
|
||||
isr8:
|
||||
cli
|
||||
push 0
|
||||
push 8
|
||||
jmp isr_common_handler
|
||||
|
||||
isr9:
|
||||
cli
|
||||
push 0
|
||||
push 9
|
||||
jmp isr_common_handler
|
||||
|
||||
isr10:
|
||||
cli
|
||||
push 0
|
||||
push 10
|
||||
jmp isr_common_handler
|
||||
|
||||
isr11:
|
||||
cli
|
||||
push 0
|
||||
push 11
|
||||
jmp isr_common_handler
|
||||
|
||||
isr12:
|
||||
cli
|
||||
push 0
|
||||
push 12
|
||||
jmp isr_common_handler
|
||||
|
||||
isr13:
|
||||
cli
|
||||
push 0
|
||||
push 13
|
||||
jmp isr_common_handler
|
||||
|
||||
; ISR 14 (Page Fault) requires error code pushed by CPU
|
||||
isr14:
|
||||
cli
|
||||
push 14 ; Push interrupt number
|
||||
jmp isr_common_handler
|
||||
|
||||
; ISRs 15 to 31 (no error code pushed by CPU)
|
||||
isr15:
|
||||
cli
|
||||
push 0
|
||||
push 15
|
||||
jmp isr_common_handler
|
||||
|
||||
isr16:
|
||||
cli
|
||||
push 0
|
||||
push 16
|
||||
jmp isr_common_handler
|
||||
|
||||
isr17:
|
||||
cli
|
||||
push 0
|
||||
push 17
|
||||
jmp isr_common_handler
|
||||
|
||||
isr18:
|
||||
cli
|
||||
push 0
|
||||
push 18
|
||||
jmp isr_common_handler
|
||||
|
||||
isr19:
|
||||
cli
|
||||
push 0
|
||||
push 19
|
||||
jmp isr_common_handler
|
||||
|
||||
isr20:
|
||||
cli
|
||||
push 0
|
||||
push 20
|
||||
jmp isr_common_handler
|
||||
|
||||
|
||||
|
||||
|
||||
; isr.asm - ISR assembly stubs
|
||||
|
||||
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
|
||||
extern isr_common_handler
|
||||
|
||||
section .text
|
||||
|
||||
; ISRs 0 to 13 (no error code pushed by CPU)
|
||||
isr0:
|
||||
cli
|
||||
push 0 ; Push error code (none for isr0)
|
||||
push 0 ; Push interrupt number
|
||||
jmp isr_common_handler
|
||||
|
||||
isr1:
|
||||
cli
|
||||
push 0
|
||||
push 1
|
||||
jmp isr_common_handler
|
||||
|
||||
isr2:
|
||||
cli
|
||||
push 0
|
||||
push 2
|
||||
jmp isr_common_handler
|
||||
|
||||
isr3:
|
||||
cli
|
||||
push 0
|
||||
push 3
|
||||
jmp isr_common_handler
|
||||
|
||||
isr4:
|
||||
cli
|
||||
push 0
|
||||
push 4
|
||||
jmp isr_common_handler
|
||||
|
||||
isr5:
|
||||
cli
|
||||
push 0
|
||||
push 5
|
||||
jmp isr_common_handler
|
||||
|
||||
isr6:
|
||||
cli
|
||||
push 0
|
||||
push 6
|
||||
jmp isr_common_handler
|
||||
|
||||
isr7:
|
||||
cli
|
||||
push 0
|
||||
push 7
|
||||
jmp isr_common_handler
|
||||
|
||||
isr8:
|
||||
cli
|
||||
push 0
|
||||
push 8
|
||||
jmp isr_common_handler
|
||||
|
||||
isr9:
|
||||
cli
|
||||
push 0
|
||||
push 9
|
||||
jmp isr_common_handler
|
||||
|
||||
isr10:
|
||||
cli
|
||||
push 0
|
||||
push 10
|
||||
jmp isr_common_handler
|
||||
|
||||
isr11:
|
||||
cli
|
||||
push 0
|
||||
push 11
|
||||
jmp isr_common_handler
|
||||
|
||||
isr12:
|
||||
cli
|
||||
push 0
|
||||
push 12
|
||||
jmp isr_common_handler
|
||||
|
||||
isr13:
|
||||
cli
|
||||
push 0
|
||||
push 13
|
||||
jmp isr_common_handler
|
||||
|
||||
; ISR 14 (Page Fault) requires error code pushed by CPU
|
||||
isr14:
|
||||
cli
|
||||
push 14 ; Push interrupt number
|
||||
jmp isr_common_handler
|
||||
|
||||
; ISRs 15 to 31 (no error code pushed by CPU)
|
||||
isr15:
|
||||
cli
|
||||
push 0
|
||||
push 15
|
||||
jmp isr_common_handler
|
||||
|
||||
isr16:
|
||||
cli
|
||||
push 0
|
||||
push 16
|
||||
jmp isr_common_handler
|
||||
|
||||
isr17:
|
||||
cli
|
||||
push 0
|
||||
push 17
|
||||
jmp isr_common_handler
|
||||
|
||||
isr18:
|
||||
cli
|
||||
push 0
|
||||
push 18
|
||||
jmp isr_common_handler
|
||||
|
||||
isr19:
|
||||
cli
|
||||
push 0
|
||||
push 19
|
||||
jmp isr_common_handler
|
||||
|
||||
isr20:
|
||||
cli
|
||||
push 0
|
||||
push 20
|
||||
jmp isr_common_handler
|
||||
|
||||
|
||||
|
||||
|
@ -1,43 +1,43 @@
|
||||
// disk_io.c
|
||||
|
||||
#include "disk_io.h"
|
||||
#include "print.h" // Assuming you have a function for kernel printing
|
||||
|
||||
#define SECTOR_SIZE 512
|
||||
|
||||
// Function to read sectors from disk
|
||||
int disk_read(uint32_t lba, void *buffer, uint32_t size) {
|
||||
// lba: logical block address
|
||||
// buffer: where to store the read data
|
||||
// size: number of bytes to read
|
||||
|
||||
if (size % SECTOR_SIZE != 0) {
|
||||
printf("Read size must be a multiple of 512 bytes\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < size / SECTOR_SIZE; i++) {
|
||||
// Placeholder for actual disk sector read. Replace with proper implementation
|
||||
if (!bios_read_sector(lba + i, buffer + (i * SECTOR_SIZE))) {
|
||||
printf("Error reading sector from disk\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Placeholder function to simulate reading sectors from the disk
|
||||
// Replace this with actual disk reading logic depending on the platform
|
||||
int bios_read_sector(uint32_t lba, void *buffer) {
|
||||
// Simulate disk sector read
|
||||
// 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 (int i = 0; i < SECTOR_SIZE; i++) {
|
||||
((uint8_t*)buffer)[i] = 0; // Fill buffer with zeros
|
||||
}
|
||||
|
||||
return 1; // Success
|
||||
}
|
||||
|
||||
// disk_io.c
|
||||
|
||||
#include "disk_io.h"
|
||||
#include "print.h" // Assuming you have a function for kernel printing
|
||||
|
||||
#define SECTOR_SIZE 512
|
||||
|
||||
// Function to read sectors from disk
|
||||
int disk_read(uint32_t lba, void *buffer, uint32_t size) {
|
||||
// lba: logical block address
|
||||
// buffer: where to store the read data
|
||||
// size: number of bytes to read
|
||||
|
||||
if (size % SECTOR_SIZE != 0) {
|
||||
printf("Read size must be a multiple of 512 bytes\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < size / SECTOR_SIZE; i++) {
|
||||
// Placeholder for actual disk sector read. Replace with proper implementation
|
||||
if (!bios_read_sector(lba + i, buffer + (i * SECTOR_SIZE))) {
|
||||
printf("Error reading sector from disk\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Placeholder function to simulate reading sectors from the disk
|
||||
// Replace this with actual disk reading logic depending on the platform
|
||||
int bios_read_sector(uint32_t lba, void *buffer) {
|
||||
// Simulate disk sector read
|
||||
// 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 (int i = 0; i < SECTOR_SIZE; i++) {
|
||||
((uint8_t*)buffer)[i] = 0; // Fill buffer with zeros
|
||||
}
|
||||
|
||||
return 1; // Success
|
||||
}
|
||||
|
@ -334,6 +334,48 @@ int my_sscanf(const char *input, const char *format, char *output) {
|
||||
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, ...) {
|
||||
va_list args;
|
@ -1,80 +1,80 @@
|
||||
#include "vector.h"
|
||||
|
||||
// Initial capacity for a new vector
|
||||
#define VECTOR_INITIAL_CAPACITY 4
|
||||
|
||||
// Create a new vector
|
||||
vector* vector_create() {
|
||||
vector* v = (vector*)malloc(sizeof(vector));
|
||||
if (!v) return NULL; // Return NULL if allocation fails
|
||||
|
||||
v->capacity = VECTOR_INITIAL_CAPACITY;
|
||||
v->size = 0;
|
||||
v->items = (void**)malloc(sizeof(void*) * v->capacity);
|
||||
if (!v->items) {
|
||||
free(v); // Free the vector if item allocation fails
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
// Destroy the vector and free allocated memory
|
||||
void vector_destroy(vector* v) {
|
||||
if (v) {
|
||||
free(v->items);
|
||||
free(v);
|
||||
}
|
||||
}
|
||||
|
||||
// Push an item to the back of the vector
|
||||
int vector_push_back(vector* v, void* item) {
|
||||
// Resize the vector if it's full
|
||||
if (v->size == v->capacity) {
|
||||
if (vector_resize(v, v->capacity * 2) != 0) {
|
||||
return -1; // Return -1 on failure to resize
|
||||
}
|
||||
}
|
||||
|
||||
v->items[v->size++] = item; // Add the new item
|
||||
return 0; // Success
|
||||
}
|
||||
|
||||
// Get the item at a specific index
|
||||
void* vector_get(vector* v, size_t index) {
|
||||
if (index >= v->size) return NULL; // Return NULL if index is out of bounds
|
||||
return v->items[index];
|
||||
}
|
||||
|
||||
// Set an item at a specific index
|
||||
int vector_set(vector* v, size_t index, void* item) {
|
||||
if (index >= v->size) return -1; // Return -1 if index is out of bounds
|
||||
v->items[index] = item;
|
||||
return 0; // Success
|
||||
}
|
||||
|
||||
// Get the size of the vector
|
||||
size_t vector_size(vector* v) {
|
||||
return v->size;
|
||||
}
|
||||
|
||||
// Resize the vector's internal array
|
||||
int vector_resize(vector* v, size_t new_capacity) {
|
||||
// Allocate new memory for the resized array
|
||||
void** new_items = (void**)malloc(sizeof(void*) * new_capacity);
|
||||
if (!new_items) return -1; // Return -1 on failure
|
||||
|
||||
// Copy the old items into the new array
|
||||
for (size_t i = 0; i < v->size; i++) {
|
||||
new_items[i] = v->items[i];
|
||||
}
|
||||
|
||||
// Free the old memory
|
||||
free(v->items);
|
||||
|
||||
// Update the vector's internal state
|
||||
v->items = new_items;
|
||||
v->capacity = new_capacity;
|
||||
|
||||
return 0; // Success
|
||||
}
|
||||
#include "vector.h"
|
||||
|
||||
// Initial capacity for a new vector
|
||||
#define VECTOR_INITIAL_CAPACITY 4
|
||||
|
||||
// Create a new vector
|
||||
vector* vector_create() {
|
||||
vector* v = (vector*)malloc(sizeof(vector));
|
||||
if (!v) return NULL; // Return NULL if allocation fails
|
||||
|
||||
v->capacity = VECTOR_INITIAL_CAPACITY;
|
||||
v->size = 0;
|
||||
v->items = (void**)malloc(sizeof(void*) * v->capacity);
|
||||
if (!v->items) {
|
||||
free(v); // Free the vector if item allocation fails
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
// Destroy the vector and free allocated memory
|
||||
void vector_destroy(vector* v) {
|
||||
if (v) {
|
||||
free(v->items);
|
||||
free(v);
|
||||
}
|
||||
}
|
||||
|
||||
// Push an item to the back of the vector
|
||||
int vector_push_back(vector* v, void* item) {
|
||||
// Resize the vector if it's full
|
||||
if (v->size == v->capacity) {
|
||||
if (vector_resize(v, v->capacity * 2) != 0) {
|
||||
return -1; // Return -1 on failure to resize
|
||||
}
|
||||
}
|
||||
|
||||
v->items[v->size++] = item; // Add the new item
|
||||
return 0; // Success
|
||||
}
|
||||
|
||||
// Get the item at a specific index
|
||||
void* vector_get(vector* v, size_t index) {
|
||||
if (index >= v->size) return NULL; // Return NULL if index is out of bounds
|
||||
return v->items[index];
|
||||
}
|
||||
|
||||
// Set an item at a specific index
|
||||
int vector_set(vector* v, size_t index, void* item) {
|
||||
if (index >= v->size) return -1; // Return -1 if index is out of bounds
|
||||
v->items[index] = item;
|
||||
return 0; // Success
|
||||
}
|
||||
|
||||
// Get the size of the vector
|
||||
size_t vector_size(vector* v) {
|
||||
return v->size;
|
||||
}
|
||||
|
||||
// Resize the vector's internal array
|
||||
int vector_resize(vector* v, size_t new_capacity) {
|
||||
// Allocate new memory for the resized array
|
||||
void** new_items = (void**)malloc(sizeof(void*) * new_capacity);
|
||||
if (!new_items) return -1; // Return -1 on failure
|
||||
|
||||
// Copy the old items into the new array
|
||||
for (size_t i = 0; i < v->size; i++) {
|
||||
new_items[i] = v->items[i];
|
||||
}
|
||||
|
||||
// Free the old memory
|
||||
free(v->items);
|
||||
|
||||
// Update the vector's internal state
|
||||
v->items = new_items;
|
||||
v->capacity = new_capacity;
|
||||
|
||||
return 0; // Success
|
||||
}
|
@ -1,185 +1,185 @@
|
||||
#include "game.h"
|
||||
#include "print.h"
|
||||
#include "keydriver.h"
|
||||
#include "strings.h"
|
||||
#include "stdint.h"
|
||||
|
||||
// Define constants for the game
|
||||
#define ROOM_COUNT 5
|
||||
#define INVENTORY_SIZE 5
|
||||
|
||||
// Global variable to hold the game state
|
||||
static GameState game_state;
|
||||
|
||||
// Room descriptions and connected rooms
|
||||
typedef struct {
|
||||
const char* description;
|
||||
int north;
|
||||
int south;
|
||||
int east;
|
||||
int west;
|
||||
} Room;
|
||||
|
||||
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 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 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 }
|
||||
};
|
||||
|
||||
// Player's inventory
|
||||
static const char* inventory[INVENTORY_SIZE];
|
||||
static int inventory_count = 0;
|
||||
|
||||
// Command buffer
|
||||
static char commandBuffer[MAX_COMMAND_LENGTH];
|
||||
static size_t commandLength = 0;
|
||||
|
||||
bool keydown = false;
|
||||
|
||||
// Function to handle user input commands
|
||||
void handle_command(const char* command) {
|
||||
|
||||
|
||||
game_clear();
|
||||
|
||||
|
||||
if (strcmp(command, "look") == 0) {
|
||||
printf(rooms[game_state.current_room].description);
|
||||
printf("\n");
|
||||
} else if (strcmp(command, "north") == 0) {
|
||||
if (rooms[game_state.current_room].north != -1) {
|
||||
game_state.current_room = rooms[game_state.current_room].north;
|
||||
printf("You walk north.\n");
|
||||
printf("%s\n", rooms[game_state.current_room].description);
|
||||
} else {
|
||||
printf("You can't go that way.\n");
|
||||
}
|
||||
} else if (strcmp(command, "south") == 0) {
|
||||
if (rooms[game_state.current_room].south != -1) {
|
||||
game_state.current_room = rooms[game_state.current_room].south;
|
||||
printf("You walk south.\n");
|
||||
printf("%s\n", rooms[game_state.current_room].description);
|
||||
} else {
|
||||
printf("You can't go that way.\n");
|
||||
}
|
||||
} else if (strcmp(command, "east") == 0) {
|
||||
if (rooms[game_state.current_room].east != -1) {
|
||||
game_state.current_room = rooms[game_state.current_room].east;
|
||||
printf("You walk east.\n");
|
||||
printf("%s\n", rooms[game_state.current_room].description);
|
||||
} else {
|
||||
printf("You can't go that way.\n");
|
||||
}
|
||||
} else if (strcmp(command, "west") == 0) {
|
||||
if (rooms[game_state.current_room].west != -1) {
|
||||
game_state.current_room = rooms[game_state.current_room].west;
|
||||
printf("You walk west.\n");
|
||||
printf("%s\n", rooms[game_state.current_room].description);
|
||||
} else {
|
||||
printf("You can't go that way.\n");
|
||||
}
|
||||
} else if (strcmp(command, "inventory") == 0) {
|
||||
printf("You are carrying:\n");
|
||||
for (int i = 0; i < inventory_count; ++i) {
|
||||
printf("- %s\n", inventory[i]);
|
||||
}
|
||||
if (inventory_count == 0) {
|
||||
printf("Nothing.\n");
|
||||
}
|
||||
} else if (strcmp(command, "take key") == 0) {
|
||||
if (game_state.current_room == 1) {
|
||||
if (inventory_count < INVENTORY_SIZE) {
|
||||
inventory[inventory_count++] = "key";
|
||||
printf("You picked up a key.\n");
|
||||
} else {
|
||||
printf("Your inventory is full.\n");
|
||||
}
|
||||
} else {
|
||||
printf("There is no key here.\n");
|
||||
}
|
||||
} else if (strcmp(command, "use key") == 0) {
|
||||
bool has_key = false;
|
||||
for (int i = 0; i < inventory_count; ++i) {
|
||||
if (strcmp(inventory[i], "key") == 0) {
|
||||
has_key = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (has_key && game_state.current_room == 2) {
|
||||
printf("You unlock the door in the cave and find a treasure!\n");
|
||||
game_state.game_active = false; // End the game
|
||||
} else {
|
||||
printf("You can't use the key here.\n");
|
||||
}
|
||||
} else if (strcmp(command, "quit") == 0) {
|
||||
printf("You quit the game.\n");
|
||||
game_state.game_active = false;
|
||||
} else {
|
||||
printf("Unknown command.\n");
|
||||
}
|
||||
}
|
||||
|
||||
// Function to print the prompt for the player
|
||||
void print_prompt() {
|
||||
printf(" > ");
|
||||
}
|
||||
|
||||
const void game_clear()
|
||||
{
|
||||
print_set_color(PRINT_COLOR_WHITE, PRINT_COLOR_BLACK); // Set text color
|
||||
|
||||
move_print_cursor(0, 0);
|
||||
move_cursor(0, 0);
|
||||
print_clear();
|
||||
}
|
||||
|
||||
// Function to initialize and run the game
|
||||
void create_game() {
|
||||
// Initialize the game state
|
||||
game_state.current_room = 0;
|
||||
game_state.game_active = true;
|
||||
|
||||
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("You can 'take key' or 'use key' in the appropriate places.\n");
|
||||
|
||||
print_prompt();
|
||||
|
||||
// Main game loop
|
||||
while (game_state.game_active) {
|
||||
char key = read_key(); // Get key input
|
||||
|
||||
if (key != 0) {
|
||||
if (!keydown) {
|
||||
if (key == 10) { // Enter key
|
||||
printf("\n");
|
||||
commandBuffer[commandLength] = '\0'; // Null-terminate the command
|
||||
handle_command(commandBuffer); // Process the command
|
||||
commandLength = 0; // Reset command buffer
|
||||
if (game_state.game_active) {
|
||||
print_prompt(); // Print prompt for the next command
|
||||
}
|
||||
} else if (key == 8) { // Backspace key
|
||||
if (commandLength > 0) {
|
||||
commandLength--;
|
||||
offset_print_cursor(-1, 0);
|
||||
print_char(' '); // Overwrite the character
|
||||
offset_print_cursor(-1, 0);
|
||||
}
|
||||
} else if (key >= 32 && key <= 126) { // Printable characters
|
||||
if (commandLength < MAX_COMMAND_LENGTH - 1) {
|
||||
commandBuffer[commandLength++] = key;
|
||||
print_char(key); // Display the key on the screen
|
||||
}
|
||||
}
|
||||
keydown = true;
|
||||
}
|
||||
} else {
|
||||
keydown = false;
|
||||
}
|
||||
}
|
||||
|
||||
printf("Thanks for playing!\n");
|
||||
}
|
||||
#include "game.h"
|
||||
#include "print.h"
|
||||
#include "keydriver.h"
|
||||
#include "strings.h"
|
||||
#include "stdint.h"
|
||||
|
||||
// Define constants for the game
|
||||
#define ROOM_COUNT 5
|
||||
#define INVENTORY_SIZE 5
|
||||
|
||||
// Global variable to hold the game state
|
||||
static GameState game_state;
|
||||
|
||||
// Room descriptions and connected rooms
|
||||
typedef struct {
|
||||
const char* description;
|
||||
int north;
|
||||
int south;
|
||||
int east;
|
||||
int west;
|
||||
} Room;
|
||||
|
||||
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 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 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 }
|
||||
};
|
||||
|
||||
// Player's inventory
|
||||
static const char* inventory[INVENTORY_SIZE];
|
||||
static int inventory_count = 0;
|
||||
|
||||
// Command buffer
|
||||
static char commandBuffer[MAX_COMMAND_LENGTH];
|
||||
static size_t commandLength = 0;
|
||||
|
||||
bool keydown = false;
|
||||
|
||||
// Function to handle user input commands
|
||||
void handle_command(const char* command) {
|
||||
|
||||
|
||||
game_clear();
|
||||
|
||||
|
||||
if (strcmp(command, "look") == 0) {
|
||||
printf(rooms[game_state.current_room].description);
|
||||
printf("\n");
|
||||
} else if (strcmp(command, "north") == 0) {
|
||||
if (rooms[game_state.current_room].north != -1) {
|
||||
game_state.current_room = rooms[game_state.current_room].north;
|
||||
printf("You walk north.\n");
|
||||
printf("%s\n", rooms[game_state.current_room].description);
|
||||
} else {
|
||||
printf("You can't go that way.\n");
|
||||
}
|
||||
} else if (strcmp(command, "south") == 0) {
|
||||
if (rooms[game_state.current_room].south != -1) {
|
||||
game_state.current_room = rooms[game_state.current_room].south;
|
||||
printf("You walk south.\n");
|
||||
printf("%s\n", rooms[game_state.current_room].description);
|
||||
} else {
|
||||
printf("You can't go that way.\n");
|
||||
}
|
||||
} else if (strcmp(command, "east") == 0) {
|
||||
if (rooms[game_state.current_room].east != -1) {
|
||||
game_state.current_room = rooms[game_state.current_room].east;
|
||||
printf("You walk east.\n");
|
||||
printf("%s\n", rooms[game_state.current_room].description);
|
||||
} else {
|
||||
printf("You can't go that way.\n");
|
||||
}
|
||||
} else if (strcmp(command, "west") == 0) {
|
||||
if (rooms[game_state.current_room].west != -1) {
|
||||
game_state.current_room = rooms[game_state.current_room].west;
|
||||
printf("You walk west.\n");
|
||||
printf("%s\n", rooms[game_state.current_room].description);
|
||||
} else {
|
||||
printf("You can't go that way.\n");
|
||||
}
|
||||
} else if (strcmp(command, "inventory") == 0) {
|
||||
printf("You are carrying:\n");
|
||||
for (int i = 0; i < inventory_count; ++i) {
|
||||
printf("- %s\n", inventory[i]);
|
||||
}
|
||||
if (inventory_count == 0) {
|
||||
printf("Nothing.\n");
|
||||
}
|
||||
} else if (strcmp(command, "take key") == 0) {
|
||||
if (game_state.current_room == 1) {
|
||||
if (inventory_count < INVENTORY_SIZE) {
|
||||
inventory[inventory_count++] = "key";
|
||||
printf("You picked up a key.\n");
|
||||
} else {
|
||||
printf("Your inventory is full.\n");
|
||||
}
|
||||
} else {
|
||||
printf("There is no key here.\n");
|
||||
}
|
||||
} else if (strcmp(command, "use key") == 0) {
|
||||
bool has_key = false;
|
||||
for (int i = 0; i < inventory_count; ++i) {
|
||||
if (strcmp(inventory[i], "key") == 0) {
|
||||
has_key = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (has_key && game_state.current_room == 2) {
|
||||
printf("You unlock the door in the cave and find a treasure!\n");
|
||||
game_state.game_active = false; // End the game
|
||||
} else {
|
||||
printf("You can't use the key here.\n");
|
||||
}
|
||||
} else if (strcmp(command, "quit") == 0) {
|
||||
printf("You quit the game.\n");
|
||||
game_state.game_active = false;
|
||||
} else {
|
||||
printf("Unknown command.\n");
|
||||
}
|
||||
}
|
||||
|
||||
// Function to print the prompt for the player
|
||||
void print_prompt() {
|
||||
printf(" > ");
|
||||
}
|
||||
|
||||
const void game_clear()
|
||||
{
|
||||
print_set_color(PRINT_COLOR_WHITE, PRINT_COLOR_BLACK); // Set text color
|
||||
|
||||
move_print_cursor(0, 0);
|
||||
move_cursor(0, 0);
|
||||
print_clear();
|
||||
}
|
||||
|
||||
// Function to initialize and run the game
|
||||
void create_game() {
|
||||
// Initialize the game state
|
||||
game_state.current_room = 0;
|
||||
game_state.game_active = true;
|
||||
|
||||
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("You can 'take key' or 'use key' in the appropriate places.\n");
|
||||
|
||||
print_prompt();
|
||||
|
||||
// Main game loop
|
||||
while (game_state.game_active) {
|
||||
char key = read_key(); // Get key input
|
||||
|
||||
if (key != 0) {
|
||||
if (!keydown) {
|
||||
if (key == 10) { // Enter key
|
||||
printf("\n");
|
||||
commandBuffer[commandLength] = '\0'; // Null-terminate the command
|
||||
handle_command(commandBuffer); // Process the command
|
||||
commandLength = 0; // Reset command buffer
|
||||
if (game_state.game_active) {
|
||||
print_prompt(); // Print prompt for the next command
|
||||
}
|
||||
} else if (key == 8) { // Backspace key
|
||||
if (commandLength > 0) {
|
||||
commandLength--;
|
||||
offset_print_cursor(-1, 0);
|
||||
print_char(' '); // Overwrite the character
|
||||
offset_print_cursor(-1, 0);
|
||||
}
|
||||
} else if (key >= 32 && key <= 126) { // Printable characters
|
||||
if (commandLength < MAX_COMMAND_LENGTH - 1) {
|
||||
commandBuffer[commandLength++] = key;
|
||||
print_char(key); // Display the key on the screen
|
||||
}
|
||||
}
|
||||
keydown = true;
|
||||
}
|
||||
} else {
|
||||
keydown = false;
|
||||
}
|
||||
}
|
||||
|
||||
printf("Thanks for playing!\n");
|
||||
}
|
@ -89,4 +89,14 @@ int strncmp(const char *s1, const char *s2, size_t n) {
|
||||
} else {
|
||||
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
|
||||
|
||||
#ifndef DISK_IO_H
|
||||
#define DISK_IO_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
// Read sectors from the disk
|
||||
int disk_read(uint32_t lba, void *buffer, uint32_t size);
|
||||
|
||||
// Optional: Write sectors to the disk (not implemented)
|
||||
int disk_write(uint32_t lba, const void *buffer, uint32_t size);
|
||||
|
||||
|
||||
int bios_read_sector(uint32_t lba, void *buffer);
|
||||
|
||||
// disk_io.h
|
||||
|
||||
#ifndef DISK_IO_H
|
||||
#define DISK_IO_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
// Read sectors from the disk
|
||||
int disk_read(uint32_t lba, void *buffer, uint32_t size);
|
||||
|
||||
// Optional: Write sectors to the disk (not implemented)
|
||||
int disk_write(uint32_t lba, const void *buffer, uint32_t size);
|
||||
|
||||
|
||||
int bios_read_sector(uint32_t lba, void *buffer);
|
||||
|
||||
#endif // DISK_IO_H
|
@ -1,25 +1,25 @@
|
||||
#ifndef GAME_H
|
||||
#define GAME_H
|
||||
|
||||
#include "stdint.h"
|
||||
|
||||
|
||||
// Define the maximum length of a command
|
||||
#define MAX_COMMAND_LENGTH 128
|
||||
|
||||
// Game state structure
|
||||
typedef struct {
|
||||
int current_room;
|
||||
bool game_active;
|
||||
} GameState;
|
||||
|
||||
// Function to initialize and run the game
|
||||
void create_game();
|
||||
|
||||
// Function to handle the command input by the player
|
||||
void handle_command(const char* command);
|
||||
|
||||
// Function to print the current prompt
|
||||
void print_prompt();
|
||||
|
||||
#endif
|
||||
#ifndef GAME_H
|
||||
#define GAME_H
|
||||
|
||||
#include "stdint.h"
|
||||
|
||||
|
||||
// Define the maximum length of a command
|
||||
#define MAX_COMMAND_LENGTH 128
|
||||
|
||||
// Game state structure
|
||||
typedef struct {
|
||||
int current_room;
|
||||
bool game_active;
|
||||
} GameState;
|
||||
|
||||
// Function to initialize and run the game
|
||||
void create_game();
|
||||
|
||||
// Function to handle the command input by the player
|
||||
void handle_command(const char* command);
|
||||
|
||||
// Function to print the current prompt
|
||||
void print_prompt();
|
||||
|
||||
#endif
|
@ -29,6 +29,7 @@ enum {
|
||||
};
|
||||
|
||||
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);
|
||||
void print_clear();
|
||||
void print_char(char character);
|
@ -5,8 +5,9 @@
|
||||
int strcmp(const char *str1, const char *str2);
|
||||
size_t strlen(const char *str);
|
||||
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);
|
||||
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
|
||||
#define VECTOR_H
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
// Define the vector structure
|
||||
typedef struct {
|
||||
void** items; // Pointer to the array of items
|
||||
size_t capacity; // Maximum number of items the vector can hold
|
||||
size_t size; // Current number of items in the vector
|
||||
} vector;
|
||||
|
||||
// Function prototypes
|
||||
vector* vector_create();
|
||||
void vector_destroy(vector* v);
|
||||
int vector_push_back(vector* v, void* item);
|
||||
void* vector_get(vector* v, size_t index);
|
||||
int vector_set(vector* v, size_t index, void* item);
|
||||
size_t vector_size(vector* v);
|
||||
int vector_resize(vector* v, size_t new_capacity);
|
||||
|
||||
#endif
|
||||
#ifndef VECTOR_H
|
||||
#define VECTOR_H
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
// Define the vector structure
|
||||
typedef struct {
|
||||
void** items; // Pointer to the array of items
|
||||
size_t capacity; // Maximum number of items the vector can hold
|
||||
size_t size; // Current number of items in the vector
|
||||
} vector;
|
||||
|
||||
// Function prototypes
|
||||
vector* vector_create();
|
||||
void vector_destroy(vector* v);
|
||||
int vector_push_back(vector* v, void* item);
|
||||
void* vector_get(vector* v, size_t index);
|
||||
int vector_set(vector* v, size_t index, void* item);
|
||||
size_t vector_size(vector* v);
|
||||
int vector_resize(vector* v, size_t new_capacity);
|
||||
|
||||
#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