Skip to content

Commit

Permalink
Before messing things up
Browse files Browse the repository at this point in the history
  • Loading branch information
madsravn committed Oct 26, 2023
1 parent 2866846 commit 75bef44
Show file tree
Hide file tree
Showing 6 changed files with 497 additions and 1 deletion.
41 changes: 41 additions & 0 deletions src/main/java/dk/madsravn/interpreter/ast/BlockStatement.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package dk.madsravn.interpreter.ast;

import dk.madsravn.interpreter.tokens.Token;

import java.util.List;

public class BlockStatement implements IStatement {
private Token token;
private List<IStatement> statements;

public BlockStatement(Token token, List<IStatement> statements) {
this.token = token;
this.statements = statements;
}

public int getStatementsLength() {
return statements.size();
}

public List<IStatement> getStatements() {
return statements;
}

@Override
public void statementNode() {}

@Override
public String string() {
StringBuilder sb = new StringBuilder();
for(IStatement statement : statements) {
sb.append(statement.string());
}

return sb.toString();
}

@Override
public String tokenLiteral() {
return token.getLiteral();
}
}
43 changes: 43 additions & 0 deletions src/main/java/dk/madsravn/interpreter/ast/CallExpression.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package dk.madsravn.interpreter.ast;

import dk.madsravn.interpreter.tokens.Token;

import java.util.List;
import java.util.stream.Collectors;

public class CallExpression implements IExpression {
private Token token;
private IExpression function;
private List<IExpression> arguments;

public CallExpression(Token token, IExpression function, List<IExpression> arguments) {
this.token = token;
this.function = function;
this.arguments = arguments;
}

public IExpression getFunction() {
return function;
}

public List<IExpression> getArguments() {
return arguments;
}
@Override
public void expressionNode() {}

public String string() {
StringBuilder sb = new StringBuilder();
String argumentString = arguments.stream().map(p -> p.string()).collect(Collectors.joining(","));
sb.append(function.string());
sb.append("(");
sb.append(argumentString);
sb.append(")");

return sb.toString();
}

public String tokenLiteral() {
return token.getLiteral();
}
}
51 changes: 51 additions & 0 deletions src/main/java/dk/madsravn/interpreter/ast/FunctionLiteral.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package dk.madsravn.interpreter.ast;

import dk.madsravn.interpreter.tokens.Token;

import java.util.List;
import java.util.stream.Collectors;

public class FunctionLiteral implements IExpression{
private Token token;
private List<Identifier> parameters;
private BlockStatement body;

public FunctionLiteral(Token token, List<Identifier> parameters, BlockStatement body) {
this.token = token;
this.parameters = parameters;
this.body = body;
}

public List<Identifier> getParameters() {
return parameters;
}

public BlockStatement getBody() {
return body;
}

public int getParametersLength() {
return parameters.size();
}
@Override
public void expressionNode() {}

@Override
public String string() {
StringBuilder sb = new StringBuilder();
String paramString = parameters.stream().map(p -> p.string()).collect(Collectors.joining(","));

sb.append(token.getLiteral());
sb.append("(");
sb.append(paramString);
sb.append(")");
sb.append(body.string());

return sb.toString();
}

@Override
public String tokenLiteral() {
return token.getLiteral();
}
}
52 changes: 52 additions & 0 deletions src/main/java/dk/madsravn/interpreter/ast/IfExpression.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package dk.madsravn.interpreter.ast;

import dk.madsravn.interpreter.tokens.Token;

public class IfExpression implements IExpression {
private Token token;
private IExpression condition;
private BlockStatement consequence;
private BlockStatement alternative;

public IfExpression(Token token, IExpression condition, BlockStatement consequence, BlockStatement alternative) {
this.token = token;
this.condition = condition;
this.consequence = consequence;
this.alternative = alternative;
}

public IExpression getCondition() {
return condition;
}

public BlockStatement getConsequence() {
return consequence;
}

public BlockStatement getAlternative() {
return alternative;
}

@Override
public void expressionNode() {}

@Override
public String string() {
StringBuilder sb = new StringBuilder();
sb.append("if ");
sb.append(condition.string());
sb.append(" ");
sb.append(consequence.string());
if (alternative != null) {
sb.append("else ");
sb.append(alternative.string());
}

return sb.toString();
}

@Override
public String tokenLiteral() {
return token.getLiteral();
}
}
123 changes: 123 additions & 0 deletions src/main/java/dk/madsravn/interpreter/parser/Parser.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import dk.madsravn.interpreter.tokens.Token;
import dk.madsravn.interpreter.tokens.TokenType;

import java.sql.Array;
import java.util.ArrayList;
import java.util.List;

Expand Down Expand Up @@ -82,13 +83,83 @@ private IExpression getPrefixExpression() {
return parseBoolean();
case LPAREN:
return parseGroupedExpression();
case IF:
return parseIfExpression();
case FUNCTION:
return parseFunctionLiteral();
default:
noPrefixParseFunctionError(currentToken.getType());
// TODO: This is ugly
return null;
}
}

private IExpression parseCallExpression(IExpression function) {
CallExpression callExpression = new CallExpression(currentToken, function, parseCallArguments());
return callExpression;
}

private List<IExpression> parseCallArguments() {
List<IExpression> callArguments = new ArrayList<IExpression>();
if (peekTokenType(RPAREN)) {
nextToken();
return callArguments;
}
nextToken();
callArguments.add(parseExpression(LOWEST));

while(peekTokenType(COMMA)) {
nextToken();
nextToken();
callArguments.add(parseExpression(LOWEST));
}
if (!expectPeekType(RPAREN)) {
return null;
}

return callArguments;
}

private IExpression parseFunctionLiteral() {
Token token = currentToken;
if(!expectPeekType(LPAREN)) {
return null;
}
List<Identifier> parameters = parseFunctionParameters();
if(!expectPeekType(LBRACE)) {
return null;
}
BlockStatement body = parseBlockStatement();
return new FunctionLiteral(token, parameters, body);
}

private List<Identifier> parseFunctionParameters() {
List<Identifier> parameters = new ArrayList<Identifier>();

if(peekTokenType(RPAREN)) {
nextToken();
return parameters;
}

nextToken();

Identifier identifier = new Identifier(currentToken, currentToken.getLiteral());
parameters.add(identifier);

while(peekTokenType(COMMA)) {
nextToken();
nextToken();
identifier = new Identifier(currentToken, currentToken.getLiteral());
parameters.add(identifier);
}

if (!expectPeekType(RPAREN)) {
return null;
}

return parameters;
}

private IExpression parseGroupedExpression() {
nextToken();
IExpression expression = parseExpression(LOWEST);
Expand All @@ -98,6 +169,56 @@ private IExpression parseGroupedExpression() {
return expression;
}

private IExpression parseIfExpression() {
Token token = currentToken;
if (!expectPeekType(LPAREN)) {
return null;
}

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

if (!expectPeekType(RPAREN)) {
return null;
}

if (!expectPeekType(LBRACE)) {
return null;
}
BlockStatement consequence = parseBlockStatement();
BlockStatement alternative = parseAlternativeBlock();

IfExpression ifExpression = new IfExpression(token, condition, consequence, alternative);
return ifExpression;
}

private BlockStatement parseAlternativeBlock() {
if (peekTokenType(ELSE)) {
nextToken();
if (!expectPeekType(LBRACE)) {
return null;
}
return parseBlockStatement();
}
return null;
}

private BlockStatement parseBlockStatement() {
Token token = currentToken;
List<IStatement> statements = new ArrayList<IStatement>();

nextToken();

while (!currentTokenType(RBRACE) && !currentTokenType(TokenType.EOF)) {
IStatement statement = parseStatement();
if (statement != null) {
statements.add(statement);
}
nextToken();
}
return new BlockStatement(token, statements);
}

private IExpression parseExpression(PrecedenceEnum precedence) {
IExpression left = getPrefixExpression();
if (left == null) {
Expand All @@ -120,6 +241,8 @@ private IExpression parseExpression(PrecedenceEnum precedence) {

private PrecedenceEnum getPrecedence(TokenType type) {
switch (type) {
case LPAREN:
return CALL;
case EQ, NOT_EQ:
return EQUALS;
case LT, GT:
Expand Down
Loading

0 comments on commit 75bef44

Please sign in to comment.