diff --git a/.gitignore b/.gitignore index c6127b3..5a80a35 100644 --- a/.gitignore +++ b/.gitignore @@ -50,3 +50,8 @@ modules.order Module.symvers Mkfile.old dkms.conf + +bin + +*.yy.c +*.yy.h \ No newline at end of file diff --git a/Makefile b/Makefile index f6378c6..e95bc05 100644 --- a/Makefile +++ b/Makefile @@ -1,3 +1,19 @@ -build: +LEXER_SRC = src/lexer/lex.l +LEXER_C = src/lexer/lex.yy.c +LEXER_H = src/lexer/lex.yy.h + +CFILES = $(shell find src -name '*.c') +BINARY = bin/cargon + +all: $(BINARY) + +$(LEXER_C) $(LEXER_H): $(LEXER_SRC) + flex --header-file=$(LEXER_H) -o $(LEXER_C) $(LEXER_SRC) + +$(BINARY): $(CFILES) $(LEXER_C) $(LEXER_H) mkdir -p bin - gcc -O3 -o bin/cargon $(shell find src -name '*.c') -lm -Wall -Wextra -Werror \ No newline at end of file + gcc -O3 -o $(BINARY) $(CFILES) -lm -Wall -Wextra -Wno-unused-function + +clean: + rm -rf bin + rm -f $(LEXER_C) $(LEXER_H) \ No newline at end of file diff --git a/bin/cargon b/bin/cargon deleted file mode 100755 index e010e00..0000000 Binary files a/bin/cargon and /dev/null differ diff --git a/src/lexer/lex.l b/src/lexer/lex.l new file mode 100644 index 0000000..166168d --- /dev/null +++ b/src/lexer/lex.l @@ -0,0 +1,47 @@ +%{ +#include "token.h" +int current_line = 1; +int current_column = 1; + +int yywrap() { + return 1; +} +%} + +%% + +\"(\\[a-z\"'`]|[^\\"])*\" { + add_token(TOKEN_STRING, yytext, current_line, current_column); + current_column += yyleng; +} + +[0-9]+ { + add_token(TOKEN_NUMBER, yytext, current_line, current_column); + current_column += yyleng; +} + +[a-zA-Z_][a-zA-Z0-9_]* { + add_token(TOKEN_IDENTIFIER, yytext, current_line, current_column); + current_column += yyleng; +} + +"." { + add_token(TOKEN_DOT, yytext, current_line, current_column); + current_column += yyleng; +} + +\n { + add_token(TOKEN_NEW_LINE, yytext, current_line, current_column); + current_line++; + current_column = 1; +} + +[ \t]+ { + current_column += yyleng; // Advance column for whitespace +} + +. { + fprintf(stderr, "Error: Unexpected character '%c' at line %d\n", *yytext, yylineno); + exit(1); +} +%% \ No newline at end of file diff --git a/src/lexer/lexer.c b/src/lexer/lexer.c new file mode 100644 index 0000000..38bc85c --- /dev/null +++ b/src/lexer/lexer.c @@ -0,0 +1,20 @@ +#include "lex.yy.h" +#include "token.h" + +int lexer() { + const char *input = "term.log\n"; + + + + void* buffer = yy_scan_string(input); + yy_switch_to_buffer(buffer); + yylex(); // This fills the token array + yy_delete_buffer(buffer); + + for (int i = 0; i < token_count; i++) { + printf("Token(type=%d, value='%s')\n", tokens[i].type, tokens[i].value); + } + + free_tokens(); + return 0; +} \ No newline at end of file diff --git a/src/lexer/lexer.h b/src/lexer/lexer.h new file mode 100644 index 0000000..c03af10 --- /dev/null +++ b/src/lexer/lexer.h @@ -0,0 +1 @@ +int lexer(); \ No newline at end of file diff --git a/src/lexer/token.c b/src/lexer/token.c new file mode 100644 index 0000000..2e1a207 --- /dev/null +++ b/src/lexer/token.c @@ -0,0 +1,35 @@ +#include +#include +#include "token.h" + +#define INITIAL_CAPACITY 64 + +Token* tokens = NULL; +int token_count = 0; +static int token_capacity = 0; + +void add_token(TokenType type, const char* value, int line, int column) { + if (tokens == NULL) { + token_capacity = INITIAL_CAPACITY; + tokens = malloc(sizeof(Token) * token_capacity); + } else if (token_count >= token_capacity) { + token_capacity *= 2; + tokens = realloc(tokens, sizeof(Token) * token_capacity); + } + + tokens[token_count].type = type; + tokens[token_count].value = strdup(value); + tokens[token_count].line = line; + tokens[token_count].column = column; + token_count++; +} + +void free_tokens() { + for (int i = 0; i < token_count; ++i) { + free(tokens[i].value); + } + free(tokens); + tokens = NULL; + token_count = 0; + token_capacity = 0; +} \ No newline at end of file diff --git a/src/lexer/token.h b/src/lexer/token.h new file mode 100644 index 0000000..b2d6131 --- /dev/null +++ b/src/lexer/token.h @@ -0,0 +1,29 @@ +#ifndef TOKEN_H +#define TOKEN_H + +typedef enum { + TOKEN_STRING, + TOKEN_NUMBER, + TOKEN_IDENTIFIER, + TOKEN_KEYWORD, + TOKEN_DOT, + TOKEN_NEW_LINE, +} TokenType; + +typedef struct { + TokenType type; + char* value; + int line; + int column; +} Token; + +extern int token_count; + +extern Token* tokens; + + +void add_token(TokenType type, const char* value, int line, int column); + +void free_tokens(); + +#endif \ No newline at end of file diff --git a/src/main.c b/src/main.c index 17bda6e..7e0f830 100644 --- a/src/main.c +++ b/src/main.c @@ -4,6 +4,7 @@ #include #include #include +#include "lexer/lexer.h" void initialize() { initNumber(); @@ -14,16 +15,6 @@ void cleanup() { } int main() { - initialize(); - char *code = "1.2e20"; - struct number mynum = translateNumber(code); - if (mynum.denominator == 0) { - printf("Invalid number\n"); - return 1; - } - double f = 1.0 * mynum.numerator / mynum.denominator; - printf("Numerator: %ld\n", mynum.numerator); - printf("Denominator: %lu\n", mynum.denominator); - printf("Float: %lf\n", f); + lexer(); return 0; } diff --git a/src/number/number.c b/src/number/number.c index 63ddef0..071473b 100644 --- a/src/number/number.c +++ b/src/number/number.c @@ -49,19 +49,19 @@ void doubleToFraction(double num, int64_t *numerator, uint64_t *denominator) { int currentSign = (num < 0) ? -1 : 1; num = fabs(num); - double tolerance = 1.0e-10; - double h1 = 1, h2 = 0, k1 = 0, k2 = 1; - double b = num; + long double tolerance = 1.0e-10; + long double h1 = 1, h2 = 0, k1 = 0, k2 = 1; + long double b = num; do { - double a = floor(b); - double aux = h1; + long double a = floor(b); + long double aux = h1; h1 = a * h1 + h2; h2 = aux; aux = k1; k1 = a * k1 + k2; k2 = aux; b = 1 / (b - a); - } while (fabs(num - h1 / k1) > num * tolerance); + } while (fabsl(num - h1 / k1) > num * tolerance); *numerator = (int64_t)(h1 * currentSign); *denominator = (uint64_t)k1;