Move integer range checking to semantic analysis
This commit is contained in:
parent
192146b99d
commit
6af6d2ca15
7 changed files with 48 additions and 22 deletions
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
/build/
|
||||
/.idea/
|
||||
/.gradle/
|
||||
|
|
@ -167,7 +167,7 @@ public class SsaTranslation {
|
|||
@Override
|
||||
public Optional<Node> visit(LiteralTree literalTree, SsaTranslation data) {
|
||||
pushSpan(literalTree);
|
||||
Node node = data.constructor.newConstInt((int) literalTree.value());
|
||||
Node node = data.constructor.newConstInt((int) literalTree.parseValue().orElseThrow());
|
||||
popSpan();
|
||||
return Optional.of(node);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -171,30 +171,12 @@ public class Parser {
|
|||
}
|
||||
case NumberLiteral(String value, int base, Span span) -> {
|
||||
this.tokenSource.consume();
|
||||
yield new LiteralTree(parseValue(value, base), span);
|
||||
yield new LiteralTree(value, base, span);
|
||||
}
|
||||
case Token t -> throw new ParseException("invalid factor " + t);
|
||||
};
|
||||
}
|
||||
|
||||
private static long parseValue(String value, int base) {
|
||||
int begin = 0;
|
||||
int end = value.length();
|
||||
if (base == 16) {
|
||||
begin = 2; // ignore 0x
|
||||
}
|
||||
long l;
|
||||
try {
|
||||
l = Long.parseLong(value, begin, end, base);
|
||||
} catch (NumberFormatException _) {
|
||||
throw new ParseException("invalid int literal " + value);
|
||||
}
|
||||
if (l < 0 || l > Integer.toUnsignedLong(Integer.MIN_VALUE)) {
|
||||
throw new ParseException("invalid int literal " + value);
|
||||
}
|
||||
return l;
|
||||
}
|
||||
|
||||
private static NameTree name(Identifier ident) {
|
||||
return new NameTree(Name.forIdentifier(ident), ident.span());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -79,7 +79,7 @@ public class Printer {
|
|||
printTree(rhs);
|
||||
print(")");
|
||||
}
|
||||
case LiteralTree(var value, _) -> this.builder.append(value);
|
||||
case LiteralTree(var value, _, _) -> this.builder.append(value);
|
||||
case NegateTree(var expression, _) -> {
|
||||
print("-(");
|
||||
printTree(expression);
|
||||
|
|
|
|||
|
|
@ -1,11 +1,34 @@
|
|||
package edu.kit.kastel.vads.compiler.parser.ast;
|
||||
|
||||
import edu.kit.kastel.vads.compiler.Span;
|
||||
import edu.kit.kastel.vads.compiler.parser.ParseException;
|
||||
import edu.kit.kastel.vads.compiler.parser.visitor.Visitor;
|
||||
import edu.kit.kastel.vads.compiler.semantic.SemanticException;
|
||||
import java.util.Optional;
|
||||
import java.util.OptionalLong;
|
||||
|
||||
public record LiteralTree(long value, Span span) implements ExpressionTree {
|
||||
public record LiteralTree(String value, int base, Span span) implements ExpressionTree {
|
||||
@Override
|
||||
public <T, R> R accept(Visitor<T, R> visitor, T data) {
|
||||
return visitor.visit(this, data);
|
||||
}
|
||||
|
||||
public OptionalLong parseValue() {
|
||||
int begin = 0;
|
||||
int end = value.length();
|
||||
if (base == 16) {
|
||||
begin = 2; // ignore 0x
|
||||
}
|
||||
long l;
|
||||
try {
|
||||
l = Long.parseLong(value, begin, end, base);
|
||||
} catch (NumberFormatException _) {
|
||||
return OptionalLong.empty();
|
||||
}
|
||||
if (l < 0 || l > Integer.toUnsignedLong(Integer.MIN_VALUE)) {
|
||||
return OptionalLong.empty();
|
||||
}
|
||||
return OptionalLong.of(l);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,17 @@
|
|||
package edu.kit.kastel.vads.compiler.semantic;
|
||||
|
||||
import edu.kit.kastel.vads.compiler.parser.ast.LiteralTree;
|
||||
import edu.kit.kastel.vads.compiler.parser.visitor.NoOpVisitor;
|
||||
import edu.kit.kastel.vads.compiler.parser.visitor.Unit;
|
||||
|
||||
public class IntegerLiteralRangeAnalysis implements NoOpVisitor<Namespace<Void>> {
|
||||
|
||||
@Override
|
||||
public Unit visit(LiteralTree literalTree, Namespace<Void> data) {
|
||||
literalTree.parseValue()
|
||||
.orElseThrow(
|
||||
() -> new SemanticException("invalid integer literal " + literalTree.value())
|
||||
);
|
||||
return NoOpVisitor.super.visit(literalTree, data);
|
||||
}
|
||||
}
|
||||
|
|
@ -12,6 +12,7 @@ public class SemanticAnalysis {
|
|||
}
|
||||
|
||||
public void analyze() {
|
||||
this.program.accept(new RecursivePostorderVisitor<>(new IntegerLiteralRangeAnalysis()), new Namespace<>());
|
||||
this.program.accept(new RecursivePostorderVisitor<>(new VariableStatusAnalysis()), new Namespace<>());
|
||||
this.program.accept(new RecursivePostorderVisitor<>(new ReturnAnalysis()), new ReturnAnalysis.ReturnState());
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue