From addd54dc31603dc204773d3108dba4e000cd7657 Mon Sep 17 00:00:00 2001
From: A404M <ahmadmahmoudiprogrammer@gmail.com>
Date: Tue, 8 Oct 2024 04:16:27 +0330
Subject: added fasm support added compiler options tried to compile to fasm
 first

---
 src/compiler/tree_parser/tree_parser.c | 262 ++++++++++++++++++++++++---------
 1 file changed, 194 insertions(+), 68 deletions(-)

(limited to 'src/compiler/tree_parser/tree_parser.c')

diff --git a/src/compiler/tree_parser/tree_parser.c b/src/compiler/tree_parser/tree_parser.c
index f657f97..07bad0a 100644
--- a/src/compiler/tree_parser/tree_parser.c
+++ b/src/compiler/tree_parser/tree_parser.c
@@ -1,15 +1,9 @@
 #include "tree_parser.h"
 
-#include <compiler/error_helper/error_helper.h>
-#include <compiler/lexer/lexer.h>
-#include <compiler/parser/parser.h>
-#include <stdint.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <utils/file.h>
-#include <utils/memory/memory.h>
-#include <utils/types.h>
 
 const char *TREE_TOKEN_STRINGS[] = {
     "TREE_TOKEN_NONE",
@@ -25,10 +19,27 @@ const char *TREE_TOKEN_STRINGS[] = {
     "TREE_TOKEN_FUNCTION",
 };
 
+static void _printParsedTreeVariable(const TreeDefineVariableMetadata *variable,
+                                     int indent) {
+  if (variable == NULL) {
+    for (int i = 0; i < indent; ++i) printf(" ");
+    printf("null\n");
+    return;
+  }
+  for (int i = 0; i < indent; ++i) printf(" ");
+  printf("{name='%.*s',type=%p,value=\n",
+         (int)(variable->nameEnd - variable->nameBegin), variable->nameBegin,
+         variable->type);
+  _printParsedTreeNode(variable->value, indent + 1);
+  for (int i = 0; i < indent; ++i) printf(" ");
+  printf("}\n");
+}
+
 void _printParsedTreeNode(const ParsedTree *parsedTree, int indent) {
+  for (int i = 0; i < indent; ++i) printf(" ");
   if (parsedTree == NULL) {
-    for (int i = 0; i < indent; ++i) printf(" ");
     printf("null\n");
+    return;
   }
   printf("{token=%s", TREE_TOKEN_STRINGS[parsedTree->token]);
   switch (parsedTree->token) {
@@ -36,19 +47,83 @@ void _printParsedTreeNode(const ParsedTree *parsedTree, int indent) {
       goto RETURN_SUCCESS;
     case TREE_TOKEN_ROOT:
     case TREE_TOKEN_GLOBAL_SCOPE:
-    case TREE_TOKEN_LOCAL_SCOPE:
-    case TREE_TOKEN_FUNCTION_CALL:
+    case TREE_TOKEN_LOCAL_SCOPE: {
+      const TreeScopeMetadata *metadata = parsedTree->metadata;
+      for (int i = 0; i < indent; ++i) printf(" ");
+      printf(",lines=\n");
+      for (size_t i = 0; i < metadata->lines_size; ++i) {
+        _printParsedTreeNode(metadata->lines[i], indent + 1);
+      }
+      for (int i = 0; i < indent; ++i) printf(" ");
+      printf(",variables=\n");
+      for (size_t i = 0; i < metadata->variables_size; ++i) {
+        _printParsedTreeVariable(metadata->variables[i], indent + 1);
+      }
+      goto RETURN_SUCCESS;
+    }
+    case TREE_TOKEN_FUNCTION_CALL: {
+      const TreeFunctionCallMetadata *metadata = parsedTree->metadata;
+      printf(",lines=\n");
+      for (size_t i = 0; i < metadata->values_size; ++i) {
+        _printParsedTreeNode(metadata->values[i], indent + 1);
+      }
+      goto RETURN_SUCCESS;
+    }
     case TREE_TOKEN_DEFINE_VARIABLE:
-    case TREE_TOKEN_IDENTIFIER:
-    case TREE_TOKEN_VALUE_STRING:
-    case TREE_TOKEN_STRUCT:
-    case TREE_TOKEN_DEFINE_CONSTANT:
-    case TREE_TOKEN_FUNCTION:
+    case TREE_TOKEN_DEFINE_CONSTANT: {
+      const TreeDefineVariableMetadata *metadata = parsedTree->metadata;
+      printf(",define=\n");
+      _printParsedTreeVariable(metadata, indent + 1);
+      goto RETURN_SUCCESS;
+    }
+    case TREE_TOKEN_IDENTIFIER: {
+      const TreeIdentifierMetadata *metadata = parsedTree->metadata;
+      printf(",variable=\n");
+      _printParsedTreeVariable(metadata->variable, indent + 1);
+      goto RETURN_SUCCESS;
+    }
+    case TREE_TOKEN_VALUE_STRING: {
+      const TreeStringValueMetadata *metadata = parsedTree->metadata;
+      printf(",str='%.*s'\n", (int)metadata->size, metadata->str);
+      goto RETURN_SUCCESS;
+    }
+    case TREE_TOKEN_STRUCT: {
+      const TreeStructMetadata *metadata = parsedTree->metadata;
+      printf(",metadata=%p\n", metadata);
+      goto RETURN_SUCCESS;
+    }
+    case TREE_TOKEN_FUNCTION: {
+      const TreeFunctionMetadata *metadata = parsedTree->metadata;
+      const TreeScopeMetadata *scope = metadata->scope;
+      printf(",scope=\n");
+      if (scope != NULL) {
+        for (int i = 0; i < indent; ++i) printf(" ");
+        printf(",lines=\n");
+        for (size_t i = 0; i < scope->lines_size; ++i) {
+          _printParsedTreeNode(scope->lines[i], indent + 1);
+        }
+        for (int i = 0; i < indent; ++i) printf(" ");
+        printf(",variables=\n");
+        for (size_t i = 0; i < scope->variables_size; ++i) {
+          _printParsedTreeVariable(scope->variables[i], indent + 1);
+        }
+      } else {
+        for (int i = 0; i < indent; ++i) printf(" ");
+        printf("null\n");
+      }
+      for (int i = 0; i < indent; ++i) printf(" ");
+      printf(",params=\n");
+      for (size_t i = 0; i < metadata->params_size; ++i) {
+        _printParsedTreeVariable(metadata->params[i], indent + 1);
+      }
+      goto RETURN_SUCCESS;
+    }
   }
   fprintf(stderr, "bad parsed tree token %d at %s:%d", parsedTree->token,
           __FILE_NAME__, __LINE__);
   exit(1);
 RETURN_SUCCESS:
+  for (int i = 0; i < indent; ++i) printf(" ");
   printf("}\n");
 };
 
@@ -143,6 +218,9 @@ ParsedTree *treeParser(SourceCode *code) {
 
   for (size_t i = 0; i < code->size; ++i) {
     ParsedNode *const nParsedNode = parser(code, i);
+    if (nParsedNode == NULL) {
+      goto RETURN_ERROR;
+    }
     ParserScopeMetadata *const nscope = nParsedNode->metadata;
     for (size_t j = 0; j < nscope->operands_size; ++j) {
       size_t scopeSize =
@@ -160,12 +238,52 @@ ParsedTree *treeParser(SourceCode *code) {
     nscope->operands_size = 0;
     deleteParsedNode(nParsedNode);
   }
-  if (parsedNode == NULL) {
-    return NULL;
+  ParsedTree *tree = _treeParser(parsedNode, code);
+  deleteParsedNode(parsedNode);
+  return tree;
+RETURN_ERROR:
+  deleteParsedNode(parsedNode);
+  return NULL;
+}
+
+ParsedTree *treeParserWithPrint(SourceCode *code) {
+  ParserScopeMetadata *scope = a404m_malloc(sizeof(*scope));
+  scope->operands_size = 0;
+  scope->operands = a404m_malloc(scope->operands_size * sizeof(ParsedNode *));
+  ParsedNode *const parsedNode =
+      newParsedNode(NULL, NULL, PARSED_TOKEN_ROOT, scope, NULL);
+
+  for (size_t i = 0; i < code->size; ++i) {
+    ParsedNode *const nParsedNode = parserWithPrint(code, i);
+    if (nParsedNode == NULL) {
+      fprintf(stderr, "Error in parser");
+      goto RETURN_ERROR;
+    }
+    printf("----parsed '%s'\n", code->codes[i]->filePath);
+    printParsedNode(parsedNode);
+    ParserScopeMetadata *const nscope = nParsedNode->metadata;
+    for (size_t j = 0; j < nscope->operands_size; ++j) {
+      size_t scopeSize =
+          a404m_malloc_usable_size(scope->operands) / sizeof(ParsedNode *);
+      if (scopeSize == scope->operands_size) {
+        scopeSize += scopeSize / 2 + 1;
+        scope->operands =
+            a404m_realloc(scope->operands, scopeSize * sizeof(ParsedNode *));
+      }
+      scope->operands[scope->operands_size] = nscope->operands[j];
+      scope->operands_size += 1;
+    }
+    free(nscope->operands);
+    nscope->operands = NULL;
+    nscope->operands_size = 0;
+    deleteParsedNode(nParsedNode);
   }
   ParsedTree *tree = _treeParser(parsedNode, code);
   deleteParsedNode(parsedNode);
   return tree;
+RETURN_ERROR:
+  deleteParsedNode(parsedNode);
+  return NULL;
 }
 
 ParsedTree *_treeParser(const ParsedNode *node, SourceCode *code) {
@@ -275,7 +393,7 @@ ParsedTree *treeParseLocalScope(const ParsedNode *node, SourceCode *code,
   const size_t newScopes_size = scopes_size + 1;
   TreeScopeMetadata *newScopes[newScopes_size];
 
-  memcpy(newScopes, scopes, scopes_size);
+  memcpy(newScopes, scopes, scopes_size * sizeof(TreeScopeMetadata *));
   newScopes[newScopes_size - 1] = metadata;
 
   for (size_t i = 0; i < operands_size; ++i) {
@@ -285,31 +403,18 @@ ParsedTree *treeParseLocalScope(const ParsedNode *node, SourceCode *code,
     if (parsedTree == NULL) {
       goto RETURN_ERROR;
     }
-    switch (parsedTree->token) {
-      case TREE_TOKEN_ROOT:
-        printError("It is not allowed here", code, operand->strBegin,
-                   operand->strEnd);
-        goto RETURN_ERROR;
-      case TREE_TOKEN_DEFINE_CONSTANT:
-      case TREE_TOKEN_DEFINE_VARIABLE: {
-        TreeDefineVariableMetadata *const variableDefine = parsedTree->metadata;
-        if (variableDefine == NULL) {
-          goto RETURN_ERROR;
-        }
-        pushVariableToScope(metadata, variableDefine);
-      }
-      /* fall through */
-      default:
-        pushLineToScope(metadata, parsedTree);
-        continue;
+    if (parsedTree->token != TREE_TOKEN_ROOT) {
+      pushLineToScope(metadata, parsedTree);
+    } else {
+      printError("'%s' Is not allowed here", code, operand->strBegin,
+                 operand->strEnd, PARSED_TOKEN_STRINGS[operand->token]);
+      goto RETURN_ERROR;
     }
-    printError("'%s' Is not allowed here", code, operand->strBegin,
-               operand->strEnd, PARSED_TOKEN_STRINGS[operand->token]);
-    goto RETURN_ERROR;
   }
 
-  metadata->variables =
-      a404m_realloc(metadata->variables, metadata->variables_size);
+  metadata->variables = a404m_realloc(
+      metadata->variables,
+      metadata->variables_size * sizeof(TreeDefineVariableMetadata *));
 
   return tree;
 
@@ -327,37 +432,37 @@ TreeDefineVariableMetadata *treeParseDefineVariable(ParsedTree *tree,
   TreeDefineVariableMetadata *define = a404m_malloc(sizeof(*define));
   define->tree = tree;
 
-  ParserVariableDefineMetadata *metadata = node->metadata;
+  const ParserVariableDefineMetadata *node_metadata = node->metadata;
 
-  if (metadata->value == NULL) {
+  if (node_metadata->value == NULL) {
     define->value = NULL;
-  } else if ((define->value = treeParseExpr(metadata->value, code, scopes,
+  } else if ((define->value = treeParseExpr(node_metadata->value, code, scopes,
                                             scopes_size)) == NULL) {
     goto RETURN_ERROR;
   }
 
-  if (metadata->name->token == PARSED_TOKEN_IDENTIFIER) {
-    define->nameBegin = metadata->name->strBegin;
-    define->nameEnd = metadata->name->strEnd;
+  if (node_metadata->name->token == PARSED_TOKEN_IDENTIFIER) {
+    define->nameBegin = node_metadata->name->strBegin;
+    define->nameEnd = node_metadata->name->strEnd;
   } else {
-    printError("Names should be an identifier", code, metadata->name->strBegin,
-               metadata->name->strEnd);
+    printError("Names should be an identifier", code,
+               node_metadata->name->strBegin, node_metadata->name->strEnd);
     goto RETURN_ERROR;
   }
 
-  if (metadata->type == NULL) {
+  if (node_metadata->type == NULL) {
     define->type = getTreeExpressionType(define->value);
-  } else if (metadata->type->token == PARSED_TOKEN_IDENTIFIER) {
+  } else if (node_metadata->type->token == PARSED_TOKEN_IDENTIFIER) {
     const TreeDefineVariableMetadata *variable =
-        getVariable(metadata->type->strBegin, metadata->type->strEnd, code,
-                    scopes, scopes_size);
+        getVariable(node_metadata->type->strBegin, node_metadata->type->strEnd,
+                    code, scopes, scopes_size);
     if (variable == NULL) {
       goto RETURN_ERROR;
     }
     define->type = getType(variable);
   } else {
     printError("Types should be an identifier (for now)", code,
-               metadata->type->strBegin, metadata->type->strEnd);
+               node_metadata->type->strBegin, node_metadata->type->strEnd);
     goto RETURN_ERROR;
   }
 
@@ -366,6 +471,8 @@ TreeDefineVariableMetadata *treeParseDefineVariable(ParsedTree *tree,
     goto RETURN_ERROR;
   }
 
+  pushVariableToScope(scopes[scopes_size - 1], define);
+
   return define;
 
 RETURN_ERROR:
@@ -536,14 +643,8 @@ ParsedTree *treeParseFunction(const ParsedNode *node, SourceCode *code,
   ParsedTree *parsedTree =
       treeParseNode(node_metadata->type, code, scopes, scopes_size);
 
-  if (parsedTree == NULL) {
-    goto RETURN_ERROR;
-  }
-  metadata->returnType = getTreeExpressionType(parsedTree);
-  // TODO: this is not right
-  deleteParsedTree(parsedTree);
-
-  const ParserScopeMetadata *params = node_metadata->params->metadata;
+  const size_t newScopes_size = scopes_size + 1;
+  TreeScopeMetadata *newScopes[newScopes_size];
 
   metadata->params = a404m_malloc(0);
   metadata->params_size = 0;
@@ -555,10 +656,30 @@ ParsedTree *treeParseFunction(const ParsedNode *node, SourceCode *code,
   metadata->scope->lines = a404m_malloc(0);
   metadata->scope->lines_size = 0;
 
+  memcpy(newScopes, scopes, scopes_size * sizeof(TreeScopeMetadata *));
+  newScopes[newScopes_size - 1] = metadata->scope;
+
+  if (parsedTree == NULL) {
+    goto RETURN_ERROR;
+  }
+  metadata->returnType = getTreeExpressionType(parsedTree);
+  // TODO: this is not right
+  deleteParsedTree(parsedTree);
+
+  const ParserScopeMetadata *params = node_metadata->params->metadata;
+
   for (size_t i = 0; i < params->operands_size; ++i) {
     const ParsedNode *operand = params->operands[i];
+    if (operand->token == PARSED_TOKEN_COMMA) {
+      operand = (ParserCommaMetadata *)operand->metadata;
+    }
+    if (operand->token != PARSED_TOKEN_DEFINE_VARIABLE) {
+      printError(
+          "Only variable definition is allowed in function parameter list",
+          code, operand->strBegin, operand->strEnd);
+    }
     TreeDefineVariableMetadata *define =
-        treeParseDefineVariable(tree, operand, code, scopes, scopes_size);
+        treeParseDefineVariable(tree, operand, code, newScopes, newScopes_size);
     if (define == NULL) {
       goto RETURN_ERROR;
     }
@@ -578,10 +699,15 @@ ParsedTree *treeParseFunction(const ParsedNode *node, SourceCode *code,
                                           sizeof(TreeDefineVariableMetadata *));
 
   if (node_metadata->body != NULL) {
-    printError("Not implemented", code, node->strBegin, node->strEnd);
-
-    goto RETURN_ERROR;
-    return NULL;
+    const ParserScopeMetadata *body = node_metadata->body->metadata;
+    for (size_t i = 0; i < body->operands_size; ++i) {
+      ParsedTree *parsedTree =
+          treeParseNode(body->operands[i], code, newScopes, newScopes_size);
+      if (parsedTree == NULL) {
+        goto RETURN_ERROR;
+      }
+      pushLineToScope(metadata->scope, parsedTree);
+    }
   } else {
     free(metadata->scope->lines);
     metadata->scope->lines_size = 0;
@@ -589,7 +715,7 @@ ParsedTree *treeParseFunction(const ParsedNode *node, SourceCode *code,
 
   return tree;
 RETURN_ERROR:
-
+  // TODO: doesn't delete all of them
   free(metadata);
   free(tree);
   return NULL;
@@ -598,12 +724,12 @@ RETURN_ERROR:
 ParsedTree *treeParseImport(const ParsedNode *node, SourceCode *code,
                             TreeScopeMetadata *[], size_t) {
   const ParserImportMetadata *node_metadata = node->metadata;
-  SizedString *path = nodeToString(node_metadata, code);
+  SizedString *const path = nodeToString(node_metadata, code);
   if (path == NULL) {
     return NULL;
   }
 
-  Code *fileCode = read_whole_file(path->str);
+  Code *const fileCode = read_whole_file(path->str);
   if (fileCode == NULL) {
     goto RETURN_ERROR;
   }
-- 
cgit v1.2.3