diff --git a/Makefile b/Makefile index bf50497..5da844a 100644 --- a/Makefile +++ b/Makefile @@ -19,6 +19,13 @@ debug: $(CFILES) $(LEXER_C) $(LEXER_H) mkdir -p bin gcc -g -O0 -o $(BINARY) $(CFILES) $(CFLAGS) +optimised: $(CFILES) $(LEXER_C) $(LEXER_H) + mkdir -p bin + gcc -O3 -fprofile-generate -o $(BINARY) $(CFILES) $(CFLAGS) + ${BINARY} + gcc -O3 -fprofile-use -o $(BINARY) $(CFILES) $(CFLAGS) + + clean: rm -rf bin rm -f $(LEXER_C) $(LEXER_H) \ No newline at end of file diff --git a/src/dynamic_array/darray.c b/src/dynamic_array/darray.c index 5b319db..6185147 100644 --- a/src/dynamic_array/darray.c +++ b/src/dynamic_array/darray.c @@ -15,8 +15,7 @@ void darray_init(DArray *arr, size_t element_size) { } void darray_resize(DArray *arr, size_t new_size) { - size_t new_capacity = ((new_size + CHUNK_SIZE - 1) / CHUNK_SIZE) * CHUNK_SIZE; - + size_t new_capacity = ((new_size + CHUNK_SIZE) / CHUNK_SIZE) * CHUNK_SIZE; if (new_capacity != arr->capacity) { void *new_data = realloc(arr->data, new_capacity * arr->element_size); if (!new_data) { @@ -37,7 +36,7 @@ void darray_push(DArray *arr, void *element) { arr->size++; } - void *target = (char *)arr->data + (arr->size - 1) * arr->element_size; + void *target = (void *)arr->data + (arr->size - 1) * arr->element_size; memcpy(target, element, arr->element_size); } @@ -48,7 +47,7 @@ void darray_pop(DArray *arr, void (*free_data)(void *)) { arr->size--; if (free_data) { - void *target = (char *)arr->data + arr->size * arr->element_size; + void *target = (void *)arr->data + arr->size * arr->element_size; free_data(target); } @@ -60,13 +59,13 @@ void *darray_get(DArray *arr, size_t index) { fprintf(stderr, "darray_get: index out of bounds\n"); exit(EXIT_FAILURE); } - return (char *)arr->data + index * arr->element_size; + return (void *)arr->data + index * arr->element_size; } void darray_free(DArray *arr, void (*free_data)(void *)) { if (free_data) { for (size_t i = 0; i < arr->size; ++i) { - void *element = (char *)arr->data + i * arr->element_size; + void *element = (void *)arr->data + i * arr->element_size; free_data(element); } } diff --git a/src/lexer/lex.l b/src/lexer/lex.l index 597bb71..345a282 100644 --- a/src/lexer/lex.l +++ b/src/lexer/lex.l @@ -18,6 +18,16 @@ int yywrap(void *) { "," {return TOKEN_COMMA; } ":" {return TOKEN_COLON; } + +"=" { return TOKEN_ASSIGN; } +"+=" { return TOKEN_ASSIGN_PLUS; } +"-=" { return TOKEN_ASSIGN_MINUS; } +"//=" { return TOKEN_ASSIGN_FLOORDIV; } +"/=" { return TOKEN_ASSIGN_SLASH; } +"%=" { return TOKEN_ASSIGN_MODULO; } +"*=" { return TOKEN_ASSIGN_STAR; } +"^=" { return TOKEN_ASSIGN_CARET; } + "not"[ \t]+"in" { return TOKEN_NOT_IN; } "&&" { return TOKEN_AND; } "||" { return TOKEN_OR; } @@ -25,7 +35,6 @@ int yywrap(void *) { ">=" { return TOKEN_GE; } "!=" { return TOKEN_NE; } "==" { return TOKEN_EQ; } -"=" { return TOKEN_ASSIGN; } "//" { return TOKEN_FLOORDIV; } "<" { return TOKEN_LT; } ">" { return TOKEN_GT; } diff --git a/src/lexer/lexer.c b/src/lexer/lexer.c index 0161805..e0455b5 100644 --- a/src/lexer/lexer.c +++ b/src/lexer/lexer.c @@ -19,6 +19,7 @@ void lexer(LexerState state) { yyget_text(scanner) ); darray_push(state.tokens, token_struct); + free(token_struct); if (token == TOKEN_NEW_LINE) { state.current_column = 0; } else { diff --git a/src/lexer/lexer.h b/src/lexer/lexer.h index dba68a3..0c27bdd 100644 --- a/src/lexer/lexer.h +++ b/src/lexer/lexer.h @@ -1,3 +1,6 @@ +#ifndef LEXER_H +#define LEXER_H + #include "token.h" #include "../dynamic_array/darray.h" #include @@ -11,3 +14,6 @@ typedef struct { } LexerState; void lexer(LexerState state); + + +#endif // LEXER_H \ No newline at end of file diff --git a/src/lexer/token.h b/src/lexer/token.h index e93b7da..f486d65 100644 --- a/src/lexer/token.h +++ b/src/lexer/token.h @@ -10,6 +10,15 @@ typedef enum { TOKEN_NEW_LINE, TOKEN_INDENT, + TOKEN_ASSIGN, + TOKEN_ASSIGN_PLUS, + TOKEN_ASSIGN_MINUS, + TOKEN_ASSIGN_FLOORDIV, + TOKEN_ASSIGN_SLASH, + TOKEN_ASSIGN_MODULO, + TOKEN_ASSIGN_STAR, + TOKEN_ASSIGN_CARET, + // Operators TOKEN_AND, // && TOKEN_OR, // || @@ -20,7 +29,6 @@ typedef enum { TOKEN_GT, // > TOKEN_NE, // != TOKEN_EQ, // == - TOKEN_ASSIGN, TOKEN_PLUS, // + TOKEN_MINUS, // - TOKEN_MODULO, // % @@ -72,5 +80,5 @@ typedef struct { } Token; Token *create_token(TokenType type, int line, int column, char *value); -void free_token(void * ptr); +void free_token(void *ptr); #endif \ No newline at end of file diff --git a/src/main.c b/src/main.c index 9ab1aa9..4c14858 100644 --- a/src/main.c +++ b/src/main.c @@ -10,7 +10,7 @@ int main() { ar_memory_init(); - const char * path = "test.ar"; + char * path = "test.ar"; DArray tokens; darray_init(&tokens, sizeof(Token)); @@ -22,16 +22,17 @@ int main() { &tokens }; lexer(state); + fclose(state.file); - DArray parsed; + DArray ast; - darray_init(&parsed, sizeof(ParsedValue)); + darray_init(&ast, sizeof(ParsedValue)); - parser(&parsed, &tokens, false); + parser(path,&ast, &tokens, false); darray_free(&tokens, free_token); - - darray_free(&parsed,free_parsed_value); + + darray_free(&ast,free_parsed); return 0; } diff --git a/src/memory.c b/src/memory.c index 9e61430..b795957 100644 --- a/src/memory.c +++ b/src/memory.c @@ -3,26 +3,10 @@ #include #include // for malloc/free (temp arena fallback) -static char* temp_arena = NULL; -static size_t temp_arena_capacity = 0; -static size_t temp_arena_offset = 0; - -#define TEMP_ARENA_INITIAL_CAPACITY 4096 - void ar_memory_init() { GC_INIT(); } -void ar_memory_shutdown() { - // No-op for Boehm, but could clean up temp arena here - if (temp_arena) { - free(temp_arena); - temp_arena = NULL; - temp_arena_capacity = 0; - temp_arena_offset = 0; - } -} - void* ar_alloc(size_t size) { return GC_MALLOC(size); } diff --git a/src/memory.h b/src/memory.h index 38319ca..839b150 100644 --- a/src/memory.h +++ b/src/memory.h @@ -8,12 +8,7 @@ void* ar_alloc(size_t size); void* ar_alloc_atomic(size_t size); char* ar_strdup(const char* str); -// Optional: temporary/arena allocations (e.g., for parsing) -void* ar_temp_alloc(size_t size); -void ar_temp_free_all(); - // Memory init/shutdown void ar_memory_init(); -void ar_memory_shutdown(); #endif // ARGON_MEMORY_H \ No newline at end of file diff --git a/src/parser/assign/assign.c b/src/parser/assign/assign.c new file mode 100644 index 0000000..087a843 --- /dev/null +++ b/src/parser/assign/assign.c @@ -0,0 +1,44 @@ +#include "assign.h" +#include "../../lexer/token.h" +#include "../parser.h" +#include +#include +#include + +ParsedValue *parse_assign(char*file,DArray *parsed, DArray *tokens, + ParsedValue *assign_to, size_t *index) { + Token *token = darray_get(tokens, *index); + ParsedAssign *assign = malloc(sizeof(ParsedAssign)); + assign->to = assign_to; + assign->type = token->type; + (*index)++; + token = darray_get(tokens, *index); + switch (token->type) { + case TOKEN_ASSIGN: + case TOKEN_ASSIGN_CARET: + case TOKEN_ASSIGN_FLOORDIV: + case TOKEN_ASSIGN_MINUS: + case TOKEN_ASSIGN_MODULO: + case TOKEN_ASSIGN_PLUS: + case TOKEN_ASSIGN_SLASH: + case TOKEN_ASSIGN_STAR: + fprintf(stderr, "%s:%u:%u error: invalid syntax\n", file, token->line, + token->column); + exit(EXIT_FAILURE); + default: + break; + } + assign->from = parse_token(file,parsed, tokens, index, true); + ParsedValue *parsedValue = malloc(sizeof(ParsedValue)); + parsedValue->type = AST_ASSIGN; + parsedValue->data = assign; + return parsedValue; +} + +void free_parse_assign(void*ptr) { + ParsedValue * parsedValue = ptr; + ParsedAssign* parsedAssign = parsedValue->data; + free_parsed(parsedAssign->to); + free_parsed(parsedAssign->from); + free(parsedAssign); +} \ No newline at end of file diff --git a/src/parser/assign/assign.h b/src/parser/assign/assign.h new file mode 100644 index 0000000..9596c51 --- /dev/null +++ b/src/parser/assign/assign.h @@ -0,0 +1,17 @@ +#ifndef ASSIGN_H +#define ASSIGN_H +#include "../parser.h" +#include "../../lexer/token.h" + +typedef struct { + ParsedValue * to; + TokenType type; + ParsedValue * from; +} ParsedAssign; + +ParsedValue *parse_assign(char*file,DArray *parsed, DArray *tokens, + ParsedValue *assign_to, size_t *index); + +void free_parse_assign(void*ptr); + +#endif // ASSIGN_H \ No newline at end of file diff --git a/src/parser/parser.c b/src/parser/parser.c index 6f58a12..454bbfb 100644 --- a/src/parser/parser.c +++ b/src/parser/parser.c @@ -1,35 +1,67 @@ #include "parser.h" #include "../dynamic_array/darray.h" #include "../lexer/token.h" +#include "assign/assign.h" #include "string/string.h" #include #include #include #include +#include -ParsedValue *parse_token(DArray *tokens, size_t *index) { +ParsedValue *parse_token(char *file, DArray *parsed, DArray *tokens, + size_t *index, bool inline_flag) { Token *token = darray_get(tokens, *index); + if (!inline_flag) { + switch (token->type) { + default: + break; + }; + } switch (token->type) { case TOKEN_STRING: (*index)++; return parse_string(*token); case TOKEN_NEW_LINE: - (*index)++; - return NULL; + while (token->type == TOKEN_NEW_LINE && *index+1 <= tokens->size) { + (*index)++; + token = darray_get(tokens, *index); + } + if (token->type == TOKEN_NEW_LINE) return NULL; + return parse_token(file, parsed, tokens, index, inline_flag); case TOKEN_INDENT: - fprintf(stderr, "error: \n"); + fprintf(stderr, "%s:%u:%u error: invalid indentation\n", file, token->line, + token->column); exit(EXIT_FAILURE); + case TOKEN_ASSIGN: + case TOKEN_ASSIGN_CARET: + case TOKEN_ASSIGN_FLOORDIV: + case TOKEN_ASSIGN_MINUS: + case TOKEN_ASSIGN_MODULO: + case TOKEN_ASSIGN_PLUS: + case TOKEN_ASSIGN_SLASH: + case TOKEN_ASSIGN_STAR: + if (parsed->size == 0) { + fprintf(stderr, "%s:%u:%u error: assigning to nothing\n", file, token->line, + token->column); + exit(EXIT_FAILURE); + } + ParsedValue *assign_to = malloc(sizeof(ParsedValue)); + memcpy(assign_to, darray_get(parsed, parsed->size-1), sizeof(ParsedValue)); + darray_resize(parsed, parsed->size-1); + return parse_assign(file, parsed, tokens, assign_to, index); default: fprintf(stderr, "Panic: unreachable\n"); exit(EXIT_FAILURE); } } -void parser(DArray *parsed, DArray *tokens, bool inline_flag) { +void parser(char *file, DArray *parsed, DArray *tokens, bool inline_flag) { size_t index = 0; size_t length = tokens->size; while (index < length) { - ParsedValue *parsed_code = parse_token(tokens, &index); + ParsedValue *parsed_code = + parse_token(file, parsed, tokens, &index, inline_flag); if (parsed_code) { darray_push(parsed, parsed_code); free(parsed_code); @@ -37,11 +69,14 @@ void parser(DArray *parsed, DArray *tokens, bool inline_flag) { } } -void free_parsed_value(void *ptr) { - ParsedValue *tagged = ptr; - switch (tagged->type) { +void free_parsed(void *ptr) { + ParsedValue *parsed = ptr; + switch (parsed->type) { case AST_STRING: - free(tagged->data); + free(parsed->data); + break; + case AST_ASSIGN: + free_parse_assign(parsed); break; } } \ No newline at end of file diff --git a/src/parser/parser.h b/src/parser/parser.h index 6304a0c..5a86160 100644 --- a/src/parser/parser.h +++ b/src/parser/parser.h @@ -10,6 +10,7 @@ typedef struct LinkedList LinkedList; typedef enum { AST_STRING, + AST_ASSIGN, } ValueType; typedef struct { @@ -18,11 +19,11 @@ typedef struct { } ParsedValue; -void parser(DArray * parsed, DArray * tokens, bool inline_flag); +void parser(char*file,DArray *parsed, DArray *tokens, bool inline_flag); -ParsedValue * parse_token(DArray * tokens, size_t *index); +ParsedValue *parse_token(char*file,DArray *parsed, DArray *tokens, size_t *index, bool inline_flag); -void free_parsed_value(void *ptr); +void free_parsed(void *ptr); #endif // PARSER_H \ No newline at end of file diff --git a/src/translator/translator.c b/src/translator/translator.c new file mode 100644 index 0000000..00ea2bc --- /dev/null +++ b/src/translator/translator.c @@ -0,0 +1,12 @@ +#include "translator.h" +#include "../dynamic_array/darray.h" +#include +#include + +Translated * init_translator() { + Translated *translated = malloc(sizeof(Translated)); + if (!translated) return NULL; + + darray_init(&translated->bytecode, sizeof(uint8_t)); + return translated; +} \ No newline at end of file diff --git a/src/translator/translator.h b/src/translator/translator.h new file mode 100644 index 0000000..b0bb091 --- /dev/null +++ b/src/translator/translator.h @@ -0,0 +1,18 @@ +#ifndef TRANSLATOR_H +#define TRANSLATOR_H + +#include +#include "../dynamic_array/darray.h" + + +typedef enum { + OP_INIT_STRING +} OperationType; + + +typedef struct { + size_t registerCount; + DArray bytecode; +} Translated; + +#endif \ No newline at end of file diff --git a/test.ar b/test.ar index 5dadd33..2d7a86c 100644 --- a/test.ar +++ b/test.ar @@ -1 +1,2 @@ -'hello world' \ No newline at end of file +"hello world" +"hello world"="hello world" \ No newline at end of file