started work on assignment operators

This commit is contained in:
SpookyDervish
2025-10-17 06:21:33 +11:00
parent 1d6c3db5e4
commit 24fcbb3fb7
10 changed files with 229 additions and 137 deletions

View File

@@ -3,7 +3,7 @@ from llvmlite import ir
from AST import Node, NodeType, Program, Expression
from AST import ExpressionStatement, AssignmentStatement, BlockStatement, ReturnStatement, FunctionStatement, ReassignStatement, IfStatement
from AST import WhileStatement, BreakStatement, ContinueStatement, ForStatement
from AST import InfixExpression, CallExpression
from AST import InfixExpression, CallExpression, PrefixExpression
from AST import IntegerLiteral, FloatLiteral, IdentifierLiteral, BooleanLiteral, StringLiteral
from AST import FunctionParameter
@@ -189,15 +189,56 @@ class Compiler:
def __visit_reassign_statement(self, node: ReassignStatement) -> None:
name: str = node.ident.value
operator: str = node.operator
value: Expression = node.right_value
value, Type = self.__resolve_value(value)
if self.environment.lookup(name) is None:
self.errors.append(f"Identifier {name} has not been declared before it was re-assigned.")
else:
ptr, _ = self.environment.lookup(name)
self.builder.store(value, ptr)
return
right_value, right_type = self.__resolve_value(value)
var_ptr, _ = self.environment.lookup(name)
orig_value = self.builder.load(var_ptr)
if isinstance(orig_value.type, ir.IntType) and isinstance(right_type, ir.FloatType):
orig_value = self.builder.sitofp(orig_value, ir.FloatType())
if isinstance(orig_value.type, ir.FloatType) and isinstance(right_type, ir.IntType):
right_value = self.builder.sitofp(right_value, ir.FloatType())
value = None
Type = None
match operator:
case "=":
value = right_value
case "+=":
if isinstance(orig_value.type, ir.IntType) and isinstance(right_type, ir.IntType):
value = self.builder.add(orig_value, right_value)
else:
value = self.builder.fadd(orig_value, right_value)
case "-=":
if isinstance(orig_value.type, ir.IntType) and isinstance(right_type, ir.IntType):
value = self.builder.sub(orig_value, right_value)
else:
value = self.builder.fsub(orig_value, right_value)
case "*=":
if isinstance(orig_value.type, ir.IntType) and isinstance(right_type, ir.IntType):
value = self.builder.mul(orig_value, right_value)
else:
value = self.builder.fmul(orig_value, right_value)
case "/=":
if isinstance(orig_value.type, ir.IntType) and isinstance(right_type, ir.IntType):
value = self.builder.sdiv(orig_value, right_value)
else:
value = self.builder.fdiv(orig_value, right_value)
case _:
print("Unsupported assignment operator.")
ptr, _ = self.environment.lookup(name)
self.builder.store(value, ptr)
def __visit_if_statement(self, node: IfStatement) -> None:
condition = node.condition
@@ -388,6 +429,32 @@ class Compiler:
ret = self.builder.call(func, args)
return ret, ret_type
def __visit_prefix_expression(self, node: PrefixExpression) -> tuple[ir.Value, ir.Type]:
operator: str = node.operator
right_node: Expression = node.right_node
right_value, right_type = self.__resolve_value(right_node)
Type = None
value = None
if isinstance(right_type, ir.FloatType):
Type = ir.FloatType
match operator:
case "-":
value = self.builder.fmul(right_value, ir.Constant(ir.FloatType(), -1.0))
case "!":
value = ir.Constant(ir.IntType(1), 0)
elif isinstance(right_type, ir.IntType):
Type = ir.IntType(32)
match operator:
case "-":
value = self.builder.mul(right_value, ir.Constant(ir.IntType(32), -1))
case "!":
value = self.builder.not_(right_value)
return value, Type
# endregion
# endregion
@@ -420,6 +487,8 @@ class Compiler:
return self.__visit_infix_expression(node)
case NodeType.CallExpression:
return self.__visit_call_expression(node)
case NodeType.PrefixExpression:
return self.__visit_prefix_expression(node)
def __convert_string(self, string: str) -> tuple[ir.Constant, ir.ArrayType]:
string = string.replace("\\n", "\n\0")