TranslatorState.java
package org.sterling.source.translator;
import static org.sterling.runtime.expression.ExpressionFactory.declaration;
import java.util.*;
import org.sterling.SterlingException;
import org.sterling.runtime.GlobalModule;
import org.sterling.runtime.expression.DeclaredExpression;
import org.sterling.runtime.expression.Expression;
import org.sterling.runtime.expression.ExpressionFactory;
import org.sterling.runtime.expression.Variable;
import org.sterling.source.syntax.SourceNode;
public class TranslatorState {
private final GlobalModule globalModule;
private final ModuleBuilder module;
private final Set<DeclaredExpression> declarations;
private final Deque<Expression> expressions;
private final Deque<Scope> scopes;
private final Deque<SourceNode> trees;
private final AliasBuilder importBuilder;
private final Map<String, String> imports;
private final Deque<ObjectBuilder> objects;
public TranslatorState(GlobalModule globalModule) {
this.globalModule = globalModule;
this.module = new ModuleBuilder();
this.declarations = new HashSet<>();
this.expressions = new ArrayDeque<>();
this.scopes = new ArrayDeque<>();
this.trees = new ArrayDeque<>();
this.importBuilder = new AliasBuilder();
this.imports = new HashMap<>();
this.objects = new ArrayDeque<>();
this.scopes.push(new Scope());
}
public void acceptImports() {
for (Alias alias : importBuilder.acceptImports()) {
imports.put(alias.getAlias(), alias.getIdentifier());
}
}
public void acceptModule() {
module.acceptModule();
}
public Expression acceptObject() {
return objects.pop().toObject();
}
public void addImport(String importName) {
importBuilder.addImport(importName);
}
public void appendFrom(String part) {
importBuilder.appendFrom(part);
}
public void appendModule(String part) {
module.appendModule(part);
}
public void beginObject() {
objects.push(new ObjectBuilder());
}
public void declare(String identifier, Expression expression) throws SterlingException {
declarations.add(declaration(identifier, expression));
}
public void declareMember(String identifier, Expression expression) {
objects.peek().declareMember(identifier, expression);
}
public Variable define(Variable variable) {
return scope().define(variable);
}
public void enterScope() {
scopes.add(new Scope());
}
public Set<DeclaredExpression> getDeclarations() {
return new HashSet<>(declarations);
}
public void leaveScope() {
scopes.pop();
}
public Expression popExpression() {
return expressions.pop();
}
public SourceNode popSource() {
return trees.pop();
}
public void pushExpression(Expression expression) {
expressions.push(expression);
}
public void pushSource(SourceNode tree) {
trees.push(tree);
}
public Expression reference(String identifier) {
if (scope().has(identifier)) {
return scope().get(identifier);
} else {
return ExpressionFactory.reference(qualifyIdentifier(identifier), globalModule);
}
}
public void setAlias(String alias) {
importBuilder.setAlias(alias);
}
private Scope scope() {
return scopes.peek();
}
private String qualifyDeclaration(String identifier) {
if (module.isDeclared()) {
return module.getIdentifier() + "/" + identifier;
} else {
return identifier;
}
}
private String qualifyIdentifier(String identifier) {
if (imports.containsKey(identifier)) {
return imports.get(identifier);
} else {
return qualifyDeclaration(identifier);
}
}
private static final class Scope {
private final Map<String, Variable> variables;
public Scope() {
variables = new HashMap<>();
}
public Variable define(Variable variable) {
variables.put(variable.getIdentifier(), variable);
return variable;
}
public Expression get(String identifier) {
return variables.get(identifier);
}
public boolean has(String identifier) {
return variables.containsKey(identifier);
}
}
}