mirror of
https://github.com/aNNiMON/Own-Programming-Language-Tutorial.git
synced 2024-09-20 00:34:20 +03:00
Show function call position in call stack
This commit is contained in:
parent
39b94a0113
commit
1fb9c8b3c5
@ -13,8 +13,16 @@ public final class CallStack {
|
||||
calls.clear();
|
||||
}
|
||||
|
||||
public static synchronized void enter(String name, Function function) {
|
||||
calls.push(new CallInfo(name, function.toString()));
|
||||
public static synchronized void enter(String name, Function function, String position) {
|
||||
String func = function.toString();
|
||||
if (func.contains("com.annimon.ownlang.modules")) {
|
||||
func = func.replaceAll(
|
||||
"com.annimon.ownlang.modules.(\\w+)\\.?\\1?", "module $1");
|
||||
}
|
||||
if (func.contains("\n")) {
|
||||
func = func.substring(0, func.indexOf("\n")).trim();
|
||||
}
|
||||
calls.push(new CallInfo(name, func, position));
|
||||
}
|
||||
|
||||
public static synchronized void exit() {
|
||||
@ -25,10 +33,14 @@ public final class CallStack {
|
||||
return calls;
|
||||
}
|
||||
|
||||
public record CallInfo(String name, String function) {
|
||||
public record CallInfo(String name, String function, String position) {
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("%s: %s", name, function);
|
||||
if (position == null) {
|
||||
return String.format("%s: %s", name, function);
|
||||
} else {
|
||||
return String.format("%s: %s %s", name, function, position);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
package com.annimon.ownlang.parser;
|
||||
package com.annimon.ownlang.util;
|
||||
|
||||
public record Pos(int row, int col) {
|
||||
public static final Pos UNKNOWN = new Pos(-1, -1);
|
@ -1,4 +1,4 @@
|
||||
package com.annimon.ownlang.parser;
|
||||
package com.annimon.ownlang.util;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
@ -18,8 +18,10 @@ public record Range(Pos start, Pos end) {
|
||||
}
|
||||
|
||||
public String format() {
|
||||
if (isOnSameLine()) {
|
||||
if (isEqualPosition())
|
||||
return start.format();
|
||||
else if (isOnSameLine()) {
|
||||
return "[%d:%d~%d]".formatted(start.row(), start.col(), end.col());
|
||||
} else {
|
||||
return start.format() + "..." + end.format();
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
package com.annimon.ownlang.util;
|
||||
|
||||
public interface SourceLocation {
|
||||
|
||||
default Range getRange() {
|
||||
return null;
|
||||
}
|
||||
|
||||
default String formatRange() {
|
||||
final var range = getRange();
|
||||
return range == null ? "" : range.format();
|
||||
}
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
package com.annimon.ownlang.exceptions;
|
||||
|
||||
import com.annimon.ownlang.parser.Range;
|
||||
import com.annimon.ownlang.util.Range;
|
||||
|
||||
/**
|
||||
* Base type for all lexer and parser exceptions
|
||||
|
@ -1,6 +1,6 @@
|
||||
package com.annimon.ownlang.exceptions;
|
||||
|
||||
import com.annimon.ownlang.parser.Range;
|
||||
import com.annimon.ownlang.util.Range;
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -31,7 +31,7 @@ public class UserDefinedFunction implements Function {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Value execute(Value... values) {
|
||||
public Value execute(Value[] values) {
|
||||
final int size = values.length;
|
||||
final int requiredArgsCount = arguments.getRequiredArgumentsCount();
|
||||
if (size < requiredArgsCount) {
|
||||
|
@ -2,6 +2,8 @@ package com.annimon.ownlang.parser;
|
||||
|
||||
import com.annimon.ownlang.exceptions.OwnLangParserException;
|
||||
import com.annimon.ownlang.parser.error.ParseError;
|
||||
import com.annimon.ownlang.util.Pos;
|
||||
import com.annimon.ownlang.util.Range;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
|
@ -8,6 +8,8 @@ import com.annimon.ownlang.lib.UserDefinedFunction;
|
||||
import com.annimon.ownlang.parser.ast.*;
|
||||
import com.annimon.ownlang.parser.error.ParseError;
|
||||
import com.annimon.ownlang.parser.error.ParseErrors;
|
||||
import com.annimon.ownlang.util.Pos;
|
||||
import com.annimon.ownlang.util.Range;
|
||||
import java.util.*;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
@ -351,12 +353,14 @@ public final class Parser {
|
||||
|
||||
private FunctionalExpression function(Expression qualifiedNameExpr) {
|
||||
// function(arg1, arg2, ...)
|
||||
final var startTokenIndex = index - 1;
|
||||
consume(TokenType.LPAREN);
|
||||
final FunctionalExpression function = new FunctionalExpression(qualifiedNameExpr);
|
||||
while (!match(TokenType.RPAREN)) {
|
||||
function.addArgument(expression());
|
||||
match(TokenType.COMMA);
|
||||
}
|
||||
function.setRange(getRange(startTokenIndex, index - 1));
|
||||
return function;
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,7 @@
|
||||
package com.annimon.ownlang.parser;
|
||||
|
||||
import com.annimon.ownlang.util.Pos;
|
||||
|
||||
/**
|
||||
* @author aNNiMON
|
||||
*/
|
||||
|
@ -2,6 +2,8 @@ package com.annimon.ownlang.parser.ast;
|
||||
|
||||
import com.annimon.ownlang.exceptions.*;
|
||||
import com.annimon.ownlang.lib.*;
|
||||
import com.annimon.ownlang.util.Range;
|
||||
import com.annimon.ownlang.util.SourceLocation;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
@ -10,10 +12,12 @@ import java.util.List;
|
||||
*
|
||||
* @author aNNiMON
|
||||
*/
|
||||
public final class FunctionalExpression extends InterruptableNode implements Expression, Statement {
|
||||
public final class FunctionalExpression extends InterruptableNode
|
||||
implements Expression, Statement, SourceLocation {
|
||||
|
||||
public final Expression functionExpr;
|
||||
public final List<Expression> arguments;
|
||||
private Range range;
|
||||
|
||||
public FunctionalExpression(Expression functionExpr) {
|
||||
this.functionExpr = functionExpr;
|
||||
@ -24,6 +28,15 @@ public final class FunctionalExpression extends InterruptableNode implements Exp
|
||||
arguments.add(arg);
|
||||
}
|
||||
|
||||
public void setRange(Range range) {
|
||||
this.range = range;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Range getRange() {
|
||||
return range;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute() {
|
||||
eval();
|
||||
@ -38,7 +51,7 @@ public final class FunctionalExpression extends InterruptableNode implements Exp
|
||||
values[i] = arguments.get(i).eval();
|
||||
}
|
||||
final Function f = consumeFunction(functionExpr);
|
||||
CallStack.enter(functionExpr.toString(), f);
|
||||
CallStack.enter(functionExpr.toString(), f, formatRange());
|
||||
final Value result = f.execute(values);
|
||||
CallStack.exit();
|
||||
return result;
|
||||
|
@ -1,6 +1,6 @@
|
||||
package com.annimon.ownlang.parser.error;
|
||||
|
||||
import com.annimon.ownlang.parser.Range;
|
||||
import com.annimon.ownlang.util.Range;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
|
@ -1,8 +1,8 @@
|
||||
package com.annimon.ownlang.parser.error;
|
||||
|
||||
import com.annimon.ownlang.Console;
|
||||
import com.annimon.ownlang.parser.Pos;
|
||||
import com.annimon.ownlang.parser.Range;
|
||||
import com.annimon.ownlang.util.Pos;
|
||||
import com.annimon.ownlang.util.Range;
|
||||
import com.annimon.ownlang.stages.SourceLoaderStage;
|
||||
import com.annimon.ownlang.stages.Stage;
|
||||
import com.annimon.ownlang.stages.StagesData;
|
||||
|
@ -8,6 +8,7 @@ import com.annimon.ownlang.lib.*;
|
||||
import com.annimon.ownlang.parser.*;
|
||||
import com.annimon.ownlang.parser.ast.BlockStatement;
|
||||
import com.annimon.ownlang.parser.ast.Statement;
|
||||
import com.annimon.ownlang.util.Pos;
|
||||
import com.annimon.ownlang.parser.visitors.PrintVisitor;
|
||||
import com.annimon.ownlang.utils.repl.JLineConsole;
|
||||
import com.annimon.ownlang.utils.repl.OwnLangCompleter;
|
||||
|
Loading…
Reference in New Issue
Block a user