From e5d9ae62fa7075f32a13d6c64ab7991815cf9605 Mon Sep 17 00:00:00 2001 From: dfsek Date: Tue, 22 Dec 2020 15:13:01 -0700 Subject: [PATCH] more cleanup --- .../terra/api/structures/parser/Parser.java | 81 +++++++++---------- .../terra/api/structures/tokenizer/Token.java | 26 +++--- 2 files changed, 52 insertions(+), 55 deletions(-) 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 fcfd5b162..700fe3523 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 @@ -57,6 +57,12 @@ public class Parser { return this; } + /** + * Parse input + * + * @return executable {@link Block} + * @throws ParseException If parsing fails. + */ public Block parse() throws ParseException { Tokenizer tokenizer = new Tokenizer(data); @@ -80,7 +86,7 @@ public class Parser { @SuppressWarnings("unchecked") - private Keyword parseKeyword(List tokens, Map> variableMap) throws ParseException { + private Keyword parseLoopLike(List tokens, Map> variableMap) throws ParseException { Token identifier = tokens.remove(0); ParserUtil.checkType(identifier, Token.Type.IF_STATEMENT, Token.Type.WHILE_LOOP); @@ -178,8 +184,9 @@ public class Parser { @SuppressWarnings("unchecked") private BinaryOperation assemble(Returnable left, Returnable right, Token binaryOperator) throws ParseException { - if(binaryOperator.isStrictNumericOperator()) ParserUtil.checkArithmeticOperation(left, right, binaryOperator); - if(binaryOperator.isStrictBooleanOperator()) ParserUtil.checkBooleanOperation(left, right, binaryOperator); + if(binaryOperator.isStrictNumericOperator()) + ParserUtil.checkArithmeticOperation(left, right, binaryOperator); // Numeric type checking + if(binaryOperator.isStrictBooleanOperator()) ParserUtil.checkBooleanOperation(left, right, binaryOperator); // Boolean type checking switch(binaryOperator.getType()) { case ADDITION_OPERATOR: if(left.returnType().equals(Returnable.ReturnType.NUMBER) && right.returnType().equals(Returnable.ReturnType.NUMBER)) { @@ -226,62 +233,48 @@ public class Parser { throw new UnsupportedOperationException("Unsupported variable type: " + type); } - @SuppressWarnings("unchecked") private Block parseBlock(List tokens, Map> superVars) throws ParseException { List> parsedItems = new GlueList<>(); Map> parsedVariables = new HashMap<>(superVars); // New hashmap as to not mutate parent scope's declarations. Token first = tokens.get(0); - ParserUtil.checkType(tokens.get(0), Token.Type.IDENTIFIER, Token.Type.IF_STATEMENT, Token.Type.WHILE_LOOP, Token.Type.NUMBER_VARIABLE, Token.Type.STRING_VARIABLE, Token.Type.BOOLEAN_VARIABLE); - main: while(tokens.size() > 0) { Token token = tokens.get(0); - ParserUtil.checkType(token, Token.Type.IDENTIFIER, Token.Type.IF_STATEMENT, Token.Type.WHILE_LOOP, Token.Type.BLOCK_END, Token.Type.NUMBER_VARIABLE, Token.Type.STRING_VARIABLE, Token.Type.BOOLEAN_VARIABLE); - switch(token.getType()) { - case IF_STATEMENT: - case WHILE_LOOP: - parsedItems.add(parseKeyword(tokens, parsedVariables)); - if(tokens.isEmpty()) break; - ParserUtil.checkType(tokens.get(0), Token.Type.IDENTIFIER, Token.Type.IF_STATEMENT, Token.Type.WHILE_LOOP, Token.Type.BLOCK_END); - break; - case IDENTIFIER: - if(parsedVariables.containsKey(token.getContent())) { - Variable variable = parsedVariables.get(token.getContent()); + if(token.getType().equals(Token.Type.BLOCK_END)) break; // Stop parsing at block end. - parsedItems.add(parseAssignment(variable, tokens, parsedVariables)); - } else parsedItems.add(parseFunction(tokens, true, parsedVariables)); - if(tokens.isEmpty()) break; - ParserUtil.checkType(tokens.remove(0), Token.Type.STATEMENT_END, Token.Type.BLOCK_END); - break; - case NUMBER_VARIABLE: - case BOOLEAN_VARIABLE: - case STRING_VARIABLE: - Variable temp; - if(token.getType().equals(Token.Type.NUMBER_VARIABLE)) - temp = parseVariableDeclaration(tokens, Returnable.ReturnType.NUMBER); - else if(token.getType().equals(Token.Type.STRING_VARIABLE)) - temp = parseVariableDeclaration(tokens, Returnable.ReturnType.STRING); - else temp = parseVariableDeclaration(tokens, Returnable.ReturnType.BOOLEAN); - Token name = tokens.get(1); + ParserUtil.checkType(token, Token.Type.IDENTIFIER, Token.Type.IF_STATEMENT, Token.Type.WHILE_LOOP, Token.Type.NUMBER_VARIABLE, Token.Type.STRING_VARIABLE, Token.Type.BOOLEAN_VARIABLE); - ParserUtil.checkType(name, Token.Type.IDENTIFIER); // Name must be an identifier. + if(token.isLoopLike()) { // Parse loop-like tokens (if, while, etc) + parsedItems.add(parseLoopLike(tokens, parsedVariables)); + } else if(token.isIdentifier()) { // Parse identifiers + if(parsedVariables.containsKey(token.getContent())) { // Assume variable assignment + Variable variable = parsedVariables.get(token.getContent()); + parsedItems.add(parseAssignment(variable, tokens, parsedVariables)); + } else parsedItems.add(parseFunction(tokens, true, parsedVariables)); + } else if(token.isVariableDeclaration()) { + Variable temp; + if(token.getType().equals(Token.Type.NUMBER_VARIABLE)) + temp = parseVariableDeclaration(tokens, Returnable.ReturnType.NUMBER); + else if(token.getType().equals(Token.Type.STRING_VARIABLE)) + temp = parseVariableDeclaration(tokens, Returnable.ReturnType.STRING); + else temp = parseVariableDeclaration(tokens, Returnable.ReturnType.BOOLEAN); + Token name = tokens.get(1); - if(functions.containsKey(name.getContent()) || parsedVariables.containsKey(name.getContent())) - throw new ParseException(name.getContent() + " is already defined in this scope: " + name.getPosition()); + ParserUtil.checkType(name, Token.Type.IDENTIFIER); // Name must be an identifier. - parsedVariables.put(name.getContent(), temp); + if(functions.containsKey(name.getContent()) || parsedVariables.containsKey(name.getContent())) + throw new ParseException(name.getContent() + " is already defined in this scope: " + name.getPosition()); - ParserUtil.checkType(tokens.remove(0), Token.Type.STRING_VARIABLE, Token.Type.BOOLEAN_VARIABLE, Token.Type.NUMBER_VARIABLE); + parsedVariables.put(name.getContent(), temp); - parsedItems.add(parseAssignment(temp, tokens, parsedVariables)); - ParserUtil.checkType(tokens.remove(0), Token.Type.STATEMENT_END); - break; - case BLOCK_END: - tokens.remove(0); // Remove block end. - break main; - } + ParserUtil.checkType(tokens.remove(0), Token.Type.STRING_VARIABLE, Token.Type.BOOLEAN_VARIABLE, Token.Type.NUMBER_VARIABLE); + + parsedItems.add(parseAssignment(temp, tokens, parsedVariables)); + } else throw new UnsupportedOperationException("Unexpected token " + token.getType() + ": " + token.getPosition()); + + if(!tokens.isEmpty()) ParserUtil.checkType(tokens.remove(0), Token.Type.STATEMENT_END, Token.Type.BLOCK_END); } return new Block(parsedItems, first.getPosition()); } diff --git a/common/src/main/java/com/dfsek/terra/api/structures/tokenizer/Token.java b/common/src/main/java/com/dfsek/terra/api/structures/tokenizer/Token.java index b85444e66..1dc40f179 100644 --- a/common/src/main/java/com/dfsek/terra/api/structures/tokenizer/Token.java +++ b/common/src/main/java/com/dfsek/terra/api/structures/tokenizer/Token.java @@ -62,6 +62,21 @@ public class Token { || type.equals(Type.BOOLEAN_OR); } + public boolean isVariableDeclaration() { + return type.equals(Type.STRING_VARIABLE) + || type.equals(Type.BOOLEAN_VARIABLE) + || type.equals(Type.NUMBER_VARIABLE); + } + + public boolean isLoopLike() { + return type.equals(Type.IF_STATEMENT) + || type.equals(Type.WHILE_LOOP); + } + + public boolean isIdentifier() { + return type.equals(Type.IDENTIFIER); + } + public enum Type { /** * Function identifier or language keyword @@ -170,15 +185,4 @@ public class Token { IF_STATEMENT, WHILE_LOOP } - - public enum Group { - KEYWORD(Type.IF_STATEMENT, Type.WHILE_LOOP, Type.BOOLEAN_VARIABLE, Type.STRING_VARIABLE, Type.NUMBER_VARIABLE), - IDENTIFIER(Type.IDENTIFIER), - BINARY_OPERATOR(Type.BOOLEAN_AND, Type.BOOLEAN_OR, Type.ADDITION_OPERATOR, Type.MULTIPLICATION_OPERATOR, Type.SUBTRACTION_OPERATOR, Type.DIVISION_OPERATOR, Type.GREATER_THAN_OPERATOR, Type.GREATER_THAN_OR_EQUALS_OPERATOR, Type.LESS_THAN_OPERATOR, Type.LESS_THAN_OR_EQUALS_OPERATOR, Type.EQUALS_OPERATOR, Type.NOT_EQUALS_OPERATOR); - private final Type[] types; - - Group(Type... types) { - this.types = types; - } - } }