/** * * 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) */ /* * ooaPrintVisitor * * Prints AST in some sort of OOA - Syntax. */ using System; using System.Collections.Generic; using System.Text; using TUG.Mogentes.Codegen; namespace TUG.Mogentes { public delegate void Action(); public sealed class OoaPrintVisitor : OoaCompleteAstTraversalVisitor { private bool writeTypes; private Identifier currentTypeDef; private OoaCodeEmitter output; private void PrintSubElementOrNull(IAst anElem) { if (anElem == null) output.Append(""); else anElem.Accept(this); } private void PrintEnumeration(System.Collections.IEnumerable arg) { int i = 0; foreach (IAst sym in arg) { if (i != 0) output.Append(", "); i++; PrintSubElementOrNull(sym); } } /*print the type identifier, or the type definition by calling the anAction delegate.*/ private void PrintType(UlyssesType atype, Action anAction) { if ( (atype.identifier != null) && (!atype.isAnonymousType) && (!ReferenceEquals(currentTypeDef, atype.identifier) || !writeTypes)) { bool write = writeTypes; writeTypes = false; atype.identifier.Accept(this); writeTypes = write; } else anAction(); } public override void visit(MainModule mainModule) { int i = 0; bool haveInstance = mainModule.instance != null; /*print all types*/ writeTypes = true; output.IncIndent(); output.AppendLine("types"); foreach (var type in mainModule.symbolTable.symbolList) { if (type.kind != IdentifierKind.TypeIdentifier) continue; if (i != 0) output.AppendLine(";"); i++; if (!haveInstance || ((TypeIdentifier)type).type.kind != TypeKind.OoActionSystemType) type.Accept(this); } if (haveInstance) mainModule.instance.Accept(this); output.DecIndent(); output.AppendLine(""); output.IncIndent(); output.IncIndent(); output.AppendLine("system"); writeTypes = false; if (!haveInstance) mainModule.systemDescription.Accept(this); else output.Append(mainModule.instance.identifier.tokenText); } public override void visit(TypeIdentifier typeIdentifier) { output.Append(typeIdentifier.tokenText); if (writeTypes) { currentTypeDef = typeIdentifier; output.Append(" = "); PrintSubElementOrNull(typeIdentifier.type); } } /*write out type definitions*/ public override void visit(BoolType boolType) { output.Append("bool"); } public override void visit(CharType charType) { output.Append("char"); } public override void visit(IntType intType) { PrintType(intType, () => { output.Append("int ["); output.Append(intType.rangeLow.ToString()); output.Append(" .. "); output.Append(intType.rangeHigh.ToString()); output.Append("]"); }); } public override void visit(FloatType floatType) { PrintType(floatType, () => { output.Append("float ["); output.Append(floatType.low.ToString()); output.Append(" .. "); output.Append(floatType.high.ToString()); output.Append("] /*"); output.Append(floatType.precision.ToString()); output.Append("*/"); }); } public override void visit(EnumIdentifier enumIdentifier) { output.Append(enumIdentifier.tokenText); if (enumIdentifier.HaveValue) output.Append(String.Format(" = {0}", enumIdentifier.Value)); } public override void visit(EnumType enumType) { PrintType(enumType, () => { output.Append("{"); PrintEnumeration(enumType.listOfEnumSymbols); output.Append("}"); }); } public override void visit(ListType listType) { PrintType(listType, () => { output.Append("list ["); output.Append(listType.maxNumberOfElements.ToString()); output.Append("] of "); PrintSubElementOrNull(listType.innerType); }); } public override void visit(MapType mapType) { PrintType(mapType, () => { output.Append("map ["); output.Append(mapType.maxNumberOfElements.ToString()); output.Append("] "); PrintSubElementOrNull(mapType.fromType); output.Append(" to "); PrintSubElementOrNull(mapType.toType); }); } public override void visit(TupleType tupleType) { PrintType(tupleType, () => { output.Append("("); PrintEnumeration(tupleType.innerTypes); output.Append(")"); }); } public override void visit(OpaqueType opaqueType) { PrintSubElementOrNull(opaqueType.resolvedType); output.Append(" /*opagque*/"); } public override void visit(QrType qrType) { PrintType(qrType, () => { output.Append("qspace of ["); PrintEnumeration(qrType.landmarks); output.Append("]"); }); } public override void visit(LandmarkIdentifier landmarkIdentifier) { output.Append(landmarkIdentifier.tokenText); } public override void visit(OoActionSystemType ooActionSystemType) { PrintType(ooActionSystemType, () => { if (ooActionSystemType.autoConstruction) output.Append("autocons "); output.Append("system "); if (ooActionSystemType.baseType != null) output.Append(String.Format("({0})", ooActionSystemType.baseType.identifier.tokenText)); output.AppendLine(""); output.IncIndent(); output.AppendLine("|["); // get a list of interesting symbols List attrs = new List(); List methods = new List(); List namedActions = new List(); foreach (var sym in ooActionSystemType.symbols.symbolList) { if (sym.kind == IdentifierKind.AttributeIdentifier) attrs.Add((AttributeIdentifier)sym); else if (sym.kind == IdentifierKind.MethodIdentifier) methods.Add((MethodIdentifier)sym); else if (sym.kind == IdentifierKind.NamedActionIdentifier) namedActions.Add((NamedActionIdentifier)sym); } int i = 0; if (attrs.Count > 0) { // variables output.IncIndent(); output.AppendLine("var"); foreach (var attr in attrs) { if (i != 0) output.AppendLine(";"); i++; PrintSubElementOrNull(attr); } output.DecIndent(); output.AppendLine(""); } bool writeTypesSave = writeTypes; writeTypes = false; i = 0; if (methods.Count > 0) { output.IncIndent(); output.AppendLine("methods"); foreach (var method in methods) { if (i != 0) output.AppendLine(";"); i++; PrintSubElementOrNull(method); } output.DecIndent(); output.AppendLine(""); } i = 0; if (namedActions.Count > 0) { output.IncIndent(); output.AppendLine("actions"); foreach (var action in namedActions) { if (i != 0) output.AppendLine(";"); i++; PrintSubElementOrNull(action); } output.DecIndent(); output.AppendLine(""); } if ((ooActionSystemType.doOdBlock != null) && (ooActionSystemType.doOdBlock.statements.Count > 0)) { output.IncIndent(); output.AppendLine("do"); PrintSubElementOrNull(ooActionSystemType.doOdBlock); output.DecIndent(); output.AppendLine(""); output.AppendLine("od"); } output.DecIndent(); output.AppendLine(""); output.Append("]|"); writeTypes = writeTypesSave; }); } public override void visit(NullType nullType) { output.Append("nil"); } public override void visit(AttributeIdentifier attributeIdentifier) { if (attributeIdentifier.isStatic) output.Append("static "); if (attributeIdentifier.isObservable) output.Append("obs "); if (attributeIdentifier.isControllable) output.Append("ctr "); output.Append(attributeIdentifier.tokenText); if (writeTypes) { output.Append(": "); PrintSubElementOrNull(attributeIdentifier.type); output.Append(" = "); PrintSubElementOrNull(attributeIdentifier.initializer); } } public override void visit(ValueExpression valueExpression) { if (valueExpression.value != null) output.Append(valueExpression.value.ToString()); else output.Append("nil"); } public override void visit(AbortStatement abortStatement) { output.Append("abort"); } public override void visit(Assignment assignment) { PrintEnumeration(assignment.places); output.Append(" := "); PrintEnumeration(assignment.values); if (assignment.nondetExpression != null) { output.IncIndent(); output.AppendLine(""); output.Append("with "); assignment.nondetExpression.Accept(this); if (assignment.symbols.symbolList.Count > 0) { output.Append(" /* vars: "); foreach (var localVar in assignment.symbols.symbolList) { localVar.Accept(this); output.Append(" "); } output.Append("*/"); } output.DecIndent(); output.AppendLine(""); } } public override void visit(KillStatement killStatement) { output.Append("kill ("); PrintSubElementOrNull(killStatement.someOne); output.Append(")"); } public override void visit(AccessExpression accessExpression) { if (accessExpression.right != null) { output.Append("("); PrintSubElementOrNull(accessExpression.left); output.Append(")."); PrintSubElementOrNull(accessExpression.right); } else { output.Append("("); PrintSubElementOrNull(accessExpression.left); output.Append(")"); } } private void PrintOperator(Expression expression) { switch (expression.kind) { case ExpressionKind.abs: // T_ABS: output.Append("abs"); break; case ExpressionKind.card: // T_CARD: output.Append("card"); break; case ExpressionKind.dom: // T_DOM: output.Append("dom"); break; case ExpressionKind.range: // T_RNG: output.Append("range"); break; case ExpressionKind.merge: // T_MERGE: output.Append("merge"); break; case ExpressionKind.len: // T_LEN: output.Append("len"); break; case ExpressionKind.elems: // T_ELEMS: output.Append("elems"); break; case ExpressionKind.head: // T_HEAD: output.Append("head"); break; case ExpressionKind.tail: // T_TAIL: output.Append("tail"); break; case ExpressionKind.conc: // T_CONC: output.Append("conc"); break; case ExpressionKind.inds: // T_INDS: output.Append("inds"); break; case ExpressionKind.dinter: // T_DINTER: output.Append("dinter"); break; case ExpressionKind.dunion: // T_DUNION: output.Append("dunion"); break; case ExpressionKind.domresby: // T_DOMRESBY: output.Append("domresby"); break; case ExpressionKind.domresto: // T_DOMRESTO: output.Append("domresto"); break; case ExpressionKind.rngresby: // T_RNGRESBY: output.Append("rngresby"); break; case ExpressionKind.rngresto: // T_RNGRESTO: output.Append("rngresto"); break; case ExpressionKind.div: // T_DIV: output.Append("div"); break; case ExpressionKind.idiv: // T_IDIV: output.Append("idiv"); break; case ExpressionKind.mod: // T_MOD: output.Append("mod"); break; case ExpressionKind.prod: // T_PROD: output.Append("*"); break; case ExpressionKind.inter: // T_INTER: output.Append("inter"); break; case ExpressionKind.sum: // T_SUM: output.Append("+"); break; case ExpressionKind.minus: // T_MINUS: output.Append("-"); break; case ExpressionKind.union: // T_UNION: output.Append("union"); break; case ExpressionKind.diff: // T_DIFF: output.Append("diff"); break; case ExpressionKind.munion: // T_MUNION: output.Append("munion"); break; case ExpressionKind.seqmod_mapoverride: // T_SEQMOD_MAPOVERRIDE: output.Append("seqmod_mapoverride"); break; case ExpressionKind.less: output.Append("<"); break; case ExpressionKind.lessequal: output.Append("<="); break; case ExpressionKind.greater: output.Append(">"); break; case ExpressionKind.greaterequal: output.Append(">="); break; case ExpressionKind.equal: output.Append("="); break; case ExpressionKind.notequal: output.Append("<>"); break; case ExpressionKind.subset: output.Append("subset"); break; case ExpressionKind.elemin: output.Append("in"); break; case ExpressionKind.notelemin: output.Append("not in"); break; case ExpressionKind.and: // T_AND: output.Append("and"); break; case ExpressionKind.or: // T_OR: output.Append("or"); break; case ExpressionKind.implies: // T_IMPLIES: output.Append("=>"); break; case ExpressionKind.biimplies: // T_BIIMPLIES: output.Append("<=>"); break; case ExpressionKind.Primed: output.Append("'"); break; case ExpressionKind.Cast: output.Append("("); if (expression.type != null) output.Append(expression.type.ToString()); else output.Append("Cast??"); output.Append(")"); break; default: output.Append(Enum.GetName(typeof(ExpressionKind), expression.kind)); break; } } public override void visit(TypeExpression typeExpression) { PrintSubElementOrNull(typeExpression.type); } public override void visit(BinaryOperator binaryOperator) { output.IncIndent(); output.AppendLine("("); PrintSubElementOrNull(binaryOperator.left); output.DecIndent(); output.AppendLine(""); output.AppendLine(")"); PrintOperator(binaryOperator); output.AppendLine(""); output.IncIndent(); output.AppendLine("("); PrintSubElementOrNull(binaryOperator.right); output.DecIndent(); output.AppendLine(""); output.AppendLine(")"); } public override void visit(UnaryOperator unaryOperator) { PrintOperator(unaryOperator); output.Append("("); PrintSubElementOrNull(unaryOperator.child); output.Append(")"); } public override void visit(UnresolvedIdentifierExpression unresolvedIdentifierExpression) { output.Append(unresolvedIdentifierExpression.tokenText); } public override void visit(CallExpression callExpression) { if (callExpression.child != null) callExpression.child.Accept(this); if ((callExpression.arguments != null) && (callExpression.arguments.Count > 0)) { output.Append("("); PrintEnumeration(callExpression.arguments); output.Append(")"); } else { output.Append("()"); } } public override void visit(TupleMapAccessExpression tupleMapAccessExpression) { if (tupleMapAccessExpression.child != null) tupleMapAccessExpression.child.Accept(this); output.Append("["); PrintSubElementOrNull(tupleMapAccessExpression.argument); output.Append("]"); } public override void visit(TupleConstructor tupleConstructor) { output.Append(tupleConstructor.tupleType.tokenText); output.Append("("); PrintEnumeration(tupleConstructor.values); output.Append(")"); } public override void visit(ListConstructor listConstructor) { output.Append("["); PrintEnumeration(listConstructor.elements); if (listConstructor.hasComprehension) { output.Append("| var "); int i = 0; foreach (var element in listConstructor.comprehensionVariables.symbolList) { if (i != 0) output.Append("; "); i++; PrintSubElementOrNull(element); } output.AppendLine(" &"); PrintSubElementOrNull(listConstructor.comprehension); } output.Append("]"); } public override void visit(QValConstructor qValConstructor) { output.Append("qval("); PrintSubElementOrNull(qValConstructor.value[0]); if (qValConstructor.value.Length == 2) { output.Append(" .. "); PrintSubElementOrNull(qValConstructor.value[1]); } output.Append(","); output.Append(qValConstructor.valueDeriv.ToString()); output.Append(")"); } private bool make_parens = false; public override void visit(NondetBlock nondetBlock) { int i = 0; if (make_parens) { output.IncIndent(); output.AppendLine("("); } foreach (var smt in nondetBlock.statements) { if (i != 0) { output.DecIndent(); output.AppendLine(""); output.IncIndent(); output.AppendLine("[] "); } i++; smt.Accept(this); } if (make_parens) { output.DecIndent(); output.AppendLine(""); output.AppendLine(")"); } } public override void visit(PrioBlock prioBlock) { int i = 0; if (make_parens) { output.IncIndent(); output.AppendLine("("); } foreach (var smt in prioBlock.statements) { if (i != 0) { output.DecIndent(); output.AppendLine(""); output.IncIndent(); output.AppendLine("// "); } i++; smt.Accept(this); } if (make_parens) { output.DecIndent(); output.AppendLine(""); output.AppendLine(")"); } } public override void visit(SeqBlock seqBlock) { int i = 0; bool old_makeparens = make_parens; output.IncIndent(); output.AppendLine("("); if (seqBlock.symbols.symbolList.Count > 0) { output.Append("var "); foreach (var id in seqBlock.symbols.symbolList) { output.Append(id.tokenText); output.Append(": "); PrintSubElementOrNull(id); } output.Append(": "); } foreach (var smt in seqBlock.statements) { if (smt == null) continue; if (i != 0) { output.DecIndent(); output.AppendLine(""); output.IncIndent(); output.AppendLine("; "); } i++; make_parens = true; smt.Accept(this); make_parens = old_makeparens; } output.DecIndent(); output.AppendLine(""); output.AppendLine(")"); } public override void visit(Call call) { call.callExpression.Accept(this); } public override void visit(GuardedCommand guardedCommand) { output.Append("requires "); PrintSubElementOrNull(guardedCommand.guard); output.IncIndent(); output.AppendLine(" :"); guardedCommand.body.Accept(this); output.DecIndent(); output.AppendLine(""); output.AppendLine("end"); } public override void visit(IdentifierExpression identifierExpression) { output.Append(identifierExpression.identifier.tokenText); } public override void visit(NondetIdentifierList nondetIdentifierList) { int i = 0; foreach (var smt in nondetIdentifierList.identifiers) { if (i != 0) { output.DecIndent(); output.AppendLine(""); output.IncIndent(); output.AppendLine("[] "); } i++; smt.Accept(this); } } public override void visit(PrioIdentifierList prioIdentifierList) { int i = 0; foreach (var smt in prioIdentifierList.identifiers) { if (i != 0) { output.DecIndent(); output.AppendLine(""); output.IncIndent(); output.AppendLine("//"); } i++; smt.Accept(this); } } public override void visit(SeqIdentifierList seqIdentifierList) { int i = 0; output.IncIndent(); output.AppendLine("("); foreach (var smt in seqIdentifierList.identifiers) { if (i != 0) { output.AppendLine("; "); } i++; smt.Accept(this); } output.DecIndent(); output.AppendLine(""); output.AppendLine(")"); } public override void visit(SkipStatement skipStatement) { output.Append("skip"); } public override void visit(TernaryOperator ternaryOperator) { if (ternaryOperator.kind == ExpressionKind.conditional) { output.Append("if"); PrintSubElementOrNull(ternaryOperator.left); output.IncIndent(); output.AppendLine("then"); PrintSubElementOrNull(ternaryOperator.mid); output.DecIndent(); output.AppendLine(""); output.IncIndent(); output.AppendLine("else"); PrintSubElementOrNull(ternaryOperator.right); output.DecIndent(); output.AppendLine(""); output.Append("end"); } else if (ternaryOperator.kind == ExpressionKind.foldLR || ternaryOperator.kind == ExpressionKind.foldRL) { PrintSubElementOrNull(ternaryOperator.left); if (ternaryOperator.mid != null) { output.Append(" :: ("); PrintSubElementOrNull(ternaryOperator.mid); output.Append(")"); } if (ternaryOperator.kind == ExpressionKind.foldLR) output.Append(" :>: ("); else output.Append(" :<: ("); PrintSubElementOrNull(ternaryOperator.right); output.Append(")"); } else throw new NotImplementedException(); } public override void visit(MethodIdentifier methodIdentifier) { if (((FunctionType)methodIdentifier.type).isMiracleSafe ?? false) output.Append("/*BASIC*/ "); FunctionType atype = (FunctionType)methodIdentifier.type; output.Append(methodIdentifier.tokenText); output.Append("("); int j = 0; foreach (var x in methodIdentifier.parameter) { if (j != 0) output.Append(", "); else j++; output.Append(x.tokenText); output.Append(": "); PrintSubElementOrNull(x.type); } output.Append(")"); if (atype.returnType != null) { output.Append(": "); PrintSubElementOrNull(atype.returnType); } output.AppendLine(""); output.IncIndent(); output.AppendLine("var"); int i = 0; foreach (var sym in methodIdentifier.symbolTable.symbolList) { if (i != 0) output.AppendLine(";"); i++; output.Append(sym.tokenText); output.Append(": "); PrintSubElementOrNull(sym.type); } output.DecIndent(); output.AppendLine(""); PrintSubElementOrNull(methodIdentifier.body); output.Append("end"); } public override void visit(NamedActionIdentifier namedActionIdentifier) { if (((FunctionType)namedActionIdentifier.type).isMiracleSafe ?? false) output.Append("/*BASIC*/ "); output.Append(namedActionIdentifier.tokenText); output.Append("("); FunctionType atype = (FunctionType)namedActionIdentifier.type; PrintEnumeration(atype.parameter); output.Append(")"); output.AppendLine(""); output.IncIndent(); output.AppendLine("var"); int i = 0; foreach (var sym in namedActionIdentifier.symbolTable.symbolList) { if (i != 0) output.AppendLine(";"); i++; output.Append(sym.tokenText); output.Append(": "); PrintSubElementOrNull(sym.type); } output.DecIndent(); output.AppendLine(""); PrintSubElementOrNull(namedActionIdentifier.body); output.Append("end"); } public override void visit(MapConstructor mapConstructor) { output.Append("{"); int i = 0; foreach (var x in mapConstructor.items) { if (i != 0) output.Append(", "); i++; PrintSubElementOrNull(x.key); output.Append(" -> "); PrintSubElementOrNull(x.value); } output.Append("}"); } public override void visit(SetConstructor setConstructor) { output.Append("["); PrintEnumeration(setConstructor.items); if (setConstructor.hasComprehension) { output.Append("| var "); int i = 0; foreach (var elem in setConstructor.comprehensionVariables.symbolList) { if (i != 0) output.Append("; "); i++; PrintSubElementOrNull(elem); } output.AppendLine(" &"); PrintSubElementOrNull(setConstructor.comprehension); } output.Append("]"); } public override void visit(ExpressionVariableIdentifier expressionVariableIdentifier) { output.Append(expressionVariableIdentifier.tokenText); output.Append(": "); PrintSubElementOrNull(expressionVariableIdentifier.type); } public override void visit(ObjectConstructor objectConstructor) { output.Append("new ("); PrintSubElementOrNull(objectConstructor.type); output.Append(")"); } public override string ToString() { return output.ToString(); } public OoaPrintVisitor(ParserState aState) : base(aState) { writeTypes = true; output = new OoaCodeEmitter(); } } }