@Override public String visit(ISymbol e) throws IVisitor.VisitorException { // Symbols do not necessarily have sorts - e.g. if they are function names ISort sort = typemap.get(e); if (!isFormula && sort != null && sort.isBool()) { throw new VisitorException( "Use of boolean in a term position is not yet implemented in the Simplify adapter", e.pos()); // FIXME - booleans as terms } // Simplify does not allow tab, newline, cr in identifiers; // these are allowed by SMTLIB. // Note that neither simplify nor SMTLIB allows \ or | // All other printable characters are allowed in both. String oldName = e.value(); String newName = fcnNames.get(oldName); if (newName != null) { // There is a direct translation of a pre-defined SMT-LIB name // into a simplify equivalent - use it. } else { // Use the ? character as an escape newName = oldName.replace("?", "??").replace("\n", "?n").replace("\r", "?r").replace("\t", "?t"); if (reservedWords.contains(newName)) { newName = newName + "?!"; } newName = "|" + newName + "|"; } return newName; }
protected IRExpression compile_impl() { ISymbol symbol = _expr().getSymbol(); ICompilableType gsClass = getGosuClass(); if ((Keyword.KW_this.equals(symbol.getName()) || Keyword.KW_super.equals(symbol.getName())) && // 'this' must be an external symbol when in a program e.g., studio debugger expression (!(gsClass instanceof IGosuProgram) || gsClass.isAnonymous())) { if (_cc().isBlockInvoke() && _cc().currentlyCompilingBlock()) { while (gsClass instanceof IBlockClass) { gsClass = gsClass.getEnclosingType(); } return pushOuter(gsClass); } else { return pushThis(); } } else if (symbol instanceof DynamicPropertySymbol && ((DynamicPropertySymbol) symbol).getGetterDfs() instanceof OuterFunctionSymbol) { // 'outer' return pushOuterForOuterSymbol(); } else { return pushSymbolValue(symbol); } }
@Override public void setChildren(final List<? extends ISymbol> children) { // First we verify the control architecture final IArchitecture control = getArchitecture(); if (control == null) { throw GamaRuntimeException.error( "The control of species " + description.getName() + " cannot be computed"); } // Then we classify the children in their categories for (final ISymbol s : children) { if (s instanceof ISpecies) { final ISpecies oneMicroSpecies = (ISpecies) s; oneMicroSpecies.setMacroSpecies(this); microSpecies.put(oneMicroSpecies.getName(), oneMicroSpecies); } else if (s instanceof IVariable) { variables.put(s.getName(), (IVariable) s); } else if (s instanceof AspectStatement) { aspects.put(s.getName(), (AspectStatement) s); } else if (s instanceof ActionStatement) { if (!s.getDescription().isBuiltIn()) { String name = s.getName(); if (name.equals(initActionName)) { isInitOverriden = true; } else if (name.equals(stepActionName)) { isStepOverriden = true; } } actions.put(s.getName(), (ActionStatement) s); } else if (s instanceof UserCommandStatement) { userCommands.put(s.getName(), (UserCommandStatement) s); } else if (s instanceof IStatement) { behaviors.add((IStatement) s); // reflexes, states or tasks } } control.setChildren(behaviors); control.verifyBehaviors(this); }
public IRExpression pushSymbolValue(ISymbol symbol) { IType type = symbol.getType(); Class symClass; IReducedSymbol reducedSym; if (symbol instanceof ReducedSymbol.SyntheticSymbol) { reducedSym = ((ReducedSymbol.SyntheticSymbol) symbol).getReducedSymbol(); symClass = reducedSym.getSymbolClass(); } else { reducedSym = symbol; symClass = symbol.getClass(); } if (_cc().isExternalSymbol(reducedSym.getName())) { // unbox( symbols.getValue( name ) ) return unboxValueToType( reducedSym.getType(), callMethod( IExternalSymbolMap.class, "getValue", new Class[] {String.class, int.class}, pushExternalSymbolsMap(), Arrays.asList( pushConstant(reducedSym.getName()), pushConstant(getArrayDims(reducedSym))))); } else if (DynamicSymbol.class.isAssignableFrom(symClass)) { // Instance or Static field IRProperty irProp = IRPropertyFactory.createIRProperty(reducedSym); if (!irProp.isStatic()) { if (isMemberOnEnclosingType(reducedSym) != null) { // Instance field from 'outer' return getField_new( irProp, pushOuter(reducedSym.getGosuClass()), getDescriptor(reducedSym.getType())); } else { // Instance field from 'this' return getField_new(irProp, pushThis(), getDescriptor(reducedSym.getType())); } } else { // Static field return getField_new(irProp, null, getDescriptor(reducedSym.getType())); } } else if (CapturedSymbol.class.isAssignableFrom(symClass)) { // Captured symbol is stored as a Field on an anonymous inner class (one elem array of // symbol's type) // e.g., val$myFiield[0] = value. Note a captured symbol is duplicated in all nested classes. IRProperty irProp = IRPropertyFactory.createIRProperty(getGosuClass(), reducedSym); return getField_new(irProp, pushThis(), getDescriptor(reducedSym.getType())); } else if (reducedSym.getIndex() >= 0) { // Local var if (reducedSym.isValueBoxed()) { // Local var is captured in an anonymous inner class. // Symbol's value maintained as a one elem array of symbol's type. return buildArrayLoad( identifier(_cc().getSymbol(reducedSym.getName())), 0, getDescriptor(type)); } else { // Simple local var return identifier(_cc().getSymbol(reducedSym.getName())); } } else if (DynamicPropertySymbol.class.isAssignableFrom(symClass)) { IRProperty irProp; if (reducedSym instanceof DynamicPropertySymbol) { irProp = IRPropertyFactory.createIRProperty((DynamicPropertySymbol) reducedSym); } else { irProp = IRPropertyFactory.createIRProperty((ReducedDynamicPropertySymbol) reducedSym); } IRExpression root; if (irProp.isStatic()) { root = null; } else { ICompilableType targetType = isMemberOnEnclosingType(reducedSym); if (targetType != null) { root = pushOuter(targetType); } else { root = pushThis(); } } IRExpression getterCall = callMethod(irProp.getGetterMethod(), root, Collections.<IRExpression>emptyList()); return castResultingTypeIfNecessary( getDescriptor(reducedSym.getType()), irProp.getType(), getterCall); } else { throw new UnsupportedOperationException( "Don't know how to compile symbol: " + reducedSym.getClass().getSimpleName() + ": " + reducedSym.getName() + ": " + reducedSym.getType()); } }
@Override public String visit(IFcnExpr e) throws IVisitor.VisitorException { boolean resultIsFormula = this.isFormula; StringBuilder sb = new StringBuilder(); try { Iterator<IExpr> iter = e.args().iterator(); if (!iter.hasNext()) throw new VisitorException("Did not expect an empty argument list", e.pos()); if (!(e.head() instanceof ISymbol)) { throw new VisitorException( "Have not yet implemented parameterized bit-vector functions", e.pos()); } ISymbol fcn = (ISymbol) e.head(); String newName = fcn.accept(this); // Determine if the arguments are formulas or terms if (resultIsFormula) { if (newName != null && logicNames.contains(newName)) { // Propositional boolean item this.isFormula = true; } else if (e.args().size() <= 1) { this.isFormula = false; } else { IExpr arg = e.args().get(1); // Use argument 1 for ite's sake ISort sort = typemap.get(arg); if (sort == null) { throw new VisitorException( "INTERNAL ERROR: Encountered an un-sorted expression node: " + smtConfig.defaultPrinter.toString(arg), arg.pos()); } if (sort.isBool()) { // Some functions can take both bool and non-bool arguments: // EQ NEQ DISTINCT ite this.isFormula = resultIsFormula; if ("EQ".equals(newName)) newName = "IFF"; } else { // Arguments must be terms this.isFormula = false; } } } else { this.isFormula = false; } ISort s = typemap.get(e); if (s == null) { throw new VisitorException( "INTERNAL ERROR: Encountered an un-sorted expression node: " + smtConfig.defaultPrinter.toString(e), e.pos()); } if (s.isBool() && !resultIsFormula) { throw new VisitorException( "Use of boolean in a term position is not yet implemented in the Simplify adapter", e.pos()); // FIXME - booleans as terms } if (isFormula && newName.equals("NEQ")) { // for formulas, NEQ is (NOT (IFF p q ...)) // In simplify, IFF is not implicitly chainable int length = e.args().size(); if ((length & 1) == 0) sb.append("(NOT "); sb.append(leftassoc("IFF", length, iter)); if ((length & 1) == 0) sb.append(")"); } else if (newName.equals("IMPLIES")) { // right-associative operators that need grouping if (!iter.hasNext()) { throw new VisitorException("implies (=>) operation without arguments", e.pos()); } sb.append(rightassoc(newName, iter)); } else if (newName.equals("DISTINCT")) { // in simplify, DISTINCT is just for term arguments but the result is a formula if (isFormula) { // arguments are formulas, result is formula if (e.args().size() > 2) { // More than two distinct boolean values? sb.append("FALSE"); } else { sb.append("(NOT (IFF"); while (iter.hasNext()) { sb.append(" "); sb.append(iter.next().accept(this)); } sb.append(" ))"); } } else if (resultIsFormula) { // arguments are terms, result is formula - standard use in Simplify sb.append("(DISTINCT"); while (iter.hasNext()) { sb.append(" "); sb.append(iter.next().accept(this)); } sb.append(")"); } else { // used in a term position throw new VisitorException( "Use of DISTINCT in a term position is not yet implemented in the Simplify adapter", e.pos()); // FIXME - distinact as a term } } else if (ite_term.equals(newName)) { if (isFormula) { sb.append("(AND (IMPLIES "); sb.append(e.args().get(0).accept(this)); sb.append(" "); sb.append(e.args().get(1).accept(this)); sb.append(")"); sb.append("(IMPLIES (NOT "); sb.append(e.args().get(0).accept(this)); sb.append(") "); sb.append(e.args().get(2).accept(this)); sb.append("))"); } } if (e.args().size() > 2 && nonchainables.contains(newName)) { Iterator<IExpr> iter2 = e.args().iterator(); sb.append("(AND "); IExpr left = iter2.next(); while (iter2.hasNext()) { IExpr right = iter2.next(); sb.append("(" + newName + " "); sb.append(left.accept(this)); sb.append(" "); sb.append(right.accept(this)); sb.append(")"); left = right; } sb.append(")"); } if (e.args().size() > 2 && (newName.equals("-") || newName.equals("/"))) { Iterator<IExpr> iter2 = e.args().iterator(); sb.append(leftassoc(newName, e.args().size(), iter2)); } if (sb.length() == 0) { sb.append("( "); sb.append(newName); while (iter.hasNext()) { sb.append(" "); sb.append(iter.next().accept(this)); } sb.append(" )"); } } finally { this.isFormula = resultIsFormula; } return sb.toString(); }