From cb7b3de48c2e8225a6df9a2581d95ba8a3e31572 Mon Sep 17 00:00:00 2001 From: dfsek Date: Mon, 21 Dec 2020 22:30:02 -0700 Subject: [PATCH] better type checking for function args --- .../terra/api/structures/parser/Parser.java | 26 ++++++++++++------- .../api/structures/parser/lang/Argument.java | 5 ---- .../lang/functions/FunctionBuilder.java | 4 ++- .../src/test/java/structure/ParserTest.java | 17 ++++++++++-- common/src/test/resources/test.tesf | 2 +- 5 files changed, 36 insertions(+), 18 deletions(-) delete mode 100644 common/src/main/java/com/dfsek/terra/api/structures/parser/lang/Argument.java diff --git a/common/src/main/java/com/dfsek/terra/api/structures/parser/Parser.java b/common/src/main/java/com/dfsek/terra/api/structures/parser/Parser.java index ee536915f..cb2f20115 100644 --- a/common/src/main/java/com/dfsek/terra/api/structures/parser/Parser.java +++ b/common/src/main/java/com/dfsek/terra/api/structures/parser/Parser.java @@ -174,8 +174,8 @@ public class Parser { @SuppressWarnings("unchecked") private BinaryOperation assemble(Returnable left, Returnable right, Token binaryOperator) throws ParseException { - if(binaryOperator.isStrictNumericOperator()) checkArithmeticOperation(left, right, binaryOperator.getType()); - if(binaryOperator.isStrictBooleanOperator()) checkBooleanOperation(left, right, binaryOperator.getType()); + if(binaryOperator.isStrictNumericOperator()) checkArithmeticOperation(left, right, binaryOperator); + if(binaryOperator.isStrictBooleanOperator()) checkBooleanOperation(left, right, binaryOperator); switch(binaryOperator.getType()) { case ADDITION_OPERATOR: if(left.returnType().equals(Returnable.ReturnType.NUMBER) && right.returnType().equals(Returnable.ReturnType.NUMBER)) { @@ -254,9 +254,17 @@ public class Parser { if(fullStatement) checkType(tokens.get(0), Token.Type.STATEMENT_END); FunctionBuilder builder = functions.get(identifier.getContent()); - if(args.size() != builder.getArguments() && builder.getArguments() != -1) - throw new ParseException("Expected " + builder.getArguments() + " arguments, found " + args.size() + ": " + identifier.getPosition()); - return functions.get(identifier.getContent()).build(args, identifier.getPosition()); + + if(builder.argNumber() != -1 && args.size() != builder.argNumber()) + throw new ParseException("Expected " + builder.argNumber() + " arguments, found " + args.size() + ": " + identifier.getPosition()); + + for(int i = 0; i < args.size(); i++) { + Returnable argument = args.get(i); + if(builder.getArgument(i) == null) + throw new ParseException("Unexpected argument at position " + i + " in function " + identifier.getContent() + ": " + identifier.getPosition()); + checkReturnType(argument, builder.getArgument(i)); + } + return builder.build(args, identifier.getPosition()); } @@ -281,15 +289,15 @@ public class Parser { throw new ParseException("Expected " + Arrays.toString(types) + " but found " + returnable.returnType() + ": " + returnable.getPosition()); } - private void checkArithmeticOperation(Returnable left, Returnable right, Token.Type operation) throws ParseException { + private void checkArithmeticOperation(Returnable left, Returnable right, Token operation) throws ParseException { if(!left.returnType().equals(Returnable.ReturnType.NUMBER) || !right.returnType().equals(Returnable.ReturnType.NUMBER)) { - throw new ParseException("Operation " + operation + " not supported between " + left.returnType() + " and " + right.returnType()); + throw new ParseException("Operation " + operation.getType() + " not supported between " + left.returnType() + " and " + right.returnType() + ": " + operation.getPosition()); } } - private void checkBooleanOperation(Returnable left, Returnable right, Token.Type operation) throws ParseException { + private void checkBooleanOperation(Returnable left, Returnable right, Token operation) throws ParseException { if(!left.returnType().equals(Returnable.ReturnType.BOOLEAN) || !right.returnType().equals(Returnable.ReturnType.BOOLEAN)) { - throw new ParseException("Operation " + operation + " not supported between " + left.returnType() + " and " + right.returnType()); + throw new ParseException("Operation " + operation.getType() + " not supported between " + left.returnType() + " and " + right.returnType() + ": " + operation.getPosition()); } } } diff --git a/common/src/main/java/com/dfsek/terra/api/structures/parser/lang/Argument.java b/common/src/main/java/com/dfsek/terra/api/structures/parser/lang/Argument.java deleted file mode 100644 index 98a7c246f..000000000 --- a/common/src/main/java/com/dfsek/terra/api/structures/parser/lang/Argument.java +++ /dev/null @@ -1,5 +0,0 @@ -package com.dfsek.terra.api.structures.parser.lang; - -public interface Argument { - T parse(String input); -} diff --git a/common/src/main/java/com/dfsek/terra/api/structures/parser/lang/functions/FunctionBuilder.java b/common/src/main/java/com/dfsek/terra/api/structures/parser/lang/functions/FunctionBuilder.java index c05622d0d..7d1cbe4ba 100644 --- a/common/src/main/java/com/dfsek/terra/api/structures/parser/lang/functions/FunctionBuilder.java +++ b/common/src/main/java/com/dfsek/terra/api/structures/parser/lang/functions/FunctionBuilder.java @@ -9,5 +9,7 @@ import java.util.List; public interface FunctionBuilder> { T build(List> argumentList, Position position) throws ParseException; - int getArguments(); + int argNumber(); + + Returnable.ReturnType getArgument(int position); } diff --git a/common/src/test/java/structure/ParserTest.java b/common/src/test/java/structure/ParserTest.java index 9eb52be0d..f69936b5e 100644 --- a/common/src/test/java/structure/ParserTest.java +++ b/common/src/test/java/structure/ParserTest.java @@ -27,9 +27,22 @@ public class ParserTest { } @Override - public int getArguments() { + public int argNumber() { return 2; } + + @Override + public Returnable.ReturnType getArgument(int position) { + switch(position) { + case 0: + return Returnable.ReturnType.STRING; + case 1: + return Returnable.ReturnType.NUMBER; + default: + return null; + } + } + }); long l = System.nanoTime(); @@ -71,7 +84,7 @@ public class ParserTest { @Override public Position getPosition() { - return null; + return position; } @Override diff --git a/common/src/test/resources/test.tesf b/common/src/test/resources/test.tesf index f067052ce..1136218f8 100644 --- a/common/src/test/resources/test.tesf +++ b/common/src/test/resources/test.tesf @@ -1,5 +1,5 @@ test("hello" + 3 + "gdfg", (2 * (3+1) * (2 * (1+1)))); if(true || false) { - test("fdsgdf" + 2, 3.4); + test("fdsgdf" + 2, 1); } \ No newline at end of file