// Path: app/src/main/java/com/annimon/hotarufx/exceptions/FunctionNotFoundException.java
// public class FunctionNotFoundException extends HotaruRuntimeException {
// 
//     public FunctionNotFoundException(String name, SourcePosition start, SourcePosition end) {
//         super("Function " + name + " does not exists", start, end);
//     }
// }
// 
// Path: app/src/main/java/com/annimon/hotarufx/exceptions/TypeException.java
// public class TypeException extends HotaruRuntimeException {
// 
//     public TypeException(String message) {
//         super(message);
//     }
// 
//     public TypeException(String message, SourcePosition start, SourcePosition end) {
//         super(message, start, end);
//     }
// }
// 
// Path: app/src/main/java/com/annimon/hotarufx/exceptions/VariableNotFoundException.java
// public class VariableNotFoundException extends HotaruRuntimeException {
// 
//     public VariableNotFoundException(String variable, SourcePosition start, SourcePosition end) {
//         super("Variable " + variable + " does not exists", start, end);
//     }
// }


import com.annimon.hotarufx.exceptions.FunctionNotFoundException;
import com.annimon.hotarufx.exceptions.TypeException;
import com.annimon.hotarufx.exceptions.VariableNotFoundException;
import com.annimon.hotarufx.lib.*;
import com.annimon.hotarufx.parser.ast.*;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.function.Supplier;
    private Optional<Value> getContainer(List<Node> nodes, Context context, Value container) {
        for (Node index : nodes) {
            switch (container.type()) {
                case Types.MAP: {
                    final var key = index.accept(this, context).asString();
                    container = ((MapValue) container).getMap().get(key);
                } break;

                case Types.NODE: {
                    final var key = index.accept(this, context).asString();
                    container = ((NodeValue) container).get(key);
                } break;

                case Types.PROPERTY: {
                    final var key = index.accept(this, context).asString();
                    final var propertyValue = (PropertyValue) container;
                    container = propertyValue.getField(key);
                } break;

                default:
                    return Optional.empty();
            }
        }
        return Optional.of(container);
    }

    @Override
    public Value get(VariableNode node, Context context) {
        final var result = context.variables().get(node.name);
        if (result == null)
// Path: app/src/main/java/com/annimon/hotarufx/exceptions/FunctionNotFoundException.java
// public class FunctionNotFoundException extends HotaruRuntimeException {
// 
//     public FunctionNotFoundException(String name, SourcePosition start, SourcePosition end) {
//         super("Function " + name + " does not exists", start, end);
//     }
// }
// 
// Path: app/src/main/java/com/annimon/hotarufx/exceptions/TypeException.java
// public class TypeException extends HotaruRuntimeException {
// 
//     public TypeException(String message) {
//         super(message);
//     }
// 
//     public TypeException(String message, SourcePosition start, SourcePosition end) {
//         super(message, start, end);
//     }
// }
// 
// Path: app/src/main/java/com/annimon/hotarufx/exceptions/VariableNotFoundException.java
// public class VariableNotFoundException extends HotaruRuntimeException {
// 
//     public VariableNotFoundException(String variable, SourcePosition start, SourcePosition end) {
//         super("Variable " + variable + " does not exists", start, end);
//     }
// }


// Path: app/src/main/java/com/annimon/hotarufx/parser/visitors/InterpreterVisitor.java
import com.annimon.hotarufx.exceptions.FunctionNotFoundException;
import com.annimon.hotarufx.exceptions.TypeException;
import com.annimon.hotarufx.exceptions.VariableNotFoundException;
import com.annimon.hotarufx.lib.*;
import com.annimon.hotarufx.parser.ast.*;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.function.Supplier;

    private Optional<Value> getContainer(List<Node> nodes, Context context, Value container) {
        for (Node index : nodes) {
            switch (container.type()) {
                case Types.MAP: {
                    final var key = index.accept(this, context).asString();
                    container = ((MapValue) container).getMap().get(key);
                } break;

                case Types.NODE: {
                    final var key = index.accept(this, context).asString();
                    container = ((NodeValue) container).get(key);
                } break;

                case Types.PROPERTY: {
                    final var key = index.accept(this, context).asString();
                    final var propertyValue = (PropertyValue) container;
                    container = propertyValue.getField(key);
                } break;

                default:
                    return Optional.empty();
            }
        }
        return Optional.of(container);
    }

    @Override
    public Value get(VariableNode node, Context context) {
        final var result = context.variables().get(node.name);
        if (result == null)
            throw new VariableNotFoundException(node.name, node.start(), node.end());