/** * * 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) */ /* * Limited C# code generation capabilities. Used for ooaObjectInstantiateVisitor to * detect how many objects the system creates. */ using System; using System.Collections.Generic; using System.Text; using TUG.Mogentes.Codegen; namespace TUG.Mogentes.Codegen.CSharp { public sealed class CSharpIdentifier { public static string GetIdentifierString(string anIdentifier) { return String.Format("_{0}", anIdentifier); } } public sealed class CSharpType : OoaTypeVisitor { private OoaCodeEmitter m_emitter = new OoaCodeEmitter(); private string GetIdentifierString(string anIdentifier) { return CSharpIdentifier.GetIdentifierString(anIdentifier); } public override void visit(CharType charType) { m_emitter.Append("int"); // ToDo: map to char? } public override void visit(IntType intType) { m_emitter.Append("int"); } public override void visit(BoolType boolType) { m_emitter.Append("bool"); } public override void visit(FloatType floatType) { m_emitter.Append("double"); } public override void visit(EnumType enumType) { m_emitter.Append(GetIdentifierString(enumType.identifier.tokenText)); } public override void visit(ListType listType) { m_emitter.Append("TUG.Mogentes.Codegen.CSharp.UlyssesList"); //listType.innerType.Accept(this); //m_emitter.Append(">"); } public override void visit(MapType mapType) { //System.Collections.Generic.Dictionary m_emitter.Append("UlyssesDictionary"); //mapType.fromType.Accept(this); //m_emitter.Append(","); //mapType.toType.Accept(this); //m_emitter.Append(">"); } public override void visit(QrType qrType) { m_emitter.Append("UlyssesQualitativeValue"); } public override void visit(TupleType tupleType) { // we map a tuple to a struct m_emitter.Append(GetIdentifierString(tupleType.identifier.tokenText)); } public override void visit(FunctionType functionType) { throw new NotImplementedException(); } public override void visit(OoActionSystemType ooActionSystemType) { m_emitter.Append(GetIdentifierString(ooActionSystemType.identifier.tokenText)); } public override void visit(OpaqueType opaqueType) { throw new NotImplementedException(); } public override string ToString() { return m_emitter.ToString(); } } public sealed class CSharpExpression : OoaExpressionVisitor { private OoaCodeEmitter m_emitter = new OoaCodeEmitter(); private StringBuilder m_helpers; private static List m_constructors = new List(); private string GetCSharpType(UlyssesType aType) { CSharpType sharptype = new CSharpType(); aType.Accept(sharptype); return sharptype.ToString(); } private string GetIdentifierString(string anIdentifier) { return CSharpIdentifier.GetIdentifierString(anIdentifier); } public static List constructors { get { return m_constructors; } } // following calls must not happen public override void visit(UnresolvedIdentifierExpression unresolvedIdentifierExpression) { System.Diagnostics.Debug.Assert(false); } public override void visit(CallExpression callExpression) { System.Diagnostics.Debug.Assert(false); } // we need to map all other things to C# constructs private string OperatorString(Expression expression) { switch (expression.kind) { case ExpressionKind.abs: // T_ABS: case ExpressionKind.card: // T_CARD: case ExpressionKind.dom: // T_DOM: case ExpressionKind.range: // T_RNG: case ExpressionKind.merge: // T_MERGE: case ExpressionKind.len: // T_LEN: case ExpressionKind.elems: // T_ELEMS: case ExpressionKind.head: // T_HEAD: case ExpressionKind.tail: // T_TAIL: case ExpressionKind.conc: // T_CONC: case ExpressionKind.inds: // T_INDS: case ExpressionKind.dinter: // T_DINTER: case ExpressionKind.dunion: // T_DUNION: case ExpressionKind.domresby: // T_DOMRESBY: case ExpressionKind.domresto: // T_DOMRESTO: case ExpressionKind.rngresby: // T_RNGRESBY: case ExpressionKind.rngresto: // T_RNGRESTO: case ExpressionKind.inter: // T_INTER: case ExpressionKind.union: // T_UNION: case ExpressionKind.diff: // T_DIFF: case ExpressionKind.munion: // T_MUNION: case ExpressionKind.seqmod_mapoverride: // T_SEQMOD_MAPOVERRIDE: case ExpressionKind.subset: case ExpressionKind.elemin: case ExpressionKind.notelemin: case ExpressionKind.implies: // T_IMPLIES: case ExpressionKind.biimplies: // T_BIIMPLIES: case ExpressionKind.Primed: throw new NotImplementedException(); case ExpressionKind.div: // T_DIV: return "/"; case ExpressionKind.idiv: // T_IDIV: return "/"; case ExpressionKind.mod: // T_MOD: return "%"; case ExpressionKind.prod: // T_PROD: return "*"; case ExpressionKind.sum: // T_SUM: return "+"; case ExpressionKind.minus: // T_MINUS: return "-"; case ExpressionKind.less: return "<"; case ExpressionKind.lessequal: return "<="; case ExpressionKind.greater: return ">"; case ExpressionKind.greaterequal: return ">="; case ExpressionKind.equal: return "=="; case ExpressionKind.notequal: return "!="; case ExpressionKind.and: // T_AND: return "&&"; case ExpressionKind.or: // T_OR: return "||"; case ExpressionKind.not: return "!"; case ExpressionKind.Cast: CSharpType ctype = new CSharpType(); expression.type.Accept(ctype); return String.Format("({0})", ctype.ToString()); ; default: return Enum.GetName(typeof(ExpressionKind), expression.kind); } } public override void visit(ValueExpression valueExpression) { if (valueExpression.value == null) m_emitter.Append("null"); else if (valueExpression is ValueExpression) m_emitter.Append(valueExpression.value.ToString().ToLower()); else m_emitter.Append(valueExpression.value.ToString()); } public override void visit(IdentifierExpression identifierExpression) { if (identifierExpression.identifier.kind == IdentifierKind.LandmarkIdentifier) { LandmarkIdentifier lmid = (LandmarkIdentifier)identifierExpression.identifier; QrType qr = (QrType)lmid.type; m_emitter.Append(qr.landmarks.IndexOf(lmid)); return; } if (identifierExpression.identifier.kind == IdentifierKind.EnumIdentifier) { m_emitter.Append(GetIdentifierString(((EnumIdentifier)identifierExpression.identifier).type.identifier.tokenText)); m_emitter.Append("."); } m_emitter.Append(GetIdentifierString(identifierExpression.identifier.tokenText)); } public override void visit(TypeExpression typeExpression) { if (typeExpression.type.kind != TypeKind.QrType && typeExpression.type.kind != TypeKind.EnumeratedType) m_emitter.Append(GetIdentifierString(typeExpression.type.identifier.tokenText)); } public override void visit(ObjectConstructor objectConstructor) { int num = m_constructors.Count; m_constructors.Add(objectConstructor); if (objectConstructor.givenObjectName != null) m_emitter.Append(String.Format("new {0}(this,{1},{2})", GetIdentifierString(objectConstructor.type.identifier.tokenText), num, objectConstructor.givenObjectName)); else m_emitter.Append(String.Format("new {0}(this,{1})", GetIdentifierString(objectConstructor.type.identifier.tokenText), num)); } public override void visit(ListConstructor listConstructor) { if (listConstructor.hasComprehension) { // we need a helper for this. string helpername = String.Format("list_constr_helper_{0}", ((uint)listConstructor.GetHashCode()).ToString()); m_emitter.Append(String.Format("{0}(new TUG.Mogentes.Codegen.CSharp.UlyssesList())", helpername)); OoaCodeEmitter helperEmitter = new OoaCodeEmitter(); helperEmitter.AppendLine(String.Format( "public TUG.Mogentes.Codegen.CSharp.UlyssesList {0} (TUG.Mogentes.Codegen.CSharp.UlyssesList newList){{", helpername)); foreach (var sym in listConstructor.comprehensionVariables.symbolList) { CSharpType atype = new CSharpType(); sym.type.Accept(atype); if (sym.type.IsNumeric()) helperEmitter.AppendLine(String.Format("for ({0} {1} = {2}; {1} <= {3}; {1}++) {{", atype.ToString(), CSharpIdentifier.GetIdentifierString(sym.tokenText), UlyssesType.Low(sym.type), UlyssesType.High(sym.type))); else throw new NotImplementedException(); } StringBuilder helperhelper = new StringBuilder(); string guardexpr = "true"; if (listConstructor.comprehension != null) { CSharpExpression expr = new CSharpExpression(helperhelper); listConstructor.comprehension.Accept(expr); guardexpr = expr.ToString(); } CSharpExpression expr2 = new CSharpExpression(helperhelper); listConstructor.elements[0].Accept(expr2); helperEmitter.AppendLine(String.Format("if ({0}) {{", guardexpr)); helperEmitter.AppendLine(String.Format("newList.Add({0});", expr2.ToString())); helperEmitter.AppendLine("}"); foreach (var sym in listConstructor.comprehensionVariables.symbolList) { helperEmitter.AppendLine("}"); } helperEmitter.AppendLineIncIndent("return newList;"); helperEmitter.AppendLine("}"); m_helpers.Append(helperEmitter.ToString()); m_helpers.Append(helperhelper.ToString()); } else { m_emitter.Append("new TUG.Mogentes.Codegen.CSharp.UlyssesList("); int i = 0; if (listConstructor.elements.Count > 0) { m_emitter.Append("new object[] { "); foreach (var x in listConstructor.elements) { if (i != 0) m_emitter.Append(","); else i++; x.Accept(this); } m_emitter.Append(" }"); } m_emitter.Append(")"); } } public override void visit(SetConstructor setConstructor) { throw new NotImplementedException(); } public override void visit(MapConstructor mapConstructor) { throw new NotImplementedException(); } public override void visit(TupleConstructor tupleConstructor) { m_emitter.Append(String.Format("new {0}(", GetIdentifierString(tupleConstructor.tupleType.tokenText))); int i = 0; foreach (var arg in tupleConstructor.values) { if (i != 0) m_emitter.Append(","); else i++; arg.Accept(this); } m_emitter.Append(")"); } public override void visit(QValConstructor qValConstructor) { StringBuilder helpers = new StringBuilder(); string landmarkOne = "null"; if (qValConstructor.value.Length >= 1 && qValConstructor.value[0] != null) { CSharpExpression lndmrk1 = new CSharpExpression(helpers); qValConstructor.value[0].Accept(lndmrk1); landmarkOne = lndmrk1.ToString(); } string landmarkTwo = "null"; if (qValConstructor.value.Length >= 2 && qValConstructor.value[1] != null) { CSharpExpression lndmrk = new CSharpExpression(helpers); qValConstructor.value[1].Accept(lndmrk); landmarkTwo = lndmrk.ToString(); } string derivation = "null"; if (qValConstructor.valueDeriv != QValDeriv.DonTCare) { derivation = Enum.Format(typeof(QValDeriv), qValConstructor.valueDeriv, "d"); } m_helpers.Append(helpers.ToString()); m_emitter.Append(String.Format("new UlyssesQualitativeValue({0},{1},{2})", landmarkOne, landmarkTwo, derivation)); } public override void visit(AccessExpression accessExpression) { if (accessExpression.left.type.kind != TypeKind.QrType && accessExpression.left.type.kind != TypeKind.EnumeratedType) { // enums and qr types are directly (statically) converted to nums... VisitSub(accessExpression.left, accessExpression); m_emitter.Append("."); } VisitSub(accessExpression.right, accessExpression); } public override void visit(BinaryOperator binaryOperator) { m_emitter.Append("("); VisitSub(binaryOperator.left, binaryOperator); m_emitter.Append(") "); m_emitter.Append(OperatorString(binaryOperator)); m_emitter.Append(" ("); VisitSub(binaryOperator.right, binaryOperator); m_emitter.Append(")"); } public override void visit(TernaryOperator ternaryOperator) { m_emitter.Append("("); VisitSub(ternaryOperator.left, ternaryOperator); m_emitter.Append(" ? "); VisitSub(ternaryOperator.mid, ternaryOperator); m_emitter.Append(" : "); VisitSub(ternaryOperator.right, ternaryOperator); m_emitter.Append(")"); } public override void visit(TupleMapAccessExpression tupleMapAccessExpression) { throw new NotImplementedException(); /*VisitSub(tupleMapAccessExpression.argument, tupleMapAccessExpression); VisitSub(tupleMapAccessExpression.child, tupleMapAccessExpression);*/ } public override void visit(ForallQuantifier quantifier) { throw new NotImplementedException(); /*foreach (var lvar in quantifier.symbols.symbolList) VisitSub(lvar, quantifier); VisitSub(quantifier.child, quantifier);*/ } public override void visit(ExistsQuantifier quantifier) { throw new NotImplementedException(); /*foreach (var lvar in quantifier.symbols.symbolList) VisitSub(lvar, quantifier); VisitSub(quantifier.child, quantifier);*/ } public override void visit(UnaryOperator unaryOperator) { m_emitter.Append(" "); m_emitter.Append(OperatorString(unaryOperator)); m_emitter.Append("("); VisitSub(unaryOperator.child, unaryOperator); m_emitter.Append(")"); } public override string ToString() { return m_emitter.ToString(); } public CSharpExpression(StringBuilder helpers) : base() { m_helpers = helpers; } } }