/// <summary> /// Renders a single MemberReferenceExpression to VHDL /// </summary> /// <returns>The VHDL equivalent of the expression.</returns> /// <param name="e">The expression to render</param> private string RenderExpression(AST.MemberReferenceExpression e) { if (e.Target.Parent is AST.Bus) { var bus = e.Target.Parent as AST.Bus; var busname = e.Target.Parent.Name; if (Process != null && Process.LocalBusNames.ContainsKey(bus)) { busname = Process.LocalBusNames[bus]; } if (Process.IsClocked && Process.Methods.Any(x => x.IsStateMachine) && Process.InputBusses.Contains(bus)) { return(Naming.ToValidName("capture_" + busname + "_" + e.Target.Name)); } return(Naming.ToValidName(busname + "_" + e.Target.Name)); } else if (e.Target is AST.Constant) { var ce = e.Target as AST.Constant; if (ce.ArrayLengthSource != null) { var p = ce.ArrayLengthSource.Parent; while (p != null && !(p is AST.Process)) { p = p.Parent; } if (p is AST.Process) { return(p.Name + "_" + ce.ArrayLengthSource.Name + "_type'LENGTH"); } return(ce.ArrayLengthSource.Name + "_type'LENGTH"); } if (ce.CecilType != null && ce.CecilType.Resolve().IsEnum) { if (ce.DefaultValue is FieldDefinition) { return(Naming.ToValidName(ce.CecilType.FullName + "_" + ((FieldDefinition)ce.DefaultValue).Name)); } } } if (string.IsNullOrEmpty(e.Target.Name)) { throw new Exception($"Cannot emit empty expression: {e.SourceExpression}"); } if (e.Target.Parent is Variable && !string.IsNullOrEmpty(e.Target.Parent.Name)) { return(e.Target.Parent.Name + "." + e.Target.Name); } return(e.Target.Name); }
/// <summary> /// Applies the transformation /// </summary> /// <returns>The transformed item.</returns> /// <param name="el">The item to visit.</param> public ASTItem Transform(ASTItem el) { var ss = el as SwitchStatement; if (ss == null) { return(el); } // We cannot support conversions as part of the switch statements, // so we statically compute them here var nonstatic = ss.Cases.SelectMany(x => x.Item1).OfType <CustomNodes.ConversionExpression>().ToArray(); if (nonstatic.Length != 0) { foreach (var e in nonstatic) { var et = State.VHDLType(e); var cx = e.Expression; var pt = State.VHDLType(cx); // If we have a coversion thing caused by an off enum if (et.IsEnum && pt == VHDLTypes.INTEGER && cx is PrimitiveExpression) { var name = State.RegisterCustomEnum(ss.SwitchExpression.SourceResultType, et, (cx as PrimitiveExpression).Value); var c = new AST.Constant() { Name = name, CecilType = ss.SwitchExpression.SourceResultType, DefaultValue = name // (cx as PrimitiveExpression).Value }; var mr = new AST.MemberReferenceExpression() { Parent = ss, SourceResultType = c.CecilType, Target = c }; e.ReplaceWith(mr); } } return(null); } return(el); }
/// <summary> /// Renders a single MemberReferenceExpression to VHDL /// </summary> /// <returns>The VHDL equivalent of the expression.</returns> /// <param name="e">The expression to render</param> private string RenderExpression(AST.MemberReferenceExpression e) { if (e.Target.Parent is AST.Bus) { return($"bus_{Naming.BusNameToValidName(e.Target.Parent as AST.Bus, Process)}->{e.Target.Name}()"); } else if (e.Target is AST.Constant) { var ce = e.Target as AST.Constant; if (ce.ArrayLengthSource != null) { return("size_" + ((Constant)e.Target).ArrayLengthSource.Name); } if (ce.CecilType != null && ce.CecilType.Resolve().IsEnum) { if (ce.DefaultValue is FieldDefinition) { return(Naming.ToValidName(ce.CecilType.FullName + "." + ((FieldDefinition)ce.DefaultValue).Name)); } } } if (string.IsNullOrEmpty(e.Target.Name)) { throw new Exception($"Cannot emit empty expression: {e.SourceExpression}"); } if (e.Target.Parent is Variable && !string.IsNullOrEmpty(e.Target.Parent.Name)) { return(e.Target.Parent.Name + "." + e.Target.Name); } return(e.Target.Name); }