Skip to content

Commit

Permalink
Fix lots of NumericValue issues - probably more to go.
Browse files Browse the repository at this point in the history
  • Loading branch information
shevek committed Jan 18, 2014
1 parent 5e8bc47 commit ca42036
Show file tree
Hide file tree
Showing 6 changed files with 182 additions and 36 deletions.
7 changes: 7 additions & 0 deletions gradle/check.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,10 @@ apply plugin: 'cobertura'
cobertura {
coverageFormats = [ 'html', 'xml' ]
}
githubPages {
pages {
from(cobertura.coverageReportDir) {
into "docs/cobertura"
}
}
}
6 changes: 6 additions & 0 deletions src/main/ghpages/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<html>
<body>
<a href="docs/javadoc/">Javadoc</a>
<a href="docs/cobertura/">Coverage</a>
</body>
</html>
85 changes: 59 additions & 26 deletions src/main/java/org/anarres/cpp/LexerSource.java
Original file line number Diff line number Diff line change
Expand Up @@ -542,32 +542,40 @@ private String _number_part(StringBuilder text, int base)

/* We already chewed a zero, so empty is fine. */
@Nonnull
private Token number_octal()
private Token number_octal(boolean negative)
throws IOException,
LexerException {
StringBuilder text = new StringBuilder("0");
StringBuilder text = new StringBuilder(negative ? "-0" : "0");
String integer = _number_part(text, 8);
NumericValue value = new NumericValue(8, negative, integer);
int d = read();
NumericValue value = new NumericValue(8, integer);
if (d == '.') {
text.append((char) d);
String fraction = _number_part(text, 16);
value.setFractionalPart(fraction);
d = read();
}
return _number_suffix(text, value, d);
}

/* We do not know whether know the first digit is valid. */
@Nonnull
private Token number_hex(char x)
private Token number_hex(char x, boolean negative)
throws IOException,
LexerException {
StringBuilder text = new StringBuilder("0");
StringBuilder text = new StringBuilder(negative ? "-0" : "0");
text.append(x);
String integer = _number_part(text, 16);
NumericValue value = new NumericValue(16, integer);
NumericValue value = new NumericValue(16, negative, integer);
int d = read();
if (d == '.') {
text.append((char) d);
String fraction = _number_part(text, 16);
value.setFractionalPart(fraction);
d = read();
}
if (d == 'P' || d == 'p') {
text.append((char) d);
String exponent = _number_part(text, 10);
value.setExponent(exponent);
d = read();
Expand All @@ -579,12 +587,12 @@ private Token number_hex(char x)
/* We know we have at least one valid digit, but empty is not
* fine. */
@Nonnull
private Token number_decimal()
private Token number_decimal(boolean negative)
throws IOException,
LexerException {
StringBuilder text = new StringBuilder();
StringBuilder text = new StringBuilder(negative ? "-" : "");
String integer = _number_part(text, 10);
NumericValue value = new NumericValue(10, integer);
NumericValue value = new NumericValue(10, negative, integer);
int d = read();
if (d == '.') {
text.append((char) d);
Expand All @@ -602,6 +610,41 @@ private Token number_decimal()
return _number_suffix(text, value, d);
}

@Nonnull
private Token number()
throws IOException,
LexerException {
boolean negative = false;
Token tok;
int c = read();
if (c == '-') {
negative = true;
c = read();
}
if (c == '0') {
int d = read();
if (d == 'x' || d == 'X') {
tok = number_hex((char) d, negative);
} else if (d == '.') {
unread(d);
unread(c);
tok = number_decimal(negative);
} else {
unread(d);
tok = number_octal(negative);
}
} else if (Character.isDigit(c)) {
unread(c);
tok = number_decimal(negative);
} else if (c == '.') {
unread(c);
tok = number_decimal(negative);
} else {
throw new LexerException("Asked to parse something as a number which isn't: " + (char) c);
}
return tok;
}

@Nonnull
private Token identifier(int c)
throws IOException,
Expand Down Expand Up @@ -722,6 +765,10 @@ else if (d == '>')
tok = new Token(ARROW);
else
unread(d);
if (Character.isDigit(d)) {
unread('-');
tok = number();
}
break;

case '*':
Expand Down Expand Up @@ -839,26 +886,11 @@ else if (d == '=')
unread(d);
if (Character.isDigit(d)) {
unread('.');
tok = number_decimal();
tok = number();
}
/* XXX decimal fraction */
break;

case '0':
/* octal or hex */
d = read();
if (d == 'x' || d == 'X')
tok = number_hex((char) d);
else if (d == '.') {
unread(d);
unread(c);
tok = number_decimal();
} else {
unread(d);
tok = number_octal();
}
break;

case '\'':
tok = string('\'', '\'');
break;
Expand All @@ -878,7 +910,7 @@ else if (d == '.') {
tok = whitespace(c);
} else if (Character.isDigit(c)) {
unread(c);
tok = number_decimal();
tok = number();
} else if (Character.isJavaIdentifierStart(c)) {
tok = identifier(c);
} else {
Expand All @@ -904,6 +936,7 @@ else if (d == '.') {
return tok;
}

@Override
public void close()
throws IOException {
if (reader != null) {
Expand Down
29 changes: 26 additions & 3 deletions src/main/java/org/anarres/cpp/NumericValue.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@

import java.math.BigDecimal;
import java.math.BigInteger;
import javax.annotation.CheckForNull;
import javax.annotation.Nonnegative;
import javax.annotation.Nonnull;

public class NumericValue extends Number {

Expand All @@ -31,24 +34,33 @@ public class NumericValue extends Number {
public static final int FF_SIZE = F_INT | F_LONG | F_LONGLONG | F_FLOAT | F_DOUBLE;

private final int base;
private final boolean negative;
private final String integer;
private String fraction;
private String exponent;
private int flags;

public NumericValue(int base, String integer) {
public NumericValue(int base, boolean negative, String integer) {
this.base = base;
this.negative = negative;
this.integer = integer;
}

@Nonnegative
public int getBase() {
return base;
}

public boolean isNegative() {
return negative;
}

@Nonnull
public String getIntegerPart() {
return integer;
}

@CheckForNull
public String getFractionalPart() {
return fraction;
}
Expand All @@ -57,6 +69,7 @@ public String getFractionalPart() {
this.fraction = fraction;
}

@CheckForNull
public String getExponent() {
return exponent;
}
Expand All @@ -78,6 +91,7 @@ public int getFlags() {
* precision numbers is nontrivial, and this routine gets it wrong
* in many important cases.
*/
@Nonnull
public BigDecimal toBigDecimal() {
int scale = 0;
String text = getIntegerPart();
Expand All @@ -93,6 +107,7 @@ public BigDecimal toBigDecimal() {
return new BigDecimal(unscaled, scale);
}

@Nonnull
public Number toJavaLangNumber() {
int flags = getFlags();
if ((flags & F_DOUBLE) != 0)
Expand All @@ -113,21 +128,27 @@ else if (getExponent() != null)

@Override
public int intValue() {
return Integer.parseInt(toString());
int v = integer.isEmpty() ? 0 : Integer.parseInt(integer, base);
return isNegative() ? -v : v;
}

@Override
public long longValue() {
return Long.parseLong(toString());
long v = integer.isEmpty() ? 0 : Long.parseLong(integer, base);
return isNegative() ? -v : v;
}

@Override
public float floatValue() {
if (getBase() != 10)
return longValue();
return Float.parseFloat(toString());
}

@Override
public double doubleValue() {
if (getBase() != 10)
return longValue();
return Double.parseDouble(toString());
}

Expand All @@ -141,6 +162,8 @@ private boolean appendFlags(StringBuilder buf, String suffix, int flag) {
@Override
public String toString() {
StringBuilder buf = new StringBuilder();
if (isNegative())
buf.append('-');
switch (base) {
case 8:
buf.append('0');
Expand Down
14 changes: 7 additions & 7 deletions src/main/java/org/anarres/cpp/Preprocessor.java
Original file line number Diff line number Diff line change
Expand Up @@ -787,8 +787,8 @@ private boolean macro(Macro m, Token orig)
push_source(new FixedTokenSource(
new Token[]{new Token(NUMBER,
orig.getLine(), orig.getColumn(),
String.valueOf(orig.getLine()),
new NumericValue(10, "" + orig.getLine()))}
Integer.toString(orig.getLine()),
new NumericValue(10, false, Integer.toString(orig.getLine())))}
), true);
} else if (m == __FILE__) {
StringBuilder buf = new StringBuilder("\"");
Expand Down Expand Up @@ -823,8 +823,8 @@ private boolean macro(Macro m, Token orig)
push_source(new FixedTokenSource(
new Token[]{new Token(NUMBER,
orig.getLine(), orig.getColumn(),
String.valueOf(value),
new NumericValue(10, "" + value))}
Integer.toString(value),
new NumericValue(10, false, Integer.toString(value)))}
), true);
} else {
push_source(new MacroTokenSource(m, args), true);
Expand Down Expand Up @@ -1388,17 +1388,17 @@ private Token expr_token()
+ la.getText());
tok = new Token(NUMBER,
la.getLine(), la.getColumn(),
"0", new NumericValue(10, "0"));
"0", new NumericValue(10, false, "0"));
} else if (macros.containsKey(la.getText())) {
// System.out.println("Found macro");
tok = new Token(NUMBER,
la.getLine(), la.getColumn(),
"1", new NumericValue(10, "1"));
"1", new NumericValue(10, false, "1"));
} else {
// System.out.println("Not found macro");
tok = new Token(NUMBER,
la.getLine(), la.getColumn(),
"0", new NumericValue(10, "0"));
"0", new NumericValue(10, false, "0"));
}

if (paren) {
Expand Down
Loading

0 comments on commit ca42036

Please sign in to comment.