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 strLiteral = literal.evaluate(table);
    List<(String, String)> irLines = [];

  for (var identifier in identifiers) {
    var varData = table.get(identifier.nodeValue);
    if (varData == null) {
      throw Exception("Variable ${identifier.nodeValue} not found");
    }
    String ptr = varData.ptrName;
    if (varData.type is ArrayType && identifier is !IndexedIdentifierNode) {
      throw Exception("Cannot scan into array");
    }
    if (varData.type is! ArrayType && identifier is IndexedIdentifierNode) {
      throw Exception("Cannot index non-array");
    }
    if (varData.type is ArrayType) {
      final indexedId = identifier as IndexedIdentifierNode;
      final indexResult = indexedId.index.evaluate(table);
      if (indexResult.type.primitiveType != PrimitiveTypes.int) {
        throw Exception("Index must be int");
      }
      Node.addIrLine(
          "%arrayPtr.${identifier.id} = getelementptr ${varData.type.primitiveType.irType}, ${varData.type.irType} ${varData.ptrName}, i64 ${indexResult.regName}");
      ptr = "%arrayPtr.${identifier.id}";
    }
    irLines.add((ptr, varData.type.primitiveType.irType));

  }
  final childrenStr = irLines.map((e) => "${e.$2}* ${e.$1}").join(", ");
  Node.addIrLine(
      "call i32 (i8*, ...) @scanf(i8* $strLiteral, $childrenStr)");
}