summaryrefslogtreecommitdiff
path: root/src/main/java/no/eliashaugsbakk/kompilator/parsing
diff options
context:
space:
mode:
authorElias Haugsbakk <[email protected]>2026-09-21 14:36:59 +0200
committerElias Haugsbakk <[email protected]>2026-09-21 14:36:59 +0200
commite7720e2d9e1319712f85cb0527e17f1251bd7d2c (patch)
tree19cb8b0f49a0fe234fc0c0bfb41dc5c520b1630b /src/main/java/no/eliashaugsbakk/kompilator/parsing
parent84215a9b8f79035ebec83fe38bc696b5ae78de5d (diff)
add position info to semantic and IRgen exceptions
Diffstat (limited to 'src/main/java/no/eliashaugsbakk/kompilator/parsing')
-rw-r--r--src/main/java/no/eliashaugsbakk/kompilator/parsing/Parser.java42
-rw-r--r--src/main/java/no/eliashaugsbakk/kompilator/parsing/ParserException.java12
-rw-r--r--src/main/java/no/eliashaugsbakk/kompilator/parsing/node/ASTNode.java8
-rw-r--r--src/main/java/no/eliashaugsbakk/kompilator/parsing/node/Program.java5
-rw-r--r--src/main/java/no/eliashaugsbakk/kompilator/parsing/node/expression/Expression.java4
-rw-r--r--src/main/java/no/eliashaugsbakk/kompilator/parsing/node/expression/FunctionCall.java4
-rw-r--r--src/main/java/no/eliashaugsbakk/kompilator/parsing/node/expression/Identifier.java5
-rw-r--r--src/main/java/no/eliashaugsbakk/kompilator/parsing/node/expression/literal/StringLiteral.java4
-rw-r--r--src/main/java/no/eliashaugsbakk/kompilator/parsing/node/statement/Assignment.java4
-rw-r--r--src/main/java/no/eliashaugsbakk/kompilator/parsing/node/statement/ExpressionStatement.java4
-rw-r--r--src/main/java/no/eliashaugsbakk/kompilator/parsing/node/statement/IdentifierDeclaration.java4
-rw-r--r--src/main/java/no/eliashaugsbakk/kompilator/parsing/node/statement/Statement.java4
12 files changed, 72 insertions, 28 deletions
diff --git a/src/main/java/no/eliashaugsbakk/kompilator/parsing/Parser.java b/src/main/java/no/eliashaugsbakk/kompilator/parsing/Parser.java
index f959daf..45eca22 100644
--- a/src/main/java/no/eliashaugsbakk/kompilator/parsing/Parser.java
+++ b/src/main/java/no/eliashaugsbakk/kompilator/parsing/Parser.java
@@ -24,6 +24,7 @@ import no.eliashaugsbakk.kompilator.parsing.node.statement.Assignment;
import no.eliashaugsbakk.kompilator.parsing.node.statement.ExpressionStatement;
import no.eliashaugsbakk.kompilator.parsing.node.statement.IdentifierDeclaration;
import no.eliashaugsbakk.kompilator.parsing.node.statement.Statement;
+import no.eliashaugsbakk.kompilator.tokenization.Position;
import no.eliashaugsbakk.kompilator.tokenization.Token;
/*
@@ -56,7 +57,7 @@ public class Parser {
public Parser(List<Token> tokens) {
this.tokens = tokens;
- this.rootNode = new Program();
+ this.rootNode = new Program(null);
}
public AST parse() throws ParserException {
@@ -101,7 +102,7 @@ public class Parser {
// must be some other token which is not a statement
else {
- throw new ParserException(token.line(), token.column(), "Unexpected token: " + token.value());
+ throw new ParserException(token.position(), "Unexpected token: " + token.value());
}
}
@@ -116,7 +117,7 @@ public class Parser {
} else if (token.value().contentEquals("skriv")) {
return parseExpressionStatement();
} else {
- throw new ParserException(token.line(), token.column(), "unknown keyword: " + token.value());
+ throw new ParserException(token.position(), "unknown keyword: " + token.value());
}
}
@@ -129,7 +130,7 @@ public class Parser {
Expression expression = parseExpression();
expectSemicolon();
- return new ExpressionStatement(expression);
+ return new ExpressionStatement(expression.position, expression);
}
private Statement parseIdentifierStatement() throws ParserException {
@@ -145,23 +146,23 @@ public class Parser {
current--; // rewind to identifier
Expression expr = parseFunctionCall();
expectSemicolon();
- return new ExpressionStatement(expr);
+ return new ExpressionStatement(expr.position, expr);
} else {
- throw new ParserException(next.line(), next.column(), "Unexpected token after identifier: " + next.value());
+ throw new ParserException(next.position(), "Unexpected token after identifier: " + next.value());
}
}
private Statement parseDeclaration(boolean isMutable) throws ParserException {
Token nameToken = tokens.get(current);
if (nameToken.type() != IDENTIFIER) {
- throw new ParserException(nameToken.line(), nameToken.column(),
+ throw new ParserException(nameToken.position(),
"Expected identifier after declaration keyword, got: " + nameToken.value());
}
String identifier = nameToken.value();
current++; // consume identifier
if (tokens.get(current).type() != COLON) {
- throw new ParserException(tokens.get(current).line(), tokens.get(current).column(),
+ throw new ParserException(tokens.get(current).position(),
"Expected : after identifier in declaration");
}
current++; // skip :
@@ -175,7 +176,7 @@ public class Parser {
}
expectSemicolon();
- return new IdentifierDeclaration(identifier, type, initializer, isMutable);
+ return new IdentifierDeclaration(nameToken.position(), identifier, type, initializer, isMutable);
}
private Statement parseAssignment(String identifier) throws ParserException {
@@ -185,13 +186,13 @@ public class Parser {
Expression value = parseExpression();
expectSemicolon();
- return new Assignment(identifier, value);
+ return new Assignment(value.position, identifier, value);
}
private Type parseType() throws ParserException {
Token token = tokens.get(current);
if (token.type() != TYPE) {
- throw new ParserException(token.line(), token.column(),
+ throw new ParserException(token.position(),
"Expected type, got: " + token.value());
}
current++;
@@ -217,32 +218,33 @@ public class Parser {
current++;
if (token.type() == STRING_LITERAL) {
- return new StringLiteral(token.value());
+ return new StringLiteral(token.position(), token.value());
} else if (token.type() == IDENTIFIER || token.type() == KEYWORD) {
// could be function call or just identifier reference
if (current < tokens.size() && tokens.get(current).type() == LPAREN) {
current--;
return parseFunctionCall();
}
- return new Identifier(token.value());
+ return new Identifier(token.position(), token.value());
} else {
- throw new ParserException(token.line(), token.column(),
+ throw new ParserException(token.position(),
"Unexpected token: " + token.value() + ". Expected an expression");
}
}
private FunctionCall parseFunctionCall() throws ParserException {
- String name = tokens.get(current).value();
+ Token token = tokens.get(current);
+ String name = token.value();
current++;
List<Expression> arguments = parseFunctionArguments();
- return new FunctionCall(name, arguments);
+ return new FunctionCall(token.position(), name, arguments);
}
private List<Expression> parseFunctionArguments() throws ParserException {
List<Expression> arguments = new ArrayList<>();
if (tokens.get(current).type() != LPAREN) {
- throw new ParserException(tokens.get(current).line(), tokens.get(current).column(),
+ throw new ParserException(tokens.get(current).position(),
"Expected (");
}
current++; // skip (
@@ -256,7 +258,7 @@ public class Parser {
}
if (current >= tokens.size() || tokens.get(current).type() != RPAREN) {
- throw new ParserException(tokens.get(current).line(), tokens.get(current).column(),
+ throw new ParserException(tokens.get(current).position(),
"Expected )");
}
current++; // skip )
@@ -266,9 +268,9 @@ public class Parser {
private void expectSemicolon() throws ParserException {
if (current >= tokens.size()) {
- throw new ParserException(-1, -1, "Expected ;");
+ throw new ParserException(null, "Expected ;");
} else if (tokens.get(current).type() != SEMICOLON) {
- throw new ParserException(tokens.get(current).line(), tokens.get(current).column(),
+ throw new ParserException(tokens.get(current).position(),
"Expected: ;");
}
current++;
diff --git a/src/main/java/no/eliashaugsbakk/kompilator/parsing/ParserException.java b/src/main/java/no/eliashaugsbakk/kompilator/parsing/ParserException.java
index ac96a5c..892cd7b 100644
--- a/src/main/java/no/eliashaugsbakk/kompilator/parsing/ParserException.java
+++ b/src/main/java/no/eliashaugsbakk/kompilator/parsing/ParserException.java
@@ -1,7 +1,15 @@
package no.eliashaugsbakk.kompilator.parsing;
+import no.eliashaugsbakk.kompilator.tokenization.Position;
+
public class ParserException extends Exception {
- public ParserException(int line, int column, String message) {
- super(line + ":" + column + ", " + message);
+ public ParserException(Position position, String message) {
+ String pos;
+ if (position == null) {
+ pos = "unknown position";
+ } else {
+ pos = position.line() + ":" + position.column();
+ }
+ super(pos + ", " + message);
}
}
diff --git a/src/main/java/no/eliashaugsbakk/kompilator/parsing/node/ASTNode.java b/src/main/java/no/eliashaugsbakk/kompilator/parsing/node/ASTNode.java
index 1eb201c..c825ea9 100644
--- a/src/main/java/no/eliashaugsbakk/kompilator/parsing/node/ASTNode.java
+++ b/src/main/java/no/eliashaugsbakk/kompilator/parsing/node/ASTNode.java
@@ -1,7 +1,15 @@
package no.eliashaugsbakk.kompilator.parsing.node;
+import no.eliashaugsbakk.kompilator.tokenization.Position;
+
/**
* Base class for all nodes in the Abstract Syntax Tree.
*/
public abstract class ASTNode {
+ public final Position position;
+
+
+ public ASTNode(Position position) {
+ this.position = position;
+ }
}
diff --git a/src/main/java/no/eliashaugsbakk/kompilator/parsing/node/Program.java b/src/main/java/no/eliashaugsbakk/kompilator/parsing/node/Program.java
index d61654f..0fcf09e 100644
--- a/src/main/java/no/eliashaugsbakk/kompilator/parsing/node/Program.java
+++ b/src/main/java/no/eliashaugsbakk/kompilator/parsing/node/Program.java
@@ -3,6 +3,7 @@ package no.eliashaugsbakk.kompilator.parsing.node;
import java.util.ArrayList;
import java.util.List;
import no.eliashaugsbakk.kompilator.parsing.node.statement.Statement;
+import no.eliashaugsbakk.kompilator.tokenization.Position;
/**
* Root node of the AST. Contains all top-level statements.
@@ -10,6 +11,10 @@ import no.eliashaugsbakk.kompilator.parsing.node.statement.Statement;
public class Program extends ASTNode {
public final List<Statement> statements = new ArrayList<>();
+ public Program(Position position) {
+ super(position);
+ }
+
public void addStatement(Statement statement) {
this.statements.add(statement);
}
diff --git a/src/main/java/no/eliashaugsbakk/kompilator/parsing/node/expression/Expression.java b/src/main/java/no/eliashaugsbakk/kompilator/parsing/node/expression/Expression.java
index 18fc585..d50e632 100644
--- a/src/main/java/no/eliashaugsbakk/kompilator/parsing/node/expression/Expression.java
+++ b/src/main/java/no/eliashaugsbakk/kompilator/parsing/node/expression/Expression.java
@@ -1,6 +1,7 @@
package no.eliashaugsbakk.kompilator.parsing.node.expression;
import no.eliashaugsbakk.kompilator.parsing.node.ASTNode;
+import no.eliashaugsbakk.kompilator.tokenization.Position;
/**
* Base class for all expression nodes.
@@ -14,4 +15,7 @@ import no.eliashaugsbakk.kompilator.parsing.node.ASTNode;
* - myFunction() (function call expression)
*/
public abstract class Expression extends ASTNode {
+ public Expression(Position position) {
+ super(position);
+ }
}
diff --git a/src/main/java/no/eliashaugsbakk/kompilator/parsing/node/expression/FunctionCall.java b/src/main/java/no/eliashaugsbakk/kompilator/parsing/node/expression/FunctionCall.java
index e18063b..f9aea4f 100644
--- a/src/main/java/no/eliashaugsbakk/kompilator/parsing/node/expression/FunctionCall.java
+++ b/src/main/java/no/eliashaugsbakk/kompilator/parsing/node/expression/FunctionCall.java
@@ -2,6 +2,7 @@ package no.eliashaugsbakk.kompilator.parsing.node.expression;
import java.util.List;
import no.eliashaugsbakk.kompilator.parsing.Type;
+import no.eliashaugsbakk.kompilator.tokenization.Position;
/**
* Represents a function call statement (e.g., print("Hello, world")).
@@ -10,7 +11,8 @@ public class FunctionCall extends Expression {
public final String functionName;
public final List<Expression> arguments;
- public FunctionCall(String functionName, List<Expression> arguments) {
+ public FunctionCall(Position position, String functionName, List<Expression> arguments) {
+ super(position);
this.functionName = functionName;
this.arguments = arguments;
}
diff --git a/src/main/java/no/eliashaugsbakk/kompilator/parsing/node/expression/Identifier.java b/src/main/java/no/eliashaugsbakk/kompilator/parsing/node/expression/Identifier.java
index 91607f8..f899ef3 100644
--- a/src/main/java/no/eliashaugsbakk/kompilator/parsing/node/expression/Identifier.java
+++ b/src/main/java/no/eliashaugsbakk/kompilator/parsing/node/expression/Identifier.java
@@ -1,12 +1,15 @@
package no.eliashaugsbakk.kompilator.parsing.node.expression;
+import no.eliashaugsbakk.kompilator.tokenization.Position;
+
/**
* Resolves to a variable's value
*/
public class Identifier extends Expression {
public final String name;
- public Identifier(String name) {
+ public Identifier(Position position, String name) {
+ super(position);
this.name = name;
}
}
diff --git a/src/main/java/no/eliashaugsbakk/kompilator/parsing/node/expression/literal/StringLiteral.java b/src/main/java/no/eliashaugsbakk/kompilator/parsing/node/expression/literal/StringLiteral.java
index 82402ed..8238880 100644
--- a/src/main/java/no/eliashaugsbakk/kompilator/parsing/node/expression/literal/StringLiteral.java
+++ b/src/main/java/no/eliashaugsbakk/kompilator/parsing/node/expression/literal/StringLiteral.java
@@ -1,6 +1,7 @@
package no.eliashaugsbakk.kompilator.parsing.node.expression.literal;
import no.eliashaugsbakk.kompilator.parsing.node.expression.Expression;
+import no.eliashaugsbakk.kompilator.tokenization.Position;
/**
* Represents a string literal expression (e.g., "Hello, World").
@@ -8,7 +9,8 @@ import no.eliashaugsbakk.kompilator.parsing.node.expression.Expression;
public class StringLiteral extends Expression {
public final String value;
- public StringLiteral(String value) {
+ public StringLiteral(Position position, String value) {
+ super(position);
this.value = value;
}
}
diff --git a/src/main/java/no/eliashaugsbakk/kompilator/parsing/node/statement/Assignment.java b/src/main/java/no/eliashaugsbakk/kompilator/parsing/node/statement/Assignment.java
index 01d207d..7b48c83 100644
--- a/src/main/java/no/eliashaugsbakk/kompilator/parsing/node/statement/Assignment.java
+++ b/src/main/java/no/eliashaugsbakk/kompilator/parsing/node/statement/Assignment.java
@@ -1,12 +1,14 @@
package no.eliashaugsbakk.kompilator.parsing.node.statement;
import no.eliashaugsbakk.kompilator.parsing.node.expression.Expression;
+import no.eliashaugsbakk.kompilator.tokenization.Position;
public class Assignment extends Statement {
public final String identifier;
public final Expression expression;
- public Assignment(String identifier, Expression expression) {
+ public Assignment(Position position, String identifier, Expression expression) {
+ super(position);
this.identifier = identifier;
this.expression = expression;
}
diff --git a/src/main/java/no/eliashaugsbakk/kompilator/parsing/node/statement/ExpressionStatement.java b/src/main/java/no/eliashaugsbakk/kompilator/parsing/node/statement/ExpressionStatement.java
index e46b691..ce900a7 100644
--- a/src/main/java/no/eliashaugsbakk/kompilator/parsing/node/statement/ExpressionStatement.java
+++ b/src/main/java/no/eliashaugsbakk/kompilator/parsing/node/statement/ExpressionStatement.java
@@ -1,6 +1,7 @@
package no.eliashaugsbakk.kompilator.parsing.node.statement;
import no.eliashaugsbakk.kompilator.parsing.node.expression.Expression;
+import no.eliashaugsbakk.kompilator.tokenization.Position;
/**
* A statement which holds an expression.
@@ -9,7 +10,8 @@ import no.eliashaugsbakk.kompilator.parsing.node.expression.Expression;
*/
public class ExpressionStatement extends Statement {
public final Expression expression;
- public ExpressionStatement(Expression expression) {
+ public ExpressionStatement(Position position, Expression expression) {
+ super(position);
this.expression = expression;
}
}
diff --git a/src/main/java/no/eliashaugsbakk/kompilator/parsing/node/statement/IdentifierDeclaration.java b/src/main/java/no/eliashaugsbakk/kompilator/parsing/node/statement/IdentifierDeclaration.java
index 69b0f1b..0659bca 100644
--- a/src/main/java/no/eliashaugsbakk/kompilator/parsing/node/statement/IdentifierDeclaration.java
+++ b/src/main/java/no/eliashaugsbakk/kompilator/parsing/node/statement/IdentifierDeclaration.java
@@ -2,6 +2,7 @@ package no.eliashaugsbakk.kompilator.parsing.node.statement;
import no.eliashaugsbakk.kompilator.parsing.Type;
import no.eliashaugsbakk.kompilator.parsing.node.expression.Expression;
+import no.eliashaugsbakk.kompilator.tokenization.Position;
public class IdentifierDeclaration extends Statement {
// identifier name: [my_var]: type = 4;
@@ -16,7 +17,8 @@ public class IdentifierDeclaration extends Statement {
public final boolean mutable;
- public IdentifierDeclaration(String identifier, Type type, Expression initializer, boolean mutable) {
+ public IdentifierDeclaration(Position position, String identifier, Type type, Expression initializer, boolean mutable) {
+ super(position);
this.identifier = identifier;
this.type = type;
this.initializer = initializer;
diff --git a/src/main/java/no/eliashaugsbakk/kompilator/parsing/node/statement/Statement.java b/src/main/java/no/eliashaugsbakk/kompilator/parsing/node/statement/Statement.java
index aed21ad..5ab16a3 100644
--- a/src/main/java/no/eliashaugsbakk/kompilator/parsing/node/statement/Statement.java
+++ b/src/main/java/no/eliashaugsbakk/kompilator/parsing/node/statement/Statement.java
@@ -1,6 +1,7 @@
package no.eliashaugsbakk.kompilator.parsing.node.statement;
import no.eliashaugsbakk.kompilator.parsing.node.ASTNode;
+import no.eliashaugsbakk.kompilator.tokenization.Position;
/**
* Base class for all statement nodes.
@@ -14,4 +15,7 @@ import no.eliashaugsbakk.kompilator.parsing.node.ASTNode;
* - if (x > 0) { } (conditional statement)
*/
public abstract class Statement extends ASTNode {
+ protected Statement(Position position) {
+ super(position);
+ }
}