Revision 3
Added by Willibald K. almost 10 years ago
branches/compiler/cSharp/ooasCompiler/src/codegen/ooaCodeEmitter.cs | ||
---|---|---|
/**
|
||
*
|
||
* 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)
|
||
*/
|
||
|
||
using System;
|
||
using System.Collections.Generic;
|
||
using System.Text;
|
||
|
||
namespace TUG.Mogentes.Codegen
|
||
{
|
||
/// <summary>
|
||
/// Class that is used as text buffer during code emission
|
||
/// </summary>
|
||
public class OoaCodeEmitter
|
||
{
|
||
private StringBuilder output;
|
||
private int indentLevel;
|
||
private int indentTabWidth;
|
||
|
||
|
||
public OoaCodeEmitter()
|
||
{
|
||
indentLevel = 0;
|
||
indentTabWidth = 4;
|
||
output = new StringBuilder();
|
||
}
|
||
|
||
public void Indent()
|
||
{
|
||
for (int i = 0; i < indentLevel * indentTabWidth; i++)
|
||
output.Append(" ");
|
||
}
|
||
|
||
public void Append(int num)
|
||
{
|
||
output.Append(num);
|
||
}
|
||
|
||
public void Append(string text)
|
||
{
|
||
output.Append(text);
|
||
}
|
||
|
||
public void AppendLineIncIndent(string text)
|
||
{
|
||
indentLevel++;
|
||
this.AppendLine(text);
|
||
}
|
||
|
||
public void AppendLineDecIndent(string text)
|
||
{
|
||
if (indentLevel > 0)
|
||
{
|
||
indentLevel--;
|
||
output.Remove(output.Length - indentTabWidth, indentTabWidth);
|
||
}
|
||
this.AppendLine(text);
|
||
}
|
||
|
||
|
||
public void AppendLine(string text)
|
||
{
|
||
output.AppendLine(text);
|
||
Indent();
|
||
}
|
||
|
||
public void AppendLine()
|
||
{
|
||
output.AppendLine();
|
||
Indent();
|
||
}
|
||
|
||
|
||
|
||
public void IncIndent()
|
||
{
|
||
indentLevel++;
|
||
}
|
||
|
||
public void DecIndent()
|
||
{
|
||
indentLevel--;
|
||
}
|
||
|
||
public void Clear()
|
||
{
|
||
output = new StringBuilder();
|
||
}
|
||
|
||
|
||
public override string ToString()
|
||
{
|
||
return output.ToString();
|
||
}
|
||
|
||
}
|
||
}
|
branches/compiler/cSharp/ooasCompiler/src/codegen/Prolog/ooaPrologExpression.cs | ||
---|---|---|
/**
|
||
*
|
||
* 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 OoaPrologExpression : OoaExpressionVisitor
|
||
{
|
||
public class Factory
|
||
{
|
||
public OoaPrologExpression create(OoaPrologIdentifier.Factory idFactory, OoaPrologType.Factory typeFactory)
|
||
{ return create(idFactory, typeFactory, false); }
|
||
public virtual OoaPrologExpression create(OoaPrologIdentifier.Factory idFactory, OoaPrologType.Factory typeFactory, bool lhs)
|
||
{ return new OoaPrologExpression(idFactory, typeFactory, this, lhs); }
|
||
}
|
||
|
||
protected OoaCodeEmitter m_emitter = new OoaCodeEmitter();
|
||
protected List<string> m_tmpVars = new List<string>();
|
||
private bool m_LhsExpression = false;
|
||
|
||
|
||
public List<string> tmpVariables { get { return m_tmpVars; } }
|
||
public bool isLhsExpression { get { return m_LhsExpression; } }
|
||
|
||
private string GetPrologType(UlyssesType aType)
|
||
{
|
||
OoaPrologType pType = createTypeVisitor();
|
||
aType.Accept(pType);
|
||
return pType.ToString();
|
||
}
|
||
|
||
protected string GetIdentifierString(Identifier anIdentifier)
|
||
{
|
||
OoaPrologIdentifier pIdent = createIdentifierVisitor();
|
||
anIdentifier.Accept(pIdent);
|
||
return pIdent.ToString();
|
||
}
|
||
|
||
|
||
// following call must not happen
|
||
public override void visit(UnresolvedIdentifierExpression unresolvedIdentifierExpression)
|
||
{
|
||
System.Diagnostics.Debug.Assert(false);
|
||
}
|
||
|
||
// call of method that returns a value..
|
||
public override void visit(CallExpression callExpression)
|
||
{
|
||
// we handle only function calls within expressions here (must have non-void return!)
|
||
FunctionType funtype = (FunctionType)callExpression.child.type;
|
||
if (funtype.returnType == null)
|
||
throw new ArgumentException("Internal error: Function call in expression with return-type void!");
|
||
|
||
string callstatement = String.Empty;
|
||
StringBuilder parameter = new StringBuilder();
|
||
|
||
OoaPrologExpression prologexpr = createExpressionVisitor();
|
||
callExpression.child.Accept(prologexpr);
|
||
|
||
m_emitter.Append(prologexpr.ToString());
|
||
callstatement = prologexpr.tmpVariables[0];
|
||
int i = 0;
|
||
foreach (var arg in callExpression.arguments)
|
||
{
|
||
if (i != 0)
|
||
parameter.Append(", ");
|
||
else
|
||
i++;
|
||
OoaPrologExpression paramexpr = createExpressionVisitor();
|
||
arg.Accept(paramexpr);
|
||
m_emitter.Append(paramexpr.ToString());
|
||
parameter.Append(paramexpr.tmpVariables[0]);
|
||
}
|
||
if (parameter.Length > 0)
|
||
m_emitter.AppendLine(String.Format("{0}({1},{2}),", callstatement, parameter, NewTempVariable()));
|
||
else
|
||
m_emitter.AppendLine(String.Format("{0}({1}),", callstatement, NewTempVariable()));
|
||
}
|
||
|
||
|
||
// we need to map all other things to Prolog constructs
|
||
private string OperatorString(Expression expression, UlyssesType resultingType)
|
||
{
|
||
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.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:
|
||
case ExpressionKind.len: // T_LEN:
|
||
throw new NotImplementedException();
|
||
|
||
case ExpressionKind.div: // T_DIV:
|
||
return "/";
|
||
case ExpressionKind.idiv: // T_IDIV:
|
||
return "/";
|
||
case ExpressionKind.mod: // T_MOD:
|
||
return "mod";
|
||
case ExpressionKind.prod: // T_PROD:
|
||
return "*";
|
||
case ExpressionKind.sum: // T_SUM:
|
||
return "+";
|
||
case ExpressionKind.minus: // T_MINUS:
|
||
return "-";
|
||
case ExpressionKind.less:
|
||
return resultingType.kind == TypeKind.QrType || !isNumericBinary(expression) ? "<" : "#<";
|
||
case ExpressionKind.lessequal:
|
||
return resultingType.kind == TypeKind.QrType || !isNumericBinary(expression) ? "=<" : "#=<";
|
||
case ExpressionKind.greater:
|
||
return resultingType.kind == TypeKind.QrType || !isNumericBinary(expression) ? ">" : "#>";
|
||
case ExpressionKind.greaterequal:
|
||
return resultingType.kind == TypeKind.QrType || !isNumericBinary(expression) ? ">=" : "#>=";
|
||
case ExpressionKind.equal:
|
||
return resultingType.kind == TypeKind.QrType || !isNumericBinary(expression) ? "==" : "#=";
|
||
case ExpressionKind.notequal:
|
||
return resultingType.kind == TypeKind.QrType || !isNumericBinary(expression) ? "\\=" : "#\\=";
|
||
case ExpressionKind.and: // T_AND:
|
||
throw new NotImplementedException(); // implemented in binaryoperator
|
||
case ExpressionKind.or: // T_OR:
|
||
throw new NotImplementedException(); // implemented in binaryoperator
|
||
case ExpressionKind.not:
|
||
throw new NotImplementedException(); // implemented in binaryoperator
|
||
|
||
case ExpressionKind.Cast:
|
||
return String.Empty;
|
||
|
||
default:
|
||
return Enum.GetName(typeof(ExpressionKind), expression.kind);
|
||
}
|
||
}
|
||
|
||
protected bool isNumericBinary(Expression expression)
|
||
{
|
||
bool result = false;
|
||
if (expression is BinaryOperator)
|
||
{
|
||
result = ((BinaryOperator)expression).left.type.kind == TypeKind.IntType &&
|
||
((BinaryOperator)expression).right.type.kind == TypeKind.IntType;
|
||
}
|
||
else if (expression is UnaryOperator)
|
||
{
|
||
result = ((UnaryOperator)expression).child.type.kind == TypeKind.IntType;
|
||
}
|
||
else throw new NotImplementedException();
|
||
return result;
|
||
}
|
||
|
||
public override void visit<T>(ValueExpression<T> valueExpression)
|
||
{
|
||
System.Diagnostics.Debug.Assert(m_tmpVars.Count == 0);
|
||
string tmpVar = NewTempVariable();
|
||
m_emitter.Append(String.Format("{0} ", tmpVar));
|
||
|
||
|
||
if (valueExpression.value == null)
|
||
m_emitter.Append("= 'null'");
|
||
else if (valueExpression is ValueExpression<bool>)
|
||
m_emitter.Append((valueExpression as ValueExpression<bool>).value ? " #= true" : " #= fail");
|
||
else if (valueExpression is ValueExpression<char>)
|
||
m_emitter.Append(String.Format("#= '{0}'", valueExpression.ToString()));
|
||
else if (valueExpression is ValueExpression<int>)
|
||
m_emitter.Append(String.Format("#= {0}", valueExpression.ToString()));
|
||
else
|
||
m_emitter.Append(String.Format("= {0}", valueExpression.value.ToString()));
|
||
|
||
m_emitter.AppendLine(",");
|
||
System.Diagnostics.Debug.Assert(m_tmpVars.Count == 1);
|
||
}
|
||
|
||
public override void visit(IdentifierExpression identifierExpression)
|
||
{
|
||
if (identifierExpression.identifier.kind == IdentifierKind.LandmarkIdentifier)
|
||
{
|
||
LandmarkIdentifier lmid = (LandmarkIdentifier)identifierExpression.identifier;
|
||
OoaPrologIdentifier pid = createIdentifierVisitor();
|
||
lmid.Accept(pid);
|
||
//m_emitter.Append(pid.ToString());
|
||
m_tmpVars.Add(pid.ToString());
|
||
return;
|
||
}
|
||
else if (identifierExpression.identifier.kind == IdentifierKind.EnumIdentifier)
|
||
{
|
||
EnumIdentifier enumid = (EnumIdentifier)identifierExpression.identifier;
|
||
EnumType enumType = (EnumType)enumid.type;
|
||
//m_emitter.Append(enumType.listOfEnumSymbols.IndexOf(enumid));
|
||
if (enumType is ValuedEnumType)
|
||
m_emitter.AppendLine(String.Format("{0} #= {1},", NewTempVariable(), enumid.Value));
|
||
else
|
||
m_emitter.AppendLine(String.Format("{0} #= {1},", NewTempVariable(), enumType.listOfEnumSymbols.IndexOf(enumid).ToString()));
|
||
}
|
||
else if (identifierExpression.isSelf)
|
||
{
|
||
m_emitter.AppendLine(String.Format("{0} = {1},", NewTempVariable(), GetIdentifierString(identifierExpression.identifier)));
|
||
}
|
||
/*else if (identifierExpression.identifier.kind == IdentifierKind.AttributeIdentifier)
|
||
{
|
||
m_emitter.AppendLine(String.Format("getVal({1},{0},_),", NewTempVariable(), GetIdentifierString(identifierExpression.identifier)));
|
||
}*/
|
||
else
|
||
{
|
||
//m_emitter.Append(GetIdentifierString(identifierExpression.identifier));
|
||
m_tmpVars.Add(GetIdentifierString(identifierExpression.identifier));
|
||
}
|
||
}
|
||
|
||
public override void visit(TypeExpression typeExpression)
|
||
{
|
||
if (typeExpression.type.kind != TypeKind.QrType &&
|
||
typeExpression.type.kind != TypeKind.EnumeratedType)
|
||
{
|
||
//m_emitter.Append(GetIdentifierString(typeExpression.type.identifier));
|
||
m_emitter.Append(GetIdentifierString(typeExpression.type.identifier));
|
||
}
|
||
}
|
||
|
||
|
||
public override void visit(ObjectConstructor objectConstructor)
|
||
{
|
||
if (objectConstructor.instances.Count > 1)
|
||
throw new NotImplementedException();
|
||
|
||
m_emitter.AppendLine(String.Format("{0} = '{1}',", NewTempVariable(), objectConstructor.instances[0].Name));
|
||
|
||
//m_emitter.Append(String.Format("new {0}(this)", GetIdentifierString(objectConstructor.type.identifier)));
|
||
}
|
||
|
||
public override void visit(ListConstructor listConstructor)
|
||
{
|
||
if (listConstructor.hasComprehension)
|
||
{
|
||
OoaPrologExpression compr = createExpressionVisitor();
|
||
listConstructor.comprehension.Accept(compr);
|
||
OoaPrologExpression elem = createExpressionVisitor();
|
||
listConstructor.elements[0].Accept(elem);
|
||
|
||
StringBuilder enumvars = new StringBuilder();
|
||
int i = 0;
|
||
foreach (var v in listConstructor.comprehensionVariables.symbolList)
|
||
{
|
||
OoaPrologIdentifier ident = createIdentifierVisitor();
|
||
v.Accept(ident);
|
||
|
||
OoaPrologType identType = createTypeVisitor();
|
||
v.type.Accept(identType);
|
||
|
||
enumvars.Append(String.Format("{2} {0}: {1}", ident.ToString(), identType.ToString(), i == 0 ? String.Empty : ","));
|
||
i++;
|
||
}
|
||
|
||
m_emitter.AppendLine("% listcomprehension");
|
||
m_emitter.AppendLine(String.Format("{0} = {{{1}:[{2}]:({3}{4},{5}{6})}}",
|
||
NewTempVariable(), elem.tmpVariables[0], enumvars.ToString(), compr.ToString(), compr.tmpVariables[0],
|
||
elem.ToString(), "1=1" /*elem.ToString() == String.Empty ? "1=1" : elem.tmpVariables[0]*/));
|
||
}
|
||
else
|
||
{
|
||
m_emitter.AppendLine("% make list");
|
||
m_emitter.AppendLine(String.Format("{0} = []", NewTempVariable()));
|
||
|
||
foreach (var expr in listConstructor.elements)
|
||
{
|
||
m_emitter.Append(", ");
|
||
|
||
OoaPrologExpression pVal = createExpressionVisitor();
|
||
expr.Accept(pVal);
|
||
m_emitter.Append(pVal.ToString());
|
||
System.Diagnostics.Debug.Assert(pVal.tmpVariables.Count == 1);
|
||
m_emitter.AppendLine(String.Format("ulyssesListConc({0},[{1}],{2})", m_tmpVars[0], pVal.tmpVariables[0], NewTempVariable()));
|
||
m_tmpVars.RemoveAt(0);
|
||
}
|
||
}
|
||
m_emitter.Append(",");
|
||
System.Diagnostics.Debug.Assert(m_tmpVars.Count == 1);
|
||
}
|
||
|
||
public override void visit(SetConstructor setConstructor)
|
||
{
|
||
throw new NotImplementedException();
|
||
}
|
||
|
||
public override void visit(MapConstructor mapConstructor)
|
||
{
|
||
throw new NotImplementedException();
|
||
}
|
||
|
||
public override void visit(TupleConstructor tupleConstructor)
|
||
{
|
||
if (tupleConstructor.isMatcher)
|
||
{
|
||
// being dealt with in binaryoperator (since we only allow tuple=MyTuple(a,b))
|
||
NewTempVariable();
|
||
return;
|
||
}
|
||
else
|
||
{
|
||
m_emitter.AppendLine("% make tuple");
|
||
m_emitter.AppendLine(String.Format("{0} = []", NewTempVariable()));
|
||
|
||
foreach (var expr in tupleConstructor.values)
|
||
{
|
||
m_emitter.Append(", ");
|
||
|
||
OoaPrologExpression pVal = createExpressionVisitor();
|
||
expr.Accept(pVal);
|
||
m_emitter.Append(pVal.ToString());
|
||
System.Diagnostics.Debug.Assert(pVal.tmpVariables.Count == 1);
|
||
m_emitter.AppendLine(String.Format("ulyssesListConc({0},[{1}],{2})", m_tmpVars[0], pVal.tmpVariables[0], NewTempVariable()));
|
||
m_tmpVars.RemoveAt(0);
|
||
}
|
||
m_emitter.Append(",");
|
||
System.Diagnostics.Debug.Assert(m_tmpVars.Count == 1);
|
||
}
|
||
}
|
||
|
||
public override void visit(QValConstructor qValConstructor)
|
||
{
|
||
OoaPrologIdentifier pident = createIdentifierVisitor();
|
||
qValConstructor.type.identifier.Accept(pident);
|
||
StringBuilder qVal = new StringBuilder();
|
||
if (qValConstructor.value != null || qValConstructor.value.Length != 0)
|
||
{
|
||
OoaPrologExpression landmark1 = createExpressionVisitor();
|
||
qValConstructor.value[0].Accept(landmark1);
|
||
qVal.Append(landmark1.ToString());
|
||
|
||
if (qValConstructor.value.Length > 1)
|
||
{
|
||
OoaPrologExpression landmark2 = createExpressionVisitor();
|
||
qValConstructor.value[1].Accept(landmark2);
|
||
qVal.Append("..");
|
||
qVal.Append(landmark2.ToString());
|
||
}
|
||
}
|
||
else
|
||
qVal.Append("_");
|
||
|
||
string deriv = "_";
|
||
switch (qValConstructor.valueDeriv)
|
||
{
|
||
case QValDeriv.Dec:
|
||
deriv = "dec";
|
||
break;
|
||
case QValDeriv.Inc:
|
||
deriv = "inc";
|
||
break;
|
||
case QValDeriv.Steady:
|
||
deriv = "std";
|
||
break;
|
||
|
||
}
|
||
string tmpVar = NewTempVariable();
|
||
m_emitter.AppendLine(String.Format("{3} = ({0}:{1}/{2}),", pident.ToString(), qVal.ToString(), deriv, tmpVar));
|
||
}
|
||
|
||
public override void visit(AccessExpression accessExpression)
|
||
{
|
||
if (accessExpression.left.type.kind != TypeKind.QrType &&
|
||
accessExpression.left.type.kind != TypeKind.EnumeratedType &&
|
||
!(accessExpression.right.kind == ExpressionKind.Identifier &&
|
||
((IdentifierExpression)accessExpression.right).identifier.kind == IdentifierKind.AttributeIdentifier))
|
||
{
|
||
System.Diagnostics.Debug.Assert(m_tmpVars.Count == 0);
|
||
// enums and qr types are directly (statically) converted to nums...
|
||
VisitSub(accessExpression.left, accessExpression);
|
||
string leftresult = m_tmpVars[0]; m_tmpVars.RemoveAt(0);
|
||
|
||
VisitSub(accessExpression.right, accessExpression);
|
||
string rightresult = m_tmpVars[0]; m_tmpVars.RemoveAt(0);
|
||
|
||
m_tmpVars.Add(String.Format("{0}\\{1}", leftresult, rightresult));
|
||
}
|
||
else
|
||
VisitSub(accessExpression.right, accessExpression);
|
||
}
|
||
|
||
public override void visit(BinaryOperator binaryOperator)
|
||
{
|
||
OoaCodeEmitter origEmitter = m_emitter;
|
||
|
||
|
||
// eval stack must be empty
|
||
System.Diagnostics.Debug.Assert(m_tmpVars.Count == 0);
|
||
// traverse left
|
||
OoaCodeEmitter leftcode = new OoaCodeEmitter();
|
||
m_emitter = leftcode;
|
||
VisitSub(binaryOperator.left, binaryOperator);
|
||
string leftresult = m_tmpVars[0]; m_tmpVars.RemoveAt(0);
|
||
System.Diagnostics.Debug.Assert(m_tmpVars.Count == 0);
|
||
// traverse right
|
||
OoaCodeEmitter rightcode = new OoaCodeEmitter();
|
||
m_emitter = rightcode;
|
||
VisitSub(binaryOperator.right, binaryOperator);
|
||
string rightresult = m_tmpVars[0]; m_tmpVars.RemoveAt(0);
|
||
// eval stack must be empty
|
||
System.Diagnostics.Debug.Assert(m_tmpVars.Count == 0);
|
||
|
||
m_emitter = origEmitter;
|
||
|
||
// get tmp.var
|
||
string tmpVar = NewTempVariable();
|
||
|
||
switch (binaryOperator.kind)
|
||
{
|
||
case ExpressionKind.elemin:
|
||
m_emitter.Append(leftcode.ToString());
|
||
m_emitter.Append(rightcode.ToString());
|
||
m_emitter.AppendLine(String.Format(" {0} = member({1},{2}),",
|
||
tmpVar, leftresult, rightresult));
|
||
break;
|
||
case ExpressionKind.and: // T_AND:
|
||
m_emitter.Append(leftcode.ToString());
|
||
m_emitter.Append(rightcode.ToString());
|
||
m_emitter.AppendLine(String.Format(" {0} = ({1} {2} {3}), ",
|
||
tmpVar, leftresult, ",", rightresult));
|
||
break;
|
||
case ExpressionKind.or: // T_OR:
|
||
m_emitter.Append(leftcode.ToString());
|
||
m_emitter.Append(rightcode.ToString());
|
||
m_emitter.AppendLine(String.Format(" {0} = ({1} {2} {3}), ",
|
||
tmpVar, leftresult, ";", rightresult));
|
||
break;
|
||
|
||
case ExpressionKind.implies:
|
||
m_emitter.Append(leftcode.ToString());
|
||
m_emitter.AppendLine(String.Format(" {0} = ({1} -> ({2}{3}); true), ", // {0} = (({1} -> ({2}{3}); true))
|
||
tmpVar, leftresult, rightcode.ToString(), rightresult));
|
||
break;
|
||
|
||
case ExpressionKind.equal:
|
||
m_emitter.Append(leftcode.ToString());
|
||
m_emitter.Append(rightcode.ToString());
|
||
/*check if we have tupleconstructors as matchers*/
|
||
TupleConstructor matcher = null;
|
||
string aTuple = null;
|
||
if (binaryOperator.left.kind == ExpressionKind.TupleConstr &&
|
||
((TupleConstructor)binaryOperator.left).isMatcher)
|
||
{
|
||
matcher = (TupleConstructor)binaryOperator.left;
|
||
aTuple = rightresult;
|
||
}
|
||
else if (binaryOperator.right.kind == ExpressionKind.TupleConstr &&
|
||
((TupleConstructor)binaryOperator.right).isMatcher)
|
||
{
|
||
matcher = (TupleConstructor)binaryOperator.right;
|
||
aTuple = leftresult;
|
||
}
|
||
|
||
if (matcher == null)
|
||
m_emitter.AppendLine(String.Format(" {0} = ({1} {2} {3}), ",
|
||
tmpVar, leftresult, OperatorString(binaryOperator, binaryOperator.left.type), rightresult));
|
||
else
|
||
{
|
||
m_emitter.Append(String.Format("{0} = unify({1} = [", tmpVar, aTuple));
|
||
int cntr = 0;
|
||
foreach (var x in matcher.values)
|
||
{
|
||
if (cntr != 0)
|
||
m_emitter.Append(", ");
|
||
else
|
||
cntr++;
|
||
|
||
if (x.kind != ExpressionKind.Identifier)
|
||
throw new ArgumentException();
|
||
|
||
IdentifierExpression ident = (IdentifierExpression)x;
|
||
OoaPrologIdentifier avisitor = createIdentifierVisitor();
|
||
ident.Accept(avisitor);
|
||
m_emitter.Append(avisitor.ToString());
|
||
}
|
||
m_emitter.AppendLine("]),");
|
||
}
|
||
break;
|
||
|
||
|
||
|
||
case ExpressionKind.conc:
|
||
m_emitter.Append(leftcode.ToString());
|
||
m_emitter.Append(rightcode.ToString());
|
||
m_emitter.AppendLine(String.Format("ulyssesListConc({1},{2},{0}),", tmpVar, leftresult, rightresult));
|
||
break;
|
||
|
||
default:
|
||
m_emitter.Append(leftcode.ToString());
|
||
m_emitter.Append(rightcode.ToString());
|
||
if (binaryOperator.left.type.kind == TypeKind.QrType)
|
||
m_emitter.Append("qEval");
|
||
//m_emitter.Append("(");
|
||
if (binaryOperator.type.kind == TypeKind.IntType)
|
||
m_emitter.AppendLine(String.Format(" {0} #= ({1} {2} {3}), ",
|
||
tmpVar, leftresult, OperatorString(binaryOperator, binaryOperator.left.type), rightresult));
|
||
else
|
||
m_emitter.AppendLine(String.Format(" {0} = ({1} {2} {3}), ",
|
||
tmpVar, leftresult, OperatorString(binaryOperator, binaryOperator.left.type), rightresult));
|
||
//m_emitter.Append(")");
|
||
break;
|
||
}
|
||
System.Diagnostics.Debug.Assert(m_tmpVars.Count == 1);
|
||
}
|
||
|
||
public override void visit(TernaryOperator ternaryOperator)
|
||
{
|
||
if (ternaryOperator.kind == ExpressionKind.conditional)
|
||
{
|
||
VisitSub(ternaryOperator.left, ternaryOperator);
|
||
string leftresult = m_tmpVars[0]; m_tmpVars.RemoveAt(0);
|
||
VisitSub(ternaryOperator.mid, ternaryOperator);
|
||
string midresult = m_tmpVars[0]; m_tmpVars.RemoveAt(0);
|
||
VisitSub(ternaryOperator.right, ternaryOperator);
|
||
string rightresult = m_tmpVars[0]; m_tmpVars.RemoveAt(0);
|
||
|
||
string varname = NewTempVariable();
|
||
|
||
// (cond, expr #= var; #\ (cond), expr #= var)
|
||
m_emitter.Append("((");
|
||
m_emitter.Append(leftresult);
|
||
m_emitter.Append(", unify(");
|
||
m_emitter.Append(midresult);
|
||
m_emitter.Append(String.Format(" = {0}) );( call(\\+({1})), unify(", varname, leftresult));
|
||
m_emitter.Append(rightresult);
|
||
m_emitter.Append(String.Format(" = {0}) )),", varname));
|
||
}
|
||
else if (ternaryOperator.kind == ExpressionKind.foldRL)
|
||
throw new NotImplementedException();
|
||
else if (ternaryOperator.kind == ExpressionKind.foldLR)
|
||
{
|
||
VisitSub(ternaryOperator.mid, ternaryOperator);
|
||
string midresult = m_tmpVars[0]; m_tmpVars.RemoveAt(0);
|
||
VisitSub(ternaryOperator.right, ternaryOperator);
|
||
string rightresult = m_tmpVars[0]; m_tmpVars.RemoveAt(0);
|
||
|
||
|
||
int uniqueNumer = GetUniqueNumber();
|
||
m_emitter.Append(String.Format("fun_fold({0},{1},(_Elem_{2}, _In_{2}, Out_{2},(", midresult,
|
||
rightresult, uniqueNumer));
|
||
|
||
|
||
// hack the current element and current result values to match the declaration above (change from __result, __elem)
|
||
CallExpression leftcall = (CallExpression)ternaryOperator.left;
|
||
IdentifierExpression elemId = (IdentifierExpression)leftcall.arguments[leftcall.arguments.Count - 1];
|
||
elemId.identifier.SetTokenText(String.Format("Elem_{0}", uniqueNumer));
|
||
IdentifierExpression currentResultId = (IdentifierExpression)leftcall.arguments[leftcall.arguments.Count - 2];
|
||
currentResultId.identifier.SetTokenText(String.Format("In_{0}", uniqueNumer));
|
||
|
||
VisitSub(leftcall, ternaryOperator);
|
||
string leftresult = m_tmpVars[0]; m_tmpVars.RemoveAt(0);
|
||
string tmpresult = NewTempVariable();
|
||
m_emitter.Append(String.Format(" Out_{1} = {2})),{0}),", tmpresult, uniqueNumer, leftresult));
|
||
}
|
||
|
||
|
||
|
||
else
|
||
throw new NotImplementedException();
|
||
}
|
||
|
||
public override void visit(TupleMapAccessExpression tupleMapAccessExpression)
|
||
{
|
||
System.Diagnostics.Debug.Assert(m_tmpVars.Count == 0);
|
||
VisitSub(tupleMapAccessExpression.child, tupleMapAccessExpression);
|
||
string childresult = m_tmpVars[0]; m_tmpVars.RemoveAt(0);
|
||
|
||
VisitSub(tupleMapAccessExpression.argument, tupleMapAccessExpression);
|
||
string accessresult = m_tmpVars[0]; m_tmpVars.RemoveAt(0);
|
||
System.Diagnostics.Debug.Assert(m_tmpVars.Count == 0);
|
||
|
||
string tmpresult = NewTempVariable();
|
||
|
||
if (!m_LhsExpression)
|
||
{
|
||
switch (tupleMapAccessExpression.child.type.kind)
|
||
{
|
||
case TypeKind.TupleType:
|
||
m_emitter.AppendLine(String.Format("ulyssesTupleAccess({0},{1},{2}),", childresult, accessresult, tmpresult));
|
||
break;
|
||
case TypeKind.MapType:
|
||
m_emitter.AppendLine(String.Format("ulyssesMapAccess({0},{1},{2}),", childresult, accessresult, tmpresult));
|
||
break;
|
||
case TypeKind.ListType:
|
||
m_emitter.AppendLine(String.Format("ulyssesListAccess({0},{1},{2}),", childresult, accessresult, tmpresult));
|
||
break;
|
||
default:
|
||
throw new NotImplementedException();
|
||
}
|
||
System.Diagnostics.Debug.Assert(m_tmpVars.Count == 1);
|
||
}
|
||
else
|
||
{
|
||
/*>>>>> See comment in ooaTypeCheckVisitor on method CheckPlace! <<<<<<<<<*/
|
||
switch (tupleMapAccessExpression.child.type.kind)
|
||
{
|
||
case TypeKind.ListType:
|
||
bool isAttribute;
|
||
isAttribute = tupleMapAccessExpression.child.kind == ExpressionKind.Identifier &&
|
||
((IdentifierExpression)tupleMapAccessExpression.child).identifier.kind == IdentifierKind.AttributeIdentifier;
|
||
|
||
isAttribute = isAttribute || tupleMapAccessExpression.child.kind == ExpressionKind.Access
|
||
&& ((AccessExpression)tupleMapAccessExpression.child).left.kind == ExpressionKind.Identifier
|
||
&& ((IdentifierExpression)((AccessExpression)tupleMapAccessExpression.child).left).isSelf
|
||
&& ((AccessExpression)tupleMapAccessExpression.child).right.kind == ExpressionKind.Identifier
|
||
&& ((IdentifierExpression)((AccessExpression)tupleMapAccessExpression.child).right).identifier.kind
|
||
== IdentifierKind.AttributeIdentifier;
|
||
|
||
|
||
tmpVarCntr++;
|
||
string newlist = String.Format("RESVAR_{0}", tmpVarCntr);
|
||
|
||
m_emitter.AppendLine(String.Format("ulyssesListWrite({0},{1},{2},{3}),", childresult, accessresult, tmpresult, newlist));
|
||
|
||
if (isAttribute)
|
||
{ m_emitter.AppendLine(String.Format("{0} := {1},", childresult, newlist)); }
|
||
else
|
||
{ throw new NotImplementedException(); }
|
||
|
||
break;
|
||
default:
|
||
throw new NotImplementedException();
|
||
}
|
||
|
||
|
||
}
|
||
}
|
||
|
||
|
||
public override void visit(ForallQuantifier quantifier)
|
||
{
|
||
OoaPrologExpression pExpr = createExpressionVisitor();
|
||
quantifier.child.Accept(pExpr);
|
||
|
||
// TEMPXY = forall(enumerate1([var:type,...]),pred(var..))
|
||
StringBuilder Generator = new StringBuilder();
|
||
int i = 0;
|
||
foreach (var v in quantifier.symbols.symbolList)
|
||
{
|
||
OoaPrologIdentifier ident = createIdentifierVisitor();
|
||
v.Accept(ident);
|
||
|
||
OoaPrologType identType = createTypeVisitor();
|
||
v.type.Accept(identType);
|
||
|
||
Generator.Append(String.Format("{2} {0}: {1}", ident.ToString(), identType.ToString(), i == 0 ? String.Empty : ","));
|
||
i++;
|
||
}
|
||
|
||
m_emitter.AppendLine(String.Format("{0} = forall([{1}],({2}{3})),",
|
||
NewTempVariable(), Generator.ToString(), pExpr.ToString(), pExpr.tmpVariables[0]));
|
||
}
|
||
|
||
|
||
|
||
public override void visit(ExistsQuantifier quantifier)
|
||
{
|
||
OoaPrologExpression pExpr = createExpressionVisitor();
|
||
quantifier.child.Accept(pExpr);
|
||
|
||
// TEMPXY = exists(enumerate1([var:type,...]),pred(var..))
|
||
StringBuilder Generator = new StringBuilder();
|
||
int i = 0;
|
||
foreach (var v in quantifier.symbols.symbolList)
|
||
{
|
||
OoaPrologIdentifier ident = createIdentifierVisitor();
|
||
v.Accept(ident);
|
||
|
||
OoaPrologType identType = createTypeVisitor();
|
||
v.type.Accept(identType);
|
||
|
||
Generator.Append(String.Format("{2} {0}: {1}", ident.ToString(), identType.ToString(), i == 0 ? String.Empty : ","));
|
||
i++;
|
||
}
|
||
|
||
m_emitter.AppendLine(String.Format("{0} = exists([{1}],({2}{3})),",
|
||
NewTempVariable(), Generator.ToString(), pExpr.ToString(), pExpr.tmpVariables[0]));
|
||
}
|
||
public override void visit(UnaryOperator unaryOperator)
|
||
{
|
||
System.Diagnostics.Debug.Assert(m_tmpVars.Count == 0);
|
||
VisitSub(unaryOperator.child, unaryOperator);
|
||
|
||
if (unaryOperator.kind == ExpressionKind.Cast)
|
||
return;
|
||
|
||
string childresult = m_tmpVars[0]; m_tmpVars.RemoveAt(0);
|
||
System.Diagnostics.Debug.Assert(m_tmpVars.Count == 0);
|
||
|
||
string tmpresult = NewTempVariable();
|
||
|
||
switch (unaryOperator.kind)
|
||
{
|
||
case ExpressionKind.head:
|
||
m_emitter.AppendLine(String.Format("ulyssesListHead({1},{0}),", tmpresult, childresult));
|
||
break;
|
||
|
||
case ExpressionKind.tail:
|
||
m_emitter.AppendLine(String.Format("ulyssesListTail({1},{0}),", tmpresult, childresult));
|
||
break;
|
||
|
||
case ExpressionKind.len: // T_LEN:
|
||
m_emitter.AppendLine(String.Format("ulyssesListLength({1},{0}),", tmpresult, childresult));
|
||
break;
|
||
|
||
case ExpressionKind.not:
|
||
|
||
if (unaryOperator.type.kind == TypeKind.IntType)
|
||
m_emitter.Append(String.Format(" {0} #= call(\\+", tmpresult));
|
||
else
|
||
m_emitter.Append(String.Format(" {0} = call(\\+", tmpresult));
|
||
m_emitter.Append("(");
|
||
m_emitter.Append(childresult);
|
||
m_emitter.AppendLine(")),");
|
||
|
||
|
||
break;
|
||
|
||
case ExpressionKind.Cast:
|
||
// todo
|
||
break;
|
||
|
||
default:
|
||
if (unaryOperator.type.kind == TypeKind.IntType)
|
||
m_emitter.Append(String.Format(" {0} #= ({1}", tmpresult, OperatorString(unaryOperator, unaryOperator.child.type)));
|
||
else
|
||
m_emitter.Append(String.Format(" {0} = ({1}", tmpresult, OperatorString(unaryOperator, unaryOperator.child.type)));
|
||
m_emitter.Append("(");
|
||
m_emitter.Append(childresult);
|
||
m_emitter.AppendLine(")),");
|
||
break;
|
||
}
|
||
System.Diagnostics.Debug.Assert(m_tmpVars.Count == 1);
|
||
}
|
||
|
||
public override string ToString()
|
||
{
|
||
return m_emitter.ToString();
|
||
}
|
||
|
||
protected OoaPrologType createTypeVisitor() { return m_typeFactory.create(m_idFactory); }
|
||
protected OoaPrologIdentifier createIdentifierVisitor() { return m_idFactory.create(); }
|
||
protected OoaPrologExpression createExpressionVisitor() { return m_exprFactory.create(m_idFactory, m_typeFactory); }
|
||
|
||
protected readonly OoaPrologIdentifier.Factory m_idFactory;
|
||
protected readonly OoaPrologType.Factory m_typeFactory;
|
||
protected readonly OoaPrologExpression.Factory m_exprFactory;
|
||
|
||
protected OoaPrologExpression(
|
||
OoaPrologIdentifier.Factory idFactory,
|
||
OoaPrologType.Factory typeFactory,
|
||
OoaPrologExpression.Factory expressionFactory)
|
||
: this(idFactory, typeFactory, expressionFactory, false)
|
||
{
|
||
}
|
||
|
||
protected OoaPrologExpression(
|
||
OoaPrologIdentifier.Factory idFactory,
|
||
OoaPrologType.Factory typeFactory,
|
||
OoaPrologExpression.Factory expressionFactory,
|
||
bool isLHS)
|
||
: base()
|
||
{
|
||
m_LhsExpression = isLHS;
|
||
m_idFactory = idFactory;
|
||
m_typeFactory = typeFactory;
|
||
m_exprFactory = expressionFactory;
|
||
}
|
||
|
||
|
||
static int tmpVarCntr = 0;
|
||
public string NewTempVariable()
|
||
{
|
||
tmpVarCntr++;
|
||
string result = String.Format("TMPVAR_{0}", tmpVarCntr);
|
||
m_tmpVars.Add(result);
|
||
return result;
|
||
}
|
||
|
||
public int GetUniqueNumber()
|
||
{
|
||
tmpVarCntr++;
|
||
return tmpVarCntr;
|
||
}
|
||
|
||
}
|
||
}
|
branches/compiler/cSharp/ooasCompiler/src/codegen/Prolog/ooaPrologStatement.cs | ||
---|---|---|
/**
|
||
*
|
||
* 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<Expression> aPlace = assignment.places.First;
|
||
LinkedListNode<Expression> aValue = assignment.values.First;
|
||
List<string> assignments = new List<string>();
|
||
|
||
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;
|
||
}
|
||
}
|
||
|
||
}
|
||
|
branches/compiler/cSharp/LICENSE | ||
---|---|---|
This is the BSD 3-Clause License.
|
||
|
||
Copyright (c) 2015, AIT Austrian Institute of Technology, and Graz University of Technology
|
||
All rights reserved.
|
||
|
||
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||
|
||
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||
|
||
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
|
||
|
||
3. Neither the names of the copyright holders nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
|
||
|
||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
branches/compiler/cSharp/ooasCompiler/src/codegen/Prolog/ooaPrologVisitor.cs | ||
---|---|---|
/**
|
||
*
|
||
* 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 Emitter ===
|
||
*
|
||
*/
|
||
|
||
using System;
|
||
using System.Collections.Generic;
|
||
using System.Text;
|
||
using TUG.Mogentes;
|
||
using TUG.Mogentes.Codegen.Prolog;
|
||
|
||
|
||
namespace TUG.Mogentes.Codegen
|
||
{
|
||
public class OoaPrologVisitor : OoaCompleteAstTraversalVisitor
|
||
{
|
||
protected OoaCodeEmitter m_emitter;
|
||
|
||
private string PrologIdentifier(Identifier id)
|
||
{
|
||
OoaPrologIdentifier identifierVisitor = m_idFactory.create();
|
||
id.Accept(identifierVisitor);
|
||
return identifierVisitor.ToString();
|
||
}
|
||
|
||
protected void ExportMethodsAndActions(MainModule mainModule)
|
||
{
|
||
StringBuilder varActions = new StringBuilder();
|
||
m_emitter.AppendLine();
|
||
m_emitter.AppendLine("% action system");
|
||
m_emitter.AppendLineIncIndent("as :- ");
|
||
|
||
/* export methods */
|
||
m_emitter.AppendLine("methods (");
|
||
ExportMethods(mainModule);
|
||
m_emitter.AppendLine("), ");
|
||
m_emitter.AppendLine("actions (");
|
||
ExportNamedActions(mainModule, varActions);
|
||
m_emitter.AppendLine("), ");
|
||
m_emitter.AppendLine("dood (");
|
||
|
||
ExportDoOdBlock(mainModule.instance.doOdBlock, m_emitter);
|
||
|
||
|
||
m_emitter.AppendLine("), qdes (none)");
|
||
m_emitter.DecIndent();
|
||
m_emitter.AppendLine(".");
|
||
m_emitter.AppendLine("");
|
||
|
||
m_emitter.Append(varActions.ToString());
|
||
}
|
||
|
||
private void ExportMethods(MainModule mainModule)
|
||
{
|
||
int y = 0;
|
||
foreach (var x in mainModule.instance.symbols.symbolList)
|
||
{
|
||
if (x.kind == IdentifierKind.MethodIdentifier)
|
||
{
|
||
if (y != 0)
|
||
m_emitter.AppendLine(", ");
|
||
else
|
||
y++;
|
||
|
||
MethodIdentifier theMethod = (MethodIdentifier)x;
|
||
OoaPrologIdentifier pIdent = m_idFactory.create();
|
||
theMethod.Accept(pIdent);
|
||
|
||
/* method */
|
||
StringBuilder parameter = new StringBuilder();
|
||
if (theMethod.parameter.Count > 0 || ((FunctionType)theMethod.type).returnType != null)
|
||
{
|
||
parameter.Append("(");
|
||
int z = 0;
|
||
foreach (var param in theMethod.parameter)
|
||
{
|
||
if (z != 0)
|
||
{
|
||
parameter.Append(", ");
|
||
}
|
||
else
|
||
z++;
|
||
OoaPrologIdentifier pParamIdent = m_idFactory.create();
|
||
param.Accept(pParamIdent);
|
||
parameter.Append(pParamIdent.ToString());
|
||
}
|
||
|
||
|
||
if (((FunctionType)theMethod.type).returnType != null)
|
||
{
|
||
if (z != 0)
|
||
parameter.Append(", ");
|
||
parameter.Append("RESULT");
|
||
}
|
||
parameter.Append(")");
|
||
}
|
||
m_emitter.AppendLineIncIndent(String.Format("{0}{1} = (", pIdent.ToString(), parameter.ToString()));
|
||
|
||
OoaPrologStatement pBody = createStatementVisitor();
|
||
((MethodIdentifier)x).body.Accept(pBody);
|
||
m_emitter.Append(pBody.ToString());
|
||
m_emitter.Append(")");
|
||
m_emitter.DecIndent();
|
||
}
|
||
}
|
||
if (y == 0)
|
||
m_emitter.Append(" none ");
|
||
}
|
||
|
||
private void ExportNamedActions(MainModule mainModule, StringBuilder varActions)
|
||
{
|
||
int y = 0;
|
||
foreach (var x in mainModule.instance.symbols.symbolList)
|
||
{
|
||
if (x.kind == IdentifierKind.NamedActionIdentifier)
|
||
{
|
||
if (y != 0)
|
||
m_emitter.AppendLine(", ");
|
||
else
|
||
y++;
|
||
NamedActionIdentifier action = (NamedActionIdentifier)x;
|
||
OoaPrologIdentifier pIdent = m_idFactory.create();
|
||
action.Accept(pIdent);
|
||
|
||
if (((FunctionType)action.type).functionType != FunctionTypeEnum.Continuous)
|
||
{
|
||
/* discrete actions */
|
||
StringBuilder parameter = new StringBuilder();
|
||
StringBuilder parametertype = new StringBuilder();
|
||
if (action.parameter.Count > 0)
|
||
{
|
||
parameter.Append("(");
|
||
parametertype.Append("(");
|
||
int z = 0;
|
||
foreach (var param in action.parameter)
|
||
{
|
||
if (z != 0)
|
||
{
|
||
parameter.Append(", ");
|
||
parametertype.Append(", ");
|
||
}
|
||
else
|
||
z++;
|
||
OoaPrologIdentifier pParamIdent = m_idFactory.create();
|
||
param.Accept(pParamIdent);
|
||
parameter.Append(pParamIdent.ToString());
|
||
|
||
OoaPrologType pParamType = createTypeVisitor(); // bugfix me!
|
||
param.type.Accept(pParamType);
|
||
parametertype.Append(pParamType.ToString());
|
Also available in: Unified diff
adding original CSharp version of the ooas compiler