Commit fd92723d authored by EmreTr1's avatar EmreTr1
Browse files

implemented execution & improvements & bug fixes

parent f1eb4fd9
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
package com.bedrockk.molang.parser;
import com.bedrockk.molang.parser.visitor.FindingVisitor;
import com.bedrockk.molang.parser.visitor.FirstFindingVisitor;
import java.util.List;
import java.util.function.Predicate;
......@@ -16,4 +17,14 @@ public class ExprFinder {
return visitor.getFoundExpressions();
}
public static Expression findFirst(List<Expression> expressions, Predicate<Expression> predicate) {
ExprTraverser traverser = new ExprTraverser();
FirstFindingVisitor visitor = new FirstFindingVisitor(predicate);
traverser.getVisitors().add(visitor);
traverser.traverse(expressions);
return visitor.getFound();
}
}
......@@ -4,7 +4,10 @@ import lombok.Getter;
import lombok.NonNull;
import java.lang.reflect.Field;
import java.util.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
@Getter
public class ExprTraverser {
......@@ -63,6 +66,10 @@ public class ExprTraverser {
traverseExpr(expression);
}
for (ExprVisitor visitor : visitors) {
visitor.onLeave(expression);
}
if (removeCurrent) {
expressions.remove(i);
} else {
......@@ -115,6 +122,10 @@ public class ExprTraverser {
traverseExpr(subExpr);
}
for (ExprVisitor visitor : visitors) {
visitor.onLeave(subExpr);
}
if (removeCurrent) {
setFieldValue(field, expression, null);
} else {
......
package com.bedrockk.molang.parser;
public final class ExprUtils {
public static Expression getExprAttribute(Expression expression, String attributeName) {
Object parent = expression.getAttributes().get(attributeName);
if (parent instanceof Expression) {
return (Expression) parent;
}
return null;
}
public static Expression parent(Expression expression) {
return getExprAttribute(expression, "parent");
}
public static Expression next(Expression expression) {
return getExprAttribute(expression, "next");
}
public static Expression previous(Expression expression) {
return getExprAttribute(expression, "previous");
}
}
......@@ -10,6 +10,10 @@ public interface ExprVisitor {
Object onVisit(Expression expression);
default void onLeave(Expression expression) {
// noop
}
default void afterTraverse(List<Expression> expressions) {
// noop
}
......
package com.bedrockk.molang.parser;
import com.bedrockk.molang.runtime.MoLangEnvironment;
import com.bedrockk.molang.runtime.MoScope;
import com.bedrockk.molang.runtime.value.MoValue;
import java.util.HashMap;
import java.util.Map;
public interface Expression {
Object evaluate(MoLangEnvironment environment);
Map<String, Object> attributes = new HashMap<>();
default Map<String, Object> getAttributes() {
return attributes;
}
MoValue evaluate(MoScope scope, MoLangEnvironment environment);
default void assign(MoScope scope, MoLangEnvironment environment, MoValue value) {
throw new RuntimeException("Cannot assign a value to " + this.getClass());
}
}
......@@ -2,20 +2,11 @@ package com.bedrockk.molang.parser;
import com.bedrockk.molang.parser.tokenizer.Token;
public abstract class InfixParselet {
public interface InfixParselet {
private final Precedence precedence;
Expression parse(MoLangParser parser, Token token, Expression leftExpr);
public InfixParselet() {
this.precedence = Precedence.ANYTHING;
}
public InfixParselet(Precedence precedence) {
this.precedence = precedence;
}
public abstract Expression parse(MoLangParser parser, Token token, Expression leftExpr);
public Precedence getPrecedence() {
return precedence;
default Precedence getPrecedence() {
return Precedence.ANYTHING;
}
}
......@@ -4,15 +4,12 @@ import com.bedrockk.molang.parser.parselet.*;
import com.bedrockk.molang.parser.tokenizer.Token;
import com.bedrockk.molang.parser.tokenizer.TokenIterator;
import com.bedrockk.molang.parser.tokenizer.TokenType;
import lombok.extern.log4j.Log4j2;
import lombok.var;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Log4j2
public final class MoLangParser {
private final static Map<TokenType, PrefixParselet> prefixParselets = new HashMap<>();
......@@ -20,14 +17,13 @@ public final class MoLangParser {
private final TokenIterator tokenIterator;
private final List<Token> readTokens = new ArrayList<>();
private Token lastConsumed;
static {
prefixParselets.put(TokenType.NAME, new NameParselet());
prefixParselets.put(TokenType.STRING, new StringParselet());
prefixParselets.put(TokenType.NUMBER, new NumberParselet());
prefixParselets.put(TokenType.TRUE, new BooleanParselet(Precedence.PREFIX));
prefixParselets.put(TokenType.FALSE, new BooleanParselet(Precedence.PREFIX));
prefixParselets.put(TokenType.TRUE, new BooleanParselet());
prefixParselets.put(TokenType.FALSE, new BooleanParselet());
prefixParselets.put(TokenType.RETURN, new ReturnParselet());
prefixParselets.put(TokenType.CONTINUE, new ContinueParselet());
prefixParselets.put(TokenType.BREAK, new BreakParselet());
......@@ -35,13 +31,13 @@ public final class MoLangParser {
prefixParselets.put(TokenType.FOR_EACH, new ForEachParselet());
prefixParselets.put(TokenType.THIS, new ThisParselet());
prefixParselets.put(TokenType.BRACKET_LEFT, new GroupParselet());
prefixParselets.put(TokenType.CURLY_BRACKET_LEFT, new BracketScopeParselet(Precedence.SCOPE));
prefixParselets.put(TokenType.MINUS, new UnaryMinusParselet(Precedence.PREFIX));
prefixParselets.put(TokenType.PLUS, new UnaryPlusParselet(Precedence.PREFIX));
prefixParselets.put(TokenType.BANG, new BooleanNotParselet(Precedence.PREFIX));
prefixParselets.put(TokenType.CURLY_BRACKET_LEFT, new BracketScopeParselet());
prefixParselets.put(TokenType.MINUS, new UnaryMinusParselet());
prefixParselets.put(TokenType.PLUS, new UnaryPlusParselet());
prefixParselets.put(TokenType.BANG, new BooleanNotParselet());
infixParselets.put(TokenType.QUESTION, new TernaryParselet(Precedence.CONDITIONAL));
infixParselets.put(TokenType.ARRAY_LEFT, new ArrayAccessParselet(Precedence.ARRAY_ACCESS));
infixParselets.put(TokenType.QUESTION, new TernaryParselet());
infixParselets.put(TokenType.ARRAY_LEFT, new ArrayAccessParselet());
infixParselets.put(TokenType.PLUS, new GenericBinaryOpParselet(Precedence.SUM));
infixParselets.put(TokenType.MINUS, new GenericBinaryOpParselet(Precedence.SUM));
infixParselets.put(TokenType.SLASH, new GenericBinaryOpParselet(Precedence.PRODUCT));
......@@ -55,8 +51,8 @@ public final class MoLangParser {
infixParselets.put(TokenType.AND, new GenericBinaryOpParselet(Precedence.AND));
infixParselets.put(TokenType.OR, new GenericBinaryOpParselet(Precedence.OR));
infixParselets.put(TokenType.COALESCE, new GenericBinaryOpParselet(Precedence.COALESCE));
infixParselets.put(TokenType.ARROW, new GenericBinaryOpParselet());
infixParselets.put(TokenType.ASSIGN, new AssignParselet(Precedence.ASSIGNMENT));
infixParselets.put(TokenType.ARROW, new GenericBinaryOpParselet(Precedence.ARROW));
infixParselets.put(TokenType.ASSIGN, new AssignParselet());
}
public MoLangParser(TokenIterator iterator) {
......@@ -95,7 +91,10 @@ public final class MoLangParser {
throw new RuntimeException("Cannot parse " + token.getType().name() + " expression");
}
return parseInfixExpression(parselet.parse(this, token), precedence);
Expression expr = parselet.parse(this, token);
initExpr(expr, token);
return parseInfixExpression(expr, precedence);
}
private Expression parseInfixExpression(Expression left, Precedence precedence) {
......@@ -104,11 +103,16 @@ public final class MoLangParser {
while (precedence.ordinal() < getPrecedence().ordinal()) {
token = consumeToken();
left = infixParselets.get(token.getType()).parse(this, token, left);
initExpr(left, token);
}
return left;
}
private void initExpr(Expression expression, Token token) {
expression.getAttributes().put("position", token.getPosition());
}
private Precedence getPrecedence() {
Token token = readToken();
......@@ -164,12 +168,6 @@ public final class MoLangParser {
return name.split("\\.")[0];
}
public boolean checkName(String name) {
String head = getNameHead(name);
return head.equals("query") || head.equals("variable") || head.equals("temp") || head.equals("context");
}
public Token consumeToken() {
return consumeToken(null);
}
......@@ -184,9 +182,7 @@ public final class MoLangParser {
}
}
lastConsumed = readTokens.remove(0);
return lastConsumed;
return readTokens.remove(0);
}
public boolean matchToken(TokenType expectedType) {
......
......@@ -17,5 +17,6 @@ public enum Precedence {
SUM,
PRODUCT,
PREFIX
PREFIX,
ARROW
}
......@@ -2,21 +2,7 @@ package com.bedrockk.molang.parser;
import com.bedrockk.molang.parser.tokenizer.Token;
public abstract class PrefixParselet {
public interface PrefixParselet {
private final Precedence precedence;
public PrefixParselet() {
this.precedence = Precedence.ANYTHING;
}
public PrefixParselet(Precedence precedence) {
this.precedence = precedence;
}
public abstract Expression parse(MoLangParser parser, Token token);
public Precedence getPrecedence() {
return precedence;
}
Expression parse(MoLangParser parser, Token token);
}
package com.bedrockk.molang.parser.expression;
import com.bedrockk.molang.parser.Expression;
import com.bedrockk.molang.runtime.MoLangEnvironment;
import com.bedrockk.molang.runtime.MoScope;
import com.bedrockk.molang.runtime.value.MoValue;
import lombok.Value;
import java.util.Map;
@Value
public class ArrayAccessExpression implements Expression {
Expression array;
Expression index;
@Override
public MoValue evaluate(MoScope scope, MoLangEnvironment environment) {
String name = array instanceof NameExpression ? ((NameExpression) array).getName() : array.evaluate(scope, environment).asString();
return environment.getValue(name + "." + (int) index.evaluate(scope, environment).asDouble());
}
@Override
public void assign(MoScope scope, MoLangEnvironment environment, MoValue value) {
String name = array instanceof NameExpression ? ((NameExpression) array).getName() : array.evaluate(scope, environment).asString();
environment.setValue(name + "." + (int) index.evaluate(scope, environment).asDouble(), value);
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment