Package com.stuffwithstuff.magpie.intrinsic

Source Code of com.stuffwithstuff.magpie.intrinsic.ClassInit

package com.stuffwithstuff.magpie.intrinsic;

import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;

import com.stuffwithstuff.magpie.ast.Expr;
import com.stuffwithstuff.magpie.ast.pattern.Pattern;
import com.stuffwithstuff.magpie.interpreter.Callable;
import com.stuffwithstuff.magpie.interpreter.ClassObj;
import com.stuffwithstuff.magpie.interpreter.Context;
import com.stuffwithstuff.magpie.interpreter.FieldObj;
import com.stuffwithstuff.magpie.interpreter.Obj;
import com.stuffwithstuff.magpie.interpreter.Scope;

/**
* Built-in callable that initializes an instance of a class from the given
* record of fields and parent class initializers.
*/
public class ClassInit implements Callable {
  public ClassInit(ClassObj classObj, Scope closure) {
    mClass = classObj;
    mClosure = closure;
  }

  @Override
  public Obj invoke(Context context, Obj arg) {
    // We don't care about the receiver.
    arg = arg.getField(1);
   
    Obj obj = context.getInterpreter().getConstructingObject();

    // Initialize the parent classes from the record.
    for (ClassObj parent : mClass.getParents()) {
      Obj value = arg.getField(parent.getName());
      if (value != null) {
        context.getInterpreter().initializeNewObject(context, parent, value);
      }
    }
   
    // Initialize the fields from the record.
    for (Entry<String, FieldObj> field : mClass.getFieldDefinitions().entrySet()) {
      // Assign it from the record.
      Obj value = arg.getField(field.getKey());
      if (value != null) {
        obj.setField(field.getKey(), arg.getField(field.getKey()));
      }
    }
   
    // Note that we've successfully reached the canonical initializer.
    context.getInterpreter().finishInitialization();
   
    return obj;
  }
 
  @Override
  public Pattern getPattern() {
    // The receiver should be the class object itself.
    Pattern receiver = Pattern.value(Expr.name(mClass.getName()));
   
    // The argument should be a record with fields for each declared field
    // in the class.
    Map<String, Pattern> fields = new HashMap<String, Pattern>();
    for (Entry<String, FieldObj> field : mClass.getFieldDefinitions().entrySet()) {
      // Only care about fields that don't have initializers.
      if (field.getValue().getInitializer() == null) {
        fields.put(field.getKey(), field.getValue().getPattern());
      }
    }

    Pattern argument = Pattern.record(fields);
   
    return Pattern.record(receiver, argument);
  }

  @Override
  public Scope getClosure() {
    return mClosure;
  }
 
  @Override
  public String getDoc() {
    return "Canonical initializer for class " + mClass.getName() + ".";
  }

  @Override
  public String toString() {
    return mClass.getName() + " init(" + getPattern() + ")";
  }
 
  private final ClassObj mClass;
  private final Scope mClosure;
}
TOP

Related Classes of com.stuffwithstuff.magpie.intrinsic.ClassInit

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.