Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DRAFT #140 #180

Draft
wants to merge 1 commit into
base: develop
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 40 additions & 13 deletions engine/src/main/java/com/github/otymko/jos/compiler/Compiler.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import com.github.otymko.jos.util.StringLineCleaner;
import lombok.Data;
import org.antlr.v4.runtime.tree.ParseTree;
import org.apache.commons.lang3.tuple.Pair;

import java.math.BigDecimal;
import java.util.ArrayDeque;
Expand Down Expand Up @@ -49,6 +50,8 @@ public class Compiler extends BSLParserBaseVisitor<ParseTree> {
private MethodDescriptor currentMethodDescriptor;
private SymbolScope localScope;

private boolean skipLineNumbers;

@Data
private static class NestedLoopInfo {
private int startPoint = DUMMY_ADDRESS;
Expand All @@ -74,6 +77,8 @@ public Compiler(ModuleImageCache imageCache, ScriptCompiler compiler) {
this.imageCache = imageCache;
this.compiler = compiler;
this.annotationProcessing = new AnnotationProcessing(this);

this.skipLineNumbers = false;
}

@Override
Expand Down Expand Up @@ -193,10 +198,10 @@ public ParseTree visitFileCodeBlockBeforeSub(BSLParser.FileCodeBlockBeforeSubCon

@Override
public ParseTree visitStatement(BSLParser.StatementContext statement) {
int numberLint = statement.getStart().getLine();
addCommand(OperationCode.LINE_NUM, numberLint);
var numberLint = statement.getStart().getLine();
var index = addLineNumCommand(numberLint);
if (currentMethodDescriptor != null && currentMethodDescriptor.getEntry() == DUMMY_ADDRESS) {
currentMethodDescriptor.setEntry(imageCache.getCode().size() - 1);
currentMethodDescriptor.setEntry(index);
}
return super.visitStatement(statement);
}
Expand Down Expand Up @@ -237,8 +242,8 @@ public ParseTree visitIfStatement(BSLParser.IfStatementContext ifStatement) {

var alternativeBranches = false;
for (var elseIfBranches : ifStatement.elsifBranch()) {
correctCommandArgument(jumpFalse, imageCache.getCode().size());
addCommand(OperationCode.LINE_NUM, elseIfBranches.getStart().getLine());
var index = addLineNumCommand(elseIfBranches.getStart().getLine());
correctCommandArgument(jumpFalse, index);

visitExpression(elseIfBranches.expression());

Expand All @@ -250,13 +255,13 @@ public ParseTree visitIfStatement(BSLParser.IfStatementContext ifStatement) {

if (ifStatement.elseBranch() != null) {
alternativeBranches = true;
correctCommandArgument(jumpFalse, imageCache.getCode().size());
addCommand(OperationCode.LINE_NUM, ifStatement.elseBranch().getStart().getLine());
var index = addLineNumCommand(ifStatement.elseBranch().getStart().getLine());
correctCommandArgument(jumpFalse, index);

visitCodeBlock(ifStatement.elseBranch().codeBlock());
}

var endIndex = addCommand(OperationCode.LINE_NUM, ifStatement.getStop().getLine());
var endIndex = addLineNumCommand(ifStatement.getStop().getLine());
if (!alternativeBranches) {
correctCommandArgument(jumpFalse, endIndex);
}
Expand All @@ -272,7 +277,13 @@ public ParseTree visitIfStatement(BSLParser.IfStatementContext ifStatement) {
public ParseTree visitWhileStatement(BSLParser.WhileStatementContext whileStatement) {
// прыжок наверх цикла должен попадать на опкод LineNum
// поэтому указываем адрес - 1
var conditionIndex = imageCache.getCode().size() - 1;
int conditionIndex;
if (skipLineNumbers) {
conditionIndex = imageCache.getCode().size();
} else {
conditionIndex = imageCache.getCode().size() - 1;
}
// var conditionIndex = imageCache.getCode().size() - 1;
var loopRecord = Compiler.NestedLoopInfo.create(conditionIndex);

nestedLoops.push(loopRecord);
Expand Down Expand Up @@ -303,7 +314,7 @@ public ParseTree visitForStatement(BSLParser.ForStatementContext forStatement) {
addCommand(OperationCode.PUSH_TMP);

var jumpIndex = addCommand(OperationCode.JMP, DUMMY_ADDRESS);
var loopStart = addCommand(OperationCode.LINE_NUM, forStatement.getStart().getLine());
var loopStart = addLineNumCommand(forStatement.getStart().getLine());

// инкремент
processIdentifier(identifier);
Expand Down Expand Up @@ -337,7 +348,7 @@ public ParseTree visitForEachStatement(BSLParser.ForEachStatementContext forEach

addCommand(OperationCode.PUSH_ITERATOR);

var loopStart = addCommand(OperationCode.LINE_NUM, forEachStatement.getStart().getLine());
var loopStart = addLineNumCommand(forEachStatement.getStart().getLine());

addCommand(OperationCode.ITERATOR_NEXT);

Expand All @@ -363,13 +374,13 @@ public ParseTree visitTryStatement(BSLParser.TryStatementContext tryStatement) {
visitTryCodeBlock(tryStatement.tryCodeBlock());
var jmpIndex = addCommand(OperationCode.JMP, DUMMY_ADDRESS);

var beginHandler = addCommand(OperationCode.LINE_NUM, tryStatement.exceptCodeBlock().getStart().getLine());
var beginHandler = addLineNumCommand(tryStatement.exceptCodeBlock().getStart().getLine());

correctCommandArgument(beginTryIndex, beginHandler);

visitExceptCodeBlock(tryStatement.exceptCodeBlock());

var endIndex = addCommand(OperationCode.LINE_NUM, tryStatement.getStop().getLine());
var endIndex = addLineNumCommand(tryStatement.getStop().getLine());

addCommand(OperationCode.END_TRY, 0);
correctCommandArgument(jmpIndex, endIndex);
Expand Down Expand Up @@ -688,6 +699,22 @@ private int addCommand(OperationCode operationCode, int argument) {
return index;
}

private int addLineNumCommand(int lineNumber) {
if (skipLineNumbers) {
imageCache.getLinesOffset().add(Pair.of(imageCache.getCode().size(), lineNumber));

if (imageCache.getCode().isEmpty()) {
return 0;
}
return imageCache.getCode().size();
}

var index = imageCache.getCode().size();
imageCache.getCode().add(new Command(OperationCode.LINE_NUM, lineNumber));

return index;
}

private int addCommand(OperationCode operationCode) {
return addCommand(operationCode, 0);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ private static ModuleImage buildImage(ModuleImageCache cache) {
.source(cache.getSource())
.entry(cache.getEntryPoint())
.code(List.copyOf(cache.getCode()))
.linesOffset(List.copyOf(cache.getLinesOffset()))
.methods(List.copyOf(cache.getMethods()))
.variables(List.copyOf(cache.getVariables()))
.constants(List.copyOf(cache.getConstants()))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@
import com.github.otymko.jos.runtime.machine.info.VariableInfo;
import lombok.Builder;
import lombok.Data;
import org.apache.commons.lang3.tuple.Pair;

import java.util.ArrayList;
import java.util.List;

/**
Expand All @@ -30,6 +32,8 @@ public class ModuleImage {
* Байткоды
*/
private List<Command> code;

private List<Pair<Integer, Integer>> linesOffset;
/**
* Методы
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import com.github.otymko.jos.runtime.machine.Command;
import com.github.otymko.jos.runtime.machine.info.VariableInfo;
import lombok.Data;
import org.apache.commons.lang3.tuple.Pair;

import java.util.ArrayList;
import java.util.List;
Expand All @@ -23,6 +24,7 @@ public class ModuleImageCache {
private ModuleSource source;
private int entryPoint = -1;
private List<Command> code = new ArrayList<>();
private List<Pair<Integer, Integer>> linesOffset = new ArrayList<>();
private List<ConstantDefinition> constants = new ArrayList<>();
private List<VariableInfo> variables = new ArrayList<>();
private List<MethodDescriptor> methods = new ArrayList<>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@
import lombok.Data;

import java.util.ArrayDeque;
import java.util.Comparator;
import java.util.Deque;
import java.util.NoSuchElementException;

@Data
public class ExecutionFrame {
Expand All @@ -31,4 +33,27 @@ public class ExecutionFrame {
private boolean discardReturnValue;

private boolean oneTimeCall;

public int getLineNumber() {
if (lineNumber == 0) {
return findLineNumberByInstructionPointer(instructionPointer);
}

return lineNumber;
}

private int findLineNumberByInstructionPointer(int instruction) {
if (instruction < 0) {
return 1;
}

try {
return image.getLinesOffset().stream()
.filter(pair -> pair.getLeft() <= instruction)
.max(Comparator.naturalOrder())
.stream().findAny().get().getRight();
} catch (NoSuchElementException e) {
throw e;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,9 @@ private void executeCode() {

var errorInfo = exception.getErrorInfo();
if (errorInfo.getLine() < 0) {

nextInstruction();

errorInfo.setLine(currentFrame.getLineNumber());
errorInfo.setSource(Common.getAbsolutPath(currentImage.getSource().getPath()));
Common.fillCodePositionInErrorInfo(errorInfo, currentImage, currentFrame.getLineNumber());
Expand Down Expand Up @@ -232,7 +235,7 @@ private void mainCommandLoop() {
runCommand(command.getCode(), command.getArgument());
}
} catch (EngineException exception) {
throw exception;
throw exception;
} catch (Exception exception) {
throw new WrappedJavaException(exception);
}
Expand Down