/** * * OOAS Compiler (Deprecated) * * Copyright 2015, Institute for Software Technology, Graz University of * Technology. Portions are copyright 2015 by the AIT Austrian Institute * of Technology. All rights reserved. * * SEE THE "LICENSE" FILE FOR THE TERMS UNDER WHICH THIS FILE IS PROVIDED. * * Please notice that this version of the OOAS compiler is considered de- * precated. Only the Java version is maintained. * * Contributors: * Willibald Krenn (TU Graz/AIT) * Stefan Tiran (TU Graz/AIT) */ /* * Prolog Code Generator */ using System; using System.Collections.Generic; using System.Text; using TUG.Mogentes.Codegen; namespace TUG.Mogentes.Codegen.Prolog { public class OoaPrologStatement : OoaStatementVisitor { public class Factory { public virtual OoaPrologStatement create( OoaPrologExpression.Factory exprFactory, OoaPrologIdentifier.Factory idFactory, OoaPrologType.Factory typeFactory) { return new OoaPrologStatement(exprFactory, idFactory, typeFactory); } } protected OoaCodeEmitter m_emitter = new OoaCodeEmitter(); public override void visit(NondetBlock nondetBlock) { int y = 0; foreach (var x in nondetBlock.statements) { if (y != 0) m_emitter.Append("; "); else y++; m_emitter.Append("("); VisitSub(x, nondetBlock); m_emitter.Append(")"); } } public override void visit(SeqBlock seqBlock) { int y = 0; if (seqBlock.symbols.symbolList.Count > 0) { m_emitter.Append("(["); foreach (var sym in seqBlock.symbols.symbolList) { if (y != 0) m_emitter.AppendLine(", "); else y++; OoaPrologType atype = createTypeVisitor(); sym.type.Accept(atype); OoaPrologIdentifier anIdent = createIdentifierVisitor(); sym.Accept(anIdent); m_emitter.Append(String.Format("{0}:{1}", anIdent.ToString(), atype.ToString())); } m_emitter.Append("]: "); } y = 0; foreach (var x in seqBlock.statements) { if (y != 0) m_emitter.AppendLine(", "); else y++; m_emitter.Append("("); VisitSub(x, seqBlock); m_emitter.Append(")"); } if (seqBlock.symbols.symbolList.Count > 0) m_emitter.Append(")"); } public override void visit(PrioBlock prioBlock) { int y = 0; foreach (var x in prioBlock.statements) { if (y != 0) m_emitter.Append("// "); else y++; m_emitter.Append("("); VisitSub(x, prioBlock); m_emitter.Append(")"); } } public override void visit(GuardedCommand guardedCommand) { OoaPrologExpression expr = createExpressionVisitor(); guardedCommand.guard.Accept(expr); m_emitter.AppendLineIncIndent(String.Format("({0}{2}) {1} ", expr.ToString(), guardedCommand.isQualitative ? "~>" : "=>", expr.tmpVariables[0])); m_emitter.AppendLineIncIndent("("); VisitSub(guardedCommand.body, guardedCommand); m_emitter.DecIndent(); m_emitter.AppendLine(""); m_emitter.Append(")"); } public override void visit(Assignment assignment) { if (assignment.nondetExpression != null) throw new NotImplementedException(); LinkedListNode aPlace = assignment.places.First; LinkedListNode aValue = assignment.values.First; List assignments = new List(); while (aPlace != null) { OoaPrologExpression prologPlace = createExpressionVisitor(true); aPlace.Value.Accept(prologPlace); System.Diagnostics.Debug.Assert(prologPlace.tmpVariables.Count == 1); OoaPrologExpression prologValue = createExpressionVisitor(); aValue.Value.Accept(prologValue); System.Diagnostics.Debug.Assert(prologValue.tmpVariables.Count == 1); m_emitter.Append(prologValue.ToString()); if (aPlace.Value.kind == ExpressionKind.Access && ((AccessExpression)aPlace.Value).right.kind == ExpressionKind.Identifier && ((IdentifierExpression)((AccessExpression)aPlace.Value).right).identifier.kind == IdentifierKind.AttributeIdentifier) { //access to attribute is always 'self.XY'... assignments.Add(String.Format("{0} := {1}", prologPlace.tmpVariables[0], prologValue.tmpVariables[0])); } else if (prologPlace.tmpVariables[0] == "RESULT") assignments.Add(String.Format("unify( RESULT = {0})", prologValue.tmpVariables[0])); else if (aPlace.Value.type.kind == TypeKind.IntType) assignments.Add(String.Format("{0} #= {1}", prologPlace.tmpVariables[0], prologValue.tmpVariables[0])); else assignments.Add(String.Format("{0} = {1}", prologPlace.tmpVariables[0], prologValue.tmpVariables[0])); if (prologPlace.ToString().Length > 0) { string place = prologPlace.ToString(); place = place.Trim(); if (place.EndsWith(",")) place = place.Substring(0, place.Length - 1); assignments.Add(place); } aPlace = aPlace.Next; aValue = aValue.Next; } int pos = 0; foreach (var s in assignments) { if (pos != 0) m_emitter.Append(","); pos++; m_emitter.Append(s); } } public override void visit(Call call) { Expression ce = call.callExpression; string callstatement = String.Empty; StringBuilder parameter = new StringBuilder(); bool hideCall = false; if (ce.kind == ExpressionKind.Identifier) callstatement = ((IdentifierExpression)ce).identifier.tokenText; else if (ce.kind == ExpressionKind.Call) { CallExpression parens = (CallExpression)ce; OoaPrologExpression prologexpr = createExpressionVisitor(); parens.child.Accept(prologexpr); if (parens.child.kind == ExpressionKind.Identifier && ((IdentifierExpression)parens.child).identifier.kind == IdentifierKind.NamedActionIdentifier) { // we need to hide internal actions NamedActionIdentifier namedactionid = (NamedActionIdentifier)((IdentifierExpression)parens.child).identifier; hideCall = ((FunctionType)namedactionid.type).functionType == FunctionTypeEnum.Internal; } m_emitter.Append(prologexpr.ToString()); callstatement = prologexpr.tmpVariables[0]; int i = 0; foreach (var arg in parens.arguments) { if (i != 0) parameter.Append(", "); else i++; OoaPrologExpression paramexpr = createExpressionVisitor(); arg.Accept(paramexpr); m_emitter.Append(paramexpr.ToString()); parameter.Append(paramexpr.tmpVariables[0]); } } else throw new NotImplementedException(); if (hideCall) m_emitter.Append("i("); if (parameter.Length > 0) m_emitter.AppendLine(String.Format("{0}({1})", callstatement, parameter)); else m_emitter.AppendLine(String.Format("{0}", callstatement, parameter)); if (hideCall) m_emitter.Append(")"); } public override void visit(SkipStatement skipStatement) { m_emitter.Append("skip"); } public override void visit(AbortStatement abortStatement) { throw new NotImplementedException(); } public override void visit(KillStatement killStatement) { throw new NotImplementedException(); } public override void visit(QualitativeConstraintStatement qalitativeConstraintStatement) { if (qalitativeConstraintStatement.tag) { m_emitter.Append("% observable assignment in actionhead"); return; } OoaPrologIdentifier id1 = createIdentifierVisitor(); OoaPrologIdentifier id2 = createIdentifierVisitor(); OoaPrologIdentifier id3 = createIdentifierVisitor(); switch (qalitativeConstraintStatement.operation) { case QualitativeConstraintOperation.Deriv: qalitativeConstraintStatement.variable0.Accept(id1); qalitativeConstraintStatement.variable1.Accept(id2); m_emitter.Append(String.Format("{0} := dt {1}", id1.ToString(), id2.ToString())); break; case QualitativeConstraintOperation.Diff: qalitativeConstraintStatement.variable0.Accept(id1); qalitativeConstraintStatement.variable1.Accept(id2); qalitativeConstraintStatement.variable2.Accept(id3); m_emitter.Append(String.Format("{0} := {1} - {2}", id1.ToString(), id2.ToString(), id3.ToString())); break; case QualitativeConstraintOperation.Equal: qalitativeConstraintStatement.variable0.Accept(id1); qalitativeConstraintStatement.variable1.Accept(id2); m_emitter.Append(String.Format("{0} := {1}", id1.ToString(), id2.ToString())); break; case QualitativeConstraintOperation.Prod: qalitativeConstraintStatement.variable0.Accept(id1); qalitativeConstraintStatement.variable1.Accept(id2); qalitativeConstraintStatement.variable2.Accept(id3); m_emitter.Append(String.Format("{0} := {1} * {2}", id1.ToString(), id2.ToString(), id3.ToString())); break; case QualitativeConstraintOperation.Sum: qalitativeConstraintStatement.variable0.Accept(id1); qalitativeConstraintStatement.variable1.Accept(id2); qalitativeConstraintStatement.variable2.Accept(id3); m_emitter.Append(String.Format("{0} := {1} + {2}", id1.ToString(), id2.ToString(), id3.ToString())); break; default: throw new NotImplementedException(); } } public override string ToString() { return m_emitter.ToString(); } protected OoaPrologExpression createExpressionVisitor() { return m_exprFactory.create(m_idFactory, m_typeFactory); } protected OoaPrologExpression createExpressionVisitor(bool lhs) { return m_exprFactory.create(m_idFactory, m_typeFactory, lhs); } protected OoaPrologIdentifier createIdentifierVisitor() { return m_idFactory.create(); } protected OoaPrologType createTypeVisitor() { return m_typeFactory.create(m_idFactory); } private readonly OoaPrologExpression.Factory m_exprFactory; private readonly OoaPrologIdentifier.Factory m_idFactory; private readonly OoaPrologType.Factory m_typeFactory; protected OoaPrologStatement( OoaPrologExpression.Factory exprFactory, OoaPrologIdentifier.Factory idFactory, OoaPrologType.Factory typeFactory) : base() { m_exprFactory = exprFactory; m_idFactory = idFactory; m_typeFactory = typeFactory; } } }