From 20f403c5e603cb7df92c67370eaa3a6119d3a166 Mon Sep 17 00:00:00 2001
From: A404M <ahmadmahmoudiprogrammer@gmail.com>
Date: Sun, 23 Feb 2025 12:42:20 +0330
Subject: add += -= *= /= %=

---
 src/compiler/ast-tree.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++++
 src/compiler/ast-tree.h |  2 ++
 src/compiler/lexer.c    | 14 +++++++++++--
 src/compiler/lexer.h    |  5 +++++
 src/compiler/parser.c   | 51 ++++++++++++++++++++++++++++++++++++++++++++++-
 src/compiler/parser.h   |  5 +++++
 test/main.felan         |  4 ++--
 7 files changed, 129 insertions(+), 5 deletions(-)

diff --git a/src/compiler/ast-tree.c b/src/compiler/ast-tree.c
index 4153d0d..6f96f49 100644
--- a/src/compiler/ast-tree.c
+++ b/src/compiler/ast-tree.c
@@ -1039,6 +1039,21 @@ AstTree *astTreeParse(ParserNode *parserNode, AstTreeHelper *helper) {
   case PARSER_TOKEN_OPERATOR_ASSIGN:
     return astTreeParseBinaryOperator(parserNode, helper,
                                       AST_TREE_TOKEN_OPERATOR_ASSIGN);
+  case PARSER_TOKEN_OPERATOR_SUM_ASSIGN:
+    return astTreeParseOperateAssignOperator(parserNode, helper,
+                                             AST_TREE_TOKEN_OPERATOR_SUM);
+  case PARSER_TOKEN_OPERATOR_SUB_ASSIGN:
+    return astTreeParseOperateAssignOperator(parserNode, helper,
+                                             AST_TREE_TOKEN_OPERATOR_SUB);
+  case PARSER_TOKEN_OPERATOR_MULTIPLY_ASSIGN:
+    return astTreeParseOperateAssignOperator(parserNode, helper,
+                                             AST_TREE_TOKEN_OPERATOR_MULTIPLY);
+  case PARSER_TOKEN_OPERATOR_DIVIDE_ASSIGN:
+    return astTreeParseOperateAssignOperator(parserNode, helper,
+                                             AST_TREE_TOKEN_OPERATOR_DIVIDE);
+  case PARSER_TOKEN_OPERATOR_MODULO_ASSIGN:
+    return astTreeParseOperateAssignOperator(parserNode, helper,
+                                             AST_TREE_TOKEN_OPERATOR_MODULO);
   case PARSER_TOKEN_OPERATOR_SUM:
     return astTreeParseBinaryOperator(parserNode, helper,
                                       AST_TREE_TOKEN_OPERATOR_SUM);
@@ -1449,6 +1464,44 @@ AstTree *astTreeParseUnaryOperator(ParserNode *parserNode,
                     parserNode->str_end);
 }
 
+AstTree *astTreeParseOperateAssignOperator(ParserNode *parserNode,
+                                           AstTreeHelper *helper,
+                                           AstTreeToken token) {
+  ParserNodeInfixMetadata *node_metadata = parserNode->metadata;
+
+  AstTree *left = astTreeParse(node_metadata->left, helper);
+  if (left == NULL) {
+    return NULL;
+  }
+  AstTree *right = astTreeParse(node_metadata->right, helper);
+  if (right == NULL) {
+    return NULL;
+  }
+
+  AstTreeInfix *metadata = a404m_malloc(sizeof(*metadata));
+
+  metadata->left = *left;
+  metadata->right = *right;
+
+  free(left);
+  free(right);
+
+  AstTreeInfix *assignMetadata = a404m_malloc(sizeof(*assignMetadata));
+
+  AstTree *assignLeft = astTreeParse(node_metadata->left, helper);
+  AstTree *assignRight = newAstTree(token, metadata, NULL,
+                                    parserNode->str_begin, parserNode->str_end);
+
+  assignMetadata->left = *assignLeft;
+  assignMetadata->right = *assignRight;
+
+  free(assignLeft);
+  free(assignRight);
+
+  return newAstTree(AST_TREE_TOKEN_OPERATOR_ASSIGN, assignMetadata, NULL,
+                    parserNode->str_begin, parserNode->str_end);
+}
+
 bool astTreeParseConstant(ParserNode *parserNode, AstTreeHelper *helper) {
   ParserNodeVariableMetadata *node_metadata = parserNode->metadata;
 
diff --git a/src/compiler/ast-tree.h b/src/compiler/ast-tree.h
index 828e3a1..0294956 100644
--- a/src/compiler/ast-tree.h
+++ b/src/compiler/ast-tree.h
@@ -205,6 +205,8 @@ AstTree *astTreeParseBinaryOperator(ParserNode *parserNode,
                                     AstTreeHelper *helper, AstTreeToken token);
 AstTree *astTreeParseUnaryOperator(ParserNode *parserNode,
                                    AstTreeHelper *helper, AstTreeToken token);
+AstTree *astTreeParseOperateAssignOperator(ParserNode *parserNode,
+                                    AstTreeHelper *helper, AstTreeToken token);
 bool astTreeParseConstant(ParserNode *parserNode, AstTreeHelper *helper);
 AstTree *astTreeParseVariable(ParserNode *parserNode, AstTreeHelper *helper);
 AstTree *astTreeParseIf(ParserNode *parserNode, AstTreeHelper *helper);
diff --git a/src/compiler/lexer.c b/src/compiler/lexer.c
index b75bd7e..18326c9 100644
--- a/src/compiler/lexer.c
+++ b/src/compiler/lexer.c
@@ -46,6 +46,11 @@ const char *LEXER_TOKEN_STRINGS[] = {
     "LEXER_TOKEN_SYMBOL_FUNCTION_ARROW",
     "LEXER_TOKEN_SYMBOL_COLON",
     "LEXER_TOKEN_SYMBOL_ASSIGN",
+    "LEXER_TOKEN_SYMBOL_SUM_ASSIGN",
+    "LEXER_TOKEN_SYMBOL_SUB_ASSIGN",
+    "LEXER_TOKEN_SYMBOL_MULTIPLY_ASSIGN",
+    "LEXER_TOKEN_SYMBOL_DIVIDE_ASSIGN",
+    "LEXER_TOKEN_SYMBOL_MODULO_ASSIGN",
     "LEXER_TOKEN_SYMBOL_COMMA",
     "LEXER_TOKEN_SYMBOL_PLUS",
     "LEXER_TOKEN_SYMBOL_MINUS",
@@ -65,8 +70,8 @@ const char *LEXER_TOKEN_STRINGS[] = {
 };
 
 const char *LEXER_SYMBOL_STRINGS[] = {
-    ";", "(", ")", "{", "}",  "->", ":", "=",  ",", "+",
-    "-", "*", "/", "%", "==", "!=", ">", ">=", "<", "<=",
+    ";", "(", ")", "{", "}", "->", ":",  "=",  "+=", "-=", "*=", "/=", "%=",
+    ",", "+", "-", "*", "/", "%",  "==", "!=", ">",  ">=", "<",  "<=",
 };
 const LexerToken LEXER_SYMBOL_TOKENS[] = {
     LEXER_TOKEN_SYMBOL_EOL,
@@ -77,6 +82,11 @@ const LexerToken LEXER_SYMBOL_TOKENS[] = {
     LEXER_TOKEN_SYMBOL_FUNCTION_ARROW,
     LEXER_TOKEN_SYMBOL_COLON,
     LEXER_TOKEN_SYMBOL_ASSIGN,
+    LEXER_TOKEN_SYMBOL_SUM_ASSIGN,
+    LEXER_TOKEN_SYMBOL_SUB_ASSIGN,
+    LEXER_TOKEN_SYMBOL_MULTIPLY_ASSIGN,
+    LEXER_TOKEN_SYMBOL_DIVIDE_ASSIGN,
+    LEXER_TOKEN_SYMBOL_MODULO_ASSIGN,
     LEXER_TOKEN_SYMBOL_COMMA,
     LEXER_TOKEN_SYMBOL_PLUS,
     LEXER_TOKEN_SYMBOL_MINUS,
diff --git a/src/compiler/lexer.h b/src/compiler/lexer.h
index 92d943e..570b472 100644
--- a/src/compiler/lexer.h
+++ b/src/compiler/lexer.h
@@ -39,6 +39,11 @@ typedef enum LexerToken {
   LEXER_TOKEN_SYMBOL_FUNCTION_ARROW,
   LEXER_TOKEN_SYMBOL_COLON,
   LEXER_TOKEN_SYMBOL_ASSIGN,
+  LEXER_TOKEN_SYMBOL_SUM_ASSIGN,
+  LEXER_TOKEN_SYMBOL_SUB_ASSIGN,
+  LEXER_TOKEN_SYMBOL_MULTIPLY_ASSIGN,
+  LEXER_TOKEN_SYMBOL_DIVIDE_ASSIGN,
+  LEXER_TOKEN_SYMBOL_MODULO_ASSIGN,
   LEXER_TOKEN_SYMBOL_COMMA,
   LEXER_TOKEN_SYMBOL_PLUS,
   LEXER_TOKEN_SYMBOL_MINUS,
diff --git a/src/compiler/parser.c b/src/compiler/parser.c
index fad6e07..a47869d 100644
--- a/src/compiler/parser.c
+++ b/src/compiler/parser.c
@@ -123,7 +123,11 @@ static constexpr ParserOrder PARSER_ORDER[] = {
     },
     {
         .ltr = false,
-        ORDER_ARRAY(LEXER_TOKEN_SYMBOL_ASSIGN, ),
+        ORDER_ARRAY(LEXER_TOKEN_SYMBOL_ASSIGN, LEXER_TOKEN_SYMBOL_SUM_ASSIGN,
+                    LEXER_TOKEN_SYMBOL_SUB_ASSIGN,
+                    LEXER_TOKEN_SYMBOL_MULTIPLY_ASSIGN,
+                    LEXER_TOKEN_SYMBOL_DIVIDE_ASSIGN,
+                    LEXER_TOKEN_SYMBOL_MODULO_ASSIGN, ),
     },
     {
         .ltr = true,
@@ -314,6 +318,11 @@ void parserNodePrint(const ParserNode *node, int indent) {
   }
     goto RETURN_SUCCESS;
   case PARSER_TOKEN_OPERATOR_ASSIGN:
+case PARSER_TOKEN_OPERATOR_SUM_ASSIGN:
+case PARSER_TOKEN_OPERATOR_SUB_ASSIGN:
+case PARSER_TOKEN_OPERATOR_MULTIPLY_ASSIGN:
+case PARSER_TOKEN_OPERATOR_DIVIDE_ASSIGN:
+case PARSER_TOKEN_OPERATOR_MODULO_ASSIGN:
   case PARSER_TOKEN_OPERATOR_SUM:
   case PARSER_TOKEN_OPERATOR_SUB:
   case PARSER_TOKEN_OPERATOR_MULTIPLY:
@@ -485,6 +494,11 @@ void parserNodeDelete(ParserNode *node) {
   }
     goto RETURN_SUCCESS;
   case PARSER_TOKEN_OPERATOR_ASSIGN:
+case PARSER_TOKEN_OPERATOR_SUM_ASSIGN:
+case PARSER_TOKEN_OPERATOR_SUB_ASSIGN:
+case PARSER_TOKEN_OPERATOR_MULTIPLY_ASSIGN:
+case PARSER_TOKEN_OPERATOR_DIVIDE_ASSIGN:
+case PARSER_TOKEN_OPERATOR_MODULO_ASSIGN:
   case PARSER_TOKEN_OPERATOR_SUM:
   case PARSER_TOKEN_OPERATOR_SUB:
   case PARSER_TOKEN_OPERATOR_MULTIPLY:
@@ -677,6 +691,21 @@ ParserNode *parseNode(LexerNode *node, LexerNode *begin, LexerNode *end,
   case LEXER_TOKEN_SYMBOL_ASSIGN:
     return parserBinaryOperator(node, begin, end, parent,
                                 PARSER_TOKEN_OPERATOR_ASSIGN);
+  case LEXER_TOKEN_SYMBOL_SUM_ASSIGN:
+    return parserBinaryOperator(node, begin, end, parent,
+                                PARSER_TOKEN_OPERATOR_SUM_ASSIGN);
+  case LEXER_TOKEN_SYMBOL_SUB_ASSIGN:
+    return parserBinaryOperator(node, begin, end, parent,
+                                PARSER_TOKEN_OPERATOR_SUB_ASSIGN);
+  case LEXER_TOKEN_SYMBOL_MULTIPLY_ASSIGN:
+    return parserBinaryOperator(node, begin, end, parent,
+                                PARSER_TOKEN_OPERATOR_MULTIPLY_ASSIGN);
+  case LEXER_TOKEN_SYMBOL_DIVIDE_ASSIGN:
+    return parserBinaryOperator(node, begin, end, parent,
+                                PARSER_TOKEN_OPERATOR_DIVIDE_ASSIGN);
+  case LEXER_TOKEN_SYMBOL_MODULO_ASSIGN:
+    return parserBinaryOperator(node, begin, end, parent,
+                                PARSER_TOKEN_OPERATOR_MODULO_ASSIGN);
   case LEXER_TOKEN_SYMBOL_SUM:
     return parserBinaryOperator(node, begin, end, parent,
                                 PARSER_TOKEN_OPERATOR_SUM);
@@ -1125,6 +1154,11 @@ ParserNode *parserFunction(LexerNode *node, LexerNode *begin, LexerNode *end,
       case PARSER_TOKEN_SYMBOL_PARENTHESIS:
       case PARSER_TOKEN_SYMBOL_COMMA:
       case PARSER_TOKEN_OPERATOR_ASSIGN:
+case PARSER_TOKEN_OPERATOR_SUM_ASSIGN:
+case PARSER_TOKEN_OPERATOR_SUB_ASSIGN:
+case PARSER_TOKEN_OPERATOR_MULTIPLY_ASSIGN:
+case PARSER_TOKEN_OPERATOR_DIVIDE_ASSIGN:
+case PARSER_TOKEN_OPERATOR_MODULO_ASSIGN:
       case PARSER_TOKEN_OPERATOR_PLUS:
       case PARSER_TOKEN_OPERATOR_MINUS:
       case PARSER_TOKEN_OPERATOR_SUM:
@@ -1456,6 +1490,11 @@ bool isExpression(ParserNode *node) {
   case PARSER_TOKEN_KEYWORD_PRINT_U64:
   case PARSER_TOKEN_KEYWORD_RETURN:
   case PARSER_TOKEN_OPERATOR_ASSIGN:
+case PARSER_TOKEN_OPERATOR_SUM_ASSIGN:
+case PARSER_TOKEN_OPERATOR_SUB_ASSIGN:
+case PARSER_TOKEN_OPERATOR_MULTIPLY_ASSIGN:
+case PARSER_TOKEN_OPERATOR_DIVIDE_ASSIGN:
+case PARSER_TOKEN_OPERATOR_MODULO_ASSIGN:
   case PARSER_TOKEN_OPERATOR_PLUS:
   case PARSER_TOKEN_OPERATOR_MINUS:
   case PARSER_TOKEN_OPERATOR_SUM:
@@ -1537,6 +1576,11 @@ bool isType(ParserNode *node) {
   case PARSER_TOKEN_KEYWORD_PRINT_U64:
   case PARSER_TOKEN_KEYWORD_RETURN:
   case PARSER_TOKEN_OPERATOR_ASSIGN:
+case PARSER_TOKEN_OPERATOR_SUM_ASSIGN:
+case PARSER_TOKEN_OPERATOR_SUB_ASSIGN:
+case PARSER_TOKEN_OPERATOR_MULTIPLY_ASSIGN:
+case PARSER_TOKEN_OPERATOR_DIVIDE_ASSIGN:
+case PARSER_TOKEN_OPERATOR_MODULO_ASSIGN:
   case PARSER_TOKEN_OPERATOR_PLUS:
   case PARSER_TOKEN_OPERATOR_MINUS:
   case PARSER_TOKEN_OPERATOR_SUM:
@@ -1566,6 +1610,11 @@ bool isValue(ParserNode *node) {
   case PARSER_TOKEN_VALUE_BOOL:
   case PARSER_TOKEN_IDENTIFIER:
   case PARSER_TOKEN_OPERATOR_ASSIGN:
+case PARSER_TOKEN_OPERATOR_SUM_ASSIGN:
+case PARSER_TOKEN_OPERATOR_SUB_ASSIGN:
+case PARSER_TOKEN_OPERATOR_MULTIPLY_ASSIGN:
+case PARSER_TOKEN_OPERATOR_DIVIDE_ASSIGN:
+case PARSER_TOKEN_OPERATOR_MODULO_ASSIGN:
   case PARSER_TOKEN_OPERATOR_PLUS:
   case PARSER_TOKEN_OPERATOR_MINUS:
   case PARSER_TOKEN_OPERATOR_SUM:
diff --git a/src/compiler/parser.h b/src/compiler/parser.h
index 6fe6d6f..2d0c828 100644
--- a/src/compiler/parser.h
+++ b/src/compiler/parser.h
@@ -45,6 +45,11 @@ typedef enum ParserToken {
   PARSER_TOKEN_SYMBOL_COMMA,
 
   PARSER_TOKEN_OPERATOR_ASSIGN,
+  PARSER_TOKEN_OPERATOR_SUM_ASSIGN,
+  PARSER_TOKEN_OPERATOR_SUB_ASSIGN,
+  PARSER_TOKEN_OPERATOR_MULTIPLY_ASSIGN,
+  PARSER_TOKEN_OPERATOR_DIVIDE_ASSIGN,
+  PARSER_TOKEN_OPERATOR_MODULO_ASSIGN,
   PARSER_TOKEN_OPERATOR_PLUS,
   PARSER_TOKEN_OPERATOR_MINUS,
   PARSER_TOKEN_OPERATOR_SUM,
diff --git a/test/main.felan b/test/main.felan
index d8aec7a..ca2694c 100644
--- a/test/main.felan
+++ b/test/main.felan
@@ -2,11 +2,11 @@ main :: () -> void {
   a :getType(i64,u64)= 0;
   while a < 10 {
     print_u64 a;
-    a = a + 1;
+    a += 1;
   }
 };
 
-signed := false;
+signed :: false;
 
 getType :: (a:type,b:type)->type {
   if signed
-- 
cgit v1.2.3