Skip to content

Commit

Permalink
feat: Dot-notation function invocation
Browse files Browse the repository at this point in the history
  • Loading branch information
JasperLorelai committed Mar 28, 2024
1 parent 4f74499 commit a16e639
Show file tree
Hide file tree
Showing 44 changed files with 478 additions and 248 deletions.
29 changes: 25 additions & 4 deletions src/main/java/eu/jasperlorelai/circe/parser/Parser.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,16 @@
import java.util.List;
import java.util.ArrayList;

import org.jetbrains.annotations.Nullable;

import eu.jasperlorelai.circe.exeption.*;
import eu.jasperlorelai.circe.tokenizer.type.*;
import eu.jasperlorelai.circe.parser.expression.*;
import eu.jasperlorelai.circe.tokenizer.Tokenizer;
import eu.jasperlorelai.circe.tokenizer.Tokenizer.Token;
import eu.jasperlorelai.circe.tokenizer.type.util.TokenType;
import eu.jasperlorelai.circe.parser.function.util.Variables;
import eu.jasperlorelai.circe.tokenizer.type.util.TokenSuperType;
import eu.jasperlorelai.circe.parser.expression.util.ExpressionNode;

public class Parser {
Expand Down Expand Up @@ -46,11 +49,23 @@ public String parse(String string) {

private ExpressionNode expression() {
if (lookahead == null) return null;
return switch (lookahead.tokenType().type()) {
case FUNCTION -> function();
ExpressionNode node = switch (lookahead.tokenType().type()) {
case FUNCTION -> function(null);
case LITERAL -> literal();
case SPECIAL -> special();
};
return tryInvoke(node);
}

private ExpressionNode tryInvoke(ExpressionNode node) {
if (lookahead == null || lookahead.tokenType() != SpecialTokenType.DOT) return node;

nextToken();
if (lookahead == null) throw new ParserException("Expected function name after '.', instead received nothing.");
if (lookahead.tokenType().type() != TokenSuperType.FUNCTION) {
throw new ParserException("Expected function name after '.', instead received: " + lookahead.tokenType() + " '" + lookahead.value() + "'");
}
return tryInvoke(function(node));
}

private ExpressionNode special() {
Expand All @@ -63,7 +78,7 @@ private ExpressionNode special() {
};
}

private ExpressionNode function() {
private ExpressionNode function(@Nullable ExpressionNode target) {
if (lookahead == null) return null;
String functionName = lookahead.value();
FunctionNode node = new FunctionNode(lookahead);
Expand Down Expand Up @@ -101,7 +116,13 @@ private ExpressionNode function() {

if (awaitingArg) throw new ParserException("Expected argument after ',' in function '" + functionName + "'.");
if (!closed) throw new ParserException("Function '" + functionName + "' does not end with ')'");
node.process(arguments);

if (target == null) {
if (arguments.isEmpty()) throw new ParserException("Function '" + functionName + "' is not invoked on any target expression.");
else target = arguments.remove(0);
}

node.process(target, arguments);
return node;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,9 @@ public FunctionNode(Token token) {
function = type.createFunction();
}

public void process(List<ExpressionNode> arguments) {
public void process(ExpressionNode target, List<ExpressionNode> arguments) {
// Convert all function nodes to other node types.
if (target instanceof FunctionNode fun) target = fun.getFunction().execute();
List<ExpressionNode> localArgs = new ArrayList<>();
for (ExpressionNode node : arguments) {
if (node instanceof FunctionNode fun) localArgs.add(fun.getFunction().execute());
Expand All @@ -35,6 +36,10 @@ public void process(List<ExpressionNode> arguments) {
List<ParameterType> paramTypes = function.getParameterTypes();
if (localArgs.size() != paramTypes.size()) throw new ParserException("Function '" + functionName + "' expects " + paramTypes.size() + " arguments, but the supplied amount was " + localArgs.size());

ParameterType targetType = function.getTargetType();
if (!targetType.isValid(target.getType())) throw new ParserException("Function '" + functionName + "' has target of " + target.getType() + " type defined when '" + targetType + " was expected'.");
function.initializeTarget(target);

for (int i = 0; i < paramTypes.size(); i++) {
ParameterType parameter = paramTypes.get(i);
NodeType argument = localArgs.get(i).getType();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package eu.jasperlorelai.circe.parser.function;

import java.util.Map;
import java.util.List;
import java.util.HashMap;

import org.jetbrains.annotations.NotNull;
Expand All @@ -13,19 +12,19 @@
import eu.jasperlorelai.circe.parser.expression.util.*;
import eu.jasperlorelai.circe.exeption.FunctionCallException;

public class CalcFunction extends Function {
public class CalcFunction extends ZeroParamFunction {

private StringLiteralNode string;

@NotNull
@Override
public List<ParameterType> getParameterTypes() {
return NodeType.STRING.asParameterTypes();
public ParameterType getTargetType() {
return NodeType.STRING.asParameterType();
}

@Override
public void initializeArguments(List<ExpressionNode> arguments) {
string = castString(arguments.get(0));
public void initializeTarget(ExpressionNode target) {
string = castString(target);
}

@NotNull
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,19 +14,26 @@ public class CharAtFunction extends Function {
private StringLiteralNode string;
private NumberLiteralNode index;

@NotNull
@Override
public ParameterType getTargetType() {
return NodeType.STRING.asParameterType();
}

@Override
public void initializeTarget(ExpressionNode target) {
string = castString(target);
}

@NotNull
@Override
public List<ParameterType> getParameterTypes() {
return List.of(
NodeType.STRING.asParameterType(),
NodeType.NUMBER.asParameterType()
);
return NodeType.NUMBER.asParameterTypes();
}

@Override
public void initializeArguments(List<ExpressionNode> arguments) {
string = castString(arguments.get(0));
index = castNumber(arguments.get(1));
index = castNumber(arguments.get(0));
}

@NotNull
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,19 +14,26 @@ public class CharCodeAtFunction extends Function {
private StringLiteralNode string;
private NumberLiteralNode index;

@NotNull
@Override
public ParameterType getTargetType() {
return NodeType.STRING.asParameterType();
}

@Override
public void initializeTarget(ExpressionNode target) {
string = castString(target);
}

@NotNull
@Override
public List<ParameterType> getParameterTypes() {
return List.of(
NodeType.STRING.asParameterType(),
NodeType.NUMBER.asParameterType()
);
return NodeType.NUMBER.asParameterTypes();
}

@Override
public void initializeArguments(List<ExpressionNode> arguments) {
string = castString(arguments.get(0));
index = castNumber(arguments.get(1));
index = castNumber(arguments.get(0));
}

@NotNull
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,21 +17,28 @@ public class ContainsFunction extends Function {
private StringLiteralNode elementString;
private NumberLiteralNode elementNumber;

@NotNull
@Override
public ParameterType getTargetType() {
return ParameterType.create(NodeType.STRING, NodeType.ARRAY);
}

@Override
public void initializeTarget(ExpressionNode target) {
array = castArray(target);
string = castString(target);
}

@NotNull
@Override
public List<ParameterType> getParameterTypes() {
return List.of(
ParameterType.create(NodeType.STRING, NodeType.ARRAY),
ParameterType.create(NodeType.STRING, NodeType.NUMBER)
);
return List.of(ParameterType.create(NodeType.STRING, NodeType.NUMBER));
}

@Override
public void initializeArguments(List<ExpressionNode> arguments) {
array = castArray(arguments.get(0));
string = castString(arguments.get(0));
elementString = castString(arguments.get(1));
elementNumber = castNumber(arguments.get(1));
elementString = castString(arguments.get(0));
elementNumber = castNumber(arguments.get(0));
}

@NotNull
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,19 +14,26 @@ public class ElementAtFunction extends Function {
private ArrayNode array;
private NumberLiteralNode index;

@NotNull
@Override
public ParameterType getTargetType() {
return NodeType.ARRAY.asParameterType();
}

@Override
public void initializeTarget(ExpressionNode target) {
array = castArray(target);
}

@NotNull
@Override
public List<ParameterType> getParameterTypes() {
return List.of(
NodeType.ARRAY.asParameterType(),
NodeType.NUMBER.asParameterType()
);
return NodeType.NUMBER.asParameterTypes();
}

@Override
public void initializeArguments(List<ExpressionNode> arguments) {
array = castArray(arguments.get(0));
index = castNumber(arguments.get(1));
index = castNumber(arguments.get(0));
}

@NotNull
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,19 +13,26 @@ public class EndsWithFunction extends Function {
private StringLiteralNode string;
private StringLiteralNode substring;

@NotNull
@Override
public ParameterType getTargetType() {
return NodeType.STRING.asParameterType();
}

@Override
public void initializeTarget(ExpressionNode target) {
string = castString(target);
}

@NotNull
@Override
public List<ParameterType> getParameterTypes() {
return List.of(
NodeType.STRING.asParameterType(),
NodeType.STRING.asParameterType()
);
return NodeType.STRING.asParameterTypes();
}

@Override
public void initializeArguments(List<ExpressionNode> arguments) {
string = castString(arguments.get(0));
substring = castString(arguments.get(1));
substring = castString(arguments.get(0));
}

@NotNull
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,28 @@ public class EqualsFunction extends Function {
private ArrayNode arrayFirst;
private ArrayNode arraySecond;

@NotNull
@Override
public ParameterType getTargetType() {
return ParameterType.create(NodeType.STRING, NodeType.ARRAY);
}

@Override
public void initializeTarget(ExpressionNode target) {
stringFirst = castString(target);
arrayFirst = castArray(target);
}

@NotNull
@Override
public List<ParameterType> getParameterTypes() {
ParameterType arrayOrString = ParameterType.create(NodeType.STRING, NodeType.ARRAY);
return List.of(arrayOrString, arrayOrString);
return List.of(ParameterType.create(NodeType.STRING, NodeType.ARRAY));
}

@Override
public void initializeArguments(List<ExpressionNode> arguments) {
stringFirst = castString(arguments.get(0));
stringSecond = castString(arguments.get(1));
arrayFirst = castArray(arguments.get(0));
arraySecond = castArray(arguments.get(1));
stringSecond = castString(arguments.get(0));
arraySecond = castArray(arguments.get(0));
}

@NotNull
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,21 +17,28 @@ public class IndexOfFunction extends Function {
private StringLiteralNode elementString;
private NumberLiteralNode elementNumber;

@NotNull
@Override
public ParameterType getTargetType() {
return ParameterType.create(NodeType.STRING, NodeType.ARRAY);
}

@Override
public void initializeTarget(ExpressionNode target) {
string = castString(target);
array = castArray(target);
}

@NotNull
@Override
public List<ParameterType> getParameterTypes() {
return List.of(
ParameterType.create(NodeType.STRING, NodeType.ARRAY),
ParameterType.create(NodeType.STRING, NodeType.NUMBER)
);
return List.of(ParameterType.create(NodeType.STRING, NodeType.NUMBER));
}

@Override
public void initializeArguments(List<ExpressionNode> arguments) {
string = castString(arguments.get(0));
array = castArray(arguments.get(0));
elementString = castString(arguments.get(1));
elementNumber = castNumber(arguments.get(1));
elementString = castString(arguments.get(0));
elementNumber = castNumber(arguments.get(0));
}

@NotNull
Expand Down
Loading

0 comments on commit a16e639

Please sign in to comment.