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/code_generator/code_generator.c | 69 ++++++++++++++++------------
 1 file changed, 39 insertions(+), 30 deletions(-)

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

diff --git a/src/compiler/code_generator/code_generator.c b/src/compiler/code_generator/code_generator.c
index 0cd2722..8560129 100644
--- a/src/compiler/code_generator/code_generator.c
+++ b/src/compiler/code_generator/code_generator.c
@@ -3,13 +3,13 @@
 #include <compiler/parser/parser.h>
 #include <stdio.h>
 #include <stdlib.h>
-
-#include "utils/memory/memory.h"
-#include "utils/types.h"
+#include <string.h>
+#include <utils/memory/memory.h>
+#include <utils/types.h>
 
 const char *COMMAND_STRINGS[] = {
     "COMMAND_NONE",
-    "COMMAND_PRINT",
+    "COMMAND_CALL_FUNCTION",
     "COMMAND_PUSH_STRING",
 };
 
@@ -17,16 +17,15 @@ void printInstruction(Instruction instruction) {
   printf("%s", COMMAND_STRINGS[instruction.command]);
   switch (instruction.command) {
     case COMMAND_NONE:
-    case COMMAND_PRINT:
-      break;
+      printf("\n");
+      return;
+    case COMMAND_CALL_FUNCTION:
     case COMMAND_PUSH_STRING:
       SizedString *sizedString = instruction.operand;
-      printf(" '%.*s'", (int)sizedString->size, sizedString->str);
-      break;
-    default:
-      fprintf(stderr, "bad instruction %d\n", instruction.command);
+      printf(" '%.*s'\n", (int)sizedString->size, sizedString->str);
+      return;
   }
-  printf("\n");
+  fprintf(stderr, "bad instruction %d\n", instruction.command);
 }
 
 void printInstructions(Instructions instructions) {
@@ -38,16 +37,15 @@ void printInstructions(Instructions instructions) {
 void deleteInstruction(Instruction instruction) {
   switch (instruction.command) {
     case COMMAND_NONE:
-    case COMMAND_PRINT:
-      break;
+      return;
     case COMMAND_PUSH_STRING:
+    case COMMAND_CALL_FUNCTION:
       SizedString *sizedString = instruction.operand;
       free(sizedString->str);
       free(sizedString);
-      break;
-    default:
-      fprintf(stderr, "bad instruction %d\n", instruction.command);
+      return;
   }
+  fprintf(stderr, "bad instruction %d\n", instruction.command);
 }
 
 void deleteInstructions(Instructions instructions) {
@@ -92,7 +90,31 @@ bool nodeToInstruction(ParsedNode *node, Instruction **instructions,
                        size_t *instructions_size,
                        size_t *instructions_inserted) {
   switch (node->token) {
-      // TODO: this is wrong when you want functions
+    case PARSED_TOKEN_FUNCTION_CALL: {
+      FunctionCallMetadata *metadata = node->metadata;
+      const ScopeMetadata *scope = metadata->scope;
+      for (size_t i = 0; i < scope->operands_size; ++i) {
+        if (!nodeToInstruction(scope->operands[i], instructions,
+                               instructions_size, instructions_inserted)) {
+          return false;
+        }
+      }
+
+      SizedString *string = a404m_malloc(sizeof(*string));
+      string->size = metadata->functionNameEnd - metadata->functionNameBegin;
+      string->str = a404m_malloc(string->size);
+      strncpy(string->str, metadata->functionNameBegin, string->size);
+      if (string == NULL) {
+        return false;
+      }
+      const Instruction instruction = {
+          .command = COMMAND_CALL_FUNCTION,
+          .operand = string,
+      };
+      insertInstruction(instruction, instructions, instructions_size,
+                        instructions_inserted);
+      return true;
+    }
     case PARSED_TOKEN_PARENTHESIS: {
       const ScopeMetadata *metadata = node->metadata;
       for (size_t i = 0; i < metadata->operands_size; ++i) {
@@ -106,19 +128,6 @@ bool nodeToInstruction(ParsedNode *node, Instruction **instructions,
     case PARSED_TOKEN_EOL:
       return nodeToInstruction(node->metadata, instructions, instructions_size,
                                instructions_inserted);
-    case PARSED_TOKEN_PRINT:
-      if (nodeToInstruction(node->metadata, instructions, instructions_size,
-                            instructions_inserted)) {
-        const Instruction instruction = {
-            .command = COMMAND_PRINT,
-            .operand = NULL,
-        };
-        insertInstruction(instruction, instructions, instructions_size,
-                          instructions_inserted);
-        return true;
-      } else {
-        return false;
-      }
     case PARSED_TOKEN_VALUE_STRING: {
       SizedString *string = nodeToString(node);
       if (string == NULL) {
-- 
cgit v1.2.3