From fc17e5eade9b48f403e162c93c787eda069c8d53 Mon Sep 17 00:00:00 2001 From: xamidev Date: Tue, 6 Aug 2024 13:43:01 +0200 Subject: [PATCH] Making: math interpreter. Need to fix printf %f --- iso/boot/kernel.elf | Bin 26384 -> 30992 bytes src/kernel/kmain.c | 1 - src/kernel/shell.c | 6 +- src/libc/ctype.c | 13 ++ src/libc/ctype.h | 9 ++ src/libc/stdio.c | 156 ++++++++++++++++-------- src/programs/math.c | 260 ++++++++++++++++++++++++++++++++++++++++ src/programs/programs.h | 1 + 8 files changed, 393 insertions(+), 53 deletions(-) create mode 100644 src/libc/ctype.c create mode 100644 src/libc/ctype.h create mode 100644 src/programs/math.c diff --git a/iso/boot/kernel.elf b/iso/boot/kernel.elf index 8f6b39682eb549da4e1063011f0aa2872a19667f..7b70d9ef88d530ee5c357a86f3044264569425d8 100755 GIT binary patch literal 30992 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 '0' && c <= '9'; +} + + +bool isspace(char c) +{ + return c == ' ' || c == '\t' || c == '\n' || c == '\v' || c == '\f' || c == '\r'; +} diff --git a/src/libc/ctype.h b/src/libc/ctype.h new file mode 100644 index 0000000..10ace98 --- /dev/null +++ b/src/libc/ctype.h @@ -0,0 +1,9 @@ +#ifndef CTYPE_H +#define CTYPE_H + +#include "stdint.h" + +bool isdigit(char c); +bool isspace(char c); + +#endif diff --git a/src/libc/stdio.c b/src/libc/stdio.c index c356875..70a8555 100644 --- a/src/libc/stdio.c +++ b/src/libc/stdio.c @@ -176,6 +176,50 @@ void colorputs(const char* str, unsigned int color) } } +// double to string for printf +void dtostrf(double val, char *buffer, int precision) +{ + int whole_part = (int)val; + double fractional_part = val - whole_part; + if (fractional_part < 0) fractional_part = -fractional_part; + + char *start = buffer; + if (whole_part == 0) + { + *buffer++ = '0'; + } + else + { + if (whole_part < 0) + { + *buffer++ = '-'; + whole_part = -whole_part; + } + char temp[32]; + int pos = 0; + + while (whole_part > 0) + { + temp[pos++] = '0' + (whole_part % 10); + whole_part /= 10; + } + while (pos > 0) + { + *buffer++ = temp[--pos]; + } + } + + *buffer++ = '.'; + for (int i = 0; i < precision; i++) + { + fractional_part *= 10; + int digit = (int)fractional_part; + *buffer++ = '0' + digit; + fractional_part -= digit; + } + *buffer = '\0'; +} + void printf(const char* fmt, ...) { int* argp = (int*) &fmt; @@ -188,52 +232,52 @@ void printf(const char* fmt, ...) while (*fmt) { switch(state) { - case PRINTF_STATE_START: - if (*fmt == '%') - { - state = PRINTF_STATE_LENGTH; - } - else { - putc(*fmt); - } - break; - case PRINTF_STATE_LENGTH: - if (*fmt == 'h') - { - length = PRINTF_LENGTH_SHORT; - state = PRINTF_STATE_SHORT; - } - else if (*fmt == 'l') - { - length = PRINTF_LENGTH_LONG; - state = PRINTF_STATE_LONG; - } - else { - goto PRINTF_STATE_SPEC_; - } - break; - case PRINTF_STATE_SHORT: - if (*fmt == 'h') - { - length = PRINTF_LENGTH_SHORT_SHORT; - state = PRINTF_STATE_SPEC; - } - else { - goto PRINTF_STATE_SPEC_; - } - break; - case PRINTF_STATE_LONG: - if (*fmt == 'l') - { - length = PRINTF_LENGTH_LONG_LONG; - state = PRINTF_STATE_SPEC; - } - else { - goto PRINTF_STATE_SPEC_; - } - break; - case PRINTF_STATE_SPEC: - PRINTF_STATE_SPEC_: + case PRINTF_STATE_START: + if (*fmt == '%') + { + state = PRINTF_STATE_LENGTH; + } + else { + putc(*fmt); + } + break; + case PRINTF_STATE_LENGTH: + if (*fmt == 'h') + { + length = PRINTF_LENGTH_SHORT; + state = PRINTF_STATE_SHORT; + } + else if (*fmt == 'l') + { + length = PRINTF_LENGTH_LONG; + state = PRINTF_STATE_LONG; + } + else { + goto PRINTF_STATE_SPEC_; + } + break; + case PRINTF_STATE_SHORT: + if (*fmt == 'h') + { + length = PRINTF_LENGTH_SHORT_SHORT; + state = PRINTF_STATE_SPEC; + } + else { + goto PRINTF_STATE_SPEC_; + } + break; + case PRINTF_STATE_LONG: + if (*fmt == 'l') + { + length = PRINTF_LENGTH_LONG_LONG; + state = PRINTF_STATE_SPEC; + } + else { + goto PRINTF_STATE_SPEC_; + } + break; + case PRINTF_STATE_SPEC: + PRINTF_STATE_SPEC_: switch(*fmt) { case 'c': @@ -270,14 +314,24 @@ void printf(const char* fmt, ...) sign = false; argp = printf_number(argp, length, sign, radix); break; + case 'f': { + // Handle floating-point numbers + double* dargp = (double*)argp; + double d = *(double*)dargp; + char buffer[64]; + dtostrf(d, buffer, 6); // Default precision: 6 + puts(buffer); + argp += 2; // Incrementing by 2 to move past the double argument + break; + } default: break; } - state = PRINTF_STATE_START; - length = PRINTF_LENGTH_START; - radix = 10; - sign = false; - break; + state = PRINTF_STATE_START; + length = PRINTF_LENGTH_START; + radix = 10; + sign = false; + break; } fmt++; } diff --git a/src/programs/math.c b/src/programs/math.c new file mode 100644 index 0000000..70d20c1 --- /dev/null +++ b/src/programs/math.c @@ -0,0 +1,260 @@ +// Math expression lexer and parser + +#include "../libc/stdint.h" +#include "../kernel/system.h" +#include "../libc/stdio.h" +#include "../libc/ctype.h" + +#define BUFFER_SIZE 256 + +typedef enum +{ + TOKEN_NUMBER, + TOKEN_PLUS, + TOKEN_MINUS, + TOKEN_MULTIPLY, + TOKEN_DIVIDE, + TOKEN_LPAREN, + TOKEN_RPAREN, + TOKEN_END +} TokenType; + +typedef struct +{ + TokenType type; + double value; +} Token; + +typedef struct +{ + const char *text; + size_t pos; + Token current_token; +} Lexer; + +void lexer_init(Lexer *lexer, const char *text) +{ + lexer->text = text; + lexer->pos = 0; + lexer->current_token.type = TOKEN_END; + lexer->current_token.value = 0; +} + +void lexer_advance(Lexer *lexer) +{ + lexer->pos++; +} + +char lexer_peek(const Lexer *lexer) +{ + return lexer->text[lexer->pos]; +} + +bool lexer_is_at_end(const Lexer *lexer) +{ + return lexer->text[lexer->pos] == '\0'; +} + +Token lexer_get_next_token(Lexer *lexer) +{ + while (!lexer_is_at_end(lexer)) + { + char current_char = lexer_peek(lexer); + + if (isspace(current_char)) { + lexer_advance(lexer); + continue; + } + + if (isdigit(current_char)) { + double value = 0; + while (isdigit(current_char)) + { + value = value * 10 + (current_char - '0'); + lexer_advance(lexer); + current_char = lexer_peek(lexer); + } + if (current_char == '.') + { + lexer_advance(lexer); + double decimal_place = 0.1; + while (isdigit(lexer_peek(lexer))) + { + value += decimal_place * (lexer_peek(lexer)-'0'); + decimal_place *= 0.1; + lexer_advance(lexer); + } + } + lexer->current_token.type = TOKEN_NUMBER; + lexer->current_token.value = value; + //printf("NUMBER %f\n", value); + return lexer->current_token; + } + + if (current_char == '+') + { + lexer_advance(lexer); + lexer->current_token.type = TOKEN_PLUS; + printf("PLUS\n"); + return lexer->current_token; + } + + if (current_char == '-') + { + lexer_advance(lexer); + lexer->current_token.type = TOKEN_MINUS; + printf("MINUS\n"); + return lexer->current_token; + } + + if (current_char == '*') + { + lexer_advance(lexer); + lexer->current_token.type = TOKEN_MULTIPLY; + printf("MULTIPLY\n"); + return lexer->current_token; + } + + if (current_char == '/') + { + lexer_advance(lexer); + lexer->current_token.type = TOKEN_DIVIDE; + printf("DIVIDE\n"); + return lexer->current_token; + } + + if (current_char == '(') + { + lexer_advance(lexer); + lexer->current_token.type = TOKEN_LPAREN; + printf("LPAREN\n"); + return lexer->current_token; + } + + if (current_char == ')') + { + lexer_advance(lexer); + lexer->current_token.type = TOKEN_RPAREN; + printf("RPAREN\n"); + return lexer->current_token; + } + + printf("Unknown character %c\n", current_char); + //shell_install(); + } + + lexer->current_token.type = TOKEN_END; + printf("END\n"); + return lexer->current_token; +} + +typedef struct +{ + Lexer lexer; + Token current_token; +} Parser; + +void parser_init(Parser *parser, const char *text) +{ + lexer_init(&parser->lexer, text); + parser->current_token = lexer_get_next_token(&parser->lexer); +} + +void parser_eat(Parser *parser, TokenType type) +{ + if (parser->current_token.type == type) + { + parser->current_token = lexer_get_next_token(&parser->lexer); + } else { + printf("Unexpected token %d\n", parser->current_token.type); + //shell_install(); + } +} + +double parser_factor(Parser *parser); +double parser_term(Parser *parser); +double parser_expression(Parser *parser); + +double parser_factor(Parser *parser) +{ + Token token = parser->current_token; + if (token.type == TOKEN_NUMBER) + { + parser_eat(parser, TOKEN_NUMBER); + //printf("Factor: %f\n", token.value); + return token.value; + } else if (token.type == TOKEN_LPAREN) { + parser_eat(parser, TOKEN_LPAREN); + double result = parser_expression(parser); + parser_eat(parser, TOKEN_RPAREN); + //printf("Factor (expression): %f\n", result); + return result; + } else { + printf("Unexpected token in factor %d\n", token.type); + //shell_install(); + } + return -1; +} + +double parser_term(Parser *parser) +{ + double result = parser_factor(parser); + //printf("Initial term: %f\n", result); + + while (parser->current_token.type == TOKEN_MULTIPLY || parser->current_token.type == TOKEN_DIVIDE) + { + Token token = parser->current_token; + if (token.type == TOKEN_MULTIPLY) + { + parser_eat(parser, TOKEN_MULTIPLY); + result *= parser_factor(parser); + //printf("Term after multiply: %f\n", result); + } else if (token.type == TOKEN_DIVIDE) { + parser_eat(parser, TOKEN_DIVIDE); + result /= parser_factor(parser); + //printf("Term after divide: %f\n", result); + } + } + return result; +} + +double parser_expression(Parser *parser) +{ + double result = parser_term(parser); + //printf("Initial expression: %f\n", result); + + while (parser->current_token.type == TOKEN_PLUS || parser->current_token.type == TOKEN_MINUS) + { + Token token = parser->current_token; + if (token.type == TOKEN_PLUS) + { + parser_eat(parser, TOKEN_PLUS); + result += parser_term(parser); + //printf("Expression after plus: %f\n", result); + } else if (token.type == TOKEN_MINUS) { + parser_eat(parser, TOKEN_MINUS); + result -= parser_term(parser); + //printf("Expression after minus: %f\n", result); + } + } + return result; +} + +double parse(const char* text) +{ + Parser parser; + parser_init(&parser, text); + double result = parser_expression(&parser); + //printf("Final result: %f\n", result); + return result; +} + +void program_math() +{ + char input_buffer[BUFFER_SIZE]; + puts("Expression? "); + get_input(input_buffer, BUFFER_SIZE); + printf("Input: %s\n", input_buffer); + double result = parse(input_buffer); + printf("\n%f\n", result); +} diff --git a/src/programs/programs.h b/src/programs/programs.h index 8f8ca31..0c57177 100644 --- a/src/programs/programs.h +++ b/src/programs/programs.h @@ -3,6 +3,7 @@ void program_words(); void program_primes(); +void program_math(); // Misc void program_rainbow();