evaluate method

  1. @override
void evaluate(
  1. SymbolTable table
)
override

Evaluates this AST node and generates corresponding LLVM IR code.

This is the main method that each AST node must implement to:

  1. Perform semantic analysis (type checking, symbol resolution)
  2. Generate LLVM IR instructions for the node's operation
  3. Return the result value (if this is an expression)

Parameters:

  • table: The current symbol table for variable and function lookups

Returns: The result of evaluating this node (type depends on node type)

Throws:

  • Exception for semantic errors (undefined variables, type mismatches, etc.)
  • Various specific exceptions for different error conditions

Note: The base implementation throws "Not implemented" - concrete subclasses must override this method with their specific evaluation logic.

Implementation

@override
void evaluate(SymbolTable table) {
  final identifierNode = identifier;

  var varData = table.get(identifier.nodeValue);



  if (varData == null) {
    throw Exception("Variable ${identifier.nodeValue} not found");
  }

  if (varData.type is ArrayType && identifierNode is !IndexedIdentifierNode) {
    throw Exception("Cannot assign to array");

  }
  if (varData.type is! ArrayType && identifierNode is IndexedIdentifierNode) {
    throw Exception("Cannot index non-array");
  }
  var value = nodeValue.evaluate(table);

  var ptrName = varData.ptrName;
  if (varData.type is ArrayType) {
    if (varData.type.primitiveType != value.type.primitiveType) {
      throw Exception("Type mismatch");
    }
    final IndexedIdentifierNode indexedIdentifierNode = identifierNode as IndexedIdentifierNode;
    final indexResult = indexedIdentifierNode.index.evaluate(table);
    if (indexResult.type.primitiveType != PrimitiveTypes.int) {
      throw Exception("Index must be int");
    }
    Node.addIrLine(
        "%arrayPtr.$id = getelementptr ${varData.type.primitiveType.irType}, ${varData.type.irType} ${varData.ptrName}, i64 ${indexResult.regName}");
    ptrName = "%arrayPtr.$id";
  } else if (varData.type != value.type) {
    throw Exception("Type mismatch");
  }
  Node.addIrLine(
      "store ${varData.type.primitiveType.irType} ${value.regName}, ptr $ptrName");
}