/** * Copyright (c) 2009-2011, The HATS Consortium. All rights reserved. * This file is licensed under the terms of the Modified BSD License. */ package abs.backend.java.lib.runtime; import java.io.PrintStream; import java.io.UnsupportedEncodingException; import java.math.BigInteger; import java.util.Random; import java.util.Scanner; import org.apfloat.Apint; import org.apfloat.Aprational; import abs.backend.java.lib.expr.UnmatchedCaseException; import abs.backend.java.lib.runtime.metaABS.ObjectMirror; import abs.backend.java.lib.runtime.metaABS.ProductLine; import abs.backend.java.lib.types.ABSBool; import abs.backend.java.lib.types.ABSDataType; import abs.backend.java.lib.types.ABSInteger; import abs.backend.java.lib.types.ABSProcess; import abs.backend.java.lib.types.ABSRational; import abs.backend.java.lib.types.ABSString; import abs.backend.java.lib.types.ABSUnit; import abs.backend.java.lib.types.ABSValue; import abs.backend.java.utils.DynamicClassUtils; public class ABSBuiltInFunctions { public static ABSInteger strlen(ABSString s) { return s.strlen(); } public static ABSString substr(ABSString s, ABSInteger from, ABSInteger length) { return s.substr(from, length); } public static ABSUnit print(ABSString s) { System.out.print(s.getString()); return ABSUnit.UNIT; } public static ABSRational currentms() { return ABSRational.fromBigInt(new Aprational(new Apint(System.currentTimeMillis()), new Apint(1000))); } public static ABSInteger lowlevelDeadline() { return ABSInteger.fromInt(-1); } public static ABSInteger random(ABSInteger i) { if (i.ltEq(ABSInteger.ZERO).toBoolean()) { throw new UnmatchedCaseException("Random function called with non positive upper bound " + i); } BigInteger n = i.getBigInteger(); Random rand = ABSRuntime.getCurrentRuntime().getRandom(); BigInteger result = new BigInteger(n.bitLength(), rand); while (result.compareTo(n) >= 0) { result = new BigInteger(n.bitLength(), rand); } return ABSInteger.fromBigInt(result); } public static abs.backend.java.lib.types.ABSInterface thisDC() { return ABSRuntime.getCurrentCOG().getDC(); } public static <T> ABSString toString(T t) { if (t == null) { return ABSString.fromString("null"); } else { return ABSString.fromString(t.toString()); } } /* * functions related to user-defined schedulers (see abslang, module * ABS.Scheduler) */ public static ABSString method(ABSProcess p) { return ABSString.fromString(p.getMethodName()); } public static ABSDataType arrival(ABSProcess p) { Class<?> type = DynamicClassUtils.getClass("ABS.StdLib.Time_Time"); return DynamicClassUtils.instance(type, ABSRational.fromLong(p.getArrivalTime())); } public static ABSDataType cost(ABSProcess p) { if (p.getCost() == -1) { Class<?> type = DynamicClassUtils.getClass("ABS.StdLib.Duration_InfDuration"); return DynamicClassUtils.instance(type); } else { Class<?> type = DynamicClassUtils.getClass("ABS.StdLib.Duration_Duration"); return DynamicClassUtils.instance(type, ABSRational.fromLong(p.getCost())); } } public static ABSDataType procDeadline(ABSProcess p) { if (p.getDeadline() == -1) { Class<?> type = DynamicClassUtils.getClass("ABS.StdLib.Duration_InfDuration"); return DynamicClassUtils.instance(type); } else { Class<?> type = DynamicClassUtils.getClass("ABS.StdLib.Duration_Duration"); return DynamicClassUtils.instance(type, ABSRational.fromLong(p.getDeadline())); } } public static ABSDataType start(ABSProcess p) { Class<?> type = DynamicClassUtils.getClass("ABS.StdLib.Time_Time"); return DynamicClassUtils.instance(type, ABSRational.fromLong(p.getStartTime())); } public static ABSDataType finish(ABSProcess p) { Class<?> type = DynamicClassUtils.getClass("ABS.StdLib.Time_Time"); return DynamicClassUtils.instance(type, ABSRational.fromLong(p.getFinishTime())); } public static ABSBool critical(ABSProcess p) { return ABSBool.fromBoolean(p.isCritical()); } public static ABSInteger value(ABSProcess p) { return ABSInteger.fromInt(p.getValue()); } /* * Functions to access the meta level * * reflect creates a "mirror object" for the given object, which gives * access to the meta API. */ public static <T> ABSDynamicObject reflect(T t) { String name = "$mirror"; try { ABSValue existingMirror = ((ABSDynamicObject) t).getFieldValue(name); return (ABSDynamicObject) existingMirror; } catch (NoSuchFieldException e) { ABSDynamicObject mirror = new ABSDynamicObject(ObjectMirror.singleton()); mirror.setFieldValue("object", (ABSValue) t); ((ABSDynamicObject) t).setFieldValue(name, mirror); return mirror; } } public static ABSDynamicObject getProductLine() { ABSDynamicObject pl = new ABSDynamicObject(ProductLine.singleton()); return pl; } /* * Convenience functions, to be removed */ public static ABSUnit println(ABSString s) { try { PrintStream out = new PrintStream(System.out, true, "UTF-8"); out.println(s.getString()); } catch (UnsupportedEncodingException e) { // TODO Auto-generated catch block e.printStackTrace(); } // System.out.println(s.getString()); return ABSUnit.UNIT; } public static ABSString readln() { Scanner scanner = new Scanner(System.in); String line = scanner.nextLine(); //scanner.close(); return ABSString.fromString(line.trim()); } /* * Functional break point * * Keep the value of the following constant in sync with the name of the * method and the according built-in function defined in abslang.abs. */ public static <A extends ABSValue, B extends ABSValue> A watchEx(String fileName, int line, A val, B info) { ABSRuntime runtime = ABSRuntime.getCurrentRuntime(); if (runtime.debuggingEnabled()) { Task<?> task = ABSRuntime.getCurrentTask(); task.newStackFrame(null, "$watch"); task.setLocalVariable("$watchValue", val); task.setLocalVariable("$watchInfo", info); runtime.nextStep(fileName, line); task.popStackFrame(); } return val; } public static <A extends ABSValue> A watch(String fileName, int line, A val) { ABSRuntime runtime = ABSRuntime.getCurrentRuntime(); if (runtime.debuggingEnabled()) { Task<?> task = ABSRuntime.getCurrentTask(); task.newStackFrame(null, "$watch"); task.setLocalVariable("$watchValue", val); runtime.nextStep(fileName, line); task.popStackFrame(); } return val; } public static ABSInteger truncate(ABSRational r) { return r.truncate(); } public static ABSInteger numerator(ABSRational r) { return r.numerator(); } public static ABSInteger denominator(ABSRational r) { return r.denominator(); } }