// Path: src/main/java/org/hummingbirdlang/objects/Function.java
// public final class Function {
//   private final FunctionType type;
//   private final Bindings bindings;
//   private final CallTarget callTarget;
//   private final String name;
// 
//   public Function(FunctionType type, Bindings bindings) {
//     this.type = type;
//     this.bindings = bindings;
//     this.callTarget = type.getCallTarget();
//     this.name = type.getName();
//   }
// 
//   public FunctionType getType() {
//     return this.type;
//   }
// 
//   public Bindings getBindings() {
//     return this.bindings;
//   }
// 
//   public CallTarget getCallTarget() {
//     return this.callTarget;
//   }
// }
// 
// Path: src/main/java/org/hummingbirdlang/types/FunctionType.java
// public final class FunctionType extends ConcreteType {
//   private final Type[] parameterTypes;
//   private final Type returnType;
//   private final String name;
//   private final CallTarget callTarget;
//   // Scope where the function was declared.
//   private Scope declarationScope;
//   // Scope inside the function (ie. of its block).
//   private Scope ownScope;
// 
//   public FunctionType(
//     Type[] parameterTypes,
//     Type returnType,
//     String name,
//     CallTarget callTarget
//   ) {
//     this.parameterTypes = parameterTypes;
//     this.returnType = returnType;
//     this.name = name;
//     this.callTarget = callTarget;
//   }
// 
//   public Type[] getParameterTypes() {
//     return this.parameterTypes;
//   }
// 
//   public Type getReturnType() {
//     return this.returnType;
//   }
// 
//   public String getName() {
//     return this.name;
//   }
// 
//   public CallTarget getCallTarget() {
//     return this.callTarget;
//   }
// 
//   public Scope getOwnScope() {
//     if (this.ownScope != null && !this.ownScope.isClosed()) {
//       throw new RuntimeException("Scope not yet closed");
//     }
//     return this.ownScope;
//   }
// 
//   public void setOwnScope(Scope scope) {
//     if (this.ownScope != null) {
//       throw new RuntimeException("Cannot re-set scope");
//     }
//     this.ownScope = scope;
//   }
// 
//   public Scope getDeclarationScope() {
//     if (this.declarationScope != null && !this.declarationScope.isClosed()) {
//       throw new RuntimeException("Scope not yet closed");
//     }
//     return this.declarationScope;
//   }
// 
//   public void setDeclarationScope(Scope declarationScope) {
//     if (this.declarationScope != null) {
//       throw new RuntimeException("Cannot re-set scope");
//     }
//     this.declarationScope = declarationScope;
//   }
// 
//   @Override
//   public Property getProperty(String name) throws PropertyNotFoundException {
//     throw new PropertyNotFoundException("Not yet implemented");
//   }
// }
// 
// Path: src/main/java/org/hummingbirdlang/types/Type.java
// public abstract class Type {
//   public abstract Property getProperty(String name) throws PropertyNotFoundException;
// 
//   public void assertEquals(Type otherType) throws TypeMismatchException {
//     // Rudimentary pointer comparison by default.
//     if (this != otherType) {
//       throw new TypeMismatchException(this, otherType);
//     }
//   }
// 
//   /**
//    * Returns whether or not this type is equal to another type.
//    */
//   public boolean equals(Type otherType) {
//     try {
//       this.assertEquals(otherType);
//     } catch (TypeMismatchException exception) {
//       return false;
//     }
//     return true;
//   }
// }
// 
// Path: src/main/java/org/hummingbirdlang/types/scope/BuiltinScope.java
// public class BuiltinScope extends AbstractScope implements Scope, Iterable<String> {
//   private final Map<String, Type> types;
// 
//   public BuiltinScope(Index index) {
//     Map<String, Type> types = new HashMap<>();
//     // Bootstrap the global types.
//     Index.Module builtin = index.getBuiltin();
//     for (String name : builtin) {
//       types.put(name, builtin.get(name));
//     }
//     this.types = types;
//     // You can't modify the builtin scope!
//     this.close();
//   }
// 
//   @Override
//   public void accept(Resolution resolution) throws NameNotFoundException {
//     resolution.pushScope(this);
//     if (this.types.containsKey(resolution.getName())) {
//       resolution.setType(this.types.get(resolution.getName()));
//     } else {
//       throw new NameNotFoundException("Name not found in BuiltinScope: " + resolution.getName());
//     }
//   }
// 
//   @Override
//   public void setLocal(String name, Type type) {
//     throw new RuntimeException("Cannot modify BuiltinScope: " + name);
//   }
// 
//   @Override
//   public Scope getParent() {
//     throw new RuntimeException("Cannot getParent of BuiltinScope");
//   }
// 
//   @Override
//   public List<Resolution> getNonLocalResolutions() {
//     throw new RuntimeException("Cannot getNonLocalResolutions of BuiltinScope");
//   }
// 
//   @Override
//   public Iterator<String> iterator() {
//     return this.types.keySet().iterator();
//   }
// }
// 
// Path: src/main/java/org/hummingbirdlang/types/scope/NameNotFoundException.java
// public class NameNotFoundException extends TypeException {
//   public NameNotFoundException(String message) {
//     super(message);
//   }
// }


import java.util.HashMap;
import java.util.Map;
import org.hummingbirdlang.objects.Function;
import org.hummingbirdlang.types.FunctionType;
import org.hummingbirdlang.types.Type;
import org.hummingbirdlang.types.scope.BuiltinScope;
import org.hummingbirdlang.types.scope.NameNotFoundException;
package org.hummingbirdlang.runtime.bindings;



// Holds references to values closed from an outer scope.
public final class Bindings {
  private Map<String, Binding> bindings;

  public Bindings() {
    this.bindings = new HashMap<>();
  }

  public Bindings(BuiltinScope builtinScope) throws NameNotFoundException {
    this();
    // Bootstrap builtins into frame.
    for (String name : builtinScope) {
      Type type = builtinScope.get(name);
      if (type instanceof FunctionType) {
// Path: src/main/java/org/hummingbirdlang/objects/Function.java
// public final class Function {
//   private final FunctionType type;
//   private final Bindings bindings;
//   private final CallTarget callTarget;
//   private final String name;
// 
//   public Function(FunctionType type, Bindings bindings) {
//     this.type = type;
//     this.bindings = bindings;
//     this.callTarget = type.getCallTarget();
//     this.name = type.getName();
//   }
// 
//   public FunctionType getType() {
//     return this.type;
//   }
// 
//   public Bindings getBindings() {
//     return this.bindings;
//   }
// 
//   public CallTarget getCallTarget() {
//     return this.callTarget;
//   }
// }
// 
// Path: src/main/java/org/hummingbirdlang/types/FunctionType.java
// public final class FunctionType extends ConcreteType {
//   private final Type[] parameterTypes;
//   private final Type returnType;
//   private final String name;
//   private final CallTarget callTarget;
//   // Scope where the function was declared.
//   private Scope declarationScope;
//   // Scope inside the function (ie. of its block).
//   private Scope ownScope;
// 
//   public FunctionType(
//     Type[] parameterTypes,
//     Type returnType,
//     String name,
//     CallTarget callTarget
//   ) {
//     this.parameterTypes = parameterTypes;
//     this.returnType = returnType;
//     this.name = name;
//     this.callTarget = callTarget;
//   }
// 
//   public Type[] getParameterTypes() {
//     return this.parameterTypes;
//   }
// 
//   public Type getReturnType() {
//     return this.returnType;
//   }
// 
//   public String getName() {
//     return this.name;
//   }
// 
//   public CallTarget getCallTarget() {
//     return this.callTarget;
//   }
// 
//   public Scope getOwnScope() {
//     if (this.ownScope != null && !this.ownScope.isClosed()) {
//       throw new RuntimeException("Scope not yet closed");
//     }
//     return this.ownScope;
//   }
// 
//   public void setOwnScope(Scope scope) {
//     if (this.ownScope != null) {
//       throw new RuntimeException("Cannot re-set scope");
//     }
//     this.ownScope = scope;
//   }
// 
//   public Scope getDeclarationScope() {
//     if (this.declarationScope != null && !this.declarationScope.isClosed()) {
//       throw new RuntimeException("Scope not yet closed");
//     }
//     return this.declarationScope;
//   }
// 
//   public void setDeclarationScope(Scope declarationScope) {
//     if (this.declarationScope != null) {
//       throw new RuntimeException("Cannot re-set scope");
//     }
//     this.declarationScope = declarationScope;
//   }
// 
//   @Override
//   public Property getProperty(String name) throws PropertyNotFoundException {
//     throw new PropertyNotFoundException("Not yet implemented");
//   }
// }
// 
// Path: src/main/java/org/hummingbirdlang/types/Type.java
// public abstract class Type {
//   public abstract Property getProperty(String name) throws PropertyNotFoundException;
// 
//   public void assertEquals(Type otherType) throws TypeMismatchException {
//     // Rudimentary pointer comparison by default.
//     if (this != otherType) {
//       throw new TypeMismatchException(this, otherType);
//     }
//   }
// 
//   /**
//    * Returns whether or not this type is equal to another type.
//    */
//   public boolean equals(Type otherType) {
//     try {
//       this.assertEquals(otherType);
//     } catch (TypeMismatchException exception) {
//       return false;
//     }
//     return true;
//   }
// }
// 
// Path: src/main/java/org/hummingbirdlang/types/scope/BuiltinScope.java
// public class BuiltinScope extends AbstractScope implements Scope, Iterable<String> {
//   private final Map<String, Type> types;
// 
//   public BuiltinScope(Index index) {
//     Map<String, Type> types = new HashMap<>();
//     // Bootstrap the global types.
//     Index.Module builtin = index.getBuiltin();
//     for (String name : builtin) {
//       types.put(name, builtin.get(name));
//     }
//     this.types = types;
//     // You can't modify the builtin scope!
//     this.close();
//   }
// 
//   @Override
//   public void accept(Resolution resolution) throws NameNotFoundException {
//     resolution.pushScope(this);
//     if (this.types.containsKey(resolution.getName())) {
//       resolution.setType(this.types.get(resolution.getName()));
//     } else {
//       throw new NameNotFoundException("Name not found in BuiltinScope: " + resolution.getName());
//     }
//   }
// 
//   @Override
//   public void setLocal(String name, Type type) {
//     throw new RuntimeException("Cannot modify BuiltinScope: " + name);
//   }
// 
//   @Override
//   public Scope getParent() {
//     throw new RuntimeException("Cannot getParent of BuiltinScope");
//   }
// 
//   @Override
//   public List<Resolution> getNonLocalResolutions() {
//     throw new RuntimeException("Cannot getNonLocalResolutions of BuiltinScope");
//   }
// 
//   @Override
//   public Iterator<String> iterator() {
//     return this.types.keySet().iterator();
//   }
// }
// 
// Path: src/main/java/org/hummingbirdlang/types/scope/NameNotFoundException.java
// public class NameNotFoundException extends TypeException {
//   public NameNotFoundException(String message) {
//     super(message);
//   }
// }


// Path: src/main/java/org/hummingbirdlang/runtime/bindings/Bindings.java
import java.util.HashMap;
import java.util.Map;
import org.hummingbirdlang.objects.Function;
import org.hummingbirdlang.types.FunctionType;
import org.hummingbirdlang.types.Type;
import org.hummingbirdlang.types.scope.BuiltinScope;
import org.hummingbirdlang.types.scope.NameNotFoundException;

package org.hummingbirdlang.runtime.bindings;



// Holds references to values closed from an outer scope.
public final class Bindings {
  private Map<String, Binding> bindings;

  public Bindings() {
    this.bindings = new HashMap<>();
  }

  public Bindings(BuiltinScope builtinScope) throws NameNotFoundException {
    this();
    // Bootstrap builtins into frame.
    for (String name : builtinScope) {
      Type type = builtinScope.get(name);
      if (type instanceof FunctionType) {
        Object function = new Function((FunctionType)type, null);