From f79290084948f3cf140395c270c07cf29ca58e8d Mon Sep 17 00:00:00 2001
From: A404M <ahmadmahmoudiprogrammer@gmail.com>
Date: Sun, 22 Sep 2024 19:34:43 +0330
Subject: Better errors Added variables

---
 src/vm/runner/runner.c | 115 +++++++++++++++++++++++++++++++++++++++++++------
 1 file changed, 101 insertions(+), 14 deletions(-)

(limited to 'src/vm/runner/runner.c')

diff --git a/src/vm/runner/runner.c b/src/vm/runner/runner.c
index de1a478..4fcea52 100644
--- a/src/vm/runner/runner.c
+++ b/src/vm/runner/runner.c
@@ -3,6 +3,7 @@
 #include <compiler/code_generator/code_generator.h>
 #include <stdio.h>
 #include <stdlib.h>
+#include <string.h>
 #include <utils/memory/memory.h>
 #include <utils/types.h>
 
@@ -15,18 +16,39 @@ const char *BUILTIN_FUNCTION_NAMES[] = {
 const size_t BUILTIN_FUNCTIONS_SIZE =
     sizeof(BUILTIN_FUNCTIONS) / sizeof(BuiltinFunction);
 
-bool runner(Instructions instructions) {
+bool runner(SourceCode code) {
+  Instructions instructions = codeGenerator(code);
+  if (instructions.size != ERROR_SIZE) {
+    bool ranSuccess = _runner(instructions);
+    deleteInstructions(instructions);
+    return ranSuccess;
+  }
+  return false;
+}
+
+bool _runner(Instructions instructions) {
   size_t stack_size = 0;
   void **stack = a404m_malloc(stack_size * sizeof(void *));
   size_t stack_inserted = 0;
 
+  size_t variables_size = 0;
+  RunnerVariable **variables =
+      a404m_malloc(variables_size * sizeof(RunnerVariable *));
+  size_t variables_inserted = 0;
+
   for (size_t i = 0; i < instructions.size; ++i) {
     if (!runInstruction(instructions.instructions[i], &stack, &stack_size,
-                        &stack_inserted)) {
+                        &stack_inserted, &variables, &variables_size,
+                        &variables_inserted)) {
       goto RETURN_ERROR;
     }
   }
 
+  for(size_t i = 0;i < variables_size;++i){
+    free(variables[i]);
+  }
+
+  free(variables);
   free(stack);
   return true;
 
@@ -38,7 +60,7 @@ RETURN_ERROR:
 BuiltinFunction getBuiltinFunction(SizedString string) {
   for (size_t i = 0; i < BUILTIN_FUNCTIONS_SIZE; ++i) {
     const char *search = BUILTIN_FUNCTION_NAMES[i];
-    // faster than strlen+strncpy
+    // faster than strlen+strncmp
     for (size_t j = 0;; ++j) {
       const char searchChar = search[j];
       if (j == string.size) {
@@ -59,21 +81,25 @@ BuiltinFunction getBuiltinFunction(SizedString string) {
 
 bool runInstruction(Instruction instruction, void ***restrict stack,
                     size_t *restrict stack_size,
-                    size_t *restrict stack_inserted) {
+                    size_t *restrict stack_inserted,
+                    RunnerVariable ***restrict variables,
+                    size_t *restrict variables_size,
+                    size_t *restrict variables_inserted) {
   switch (instruction.command) {
+    case COMMAND_PUSH_IDENTIFIER: {
+      const CommandPushIdentifierOperand *operand = instruction.operand;
+      pushToStack(getRunnerVariable(operand, variables, variables_inserted)->value,
+                  stack, stack_size, stack_inserted);
+      return true;
+    }
     case COMMAND_PUSH_STRING: {
-      SizedString *string = instruction.operand;
-      if (*stack_inserted == *stack_size) {
-        *stack_size += *stack_size / 2 + 1;
-        *stack = a404m_realloc(*stack, *stack_size * sizeof(void *));
-      }
-      (*stack)[*stack_inserted] = string;
-      ++*stack_inserted;
+      CommandPushStringOperand *operand = instruction.operand;
+      pushToStack(operand, stack, stack_size, stack_inserted);
       return true;
     }
     case COMMAND_CALL_FUNCTION: {
       SizedString *functionName = instruction.operand;
-      BuiltinFunction function = getBuiltinFunction(*functionName);
+      const BuiltinFunction function = getBuiltinFunction(*functionName);
       if (function == NULL) {
         fprintf(stderr, "function '%.*s' not found\n", (int)functionName->size,
                 functionName->str);
@@ -82,13 +108,74 @@ bool runInstruction(Instruction instruction, void ***restrict stack,
       function(stack, stack_inserted);
       return true;
     }
+    case COMMAND_POP_IDENTIFIER: {
+      const CommandPopIdentifierOperand *operand = instruction.operand;
+      setRunnerVariable(popFromStack(stack, stack_inserted), operand, variables,
+                        variables_size, variables_inserted);
+      return true;
+    }
     case COMMAND_NONE:
   }
-  fprintf(stderr, "unknown command '%d'\n", instruction.command);
+  fprintf(stderr, "bad command '%d'\n", instruction.command);
   return false;
 }
 
+RunnerVariable *getRunnerVariable(const SizedString *varName,
+                                  RunnerVariable ***restrict variables,
+                                  size_t *restrict variables_inserted) {
+  for (size_t i = *variables_inserted - 1; i != (typeof(i))-1; ++i) {
+    RunnerVariable *variable = (*variables)[i];
+    if (variable->name->size == varName->size &&
+        strncmp(varName->str, variable->name->str, varName->size) == 0) {
+      return variable;
+    }
+  }
+  return NULL;
+}
+
+void setRunnerVariable(void *value, const SizedString *varName,
+                       RunnerVariable ***restrict variables,
+                       size_t *restrict variables_size,
+                       size_t *restrict variables_inserted) {
+  RunnerVariable *variable =
+      getRunnerVariable(varName, variables, variables_inserted);
+  if (variable != NULL) {
+    variable->value = value;
+    return;
+  }
+
+  variable = a404m_malloc(sizeof(*variable));
+  variable->name = varName;
+  variable->value = value;
+
+  if (*variables_inserted == *variables_size) {
+    *variables_size += *variables_size / 2 + 1;
+    *variables =
+        a404m_realloc(*variables, *variables_size * sizeof(RunnerVariable *));
+  }
+  (*variables)[*variables_inserted] = variable;
+  *variables_inserted += 1;
+}
+
+void *popFromStack(void ***restrict stack, size_t *restrict stack_inserted) {
+  if (*stack_inserted == 0) {
+    fprintf(stderr, "stack underflow\n");
+    exit(1);
+  }
+  return (*stack)[--*stack_inserted];
+}
+
+void pushToStack(void *value, void ***restrict stack,
+                 size_t *restrict stack_size, size_t *restrict stack_inserted) {
+  if (*stack_inserted == *stack_size) {
+    *stack_size += *stack_size / 2 + 1;
+    *stack = a404m_realloc(*stack, *stack_size * sizeof(void *));
+  }
+  (*stack)[*stack_inserted] = value;
+  ++*stack_inserted;
+}
+
 void print(void ***restrict stack, size_t *restrict stack_inserted) {
-  const SizedString *string = (*stack)[--*stack_inserted];
+  const SizedString *string = popFromStack(stack, stack_inserted);
   printf("%.*s", (int)string->size, string->str);
 }
-- 
cgit v1.2.3