From 59f43dc7ca6fddecf6678e8c31bae0d8a335d50e Mon Sep 17 00:00:00 2001 From: Keyvan Kambakhsh Date: Sat, 30 Nov 2024 00:33:38 +0330 Subject: [PATCH] feat: Add __asm__ statement --- lexer.c | 2 ++ lexer.h | 1 + parser/asm.c | 81 ++++++++++++++++++++++++++++++++++++++++++++++ parser/asm.h | 15 +++++++++ parser/statement.c | 9 ++++++ 5 files changed, 108 insertions(+) create mode 100644 parser/asm.c create mode 100644 parser/asm.h diff --git a/lexer.c b/lexer.c index 352dde2..c157642 100644 --- a/lexer.c +++ b/lexer.c @@ -126,6 +126,8 @@ typed_token *next_keyword_or_identifier(char **inp_ptr) return new_simp_tkn(TKN_DEFAULT); else if (strcmp(val, "extern") == 0) return new_simp_tkn(TKN_EXTERN); + else if (strcmp(val, "__asm__") == 0) + return new_simp_tkn(TKN_ASM); else return new_tkn(TKN_ID, val, ident_tkn_debug); } diff --git a/lexer.h b/lexer.h index d2d303b..db788f9 100644 --- a/lexer.h +++ b/lexer.h @@ -29,6 +29,7 @@ typed_token *tokenize(char *inp); #define TKN_TYPEDEF 12 #define TKN_GOTO 13 #define TKN_EXTERN 14 +#define TKN_ASM 15 // Single letter symbols #define TKN_L_PAREN 16 diff --git a/parser/asm.c b/parser/asm.c new file mode 100644 index 0000000..223dec3 --- /dev/null +++ b/parser/asm.c @@ -0,0 +1,81 @@ + +#include + +#include "../lexer.h" +#include "parser.h" +#include "asm.h" +#include "statement.h" +#include "../codegen/codegen.h" +#include "../linked_list.h" + +apply_result *asm_apply(parser_node *node, context *ctx) +{ + node_asm *as = (node_asm *)node->data; + list_node *curr = as->lines->first; + while (curr) + { + add_text(ctx, curr->value); + curr = curr->next; + } + return NULL; +} + +void asm_debug(int depth, parser_node *node) +{ + node_asm *as = (node_asm *)node->data; + printtabs(depth); + list_node *curr = as->lines->first; + printf("Asm:\n"); + while (curr) + { + printtabs(depth + 1); + printf("\"%s\"", (char *)curr->value); + curr = curr->next; + } +} + +parser_node *parse_asm(typed_token **tkns_ptr) +{ + typed_token *tkn = *tkns_ptr; + + if (tkn->type_id == TKN_ASM) + { + tkn = tkn->next; + if (tkn->type_id == TKN_L_PAREN) + { + tkn = tkn->next; + linked_list *lines = new_linked_list(); + while (tkn) + { + if (tkn->type_id == TKN_R_PAREN) + { + tkn = tkn->next; + if (tkn->type_id == TKN_SEMICOLON) + { + tkn = tkn->next; + *tkns_ptr = tkn; + + parser_node *node = (parser_node *)malloc(sizeof(parser_node)); + node->data = (void *)malloc(sizeof(node_compound_statement)); + node->debug = asm_debug; + node->apply = asm_apply; + node_asm *as = (node_asm *)node->data; + as->lines = lines; + + return node; + } + } + else if (tkn->type_id == TKN_LIT_STR) + { + add_to_list(lines, tkn->data); + tkn = tkn->next; + } + else + { + return NULL; + } + } + } + } + return NULL; +} \ No newline at end of file diff --git a/parser/asm.h b/parser/asm.h new file mode 100644 index 0000000..dc28016 --- /dev/null +++ b/parser/asm.h @@ -0,0 +1,15 @@ +#ifndef ASM_H +#define ASM_H + +#include "../lexer.h" +#include "parser.h" +#include "../linked_list.h" + +parser_node *parse_asm(typed_token **tkns_ptr); + +typedef struct +{ + linked_list *lines; +} node_asm; + +#endif diff --git a/parser/statement.c b/parser/statement.c index 12782ed..09629ae 100644 --- a/parser/statement.c +++ b/parser/statement.c @@ -12,6 +12,7 @@ #include "if.h" #include "while.h" #include "goto.h" +#include "asm.h" apply_result *compound_statement_apply(parser_node *node, context *ctx) { @@ -165,6 +166,14 @@ parser_node *parse_statement(typed_token **tkns_ptr) { typed_token *tkn = *tkns_ptr; parser_node *ret = NULL; + + ret = parse_asm(&tkn); + if (ret) + { + *tkns_ptr = tkn; + return ret; + } + ret = parse_var_decl(&tkn); if (ret) {