summaryrefslogtreecommitdiff
path: root/src/main/java/no/eliashaugsbakk/kompilator/parsing
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/no/eliashaugsbakk/kompilator/parsing')
-rw-r--r--src/main/java/no/eliashaugsbakk/kompilator/parsing/Parser.java64
-rw-r--r--src/main/java/no/eliashaugsbakk/kompilator/parsing/Type.java18
-rw-r--r--src/main/java/no/eliashaugsbakk/kompilator/parsing/node/expression/FunctionCall.java9
-rw-r--r--src/main/java/no/eliashaugsbakk/kompilator/parsing/node/expression/Identifier.java2
-rw-r--r--src/main/java/no/eliashaugsbakk/kompilator/parsing/node/statement/Assignment.java2
-rw-r--r--src/main/java/no/eliashaugsbakk/kompilator/parsing/node/statement/IdentifierDeclaration.java6
6 files changed, 59 insertions, 42 deletions
diff --git a/src/main/java/no/eliashaugsbakk/kompilator/parsing/Parser.java b/src/main/java/no/eliashaugsbakk/kompilator/parsing/Parser.java
index 356a6d7..f959daf 100644
--- a/src/main/java/no/eliashaugsbakk/kompilator/parsing/Parser.java
+++ b/src/main/java/no/eliashaugsbakk/kompilator/parsing/Parser.java
@@ -108,9 +108,11 @@ public class Parser {
private Statement parseKeyword() throws ParserException {
Token token = tokens.get(current);
if (token.value().contentEquals("set")) {
- return parseIdentifierStatement();
+ current++; // consume "set"
+ return parseDeclaration(false);
} else if (token.value().contentEquals("mut")) {
- return parseIdentifierStatement();
+ current++; // consume "mut"
+ return parseDeclaration(true);
} else if (token.value().contentEquals("skriv")) {
return parseExpressionStatement();
} else {
@@ -130,60 +132,50 @@ public class Parser {
return new ExpressionStatement(expression);
}
-
-
private Statement parseIdentifierStatement() throws ParserException {
- // this is either:
- // - declaration of a new variable with an associated value
- // - declaration of a new variable without an associated value
- // - reassigning an existing variable
-
- /*
- mut x: string?; IDENTIFIER, COLON, TYPE, SEMICOLON
- set x: string = "string"; IDENTIFIER, COLON, TYPE, ASSIGN, STRING, SEMICOLON
- x = "string"; IDENTIFIER, ASSIGN, STRING, SEMICOLON
- */
-
- boolean mutable = false;
-
- if (tokens.get(current).value().contentEquals("mut")) {
- mutable = true;
- current++;
- } else if (tokens.get(current).value().contentEquals("set")) {
- current++;
- }
-
String identifier = tokens.get(current).value();
- current++;
+ current++; // consume identifier
Token next = tokens.get(current);
- if (next.type() == COLON) {
- // x: string = "hello";
- return parseDeclaration(identifier, mutable);
- } else if (next.type() == ASSIGN) {
- // x = "hello";
+ if (next.type() == ASSIGN) {
return parseAssignment(identifier);
+ } else if (next.type() == LPAREN) {
+ // Future expansion: standalone function calls like `doSomething();`
+ current--; // rewind to identifier
+ Expression expr = parseFunctionCall();
+ expectSemicolon();
+ return new ExpressionStatement(expr);
} else {
- throw new ParserException(next.line(), next.column(), "Expected : or = after: " + identifier);
+ throw new ParserException(next.line(), next.column(), "Unexpected token after identifier: " + next.value());
}
}
- private Statement parseDeclaration(String identifier, boolean mutable) throws ParserException {
- // x: type;
- current++; // skip colon
+ private Statement parseDeclaration(boolean isMutable) throws ParserException {
+ Token nameToken = tokens.get(current);
+ if (nameToken.type() != IDENTIFIER) {
+ throw new ParserException(nameToken.line(), nameToken.column(),
+ "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(),
+ "Expected : after identifier in declaration");
+ }
+ current++; // skip :
Type type = parseType();
Expression initializer = null;
- // x: type = "hello";
if (tokens.get(current).type() == ASSIGN) {
current++; // skip =
initializer = parseExpression();
}
expectSemicolon();
- return new IdentifierDeclaration(identifier, type, initializer, mutable);
+ return new IdentifierDeclaration(identifier, type, initializer, isMutable);
}
private Statement parseAssignment(String identifier) throws ParserException {
diff --git a/src/main/java/no/eliashaugsbakk/kompilator/parsing/Type.java b/src/main/java/no/eliashaugsbakk/kompilator/parsing/Type.java
index d707696..6b1007c 100644
--- a/src/main/java/no/eliashaugsbakk/kompilator/parsing/Type.java
+++ b/src/main/java/no/eliashaugsbakk/kompilator/parsing/Type.java
@@ -1,12 +1,28 @@
package no.eliashaugsbakk.kompilator.parsing;
+import java.util.Objects;
+
public class Type {
- final String type;
+ public final String type;
public final boolean nullable;
public Type(String type, boolean nullable) {
this.type = type;
this.nullable = nullable;
}
+
+ @Override
+ public boolean equals(Object o) {
+ if (o instanceof Type t) {
+ return this.type.equals(t.type) && this.nullable == t.nullable;
+ } else {
+ return false;
+ }
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(type, nullable);
+ }
}
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 3c46ec4..2537d9c 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
@@ -1,6 +1,7 @@
package no.eliashaugsbakk.kompilator.parsing.node.expression;
import java.util.List;
+import no.eliashaugsbakk.kompilator.parsing.Type;
/**
* Represents a function call statement (e.g., print("Hello, world")).
@@ -13,4 +14,12 @@ public class FunctionCall extends Expression {
this.functionName = functionName;
this.arguments = arguments;
}
+
+ public Type getReturnType() {
+ if (functionName.equals("skriv")) {
+ return new Type("void", false);
+ }
+ // TODO: Look up return type in function table when you add more functions
+ return null;
+ }
}
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 c1f475f..91607f8 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
@@ -4,7 +4,7 @@ package no.eliashaugsbakk.kompilator.parsing.node.expression;
* Resolves to a variable's value
*/
public class Identifier extends Expression {
- final String name;
+ public final String name;
public Identifier(String name) {
this.name = name;
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 bca16df..01d207d 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
@@ -4,7 +4,7 @@ import no.eliashaugsbakk.kompilator.parsing.node.expression.Expression;
public class Assignment extends Statement {
public final String identifier;
- final Expression expression;
+ public final Expression expression;
public Assignment(String identifier, Expression expression) {
this.identifier = identifier;
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 d3c5474..69b0f1b 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
@@ -12,14 +12,14 @@ public class IdentifierDeclaration extends Statement {
// identifier initialization: my_var: type [4];
// may be null: my_var: type?;
- public final Expression expression; // may be null: x: int?;
+ public final Expression initializer; // may be null: x: int?;
public final boolean mutable;
- public IdentifierDeclaration(String identifier, Type type, Expression expression, boolean mutable) {
+ public IdentifierDeclaration(String identifier, Type type, Expression initializer, boolean mutable) {
this.identifier = identifier;
this.type = type;
- this.expression = expression;
+ this.initializer = initializer;
this.mutable = mutable;
}
}