/******************************************************************************* * Copyright (c) 2009, 2012-2013 Centrum Wiskunde en Informatica (CWI) * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Jurgen Vinju - interface and implementation * Arnold Lankamp - implementation * Anya Helene Bagge - rational support, labeled maps and tuples * Davy Landman - added PI & E constants * Michael Steindorfer - Michael.Steindorfer@cwi.nl - CWI *******************************************************************************/ package org.rascalmpl.value.impl.primitive; import java.net.URI; import java.net.URISyntaxException; import java.util.concurrent.atomic.AtomicInteger; import org.rascalmpl.value.IBool; import org.rascalmpl.value.IDateTime; import org.rascalmpl.value.IInteger; import org.rascalmpl.value.IRational; import org.rascalmpl.value.IReal; import org.rascalmpl.value.ISourceLocation; import org.rascalmpl.value.IString; import org.rascalmpl.value.IValue; import org.rascalmpl.value.IValueFactory; import org.rascalmpl.value.type.Type; import org.rascalmpl.value.type.TypeFactory; import org.rascalmpl.value.util.ShareableHashMap; /** * Base value factory with optimized representations of primitive values. */ public abstract class AbstractPrimitiveValueFactory implements IValueFactory { private final static int DEFAULT_PRECISION = 10; private final AtomicInteger currentPrecision = new AtomicInteger(DEFAULT_PRECISION); protected Type inferInstantiatedTypeOfConstructor(final Type constructorType, final IValue... children) { Type instantiatedType; if (!constructorType.getAbstractDataType().isParameterized()) { instantiatedType = constructorType; } else { ShareableHashMap<Type, Type> bindings = new ShareableHashMap<>(); TypeFactory tf = TypeFactory.getInstance(); Type params = constructorType.getAbstractDataType().getTypeParameters(); for (Type p : params) { if (p.isOpen()) { bindings.put(p, tf.voidType()); } } constructorType.getFieldTypes().match(tf.tupleType(children), bindings); instantiatedType = constructorType.instantiate(bindings); } return instantiatedType; } @Override public IInteger integer(String integerValue) { return IntegerValue.newInteger(integerValue); } @Override public IInteger integer(int value) { return IntegerValue.newInteger(value); } @Override public IInteger integer(long value) { return IntegerValue.newInteger(value); } @Override public IInteger integer(byte[] integerData) { return IntegerValue.newInteger(integerData); } @Override public IRational rational(int a, int b) { return rational(integer(a), integer(b)); } @Override public IRational rational(long a, long b) { return rational(integer(a), integer(b)); } @Override public IRational rational(IInteger a, IInteger b) { return RationalValue.newRational(a, b); } @Override public IRational rational(String rat) throws NumberFormatException { if (rat.contains("r")) { String[] parts = rat.split("r"); if (parts.length == 2) { return rational(integer(parts[0]), integer(parts[1])); } if (parts.length == 1) { return rational(integer(parts[0]), integer(1)); } throw new NumberFormatException(rat); } else { return rational(integer(rat), integer(1)); } } @Override public IReal real(String value) { return BigDecimalValue.newReal(value); } @Override public IReal real(String value, int precision) throws NumberFormatException { return BigDecimalValue.newReal(value, precision); } @Override public IReal real(double value) { return BigDecimalValue.newReal(value); } @Override public IReal real(double value, int precision) { return BigDecimalValue.newReal(value, precision); } @Override public int getPrecision() { return currentPrecision.get(); } @Override public int setPrecision(int p) { return currentPrecision.getAndSet(p); } @Override public IReal pi(int precision) { return BigDecimalValue.pi(precision); } @Override public IReal e(int precision) { return BigDecimalValue.e(precision); } @Override public IString string(String value) { return StringValue.newString(value); } @Override public IString string(int[] chars) { StringBuilder b = new StringBuilder(chars.length); for (int ch : chars) { b.appendCodePoint(ch); } return string(b.toString()); } @Override public IString string(int ch) { StringBuilder b = new StringBuilder(1); b.appendCodePoint(ch); return string(b.toString()); } @Override public IBool bool(boolean value) { return BoolValue.getBoolValue(value); } @Override public IDateTime date(int year, int month, int day) { return DateTimeValues.newDate(year, month, day); } @Override public IDateTime time(int hour, int minute, int second, int millisecond) { return DateTimeValues.newTime(hour, minute, second, millisecond); } @Override public IDateTime time(int hour, int minute, int second, int millisecond, int hourOffset, int minuteOffset) { return DateTimeValues.newTime(hour, minute, second, millisecond, hourOffset, minuteOffset); } @Override public IDateTime datetime(int year, int month, int day, int hour, int minute, int second, int millisecond) { return DateTimeValues.newDateTime(year, month, day, hour, minute, second, millisecond); } @Override public IDateTime datetime(int year, int month, int day, int hour, int minute, int second, int millisecond, int hourOffset, int minuteOffset) { return DateTimeValues.newDateTime(year, month, day, hour, minute, second, millisecond, hourOffset, minuteOffset); } @Override public IDateTime datetime(long instant) { return DateTimeValues.newDateTime(instant); } @Override public IDateTime datetime(long instant, int timezoneHours, int timezoneMinutes) { return DateTimeValues.newDateTime(instant, timezoneHours, timezoneMinutes); } @Override public ISourceLocation sourceLocation(URI uri, int offset, int length) { return sourceLocation(sourceLocation(uri), offset, length); } @Override public ISourceLocation sourceLocation(ISourceLocation loc, int offset, int length) { return SourceLocationValues.newSourceLocation(loc, offset, length); } @Override public ISourceLocation sourceLocation(URI uri, int offset, int length, int beginLine, int endLine, int beginCol, int endCol) { return sourceLocation(sourceLocation(uri), offset, length, beginLine, endLine, beginCol, endCol); } @Override public ISourceLocation sourceLocation(ISourceLocation loc, int offset, int length, int beginLine, int endLine, int beginCol, int endCol) { return SourceLocationValues.newSourceLocation(loc, offset, length, beginLine, endLine, beginCol, endCol); } @Override public ISourceLocation sourceLocation(String path, int offset, int length, int beginLine, int endLine, int beginCol, int endCol) { return sourceLocation(sourceLocation(path), offset, length, beginLine, endLine, beginCol, endCol); } @Override public ISourceLocation sourceLocation(URI uri) { try { return SourceLocationValues.newSourceLocation(uri); } catch (URISyntaxException e) { throw new RuntimeException("An URI should always be a correct URI", e); } } @Override public ISourceLocation sourceLocation(String path) { if (!path.startsWith("/")) path = "/" + path; try { return sourceLocation("file", "", path); } catch (URISyntaxException e) { throw new RuntimeException("Paths should not cause a incorrect syntax exception", e); } } @Override public ISourceLocation sourceLocation(String scheme, String authority, String path) throws URISyntaxException { return sourceLocation(scheme, authority, path, null, null); } @Override public ISourceLocation sourceLocation(String scheme, String authority, String path, String query, String fragment) throws URISyntaxException { return SourceLocationValues.newSourceLocation(scheme, authority, path, query, fragment); } }