Package com.stuffwithstuff.magpie.intrinsic

Source Code of com.stuffwithstuff.magpie.intrinsic.IntrinsicMethods$Record_ToString

package com.stuffwithstuff.magpie.intrinsic;

import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.Map.Entry;

import com.stuffwithstuff.magpie.Def;
import com.stuffwithstuff.magpie.Doc;
import com.stuffwithstuff.magpie.ast.Expr;
import com.stuffwithstuff.magpie.interpreter.Callable;
import com.stuffwithstuff.magpie.interpreter.Context;
import com.stuffwithstuff.magpie.interpreter.FnObj;
import com.stuffwithstuff.magpie.interpreter.Name;
import com.stuffwithstuff.magpie.interpreter.Obj;
import com.stuffwithstuff.magpie.interpreter.PatternTester;
import com.stuffwithstuff.magpie.parser.MagpieParser;
import com.stuffwithstuff.magpie.parser.ParseException;
import com.stuffwithstuff.magpie.parser.StringReader;

/**
* Defines built-in methods that are available as top-level global functions.
*/
public class IntrinsicMethods {
  @Def("currentTime()")
  public static class CurrentTime implements Intrinsic {
    public Obj invoke(Context context, Obj left, Obj right) {
      // TODO(bob): Total hack to fit in an int.
      int time = (int) (System.currentTimeMillis() - 1289000000000L);
      return context.toObj(time);
    }
  }
 
  @Def("(is Function) call(arg)")
  @Doc("Invokes the given function.")
  public static class Call implements Intrinsic {
    public Obj invoke(Context context, Obj left, Obj right) {
      FnObj function = left.asFn();
      Obj fnArg = right;
     
      // Make sure the argument matches the function's pattern.
      Callable callable = function.getCallable();
      if (!PatternTester.test(context, callable.getPattern(), fnArg,
          callable.getClosure())) {
        throw context.error(Name.NO_METHOD_ERROR, "The argument \"" +
            context.getInterpreter().evaluateToString(fnArg) + "\" does not match the " +
            "function's pattern " + callable.getPattern());
      }

      return function.invoke(context, fnArg);
    }
  }

  // TODO(bob): More or less temporary.
  @Def("canParse(source is String)")
  public static class CanParse implements Intrinsic {
    public Obj invoke(Context context, Obj left, Obj right) {
      String source = right.asString();
     
      boolean canParse = true;
     
      try {
        MagpieParser parser = new MagpieParser(new StringReader("", source));

        while (true) {
          Expr expr = parser.parseStatement();
          if (expr == null) break;
        }
      } catch (ParseException e) {
        canParse = false;
      }
     
      return context.toObj(canParse);
    }
  }
 
  @Def("(this is Class) name")
  @Doc("Gets the name of the class.")
  public static class Class_Name implements Intrinsic {
    public Obj invoke(Context context, Obj left, Obj right) {
      return context.toObj(left.asClass().getName());
    }
  }

  @Def("(left) == (right)")
  @Doc("Returns true if left and right are the same object.")
  public static class Equals implements Intrinsic {
    public Obj invoke(Context context, Obj left, Obj right) {
      // By default, "==" does reference equality.
      return context.toObj(left == right);
    }
  }

  @Def("(left is Record) ==(right is Record)")
  @Doc("Returns true if the two records have the same fields.")
  public static class Equals_Record implements Intrinsic {
    public Obj invoke(Context context, Obj left, Obj right) {
      Map<String, Obj> fields = left.getFields();
      Set<String> compared = new HashSet<String>();
     
      // Make sure the right record has all of the left record's fields.
      for (Entry<String, Obj> entry : fields.entrySet()) {
        Obj rightField = right.getField(entry.getKey());
        if (rightField == null) return context.toObj(false);
        if (!context.getInterpreter().objectsEqual(
            entry.getValue(), rightField)) {
          return context.toObj(false);
        }
        compared.add(entry.getKey());
      }
     
      // Make sure the right record doesn't have any extra fields.
      for (String field : right.getFields().keySet()) {
        if (!compared.contains(field)) return context.toObj(false);
      }
     
      return context.toObj(true);
    }
  }
 
  @Def("(this) toString")
  @Doc("Returns a generic string representation of the object.")
  public static class ToString implements Intrinsic {
    public Obj invoke(Context context, Obj left, Obj right) {
      return context.toObj("<" + left.getClassObj().getName() + ">");
    }
  }

  @Def("(is Record) toString")
  @Doc("Returns a string representation of the given record.")
  public static class Record_ToString implements Intrinsic {
    public Obj invoke(Context context, Obj left, Obj right) {
      return context.toObj(left.toString());
    }
  }

  @Def("(is Error) toString")
  @Doc("Returns a string representation of the error.")
  public static class Error_ToString implements Intrinsic {
    public Obj invoke(Context context, Obj left, Obj right) {
      // If we've crammed a message in it (which internal errors do), then
      // show that.
      if (left.getValue() instanceof String) {
        String message = (String)left.getValue();
        return context.toObj(message);
      }
     
      // Just do the default.
      return context.toObj("<" + left.getClassObj().getName() + ">");
    }
  }
}
TOP

Related Classes of com.stuffwithstuff.magpie.intrinsic.IntrinsicMethods$Record_ToString

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.