Skip to content

Commit

Permalink
We did it
Browse files Browse the repository at this point in the history
  • Loading branch information
madsravn committed Oct 26, 2023
1 parent 75bef44 commit 5b2b9c5
Show file tree
Hide file tree
Showing 7 changed files with 51 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public void expressionNode() {}

public String string() {
StringBuilder sb = new StringBuilder();
String argumentString = arguments.stream().map(p -> p.string()).collect(Collectors.joining(","));
String argumentString = arguments.stream().map(p -> p.string()).collect(Collectors.joining(", "));
sb.append(function.string());
sb.append("(");
sb.append(argumentString);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ public void expressionNode() {}
@Override
public String string() {
StringBuilder sb = new StringBuilder();
String paramString = parameters.stream().map(p -> p.string()).collect(Collectors.joining(","));
String paramString = parameters.stream().map(p -> p.string()).collect(Collectors.joining(", "));

sb.append(token.getLiteral());
sb.append("(");
Expand Down
4 changes: 3 additions & 1 deletion src/main/java/dk/madsravn/interpreter/ast/LetStatement.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,10 @@ public class LetStatement implements IStatement {
Identifier name;
IExpression value;

public LetStatement(Token token) {
public LetStatement(Token token, Identifier name, IExpression value) {
this.token = token;
this.name = name;
this.value = value;
}
@Override
public void statementNode() {}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@ public class ReturnStatement implements IStatement{
private Token token;
private IExpression expression;

public ReturnStatement(Token token) {
public ReturnStatement(Token token, IExpression expression) {
this.token = token;
this.expression = expression;
}

@Override
Expand Down
29 changes: 23 additions & 6 deletions src/main/java/dk/madsravn/interpreter/parser/Parser.java
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ private IStatement parseStatement() {

private boolean getInfixExpression(TokenType type) {
switch(type) {
case PLUS, MINUS, SLASH, ASTERISK, EQ, NOT_EQ, LT, GT:
case PLUS, MINUS, SLASH, ASTERISK, EQ, NOT_EQ, LT, GT, LPAREN:
return true;
default:
return false;
Expand Down Expand Up @@ -222,6 +222,7 @@ private BlockStatement parseBlockStatement() {
private IExpression parseExpression(PrecedenceEnum precedence) {
IExpression left = getPrefixExpression();
if (left == null) {
noPrefixParseFunctionError(currentToken.getType());
return null;
}

Expand All @@ -230,10 +231,16 @@ private IExpression parseExpression(PrecedenceEnum precedence) {
if (infix == false) {
return null;
}
// TODO: This needs to be prettier!!!
if(peekToken.getType() == LPAREN) {
nextToken();
left = parseCallExpression(left);

nextToken();
} else {

left = parseInfixExpression(left);
nextToken();
left = parseInfixExpression(left);
}
}

return left;
Expand Down Expand Up @@ -312,34 +319,44 @@ private ExpressionStatement parseExpressionStatement() {
}

private ReturnStatement parseReturnStatement() {
ReturnStatement statement = new ReturnStatement(currentToken);
Token token = currentToken;
nextToken();

IExpression value = parseExpression(LOWEST);

while(!currentTokenType(TokenType.SEMICOLON)) {
nextToken();
}

ReturnStatement statement = new ReturnStatement(token, value);
return statement;
}

private LetStatement parseLetStatement() {
LetStatement statement = new LetStatement(currentToken);
Token token = currentToken;

if (!expectPeekType(TokenType.IDENT)) {
// TODO: This is ugly
return null;
}

statement.setName(new Identifier(currentToken, currentToken.getLiteral()));
// TODO: Remove method and replace with constructor call to LetStatement
Identifier name = new Identifier(currentToken, currentToken.getLiteral());

if (!expectPeekType(TokenType.ASSIGN)) {
// TODO: This is ugly
return null;
}

nextToken();
IExpression value = parseExpression(LOWEST);


while (!currentTokenType(TokenType.SEMICOLON)) {
nextToken();
}

LetStatement statement = new LetStatement(token, name, value);
return statement;
}

Expand Down
16 changes: 14 additions & 2 deletions src/main/java/dk/madsravn/interpreter/repl/Repl.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package dk.madsravn.interpreter.repl;

import dk.madsravn.interpreter.ast.Program;
import dk.madsravn.interpreter.lexer.Lexer;
import dk.madsravn.interpreter.parser.Parser;
import dk.madsravn.interpreter.tokens.Token;

import java.io.BufferedReader;
Expand All @@ -17,12 +19,22 @@ public void start() {
try {
String input = br.readLine();
Lexer lexer = new Lexer(input);
List<Token> tokens = lexer.readAllTokens();
tokens.stream().forEach(System.out::println);
Parser parser = new Parser(lexer);
Program program = parser.parseProgram();
if (parser.getErrors().size() > 0) {
printParserErrors(parser.getErrors());
continue;
}
System.out.println(program.string());
System.out.println("");
} catch (Exception e) {

}

}
}

private void printParserErrors(List<String> errors) {
errors.stream().map(s -> "\t" + s).forEach(System.out::println);
}
}
11 changes: 7 additions & 4 deletions src/test/java/dk/madsravn/interpreter/parser/ParserTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ public void TestLetStatementWithErrors() {

// TODO: Should the errors be on the program or on the parser?
Program program = parser.parseProgram();
assertEquals(parser.getErrors().size(), 4);
assertEquals(parser.getErrors().size(), 5);
}

@Test
Expand All @@ -82,8 +82,7 @@ public void testStringMethods() {
Program program = parser.parseProgram();

assertEquals(parser.getErrors().size(), 0);
// TODO: THIS DOESNT COMPLETELY WORK YET
assertEquals(program.string(), "let myVar = ;");
assertEquals(program.string(), "let myVar = 5;");
}

@Test
Expand Down Expand Up @@ -348,7 +347,11 @@ public void testOperatorPrecedenceParsing() {
new OperatorPrecedenceParsing("(5 + 5) * 2", "((5 + 5) * 2)"),
new OperatorPrecedenceParsing("2 / (5 + 5)", "(2 / (5 + 5))"),
new OperatorPrecedenceParsing("-(5 + 5)", "(-(5 + 5))"),
new OperatorPrecedenceParsing("!(true == true)", "(!(true == true))")
new OperatorPrecedenceParsing("!(true == true)", "(!(true == true))"),
new OperatorPrecedenceParsing("a + add(b * c) + d", "((a + add((b * c))) + d)"),
new OperatorPrecedenceParsing("add(a, b, 1, 2 * 3, 4 + 5, add(6, 7 * 8))", "add(a, b, 1, (2 * 3), (4 + 5), add(6, (7 * 8)))"),
new OperatorPrecedenceParsing("add(a + b + c * d / f + g)", "add((((a + b) + ((c * d) / f)) + g))")


);

Expand Down

0 comments on commit 5b2b9c5

Please sign in to comment.