mirror of
https://github.com/PolyhedralDev/Terra.git
synced 2026-06-18 14:50:56 +00:00
Implement variable reassignment and while loops
This commit is contained in:
@@ -11,6 +11,7 @@ import com.dfsek.terra.api.structures.parser.lang.constants.StringConstant;
|
|||||||
import com.dfsek.terra.api.structures.parser.lang.functions.Function;
|
import com.dfsek.terra.api.structures.parser.lang.functions.Function;
|
||||||
import com.dfsek.terra.api.structures.parser.lang.functions.FunctionBuilder;
|
import com.dfsek.terra.api.structures.parser.lang.functions.FunctionBuilder;
|
||||||
import com.dfsek.terra.api.structures.parser.lang.keywords.IfKeyword;
|
import com.dfsek.terra.api.structures.parser.lang.keywords.IfKeyword;
|
||||||
|
import com.dfsek.terra.api.structures.parser.lang.keywords.WhileKeyword;
|
||||||
import com.dfsek.terra.api.structures.parser.lang.operations.BinaryOperation;
|
import com.dfsek.terra.api.structures.parser.lang.operations.BinaryOperation;
|
||||||
import com.dfsek.terra.api.structures.parser.lang.operations.BooleanAndOperation;
|
import com.dfsek.terra.api.structures.parser.lang.operations.BooleanAndOperation;
|
||||||
import com.dfsek.terra.api.structures.parser.lang.operations.BooleanNotOperation;
|
import com.dfsek.terra.api.structures.parser.lang.operations.BooleanNotOperation;
|
||||||
@@ -47,7 +48,7 @@ import java.util.Set;
|
|||||||
public class Parser {
|
public class Parser {
|
||||||
private final String data;
|
private final String data;
|
||||||
private final Map<String, FunctionBuilder<? extends Function<?>>> functions = new HashMap<>();
|
private final Map<String, FunctionBuilder<? extends Function<?>>> functions = new HashMap<>();
|
||||||
private final Set<String> keywords = Sets.newHashSet("if", "return", "var");
|
private final Set<String> keywords = Sets.newHashSet("if", "return", "while");
|
||||||
|
|
||||||
Set<Token.Type> allowedArguments = Sets.newHashSet(Token.Type.STRING, Token.Type.NUMBER, Token.Type.IDENTIFIER);
|
Set<Token.Type> allowedArguments = Sets.newHashSet(Token.Type.STRING, Token.Type.NUMBER, Token.Type.IDENTIFIER);
|
||||||
|
|
||||||
@@ -90,7 +91,7 @@ public class Parser {
|
|||||||
if(!keywords.contains(identifier.getContent()))
|
if(!keywords.contains(identifier.getContent()))
|
||||||
throw new ParseException("No such keyword " + identifier.getContent() + ": " + identifier.getPosition());
|
throw new ParseException("No such keyword " + identifier.getContent() + ": " + identifier.getPosition());
|
||||||
Keyword<?> k = null;
|
Keyword<?> k = null;
|
||||||
if(identifier.getContent().equals("if")) {
|
if(identifier.getContent().equals("if") || identifier.getContent().equals("while")) {
|
||||||
|
|
||||||
ParserUtil.checkType(tokens.remove(0), Token.Type.GROUP_BEGIN);
|
ParserUtil.checkType(tokens.remove(0), Token.Type.GROUP_BEGIN);
|
||||||
|
|
||||||
@@ -101,7 +102,10 @@ public class Parser {
|
|||||||
|
|
||||||
ParserUtil.checkType(tokens.remove(0), Token.Type.BLOCK_BEGIN);
|
ParserUtil.checkType(tokens.remove(0), Token.Type.BLOCK_BEGIN);
|
||||||
|
|
||||||
k = new IfKeyword(parseBlock(tokens, variableMap), (Returnable<Boolean>) comparator, identifier.getPosition());
|
if(identifier.getContent().equals("if"))
|
||||||
|
k = new IfKeyword(parseBlock(tokens, variableMap), (Returnable<Boolean>) comparator, identifier.getPosition()); // If statement
|
||||||
|
else
|
||||||
|
k = new WhileKeyword(parseBlock(tokens, variableMap), (Returnable<Boolean>) comparator, identifier.getPosition()); // While loop
|
||||||
|
|
||||||
}
|
}
|
||||||
return k;
|
return k;
|
||||||
@@ -232,6 +236,7 @@ public class Parser {
|
|||||||
throw new UnsupportedOperationException("Unsupported variable type: " + type);
|
throw new UnsupportedOperationException("Unsupported variable type: " + type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
private Block parseBlock(List<Token> tokens, Map<String, Variable<?>> superVars) throws ParseException {
|
private Block parseBlock(List<Token> tokens, Map<String, Variable<?>> superVars) throws ParseException {
|
||||||
List<Item<?>> parsedItems = new GlueList<>();
|
List<Item<?>> parsedItems = new GlueList<>();
|
||||||
|
|
||||||
@@ -251,7 +256,11 @@ public class Parser {
|
|||||||
ParserUtil.checkType(tokens.get(0), Token.Type.IDENTIFIER, Token.Type.KEYWORD, Token.Type.BLOCK_END);
|
ParserUtil.checkType(tokens.get(0), Token.Type.IDENTIFIER, Token.Type.KEYWORD, Token.Type.BLOCK_END);
|
||||||
break;
|
break;
|
||||||
case IDENTIFIER:
|
case IDENTIFIER:
|
||||||
parsedItems.add(parseFunction(tokens, true, parsedVariables));
|
if(parsedVariables.containsKey(token.getContent())) {
|
||||||
|
Variable<?> variable = parsedVariables.get(token.getContent());
|
||||||
|
|
||||||
|
parsedItems.add(parseAssignment(variable, tokens, parsedVariables));
|
||||||
|
} else parsedItems.add(parseFunction(tokens, true, parsedVariables));
|
||||||
if(tokens.isEmpty()) break;
|
if(tokens.isEmpty()) break;
|
||||||
ParserUtil.checkType(tokens.remove(0), Token.Type.STATEMENT_END, Token.Type.BLOCK_END);
|
ParserUtil.checkType(tokens.remove(0), Token.Type.STATEMENT_END, Token.Type.BLOCK_END);
|
||||||
break;
|
break;
|
||||||
@@ -272,6 +281,9 @@ public class Parser {
|
|||||||
throw new ParseException(name.getContent() + " is already defined in this scope: " + name.getPosition());
|
throw new ParseException(name.getContent() + " is already defined in this scope: " + name.getPosition());
|
||||||
|
|
||||||
parsedVariables.put(name.getContent(), temp);
|
parsedVariables.put(name.getContent(), temp);
|
||||||
|
|
||||||
|
ParserUtil.checkType(tokens.remove(0), Token.Type.STRING_VARIABLE, Token.Type.BOOLEAN_VARIABLE, Token.Type.NUMBER_VARIABLE);
|
||||||
|
|
||||||
parsedItems.add(parseAssignment(temp, tokens, parsedVariables));
|
parsedItems.add(parseAssignment(temp, tokens, parsedVariables));
|
||||||
ParserUtil.checkType(tokens.remove(0), Token.Type.STATEMENT_END);
|
ParserUtil.checkType(tokens.remove(0), Token.Type.STATEMENT_END);
|
||||||
break;
|
break;
|
||||||
@@ -285,8 +297,6 @@ public class Parser {
|
|||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
private Assignment<?> parseAssignment(Variable<?> variable, List<Token> tokens, Map<String, Variable<?>> variableMap) throws ParseException {
|
private Assignment<?> parseAssignment(Variable<?> variable, List<Token> tokens, Map<String, Variable<?>> variableMap) throws ParseException {
|
||||||
ParserUtil.checkType(tokens.remove(0), Token.Type.STRING_VARIABLE, Token.Type.BOOLEAN_VARIABLE, Token.Type.NUMBER_VARIABLE);
|
|
||||||
|
|
||||||
Token name = tokens.get(0);
|
Token name = tokens.get(0);
|
||||||
|
|
||||||
ParserUtil.checkType(tokens.remove(0), Token.Type.IDENTIFIER);
|
ParserUtil.checkType(tokens.remove(0), Token.Type.IDENTIFIER);
|
||||||
|
|||||||
+42
@@ -0,0 +1,42 @@
|
|||||||
|
package com.dfsek.terra.api.structures.parser.lang.keywords;
|
||||||
|
|
||||||
|
import com.dfsek.terra.api.math.vector.Location;
|
||||||
|
import com.dfsek.terra.api.platform.world.Chunk;
|
||||||
|
import com.dfsek.terra.api.structures.parser.lang.Block;
|
||||||
|
import com.dfsek.terra.api.structures.parser.lang.Keyword;
|
||||||
|
import com.dfsek.terra.api.structures.parser.lang.Returnable;
|
||||||
|
import com.dfsek.terra.api.structures.tokenizer.Position;
|
||||||
|
|
||||||
|
public class WhileKeyword implements Keyword<Void> {
|
||||||
|
private final Block conditional;
|
||||||
|
private final Returnable<Boolean> statement;
|
||||||
|
private final Position position;
|
||||||
|
|
||||||
|
public WhileKeyword(Block conditional, Returnable<Boolean> statement, Position position) {
|
||||||
|
this.conditional = conditional;
|
||||||
|
this.statement = statement;
|
||||||
|
this.position = position;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Void apply(Location location) {
|
||||||
|
while(statement.apply(location)) conditional.apply(location);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Void apply(Location location, Chunk chunk) {
|
||||||
|
while(statement.apply(location, chunk)) conditional.apply(location, chunk);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Position getPosition() {
|
||||||
|
return position;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ReturnType returnType() {
|
||||||
|
return ReturnType.VOID;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -12,7 +12,7 @@ public class Tokenizer {
|
|||||||
private final Lookahead reader;
|
private final Lookahead reader;
|
||||||
|
|
||||||
private final Set<Character> syntaxSignificant = Sets.newHashSet(';', '(', ')', '"', ',', '\\', '=', '{', '}', '+', '-', '*', '/', '>', '<', '!'); // Reserved chars
|
private final Set<Character> syntaxSignificant = Sets.newHashSet(';', '(', ')', '"', ',', '\\', '=', '{', '}', '+', '-', '*', '/', '>', '<', '!'); // Reserved chars
|
||||||
private final Set<String> keywords = Sets.newHashSet("if", "return", "num", "bool", "str");
|
private final Set<String> keywords = Sets.newHashSet("if", "while", "num", "bool", "str");
|
||||||
|
|
||||||
|
|
||||||
public Tokenizer(String data) {
|
public Tokenizer(String data) {
|
||||||
|
|||||||
@@ -1,9 +1,18 @@
|
|||||||
test("hello" + 3 + "gdfg", (2 * (3+1) * (2 * (1+1))));
|
test("hello" + 3 + "gdfg", (2 * (3+1) * (2 * (1+1))));
|
||||||
//
|
//
|
||||||
|
|
||||||
num testVar = 3.4;
|
num testVar = 3.4;
|
||||||
bool boolean = true;
|
bool boolean = true;
|
||||||
str stringVar = "hello!";
|
str stringVar = "hello!";
|
||||||
|
|
||||||
|
num iterator = 0;
|
||||||
|
|
||||||
|
while(iterator < 5) {
|
||||||
|
test("fdsgdf" + 2 + stringVar, iterator);
|
||||||
|
iterator = iterator + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if(true && boolean) {
|
if(true && boolean) {
|
||||||
num scopedVar = 2;
|
num scopedVar = 2;
|
||||||
test("fdsgdf" + 2 + stringVar, 1 + testVar + scopedVar);
|
test("fdsgdf" + 2 + stringVar, 1 + testVar + scopedVar);
|
||||||
|
|||||||
Reference in New Issue
Block a user