From 9eb9be33d7623a4759b0794073bd32489b865b3d Mon Sep 17 00:00:00 2001
From: A404M <ahmadmahmoudiprogrammer@gmail.com>
Date: Tue, 18 Feb 2025 21:46:27 +0330
Subject: add plus minus to floats fix memory leaks

---
 src/compiler/ast-tree.c |  25 +++++-----
 src/runner/runner.c     | 120 +++++++++++++++++++++++++++++++-----------------
 test/main.felan         |   2 +-
 3 files changed, 89 insertions(+), 58 deletions(-)

diff --git a/src/compiler/ast-tree.c b/src/compiler/ast-tree.c
index 9347303..66a5f6b 100644
--- a/src/compiler/ast-tree.c
+++ b/src/compiler/ast-tree.c
@@ -416,7 +416,8 @@ void astTreeDestroy(AstTree tree) {
   case AST_TREE_TOKEN_VARIABLE_DEFINE:
     return;
   case AST_TREE_TOKEN_VALUE_FLOAT: {
-    free(tree.metadata);
+    AstTreeFloat *metadata = tree.metadata;
+    free(metadata);
     return;
   }
   case AST_TREE_TOKEN_OPERATOR_PLUS:
@@ -2119,7 +2120,7 @@ bool setTypesValueInt(AstTree *tree, AstTreeSetTypesHelper helper) {
     AstTreeInt value = (AstTreeInt)tree->metadata;
     f16 newValue = value;
     tree->metadata = a404m_malloc(sizeof(f128));
-    *(f128 *)tree->metadata = value;
+    *(AstTreeFloat *)tree->metadata = value;
     if (value - newValue != 0) {
       printWarning(tree->str_begin, tree->str_end, "Value is overflowing");
     }
@@ -2129,7 +2130,7 @@ bool setTypesValueInt(AstTree *tree, AstTreeSetTypesHelper helper) {
     AstTreeInt value = (AstTreeInt)tree->metadata;
     f32 newValue = value;
     tree->metadata = a404m_malloc(sizeof(f128));
-    *(f128 *)tree->metadata = value;
+    *(AstTreeFloat *)tree->metadata = value;
     if (value - newValue != 0) {
       printWarning(tree->str_begin, tree->str_end, "Value is overflowing");
     }
@@ -2139,7 +2140,7 @@ bool setTypesValueInt(AstTree *tree, AstTreeSetTypesHelper helper) {
     AstTreeInt value = (AstTreeInt)tree->metadata;
     f64 newValue = value;
     tree->metadata = a404m_malloc(sizeof(f128));
-    *(f128 *)tree->metadata = value;
+    *(AstTreeFloat *)tree->metadata = value;
     if (value - newValue != 0) {
       printWarning(tree->str_begin, tree->str_end, "Value is overflowing");
     }
@@ -2149,7 +2150,7 @@ bool setTypesValueInt(AstTree *tree, AstTreeSetTypesHelper helper) {
     AstTreeInt value = (AstTreeInt)tree->metadata;
     f128 newValue = value;
     tree->metadata = a404m_malloc(sizeof(f128));
-    *(f128 *)tree->metadata = value;
+    *(AstTreeFloat *)tree->metadata = value;
     if (value - newValue != 0) {
       printWarning(tree->str_begin, tree->str_end, "Value is overflowing");
     }
@@ -2165,8 +2166,7 @@ bool setTypesValueFloat(AstTree *tree, AstTreeSetTypesHelper helper) {
     tree->token = AST_TREE_TOKEN_VALUE_FLOAT;
     AstTreeFloat value = *(AstTreeFloat *)tree->metadata;
     f16 newValue = value;
-    tree->metadata = a404m_malloc(sizeof(f128));
-    *(f128 *)tree->metadata = value;
+    *(AstTreeFloat *)tree->metadata = value;
     if (value - newValue != 0) {
       printWarning(tree->str_begin, tree->str_end, "Value is overflowing");
     }
@@ -2175,9 +2175,8 @@ bool setTypesValueFloat(AstTree *tree, AstTreeSetTypesHelper helper) {
     tree->token = AST_TREE_TOKEN_VALUE_FLOAT;
     AstTreeFloat value = *(AstTreeFloat *)tree->metadata;
     f32 newValue = value;
-    tree->metadata = a404m_malloc(sizeof(f128));
-    *(f128 *)tree->metadata = value;
-    if (value - newValue != 0) {
+    *(AstTreeFloat *)tree->metadata = value;
+    if (value != newValue) {
       printWarning(tree->str_begin, tree->str_end, "Value is overflowing");
     }
     tree->type = &AST_TREE_F32_TYPE;
@@ -2185,8 +2184,7 @@ bool setTypesValueFloat(AstTree *tree, AstTreeSetTypesHelper helper) {
     tree->token = AST_TREE_TOKEN_VALUE_FLOAT;
     AstTreeFloat value = *(AstTreeFloat *)tree->metadata;
     f64 newValue = value;
-    tree->metadata = a404m_malloc(sizeof(f128));
-    *(f128 *)tree->metadata = value;
+    *(AstTreeFloat *)tree->metadata = value;
     if (value - newValue != 0) {
       printWarning(tree->str_begin, tree->str_end, "Value is overflowing");
     }
@@ -2195,8 +2193,7 @@ bool setTypesValueFloat(AstTree *tree, AstTreeSetTypesHelper helper) {
     tree->token = AST_TREE_TOKEN_VALUE_FLOAT;
     AstTreeFloat value = *(AstTreeFloat *)tree->metadata;
     f128 newValue = value;
-    tree->metadata = a404m_malloc(sizeof(f128));
-    *(f128 *)tree->metadata = value;
+    *(AstTreeFloat *)tree->metadata = value;
     if (value - newValue != 0) {
       printWarning(tree->str_begin, tree->str_end, "Value is overflowing");
     }
diff --git a/src/runner/runner.c b/src/runner/runner.c
index 4c9dc2e..0c8fbdd 100644
--- a/src/runner/runner.c
+++ b/src/runner/runner.c
@@ -17,24 +17,32 @@
       (void *)(u64)((type) * (originalType *)(op0)->metadata operator(type) *  \
                     (originalType *)(op1)->metadata)
 
-#define doLogicalOperation(op0, op1, operator, originalType, type)             \
-  (op0)->metadata = (void *)(u64)(bool)((type)(originalType)(op0)              \
-                                            ->metadata                         \
-                                            operator(type)(originalType)(op1)  \
-                                            ->metadata)
+#define doLogicalOperation(op0, op1, operator, originalType, _type)             \
+  {                                                                            \
+    bool res = (bool)((_type)(originalType)(op0)                                \
+                          ->metadata                                           \
+                          operator(_type)(originalType)(op1)                    \
+                          ->metadata);                                         \
+    astTreeDestroy(*(op0));                                                    \
+    (op0)->metadata = (void*)(u64)res;                                                     \
+    (op0)->type = &AST_TREE_BOOL_TYPE;                                          \
+  }
 
-#define doLogicalOperationFloat(op0, op1, operator, originalType, type)        \
-  (op0)->metadata =                                                            \
-      (void *)(u64)(bool)((type) *                                             \
-                          (originalType *)(op0)->metadata operator(type) *     \
-                          (originalType *)(op1)->metadata)
+#define doLogicalOperationFloat(op0, op1, operator, originalType, _type)        \
+  {                                                                            \
+    bool res = (bool)(((_type) * ((originalType *)(op0)->metadata)) operator(   \
+        (_type) * ((originalType *)(op1)->metadata)));                          \
+    astTreeDestroy(*(op0));                                                    \
+    (op0)->metadata = (void*)(u64)res;                                                     \
+    (op0)->type = &AST_TREE_BOOL_TYPE;                                          \
+  }
 
 #define doLeftOperation(op0, operator, originalType, type)                     \
   (op0)->metadata = (void *)(u64)(operator(type)(originalType)(op0)->metadata)
 
 #define doLeftOperationFloat(op0, operator, originalType, type)                \
-  (op0)->metadata =                                                            \
-      (void *)(u64)(operator(type) * (originalType *)(op0)->metadata)
+  *((originalType *)(op0)->metadata) = operator(                               \
+      (type) * (originalType *)(op0)->metadata)
 
 #define doAllOperationsInt(op0, op1, operator, originalType, type)             \
   switch (operator) {                                                          \
@@ -53,12 +61,6 @@
   case AST_TREE_TOKEN_OPERATOR_MODULO:                                         \
     doOperation(op0, op1, %, originalType, type);                              \
     break;                                                                     \
-  case AST_TREE_TOKEN_OPERATOR_PLUS:                                           \
-    doLeftOperation(op0, +, originalType, type);                               \
-    break;                                                                     \
-  case AST_TREE_TOKEN_OPERATOR_MINUS:                                          \
-    doLeftOperation(op0, -, originalType, type);                               \
-    break;                                                                     \
   case AST_TREE_TOKEN_OPERATOR_EQUAL:                                          \
     doLogicalOperation(op0, op1, ==, originalType, type);                      \
     break;                                                                     \
@@ -95,12 +97,6 @@
   case AST_TREE_TOKEN_OPERATOR_DIVIDE:                                         \
     doOperationFloat(op0, op1, /, originalType, type);                         \
     break;                                                                     \
-  case AST_TREE_TOKEN_OPERATOR_PLUS:                                           \
-    doLeftOperationFloat(op0, +, originalType, type);                          \
-    break;                                                                     \
-  case AST_TREE_TOKEN_OPERATOR_MINUS:                                          \
-    doLeftOperationFloat(op0, -, originalType, type);                          \
-    break;                                                                     \
   case AST_TREE_TOKEN_OPERATOR_EQUAL:                                          \
     doLogicalOperationFloat(op0, op1, ==, originalType, type);                 \
     break;                                                                     \
@@ -495,29 +491,67 @@ AstTree *calcAstTreeValue(AstTree *tree, RunnerVariablePages *pages) {
     astTreeDelete(right);
     return left;
   }
-  case AST_TREE_TOKEN_OPERATOR_PLUS:
+  case AST_TREE_TOKEN_OPERATOR_PLUS: {
+    AstTreeSingleChild *operand = calcAstTreeValue(tree->metadata, pages);
+    if (operand->type == &AST_TREE_U64_TYPE) {
+      doLeftOperation(operand, +, AstTreeInt, u64);
+    } else if (operand->type == &AST_TREE_I64_TYPE) {
+      doLeftOperation(operand, +, AstTreeInt, i64);
+    } else if (operand->type == &AST_TREE_U32_TYPE) {
+      doLeftOperation(operand, +, AstTreeInt, u32);
+    } else if (operand->type == &AST_TREE_I32_TYPE) {
+      doLeftOperation(operand, +, AstTreeInt, i32);
+    } else if (operand->type == &AST_TREE_U16_TYPE) {
+      doLeftOperation(operand, +, AstTreeInt, u16);
+    } else if (operand->type == &AST_TREE_I16_TYPE) {
+      doLeftOperation(operand, +, AstTreeInt, i16);
+    } else if (operand->type == &AST_TREE_U8_TYPE) {
+      doLeftOperation(operand, +, AstTreeInt, u8);
+    } else if (operand->type == &AST_TREE_I8_TYPE) {
+      doLeftOperation(operand, +, AstTreeInt, i8);
+    } else if (operand->type == &AST_TREE_F128_TYPE) {
+      doLeftOperationFloat(operand, +, AstTreeFloat, f128);
+    } else if (operand->type == &AST_TREE_F64_TYPE) {
+      doLeftOperationFloat(operand, +, AstTreeFloat, f64);
+    } else if (operand->type == &AST_TREE_F32_TYPE) {
+      doLeftOperationFloat(operand, +, AstTreeFloat, f32);
+    } else if (operand->type == &AST_TREE_F16_TYPE) {
+      doLeftOperationFloat(operand, +, AstTreeFloat, f16);
+    } else {
+      UNREACHABLE;
+    }
+    return operand;
+  }
   case AST_TREE_TOKEN_OPERATOR_MINUS: {
-    AstTreeSingleChild *metadata = tree->metadata;
-    if (typeIsEqual(metadata->type, &AST_TREE_U64_TYPE)) {
-      AstTree *operand = calcAstTreeValue(metadata, pages);
-      if (operand->token == AST_TREE_TOKEN_VALUE_INT) {
-        switch (tree->token) {
-        case AST_TREE_TOKEN_OPERATOR_PLUS:
-          operand->metadata = (void *)(+(AstTreeInt)operand->metadata);
-          break;
-        case AST_TREE_TOKEN_OPERATOR_MINUS:
-          operand->metadata = (void *)(-(AstTreeInt)operand->metadata);
-          break;
-        default:
-          UNREACHABLE;
-        }
-        return operand;
-      } else {
-        UNREACHABLE;
-      }
+    AstTreeSingleChild *operand = calcAstTreeValue(tree->metadata, pages);
+    if (operand->type == &AST_TREE_U64_TYPE) {
+      doLeftOperation(operand, -, AstTreeInt, u64);
+    } else if (operand->type == &AST_TREE_I64_TYPE) {
+      doLeftOperation(operand, -, AstTreeInt, i64);
+    } else if (operand->type == &AST_TREE_U32_TYPE) {
+      doLeftOperation(operand, -, AstTreeInt, u32);
+    } else if (operand->type == &AST_TREE_I32_TYPE) {
+      doLeftOperation(operand, -, AstTreeInt, i32);
+    } else if (operand->type == &AST_TREE_U16_TYPE) {
+      doLeftOperation(operand, -, AstTreeInt, u16);
+    } else if (operand->type == &AST_TREE_I16_TYPE) {
+      doLeftOperation(operand, -, AstTreeInt, i16);
+    } else if (operand->type == &AST_TREE_U8_TYPE) {
+      doLeftOperation(operand, -, AstTreeInt, u8);
+    } else if (operand->type == &AST_TREE_I8_TYPE) {
+      doLeftOperation(operand, -, AstTreeInt, i8);
+    } else if (operand->type == &AST_TREE_F128_TYPE) {
+      doLeftOperationFloat(operand, -, AstTreeFloat, f128);
+    } else if (operand->type == &AST_TREE_F64_TYPE) {
+      doLeftOperationFloat(operand, -, AstTreeFloat, f64);
+    } else if (operand->type == &AST_TREE_F32_TYPE) {
+      doLeftOperationFloat(operand, -, AstTreeFloat, f32);
+    } else if (operand->type == &AST_TREE_F16_TYPE) {
+      doLeftOperationFloat(operand, -, AstTreeFloat, f16);
     } else {
       UNREACHABLE;
     }
+    return operand;
   }
   case AST_TREE_TOKEN_KEYWORD_IF:
   case AST_TREE_TOKEN_FUNCTION:
diff --git a/test/main.felan b/test/main.felan
index 4b635bb..9d77aea 100644
--- a/test/main.felan
+++ b/test/main.felan
@@ -3,7 +3,7 @@ main :: () -> void {
   b :f64 = 54.5;
   c :f128 = 1.0;
   d :f16 = 5.5;
-  if a == 23
+  if -a == -23.0
     print_u64 1;
   else
     print_u64 2;
-- 
cgit v1.2.3