/** * Copyright 2004-2016 Riccardo Solmi. All rights reserved. * This file is part of the Whole Platform. * * The Whole Platform is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * The Whole Platform is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with the Whole Platform. If not, see <http://www.gnu.org/licenses/>. */ package org.whole.lang.semantics.visitors; import org.whole.lang.actions.factories.ActionsEntityFactory; import org.whole.lang.actions.model.ActionCall; import org.whole.lang.actions.reflect.ActionsEntityDescriptorEnum; import org.whole.lang.bindings.BindingManagerFactory; import org.whole.lang.bindings.IBindingManager; import org.whole.lang.iterators.IEntityIterator; import org.whole.lang.matchers.Matcher; import org.whole.lang.model.IEntity; import org.whole.lang.operations.DynamicCompilerOperation; import org.whole.lang.operations.NormalizerOperation; import org.whole.lang.queries.factories.QueriesEntityFactory; import org.whole.lang.resources.FunctionLibraryRegistry; import org.whole.lang.semantics.model.BindingOpEnum; import org.whole.lang.semantics.model.BindingsScope; import org.whole.lang.semantics.model.EntityType; import org.whole.lang.semantics.model.EnvironmentVariable; import org.whole.lang.semantics.model.FunctionApplication; import org.whole.lang.semantics.model.FunctionBody; import org.whole.lang.semantics.model.LanguageType; import org.whole.lang.semantics.model.LocalBinding; import org.whole.lang.semantics.model.Name; import org.whole.lang.semantics.model.SemanticFunction; import org.whole.lang.semantics.model.SemanticTheory; import org.whole.lang.semantics.model.StructuredVariable; import org.whole.lang.semantics.model.TypeCast; import org.whole.lang.semantics.model.Variable; import org.whole.lang.semantics.model.VariableValue; import org.whole.lang.semantics.reflect.SemanticsEntityDescriptorEnum; import org.whole.lang.semantics.util.SemanticsUtils; import org.whole.lang.util.BehaviorUtils; import org.whole.lang.util.BindingUtils; import org.whole.lang.util.EntityUtils; import org.whole.lang.visitors.MissingVariableException; /** * @author Riccardo Solmi */ public class SemanticsInterpreterVisitor extends SemanticsTraverseAllChildrenVisitor { @Override public void setResultIterator(IEntityIterator<?> iterator) { if (iterator != null) iterator.setBindings(getBindings()); super.setResultIterator(iterator); } @Override public void visit(SemanticTheory entity) { SemanticTheory semanticTheory = EntityUtils.clone(entity); IBindingManager bm = getBindings(); bm.wEnterScope(); NormalizerOperation.normalize(semanticTheory, bm); bm.wExitScope(); FunctionLibraryRegistry.instance().addResource(semanticTheory, libraryUri = semanticTheory.getUri().getValue(), false); semanticTheory.getFunctions().accept(this); setResult(BindingManagerFactory.instance.createVoid()); } protected String libraryUri; protected String getLibraryUri(IEntity entity) { if (libraryUri == null) { SemanticTheory st = Matcher.findAncestor(SemanticsEntityDescriptorEnum.SemanticTheory, entity); libraryUri = st != null ? st.getUri().getValue() : getBindings().wStringValue("libraryUri"); } return libraryUri; } @Override public void visit(SemanticFunction entity) { FunctionBody rules = entity.getRules(); if (Matcher.match(SemanticsEntityDescriptorEnum.InferenceRules, rules)) return; FunctionLibraryRegistry.instance().putFunctionModel( getLibraryUri(entity)+"#"+entity.getName().getValue(), entity); IBindingManager bm = getBindings(); if (!bm.wIsSet("LazyInterpretation") || !bm.wBooleanValue("LazyInterpretation")) DynamicCompilerOperation.compile(entity, getBindings()); } @Override public void visit(FunctionApplication entity) { handleCancelRequest(); DynamicCompilerOperation.compile(entity, getBindings()); } @Override public void visit(TypeCast entity) { DynamicCompilerOperation.compile(entity, getBindings()); } @Override public void visit(Name entity) { setResult(entity); } @Override public void visit(EntityType entity) { setResult(BindingManagerFactory.instance.createValue(entity.getValue())); } @Override public void visit(LanguageType entity) { setResult(BindingManagerFactory.instance.createValue(entity.getValue())); } @Override public void visit(StructuredVariable entity) { ActionsEntityFactory aef = ActionsEntityFactory.instance; QueriesEntityFactory qef = QueriesEntityFactory.instance; ActionCall actionCall = aef.createActionCall( aef.createLabel("whole:org.whole.lang.semantics:SemanticsActions:1.0.0#toVariableFlatName"), qef.createVariableRefStep("variable").wGetAdapter(ActionsEntityDescriptorEnum.SelectedEntities)); getBindings().wDef("variable", entity); IEntity varNameEntity = BehaviorUtils.evaluate(actionCall, 0, getOperation()); if (isSelectedFeature(SemanticsUtils.USE_IDENTIFIER_SEMANTICS)) setResult(varNameEntity); else { IEntity varValue = BindingUtils.wGet(getBindings(), varNameEntity.wStringValue()); if (varValue == null) throw new MissingVariableException(entity.toString()).withSourceEntity(entity).withBindings(getBindings()); setResult(varValue); } } @Override public void visit(Variable entity) { if (isSelectedFeature(SemanticsUtils.USE_IDENTIFIER_SEMANTICS)) setResult(entity); else { IEntity varValue = BindingUtils.wGet(getBindings(), entity.getValue()); if (varValue == null) throw new MissingVariableException(entity.toString()).withSourceEntity(entity).withBindings(getBindings()); setResult(varValue); } } @Override public void visit(VariableValue entity) { IEntity oldSematics = setFeature(SemanticsUtils.USE_IDENTIFIER_SEMANTICS, false); try { entity.getIdentifier().accept(this); } finally { setFeature(SemanticsUtils.USE_IDENTIFIER_SEMANTICS, oldSematics); } } @Override public void visit(EnvironmentVariable entity) { IEntity oldSematics = setFeature(SemanticsUtils.USE_IDENTIFIER_SEMANTICS, true); try { entity.getEnvironment().accept(this); IBindingManager bm = getBindings().wGetEnvironmentManager() .getEnvironment(getResult().wStringValue()); entity.getVariable().accept(this); String varName = getResult().wStringValue(); IEntity varValue = bm.wGet(varName); if (varValue == null) throw new MissingVariableException(entity.getVariable().toString()).withSourceEntity(entity).withBindings(getBindings()); setResult(varValue); } finally { setFeature(SemanticsUtils.USE_IDENTIFIER_SEMANTICS, oldSematics); } } @Override public void visit(BindingsScope entity) { IEntity oldSematics = setFeature(SemanticsUtils.USE_IDENTIFIER_SEMANTICS, true); try { entity.getIdentifier().accept(this); IBindingManager bm = getBindings().wGetEnvironmentManager() .getEnvironment(getResult().wStringValue()); for (LocalBinding b : entity.getBindings()) { setFeature(SemanticsUtils.USE_IDENTIFIER_SEMANTICS, true); b.getIdentifier().accept(this); String varName = getResult().wStringValue(); setFeature(SemanticsUtils.USE_IDENTIFIER_SEMANTICS, false); IEntity varValue = BehaviorUtils.evaluate(b.getExpression(), 0, getOperation()); switch (b.getOp().getValue().getOrdinal()) { case BindingOpEnum.UNBIND_ord: bm.wUnset(varName); break; case BindingOpEnum.BIND_ord: bm.wDef(varName, varValue); break; case BindingOpEnum.FRESH_BIND_ord: //TODO bm.wDef(varName, varValue); break; case BindingOpEnum.MATCH_BIND_ord: //TODO bm.wDef(varName, varValue); break; } } setResult(BindingManagerFactory.instance.createValue(bm)); } finally { setFeature(SemanticsUtils.USE_IDENTIFIER_SEMANTICS, oldSematics); } } }