From b296ecf265120a0cac9cc5c558bdc60c6a27fff2 Mon Sep 17 00:00:00 2001 From: bculkin2442 Date: Mon, 4 Apr 2016 10:07:30 -0400 Subject: Changed terminology to match common use --- .../main/java/bjc/dicelang/ast/DiceASTInliner.java | 136 +++++++++++++++++++++ 1 file changed, 136 insertions(+) create mode 100644 dice-lang/src/main/java/bjc/dicelang/ast/DiceASTInliner.java (limited to 'dice-lang/src/main/java') 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> { + private FunctionalMap> enviroment; + + public NodeInliner(FunctionalMap> env) { + enviroment = env; + } + + @Override + public AST apply(IDiceASTNode nod) { + if (nod.getType() == DiceASTType.VARIABLE) { + return expandNode((VariableDiceNode) nod); + } else { + return new AST<>(nod); + } + } + + protected AST + 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 variableNames; + + public SelectiveInliner( + FunctionalMap> env, + FunctionalList varNames) { + super(env); + + variableNames = varNames; + } + + @Override + protected AST + 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 inlineAST(AST tree, + FunctionalMap> 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 inlineAST(DiceASTExpression tree, + FunctionalMap 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 selectiveInline(AST tree, + FunctionalMap> 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 selectiveInline(AST tree, + FunctionalMap> env, + FunctionalList varNames) { + return tree.expand(new SelectiveInliner(env, varNames)); + } +} \ No newline at end of file -- cgit v1.2.3