package builtin.type; import builtin.BuiltinSub; import gui.Constants; import gui.Heap; import gui.MintException; import gui.Pointer; import gui.PointerTools; import gui.SmartList; /** * Type is a subprogram that returns the type of any Mint value, as a * string. * * When "object" is returned, that refers to objects created using * return this, also known as environment frames. * When "value" is returned, it is ANY generic Mint object of unknown type. * @author Oliver Chu */ public class Type extends BuiltinSub { private static Pointer LIST_TYPE_STR = Heap.allocateString("list"); private static Pointer ELLIPSIS_TYPE_STR = Heap.allocateString("ellipsis"); private static Pointer TABLE_TYPE_STR = Heap.allocateString("table"); @Override public Pointer apply(SmartList<Pointer> args) throws MintException { if (args == null || args.isEmpty()) { return Heap.allocateString("Java Virtual Machine null"); } Pointer p = args.get(0); if (p == null) { return Heap.allocateString("Java Virtual Machine null"); } if (p.type == Constants.RAT_TYPE) { return Heap.allocateString("fraction"); } else if (p.type == Constants.IMG_TYPE) { return Heap.allocateString("image"); } String strData = PointerTools.dereferenceAsString(p); boolean isNotString = p.type != Constants.STR_TYPE; if (strData.toLowerCase().contains("infinity") && isNotString) { return Heap.allocateString("infinite number"); } if (p.value == Constants.ELLIPSIS && p.type == Constants.KEYWORD_TYPE || (strData.equals("...") && p.type != Constants.STR_TYPE)) { return ELLIPSIS_TYPE_STR; } if (p.type == Constants.TABLE_TYPE) { return TABLE_TYPE_STR; } if (p.type == Constants.LIST_TYPE) { SmartList<Pointer> slp = PointerTools.dereferenceList(p); if (slp.size() == 0) { return Heap.allocateString("empty sequence"); } // Check if this list is really a table. for (Pointer ptr : slp) { if (ptr.type == Constants.LIST_TYPE) { SmartList<Pointer> possiblePair = PointerTools.dereferenceList(ptr); if (possiblePair.size() != 2) { return LIST_TYPE_STR; } } else { return LIST_TYPE_STR; } } return TABLE_TYPE_STR; } switch (p.type) { case Constants.INT_TYPE: return Heap.allocateString("integer number"); case Constants.REAL_TYPE: return Heap.allocateString("real number"); case Constants.RAT_TYPE: return Heap.allocateString("rational number"); case Constants.STR_TYPE: return Heap.allocateString("string"); case Constants.TRUTH_TYPE: return Heap.allocateString("truth"); case Constants.NULL_TYPE: return Heap.allocateString("null"); case Constants.MESSAGE_TYPE: return Heap.allocateString("message"); case Constants.OBJECT_TYPE: return Heap.allocateString("object"); case Constants.LIST_TYPE: return Heap.allocateString("list"); case Constants.SUBPROGRAM_TYPE: return Heap.allocateString("subprogram"); case Constants.BLOCK_TYPE: return Heap.allocateString("block"); case Constants.BIG_INT_TYPE: return Heap.allocateString("big integer"); case Constants.PRECISE_REAL_TYPE: return Heap.allocateString("precise real"); case Constants.BYTES_TYPE: return Heap.allocateString("bytes"); case Constants.WINDOW_TYPE: return Heap.allocateString("window"); case Constants.BUTTON_TYPE: return Heap.allocateString("button"); case Constants.INTERPRETER_TYPE: return Heap.allocateString("interpreter"); case Constants.SHAPE_TYPE: return Heap.allocateString("shape"); case Constants.MATCHER_TYPE: return Heap.allocateString("matcher"); case Constants.KEYWORD_TYPE: if (PointerTools.dereferenceKeyword(p) == Constants.ELLIPSIS) { return ELLIPSIS_TYPE_STR; } else { return Heap.allocateString("keyword"); } default: return Heap.allocateString("value"); } } }