From d2ab53c625d386a4fbc6a9d5a5eb29faab1b3f0c Mon Sep 17 00:00:00 2001
From: A404M <ahmadmahmoudiprogrammer@gmail.com>
Date: Thu, 19 Sep 2024 15:53:13 +0330
Subject: removing print command and keyword added function call support
 cleaned up keyword and operator checking and speed it up a little bit
 cleaning includes added builtin functions

---
 src/compiler/parser/parser.c | 148 +++++++++++++++++++------------------------
 src/compiler/parser/parser.h |   9 ++-
 2 files changed, 71 insertions(+), 86 deletions(-)

(limited to 'src/compiler/parser')

diff --git a/src/compiler/parser/parser.c b/src/compiler/parser/parser.c
index 2f5b89b..36b2574 100644
--- a/src/compiler/parser/parser.c
+++ b/src/compiler/parser/parser.c
@@ -7,7 +7,7 @@
 
 const char *PARSED_TOKEN_STRINGS[] = {
     "PARSED_TOKEN_NONE",         "PARSED_TOKEN_ROOT",
-    "PARSED_TOKEN_PRINT",        "PARSED_TOKEN_PARENTHESIS",
+    "PARSED_TOKEN_PARENTHESIS",  "PARSED_TOKEN_FUNCTION_CALL",
     "PARSED_TOKEN_VALUE_STRING", "PARSED_TOKEN_EOL",
 };
 
@@ -31,14 +31,6 @@ static const ParseOrder PARSE_ORDER[] = {
                 TOKEN_OPERATOR_COLON,
             },
     },
-    {
-        .ltr = true,
-        .size = 1,
-        .tokens =
-            {
-                TOKEN_KEYWORD_PRINT,
-            },
-    },
     {
         .ltr = true,
         .size = 1,
@@ -88,11 +80,6 @@ void _printParsedNode(const ParsedNode *parsedNode, int indent) {
       printf("]\n");
       --indent;
     } break;
-    case PARSED_TOKEN_PRINT: {
-      const PrintMetadata *metadata = parsedNode->metadata;
-      printf(",operand=\n");
-      _printParsedNode(metadata, indent + 1);
-    } break;
     case PARSED_TOKEN_VALUE_STRING:
       printf("\n");
       break;
@@ -124,7 +111,8 @@ ParsedNode *getUntilCommonFather(ParsedNode *parsedNode, ParsedNode *parent) {
 void deleteParsedNode(ParsedNode *parsedNode) {
   switch (parsedNode->token) {
     case PARSED_TOKEN_NONE:
-      break;
+    case PARSED_TOKEN_VALUE_STRING:
+      goto FREE;
     case PARSED_TOKEN_PARENTHESIS:
     case PARSED_TOKEN_ROOT: {
       ScopeMetadata *metadata = parsedNode->metadata;
@@ -133,23 +121,29 @@ void deleteParsedNode(ParsedNode *parsedNode) {
       }
       free(metadata->operands);
       free(metadata);
-    } break;
-    case PARSED_TOKEN_PRINT: {
-      PrintMetadata *metadata = parsedNode->metadata;
-      deleteParsedNode(metadata);
-    } break;
-    case PARSED_TOKEN_VALUE_STRING:
-      break;
+      goto FREE;
+    }
     case PARSED_TOKEN_EOL: {
       EOLMetadata *metadata = parsedNode->metadata;
       deleteParsedNode(metadata);
-      break;
+      goto FREE;
+    }
+    case PARSED_TOKEN_FUNCTION_CALL: {
+      FunctionCallMetadata *metadata = parsedNode->metadata;
+      ScopeMetadata *scope = metadata->scope;
+      for (size_t i = 0; i < scope->operands_size; ++i) {
+        deleteParsedNode(scope->operands[i]);
+      }
+      free(scope->operands);
+      free(scope);
+      free(metadata);
+      goto FREE;
     }
-    default:
-      fprintf(stderr, "bad parsed token %d at compiler line %d\n",
-              parsedNode->token, __LINE__);
-      exit(1);
   }
+  fprintf(stderr, "bad parsed token %d at compiler line %d\n",
+          parsedNode->token, __LINE__);
+  exit(1);
+FREE:
   free(parsedNode);
 }
 
@@ -168,22 +162,18 @@ ParsedNode *parser(Nodes lexedNodes) {
 
 ScopeMetadata *parserScope(Node *nodesBegin, Node *nodesEnd, ParsedNode *parent,
                            bool (*isAllowed)(ParsedToken)) {
-  if (nodesBegin >= nodesEnd) {
-    return NULL;
-  }
-
   size_t nodes_size = 0;
   ParsedNode **nodes = a404m_malloc(nodes_size * sizeof(ParsedNode *));
   size_t nodes_inserted = 0;
 
   for (size_t order_index = 0; order_index < PARSE_ORDER_SIZE; ++order_index) {
-    const ParseOrder order = PARSE_ORDER[order_index];
+    const ParseOrder *order = &PARSE_ORDER[order_index];
 
-    for (Node *node = order.ltr ? nodesBegin : (nodesEnd - 1);
-         nodesBegin <= node && node < nodesEnd; order.ltr ? ++node : --node) {
-      for (size_t order_tokens_index = 0; order_tokens_index < order.size;
+    for (Node *node = order->ltr ? nodesBegin : (nodesEnd - 1);
+         nodesBegin <= node && node < nodesEnd; order->ltr ? ++node : --node) {
+      for (size_t order_tokens_index = 0; order_tokens_index < order->size;
            ++order_tokens_index) {
-        if (node->token == order.tokens[order_tokens_index]) {
+        if (node->token == order->tokens[order_tokens_index]) {
           ParsedNode *parsedNode =
               parseNode(nodesBegin, nodesEnd, node, parent);
           if (parsedNode == NULL) {
@@ -246,9 +236,9 @@ static bool isAllowedCodeScope(ParsedToken token) {
   switch (token) {
     case PARSED_TOKEN_NONE:
     case PARSED_TOKEN_ROOT:
-    case PARSED_TOKEN_PRINT:
     case PARSED_TOKEN_PARENTHESIS:
     case PARSED_TOKEN_VALUE_STRING:
+    case PARSED_TOKEN_FUNCTION_CALL:
       return false;
     case PARSED_TOKEN_EOL:
       return true;
@@ -261,10 +251,10 @@ static bool isAllowedParenthesisScope(ParsedToken token) {
   switch (token) {
     case PARSED_TOKEN_PARENTHESIS:
     case PARSED_TOKEN_VALUE_STRING:
+    case PARSED_TOKEN_FUNCTION_CALL:
       return true;
     case PARSED_TOKEN_NONE:
     case PARSED_TOKEN_ROOT:
-    case PARSED_TOKEN_PRINT:
     case PARSED_TOKEN_EOL:
       return false;
   }
@@ -285,8 +275,6 @@ ScopeMetadata *parserScopeParenthesis(Node *nodesBegin, Node *nodesEnd,
 ParsedNode *parseNode(Node *nodesBegin, Node *nodesEnd, Node *node,
                       ParsedNode *parent) {
   switch (node->token) {
-    case TOKEN_KEYWORD_PRINT:
-      return parserPrint(nodesBegin, nodesEnd, node, parent);
     case TOKEN_OPERATOR_PARENTHESES_CLOSE:
       return parseParenthesis(nodesBegin, nodesEnd, node, parent);
     case TOKEN_STRING:
@@ -300,37 +288,9 @@ ParsedNode *parseNode(Node *nodesBegin, Node *nodesEnd, Node *node,
   }
 }
 
-ParsedNode *parserPrint(Node *, Node *nodesEnd, Node *node,
-                        ParsedNode *parent) {
-  Node *follow = node + 1;
-
-  if (follow < nodesEnd && follow->token == TOKEN_PARSED) {
-    ParsedNode *root = a404m_malloc(sizeof(ParsedNode));
-    root->strBegin = node->strBegin;
-    root->strEnd = node->strEnd;
-    root->token = PARSED_TOKEN_PRINT;
-    root->parent = parent;
-
-    ParsedNode *operand = root->metadata =
-        getUntilCommonFather(follow->parsedNode, parent);
-    if (operand == NULL || operand->token != PARSED_TOKEN_PARENTHESIS) {
-      fprintf(stderr, "error in parsing token '%s' at compiler line %d\n",
-              TOKEN_STRINGS[node->token], __LINE__);
-      free(root);
-      return NULL;
-    }
-    operand->parent = root;
-
-    node->parsedNode = root;
-    node->token = TOKEN_PARSED;
-    return root;
-  }
-  return NULL;
-}
-
 ParsedNode *parseParenthesis(Node *nodesBegin, Node *, Node *node,
                              ParsedNode *parent) {
-  ParsedNode *parsedNode = a404m_malloc(sizeof(*parsedNode));
+  ParsedNode *root = a404m_malloc(sizeof(*root));
   Node *opening = NULL;
   Node *closing = node;
   for (Node *iter = closing - 1; iter >= nodesBegin; --iter) {
@@ -345,26 +305,48 @@ ParsedNode *parseParenthesis(Node *nodesBegin, Node *, Node *node,
     goto RETURN_ERROR;
   }
 
-  parsedNode->strBegin = opening->strBegin;
-  parsedNode->strEnd = closing->strEnd;
-  parsedNode->token = PARSED_TOKEN_PARENTHESIS;
-  parsedNode->parent = parent;
+  Node *functionName = opening - 1;
+  if (functionName >= nodesBegin && functionName->token == TOKEN_IDENTIFIER) {
+    functionName->token = TOKEN_PARSED;
+    functionName->parsedNode = root;
 
-  const ScopeMetadata *metadata = parsedNode->metadata =
-      parserScopeParenthesis(opening + 1, closing, parsedNode);
+    root->token = PARSED_TOKEN_FUNCTION_CALL;
+    root->strBegin = (opening - 1)->strBegin;
+    root->strEnd = closing->strEnd;
+    root->parent = parent;
 
-  if (metadata == NULL) {
-    fprintf(stderr, "error in parsing token '%s' at compiler line %d\n",
-            TOKEN_STRINGS[node->token], __LINE__);
-    goto RETURN_ERROR;
+    FunctionCallMetadata *metadata = root->metadata =
+        a404m_malloc(sizeof(*metadata));
+    metadata->functionNameBegin = functionName->strBegin;
+    metadata->functionNameEnd = functionName->strEnd;
+
+    if ((metadata->scope =
+             parserScopeParenthesis(opening + 1, closing, root)) == NULL) {
+      fprintf(stderr, "error in parsing token '%s' at compiler line %d\n",
+              TOKEN_STRINGS[node->token], __LINE__);
+      free(metadata);
+      goto RETURN_ERROR;
+    }
+  } else {
+    root->token = PARSED_TOKEN_PARENTHESIS;
+    root->strBegin = opening->strBegin;
+    root->strEnd = closing->strEnd;
+    root->parent = parent;
+
+    if ((root->metadata = parserScopeParenthesis(opening + 1, closing, root)) ==
+        NULL) {
+      fprintf(stderr, "error in parsing token '%s' at compiler line %d\n",
+              TOKEN_STRINGS[node->token], __LINE__);
+      goto RETURN_ERROR;
+    }
   }
 
-  closing->parsedNode = opening->parsedNode = parsedNode;
+  closing->parsedNode = opening->parsedNode = root;
   opening->token = closing->token = TOKEN_PARSED;
-  return parsedNode;
+  return root;
 
 RETURN_ERROR:
-  free(parsedNode);
+  free(root);
   return NULL;
 }
 
@@ -377,7 +359,7 @@ ParsedNode *parseString(Node *node, ParsedNode *parent) {
 
 ParsedNode *parseEOL(Node *nodesBegin, Node *, Node *node, ParsedNode *parent) {
   Node *before = node - 1;
-  if (before < nodesBegin && before->token != TOKEN_PARSED) {
+  if (before < nodesBegin || before->token != TOKEN_PARSED) {
     return NULL;
   }
 
diff --git a/src/compiler/parser/parser.h b/src/compiler/parser/parser.h
index 4a39e17..520c5d1 100644
--- a/src/compiler/parser/parser.h
+++ b/src/compiler/parser/parser.h
@@ -5,8 +5,8 @@
 typedef enum ParsedToken {
   PARSED_TOKEN_NONE = 0,
   PARSED_TOKEN_ROOT,
-  PARSED_TOKEN_PRINT,
   PARSED_TOKEN_PARENTHESIS,
+  PARSED_TOKEN_FUNCTION_CALL,
   PARSED_TOKEN_VALUE_STRING,
   PARSED_TOKEN_EOL,
 } ParsedToken;
@@ -31,6 +31,11 @@ typedef struct ScopeMetadata {
   struct ParsedNode **operands;
   size_t operands_size;
 } ScopeMetadata;
+typedef struct FunctionCallMetadata {
+  char const *functionNameBegin;
+  char const *functionNameEnd;
+  ScopeMetadata *scope;
+} FunctionCallMetadata ;
 typedef ParsedNode PrintMetadata;
 typedef ParsedNode EOLMetadata;
 
@@ -56,8 +61,6 @@ extern ScopeMetadata *parserScopeParenthesis(Node *nodesBegin, Node *nodesEnd,
 extern ParsedNode *parseNode(Node *nodesBegin, Node *nodesEnd, Node *node,
                              ParsedNode *parent);
 
-extern ParsedNode *parserPrint(Node *nodesBegin, Node *nodesEnd, Node *node,
-                               ParsedNode *parent);
 extern ParsedNode *parseParenthesis(Node *nodesBegin, Node *nodesEnd,
                                     Node *node, ParsedNode *parent);
 extern ParsedNode *parseString(Node *node, ParsedNode *parent);
-- 
cgit v1.2.3