diff options
Diffstat (limited to 'dice-lang/src')
3 files changed, 163 insertions, 26 deletions
diff --git a/dice-lang/src/examples/java/bjc/dicelang/examples/DiceASTLanguagePragmaHandlers.java b/dice-lang/src/examples/java/bjc/dicelang/examples/DiceASTLanguagePragmaHandlers.java index cbe060a..420391e 100644 --- a/dice-lang/src/examples/java/bjc/dicelang/examples/DiceASTLanguagePragmaHandlers.java +++ b/dice-lang/src/examples/java/bjc/dicelang/examples/DiceASTLanguagePragmaHandlers.java @@ -4,7 +4,7 @@ import java.util.Map; import java.util.function.BiConsumer; import bjc.dicelang.ast.DiceASTExpression; -import bjc.dicelang.ast.DiceASTFreezer; +import bjc.dicelang.ast.DiceASTInliner; import bjc.dicelang.ast.DiceASTParser; import bjc.dicelang.ast.nodes.IDiceASTNode; import bjc.utils.funcdata.FunctionalMap; @@ -18,45 +18,45 @@ import bjc.utils.parserutils.AST; */ public class DiceASTLanguagePragmaHandlers { /** - * Handles freezing a specified expression to a new name + * Handles inlining a specified expression to a new name * * @author ben * */ - public static final class FreezeHandler implements + public static final class InlineHandler implements BiConsumer<DiceASTParser, Map<String, DiceASTExpression>> { - private String expressionToFreeze; + private String expressionToInline; private String resultingVariable; /** - * Create a new freeze handler + * Create a new inlining handler * - * @param expressionToFreeze - * The name of the expression to freeze + * @param expressionToInline + * The name of the expression to inline * @param resultingVariable - * The name of the variable to bind the frozen + * The name of the variable to bind the inline * expression to */ - public FreezeHandler(String expressionToFreeze, + public InlineHandler(String expressionToInline, String resultingVariable) { - this.expressionToFreeze = expressionToFreeze; + this.expressionToInline = expressionToInline; this.resultingVariable = resultingVariable; } @Override public void accept(DiceASTParser astParser, Map<String, DiceASTExpression> enviroment) { - if (enviroment.containsKey(expressionToFreeze)) { + if (enviroment.containsKey(expressionToInline)) { System.err.println( "ERROR: There is no expression bound to the variable " - + expressionToFreeze + "."); + + expressionToInline + "."); } else { - AST<IDiceASTNode> frozenAST = DiceASTFreezer.freezeAST( - enviroment.get(expressionToFreeze), + AST<IDiceASTNode> inlinedAST = DiceASTInliner.inlineAST( + enviroment.get(expressionToInline), new FunctionalMap<>(enviroment)); enviroment.put(resultingVariable, - new DiceASTExpression(frozenAST, enviroment)); + new DiceASTExpression(inlinedAST, enviroment)); } } } diff --git a/dice-lang/src/examples/java/bjc/dicelang/examples/DiceASTLanguageTest.java b/dice-lang/src/examples/java/bjc/dicelang/examples/DiceASTLanguageTest.java index 0607329..7bd85af 100644 --- a/dice-lang/src/examples/java/bjc/dicelang/examples/DiceASTLanguageTest.java +++ b/dice-lang/src/examples/java/bjc/dicelang/examples/DiceASTLanguageTest.java @@ -8,7 +8,7 @@ import java.util.function.BiConsumer; import bjc.dicelang.IDiceExpression; import bjc.dicelang.ast.DiceASTDefinedChecker; import bjc.dicelang.ast.DiceASTExpression; -import bjc.dicelang.ast.DiceASTFreezer; +import bjc.dicelang.ast.DiceASTInliner; import bjc.dicelang.ast.DiceASTParser; import bjc.dicelang.ast.DiceASTReferenceChecker; import bjc.dicelang.ast.nodes.IDiceASTNode; @@ -40,11 +40,11 @@ public class DiceASTLanguageTest { // Put all the defined special commands in place specialCommands.put("roll", DiceASTLanguageTest::rollReference); specialCommands.put("env", DiceASTLanguageTest::printEnv); - specialCommands.put("freeze", DiceASTLanguageTest::freezeVar); + specialCommands.put("inline", DiceASTLanguageTest::inlineVariable); } /** - * Freeze the references in an expression. + * Inline the references in an expression. * * This means replace variable references with the current contents of * the variables they refer to @@ -54,7 +54,7 @@ public class DiceASTLanguageTest { * @param languageState * The state of the language at the moment */ - private static void freezeVar(String command, + private static void inlineVariable(String command, DiceASTLanguageState languageState) { // Split the string into components String[] args = command.split(" "); @@ -62,21 +62,21 @@ public class DiceASTLanguageTest { // Make sure we have the correct amount of arguments if (args.length != 3) { System.err.println( - "ERROR: Freeze requires you provide the name of expression" - + " to freeze, as well as the name of the variable to bind" + "ERROR: Inline requires you provide the name of expression" + + " to inline, as well as the name of the variable to bind" + " the result to."); return; } - String expressionToFreeze = args[1]; + String expressionToInline = args[1]; String resultingVariable = args[2]; - System.out.println("Freezing references in " + args[1] + System.out.println("Inlining references in " + args[1] + " and binding to " + resultingVariable); languageState.doWith( - new FreezeHandler(expressionToFreeze, resultingVariable)); + new InlineHandler(expressionToInline, resultingVariable)); } /** @@ -143,6 +143,7 @@ public class DiceASTLanguageTest { System.err.println( "ERROR: There is no expression bound to the variable " + expressionName + "."); + return; } for (int i = 1; i <= numberOfRolls; i++) { @@ -297,8 +298,8 @@ public class DiceASTLanguageTest { new FunctionalMap<>(enviroment) .mapValues((expr) -> expr.getAst()); - AST<IDiceASTNode> expressionSansLast = DiceASTFreezer - .selectiveFreeze(builtAST, transformedEnviroment, "last"); + AST<IDiceASTNode> expressionSansLast = DiceASTInliner + .selectiveInline(builtAST, transformedEnviroment, "last"); return new DiceASTExpression(expressionSansLast, enviroment); } diff --git a/dice-lang/src/main/java/bjc/dicelang/ast/DiceASTInliner.java b/dice-lang/src/main/java/bjc/dicelang/ast/DiceASTInliner.java new file mode 100644 index 0000000..ef4a904 --- /dev/null +++ b/dice-lang/src/main/java/bjc/dicelang/ast/DiceASTInliner.java @@ -0,0 +1,136 @@ +package bjc.dicelang.ast; + +import java.util.function.Function; + +import bjc.dicelang.ast.nodes.DiceASTType; +import bjc.dicelang.ast.nodes.IDiceASTNode; +import bjc.dicelang.ast.nodes.VariableDiceNode; +import bjc.utils.funcdata.FunctionalList; +import bjc.utils.funcdata.FunctionalMap; +import bjc.utils.parserutils.AST; + +/** + * Inline references in a dice AST, replacing variable references with what + * the variables refer to + * + * @author ben + * + */ +public class DiceASTInliner { + private static class NodeInliner + implements Function<IDiceASTNode, AST<IDiceASTNode>> { + private FunctionalMap<String, AST<IDiceASTNode>> enviroment; + + public NodeInliner(FunctionalMap<String, AST<IDiceASTNode>> env) { + enviroment = env; + } + + @Override + public AST<IDiceASTNode> apply(IDiceASTNode nod) { + if (nod.getType() == DiceASTType.VARIABLE) { + return expandNode((VariableDiceNode) nod); + } else { + return new AST<>(nod); + } + } + + protected AST<IDiceASTNode> + expandNode(VariableDiceNode variableNode) { + String varName = variableNode.getVariable(); + + if (!enviroment.containsKey(varName)) { + throw new IllegalArgumentException( + "Attempted to freeze reference" + + " to an undefined variable " + varName); + } + + return enviroment.get(varName); + } + } + + private static final class SelectiveInliner extends NodeInliner { + + private FunctionalList<String> variableNames; + + public SelectiveInliner( + FunctionalMap<String, AST<IDiceASTNode>> env, + FunctionalList<String> varNames) { + super(env); + + variableNames = varNames; + } + + @Override + protected AST<IDiceASTNode> + expandNode(VariableDiceNode variableNode) { + if (variableNames.contains(variableNode.getVariable())) { + return super.expandNode(variableNode); + } else { + return new AST<>(variableNode); + } + } + } + + /** + * Inline the references in an AST + * + * @param tree + * The tree to inline references in + * @param env + * The enviroment to get reference values from + * @return The tree with references inlined + */ + public static AST<IDiceASTNode> inlineAST(AST<IDiceASTNode> tree, + FunctionalMap<String, AST<IDiceASTNode>> env) { + return selectiveInline(tree, env); + } + + /** + * Inline the references in an expression backed by an AST + * + * @param tree + * The tree-backed expression to inline references in + * @param env + * The enviroment to get reference values from + * @return The tree with references inlined + */ + public static AST<IDiceASTNode> inlineAST(DiceASTExpression tree, + FunctionalMap<String, DiceASTExpression> env) { + return inlineAST(tree.getAst(), + env.mapValues(expression -> expression.getAst())); + } + + /** + * Inline references to specified variables + * + * @param tree + * The tree-backed expression to inline references in + * @param env + * The enviroment to resolve variables against + * @param varNames + * The names of the variables to inline + * @return An AST with the specified variables inlined + */ + public static AST<IDiceASTNode> selectiveInline(AST<IDiceASTNode> tree, + FunctionalMap<String, AST<IDiceASTNode>> env, + String... varNames) { + return selectiveInline(tree, env, new FunctionalList<>(varNames)); + } + + /** + * Inline references to specified variables + * + * @param tree + * The tree-backed expression to inline references in + * @param env + * The enviroment to resolve variables against + * @param varNames + * The names of the variables to inline + * @return An AST with the specified variables inline + */ + public static AST<IDiceASTNode> selectiveInline(AST<IDiceASTNode> tree, + FunctionalMap<String, AST<IDiceASTNode>> env, + FunctionalList<String> varNames) { + return tree.expand(new SelectiveInliner(env, varNames)); + } +}
\ No newline at end of file |
