Skip to content

Commit

Permalink
Schemacode compiler messages overhaul
Browse files Browse the repository at this point in the history
  • Loading branch information
cardillan committed Nov 2, 2024
1 parent df68261 commit 8d27de8
Show file tree
Hide file tree
Showing 114 changed files with 1,170 additions and 1,033 deletions.
25 changes: 16 additions & 9 deletions CHANGELOG.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,19 @@ All notable changes to this project will be documented in this file.

### Changed

* **Deprecation:** Changed the syntax of properties to use the `@` prefix for Mindustry built-in variables (e.g. `vault1.@coal`). Omitting the `@` prefix from a property name generates a deprecation warning.
* **Deprecation:** Changed Mindustry Logic functions to require the `out` modifier when passing in an output argument, in the same way as the user-defined functions. Omitting the `out` modifier from a Mindustry Logic function calls generates a deprecation warning.
* Changed the [Loop Unrolling optimization](doc/syntax/SYNTAX-6-OPTIMIZATIONS.markdown#loop-unrolling) to replace output iterator variables with the variable assigned to them.
* Changed the [Single Step Eliminator](doc/syntax/SYNTAX-6-OPTIMIZATIONS.markdown#single-step-elimination) to remove a jump is if there is an identical jump preceding it and there are no other jumps or labels between them. Active on `experimental`.
* Changed the expression evaluator to evaluate operations over known built-in values. The change enhances the Data Flow and Jump Normalization optimizations.
* Changed the Schemacode compiler to correctly output positions of error messages generated by Mindcode compiler, taking into account both the source file and/or position of the Mindcode program or program snippet within the source file.
* Changed the Schemacode compiler to correctly output positions of error messages generated by both the Schemacode and Mindcode compilers, taking into account both the source file and/or position of the Mindcode program or program snippet within the source file.

### Deprecated

* Deprecated the syntax of properties omitting the `@` prefix for Mindustry built-in variables (e.g. `vault1.coal` instead of `vault1.@coal`).
* Deprecated the syntax of Mindustry Logic function calls not requiring the `out` modifier when passing in an output argument.

### Miscellaneous

* Improved the command-line tool output of the Compile Schemacode action.

## 2.4.0 - 2024-10-23

Expand Down Expand Up @@ -97,12 +104,12 @@ All notable changes to this project will be documented in this file.

### Deprecated

- Deprecated the original Mindcode syntax.
- Deprecated the usage of parentheses around the list of values in list iteration loops.
- Deprecated escaped double quotes in string literals.
- Deprecated kebab-case identifiers (note that built-in mlog variables, such as `@blast-compound`, will continue to be supported).
- Deprecated the `printf()` function in language target `ML7A` and earlier.
- Deprecated the `configure` property. This property from Mindustry Logic 6 was replaced by `config` in Mindustry Logic 7.
* Deprecated the original Mindcode syntax.
* Deprecated the usage of parentheses around the list of values in list iteration loops.
* Deprecated escaped double quotes in string literals.
* Deprecated kebab-case identifiers (note that built-in mlog variables, such as `@blast-compound`, will continue to be supported).
* Deprecated the `printf()` function in language target `ML7A` and earlier.
* Deprecated the `configure` property. This property from Mindustry Logic 6 was replaced by `config` in Mindustry Logic 7.

### Miscellaneous

Expand Down
7 changes: 7 additions & 0 deletions compiler/src/main/java/info/teksol/mindcode/AstElement.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package info.teksol.mindcode;

public interface AstElement {

InputPosition inputPosition();

}
57 changes: 55 additions & 2 deletions compiler/src/main/java/info/teksol/mindcode/CompilerMessage.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,60 @@
package info.teksol.mindcode;

public interface CompilerMessage extends MindcodeMessage {
import org.intellij.lang.annotations.PrintFormat;

InputPosition inputPosition();
import java.util.Locale;
import java.util.Objects;
import java.util.function.Function;

public record CompilerMessage(MessageLevel level, InputPosition inputPosition, String message) implements MindcodeMessage {

public CompilerMessage {
Objects.requireNonNull(level);
Objects.requireNonNull(inputPosition);
Objects.requireNonNull(message);
}

@Override
public MindcodeMessage translatePosition(InputPositionTranslator translator) {
if (!inputPosition.isEmpty()) {
InputPosition translated = translator.apply(inputPosition);
if (translated != inputPosition) {
return new CompilerMessage(level, translated, message);
}
}
return this;
}

public static CompilerMessage error(InputPosition inputPosition, @PrintFormat String format, Object... args) {
Objects.requireNonNull(inputPosition);
return new CompilerMessage(MessageLevel.ERROR, inputPosition, String.format(Locale.US, format, args));
}

public static CompilerMessage warn(InputPosition inputPosition, @PrintFormat String format, Object... args) {
Objects.requireNonNull(inputPosition);
return new CompilerMessage(MessageLevel.WARNING, inputPosition, String.format(Locale.US, format, args));
}

public static CompilerMessage info(InputPosition inputPosition, @PrintFormat String format, Object... args) {
Objects.requireNonNull(inputPosition);
return new CompilerMessage(MessageLevel.INFO, inputPosition, String.format(Locale.US, format, args));
}

public static CompilerMessage debug(InputPosition inputPosition, @PrintFormat String format, Object... args) {
Objects.requireNonNull(inputPosition);
return new CompilerMessage(MessageLevel.DEBUG, inputPosition, String.format(Locale.US, format, args));
}

public String formatMessage(Function<InputPosition, String> positionFormatter) {
return positionFormatter.apply(inputPosition()) + " " + (isErrorOrWarning() ? level().getTitle() + ": " : "") + formatMessage();
}

@Override
public String toString() {
return "MindcodeCompilerMessage{" +
"level=" + level +
", inputPosition=" + inputPosition +
", message='" + message + '\'' +
'}';
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package info.teksol.mindcode;

import info.teksol.mindcode.compiler.MindcodeCompilerMessage;
import info.teksol.mindcode.grammar.MissingSemicolonException;
import org.antlr.v4.runtime.*;
import org.antlr.v4.runtime.atn.ATNConfigSet;
Expand Down Expand Up @@ -34,10 +33,10 @@ public int getAmbiguities() {
return ambiguities;
}

private final Set<MindcodeCompilerMessage> reportedMessages = new HashSet<>();
private final Set<CompilerMessage> reportedMessages = new HashSet<>();

private void reportError(int line, int charPositionInLine, @PrintFormat String format, Object... args) {
MindcodeCompilerMessage message = MindcodeCompilerMessage.error(
CompilerMessage message = CompilerMessage.error(
new InputPosition(inputFile, line, charPositionInLine + 1), format, args);
if (reportedMessages.add(message)) {
messageConsumer.accept(message);
Expand Down
6 changes: 2 additions & 4 deletions compiler/src/main/java/info/teksol/mindcode/ast/AstNode.java
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
package info.teksol.mindcode.ast;

import info.teksol.mindcode.InputPosition;
import info.teksol.mindcode.AstElement;
import info.teksol.mindcode.compiler.generator.AstContextType;
import info.teksol.mindcode.compiler.generator.AstSubcontextType;

import java.util.List;

public interface AstNode {
public interface AstNode extends AstElement {
List<AstNode> getChildren();

InputPosition getInputPosition();

AstContextType getContextType();

AstSubcontextType getSubcontextType();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package info.teksol.mindcode.ast;

import info.teksol.mindcode.*;
import info.teksol.mindcode.compiler.MindcodeCompilerMessage;
import info.teksol.mindcode.grammar.MindcodeBaseVisitor;
import info.teksol.mindcode.grammar.MindcodeParser;
import org.antlr.v4.runtime.ParserRuleContext;
Expand Down Expand Up @@ -35,11 +34,11 @@ public static Seq generate(InputFile inputFile, Consumer<MindcodeMessage> messag
}

private void error(InputPosition position, @PrintFormat String format, Object... args) {
messageConsumer.accept(MindcodeCompilerMessage.error(position, format, args));
messageConsumer.accept(CompilerMessage.error(position, format, args));
}

private void warn(InputPosition position, @PrintFormat String format, Object... args) {
messageConsumer.accept(MindcodeCompilerMessage.warn(position, format, args));
messageConsumer.accept(CompilerMessage.warn(position, format, args));
}

@Override
Expand Down Expand Up @@ -463,7 +462,7 @@ public AstNode visitFunction_declaration(MindcodeParser.Function_declarationCont
if (parameters.size() > offset) {
parameters.subList(0, parameters.size() - offset).stream()
.filter(FunctionParameter::isVarArgs)
.forEach(p -> error(p.getInputPosition(),
.forEach(p -> error(p.inputPosition(),
"Only the last parameter of an inline function can be declared as vararg."));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ protected BaseAstNode(InputPosition inputPosition, List<? extends AstNode> child
this.children = safeCopy(tmp);
}

public InputPosition getInputPosition() {
public InputPosition inputPosition() {
return inputPosition;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public NumericValue(InputPosition inputPosition, double value) {
* @return numeric literal representation of the value, or null if literal representation doesn't exist
*/
public NumericLiteral toNumericLiteral(InstructionProcessor instructionProcessor) {
return instructionProcessor.mlogFormat(value).map(str -> new NumericLiteral(getInputPosition(), str)).orElse(null);
return instructionProcessor.mlogFormat(value).map(str -> new NumericLiteral(inputPosition(), str)).orElse(null);
}

@Override
Expand Down
2 changes: 1 addition & 1 deletion compiler/src/main/java/info/teksol/mindcode/ast/Seq.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public static Seq append(Seq first, Seq second) {
} else if (second == null) {
return first;
} else {
return new Seq(second.getInputPosition(), first, second);
return new Seq(second.inputPosition(), first, second);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -129,16 +129,16 @@ public static String toStringWithSourceCode(InstructionProcessor instructionProc
addArgs(instructionProcessor.getPrintArgumentCount(instruction), lineBuffer, instruction);

AstContext astContext = instruction.getAstContext();
if (astContext.node() != null && astContext.node().getInputPosition() != null) {
InputFile file = astContext.node().getInputPosition().inputFile();
if (astContext.node() != null && astContext.node().inputPosition() != null) {
InputFile file = astContext.node().inputPosition().inputFile();
String srcLine = "** Corresponding source code line not found! **";
List<String> lines = allLines.get(file);
if (lines == null) {
lines = file.code().lines().toList();
allLines.put(file, lines);
}

int line = astContext.node().getInputPosition().line() - 1;
int line = astContext.node().inputPosition().line() - 1;
if (line == prevLine) {
srcLine = "...";
} else if (line >= 0 && line < lines.size()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ private GeneratorOutput generateCode(Seq program) {

private List<LogicInstruction> optimize(GeneratorOutput generatorOutput) {
messageConsumer.accept(
MindcodeOptimizerMessage.debug("%s", profile.getOptimizationLevels().entrySet().stream()
OptimizerMessage.debug("%s", profile.getOptimizationLevels().entrySet().stream()
.sorted(Comparator.comparing(e -> e.getKey().getOptionName()))
.map(e -> e.getKey().getOptionName() + " = " + e.getValue().name().toLowerCase())
.collect(Collectors.joining(",\n ", "Active optimizations:\n ", "\n"))
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package info.teksol.mindcode.compiler.functions;

import info.teksol.mindcode.CompilerMessage;
import info.teksol.mindcode.ast.AstNode;
import info.teksol.mindcode.compiler.MindcodeCompilerMessage;
import info.teksol.mindcode.compiler.generator.AbstractMessageEmitter;
import info.teksol.mindcode.compiler.instructions.LogicInstruction;
import info.teksol.mindcode.compiler.instructions.MlogInstruction;
Expand Down Expand Up @@ -73,7 +73,7 @@ public String getNote() {
@Override
public LogicValue handleProperty(AstNode node, Consumer<LogicInstruction> program, LogicValue target, List<LogicFunctionArgument> arguments) {
if (!warningEmitted) {
functionMapper.getMessageConsumer().accept(MindcodeCompilerMessage.warn(node.getInputPosition(),
functionMapper.getMessageConsumer().accept(CompilerMessage.warn(node.inputPosition(),
"Function '%s' is no longer supported in Mindustry Logic version %s; using '%s' instead.",
deprecated, functionMapper.processorVersion, replacement.getName()));
warningEmitted = true;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
package info.teksol.mindcode.compiler.generator;

import info.teksol.mindcode.AstElement;
import info.teksol.mindcode.CompilerMessage;
import info.teksol.mindcode.InputPosition;
import info.teksol.mindcode.MindcodeMessage;
import info.teksol.mindcode.ast.AstNode;
import info.teksol.mindcode.compiler.MindcodeCompilerMessage;
import org.intellij.lang.annotations.PrintFormat;

import java.util.function.Consumer;
Expand All @@ -21,22 +21,27 @@ public Consumer<MindcodeMessage> getMessageConsumer() {
}

@Override
public void error(AstNode node, @PrintFormat String format, Object... args) {
messageConsumer.accept(MindcodeCompilerMessage.error(node.getInputPosition(), format, args));
public void addMessage(MindcodeMessage message) {
messageConsumer.accept(message);
}

@Override
public void error(AstElement element, @PrintFormat String format, Object... args) {
messageConsumer.accept(CompilerMessage.error(element.inputPosition(), format, args));
}

@Override
public void error(InputPosition position, @PrintFormat String format, Object... args) {
messageConsumer.accept(MindcodeCompilerMessage.error(position, format, args));
messageConsumer.accept(CompilerMessage.error(position, format, args));
}

@Override
public void warn(AstNode node, @PrintFormat String format, Object... args) {
messageConsumer.accept(MindcodeCompilerMessage.warn(node.getInputPosition(), format, args));
public void warn(AstElement element, @PrintFormat String format, Object... args) {
messageConsumer.accept(CompilerMessage.warn(element.inputPosition(), format, args));
}

@Override
public void warn(InputPosition position, @PrintFormat String format, Object... args) {
messageConsumer.accept(MindcodeCompilerMessage.warn(position, format, args));
messageConsumer.accept(CompilerMessage.warn(position, format, args));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -285,7 +285,7 @@ public AstNode node() {
}

public InputPosition inputPosition() {
return node != null ? node.getInputPosition() : null;
return node != null ? node.inputPosition() : null;
}

public String functionPrefix() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,11 +59,11 @@ private void visitNode(AstNode nodeToVisit) {

private void visitStackAllocation(StackAllocation node) {
if (allocatedStack != null) {
error(node.getInputPosition(), "Multiple stack allocations.");
error(node.inputPosition(), "Multiple stack allocations.");
}

if (!activeFunction.isMain()) {
error(node.getInputPosition(), "Stack allocation must not be declared within a function.");
error(node.inputPosition(), "Stack allocation must not be declared within a function.");
}

allocatedStack = node;
Expand Down
Loading

0 comments on commit 8d27de8

Please sign in to comment.