public Calculator(IVariableScope variables = null, IFunctionScope functions = null) { this.variables = variables; this.functions = functions; this.simplifier = new SimplifyBinary(variables, functions); }
/// <summary> /// Creates all (or filtered set) constructors from a type (that should be the base type) /// to this type which simply relay the call to the base class. /// </summary> /// <param name="this">This type scope.</param> /// <param name="baseType">The base type.</param> /// <param name="accessBuilder"> /// Optional filter (returning null skips the constructor) and /// access protection builder. The default access protection is "public ". /// </param> /// <returns>This function scopes created.</returns> public static List <IFunctionScope> CreatePassThroughConstructors(this ITypeScope @this, Type baseType, Func <ConstructorInfo, string?>?accessBuilder = null) { if (@this == null) { throw new ArgumentNullException(nameof(@this)); } if (baseType == null) { throw new ArgumentNullException(nameof(baseType)); } List <IFunctionScope> result = new List <IFunctionScope>(); foreach (var c in baseType.GetConstructors(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) .Where(c => c.IsPublic || c.IsFamily || c.IsFamilyOrAssembly)) { string?access = "public "; if (accessBuilder != null && (access = accessBuilder(c)) == null) { continue; } IFunctionScope built = @this.CreateFunction(scope => { if (access.Length > 0) { scope.Append(access); if (!Char.IsWhiteSpace(access, access.Length - 1)) { scope.Space(); } } var parameters = c.GetParameters(); scope.Append(Helper.RemoveGenericParameters(@this.Name)) .AppendParameters(parameters); if (parameters.Length > 0) { scope.Append(" : base( "); bool atLeastOne = false; foreach (var p in parameters) { if (atLeastOne) { scope.Append(", "); } else { atLeastOne = true; } scope.Append(p.Name); } scope.Append(" )"); } }); result.Add(built); } return(result); }
// static void AppendArrayDecl(IFunctionScope f, string typeName, int count) { if (count > 0) { f.Append("new ").Append(typeName).Append("[").Append(count).Append("];").NewLine(); } else { f.Append("Array.Empty<").Append(typeName).Append(">();").NewLine(); } }
public CSCodeGenerationResult Implement(IActivityMonitor monitor, MethodInfo m, ICSCodeGenerationContext c, ITypeScope b) { IFunctionScope mB = b.CreateOverride(m); mB.Parent.Should().BeSameAs(b, "The function is ready to be implemented."); if (IsLambda) { mB.Append("=> ").Append(ActualCode).Append(';').NewLine(); } else { mB.Append(ActualCode); } return(CSCodeGenerationResult.Success); }
/// <summary> /// If an identifier is used in a function of an IncludeFile and references another /// Object (e.g. function or record type) from within the file the identifier must /// be prepended with the CodeFileAlias of that IncludeFile. /// This method checks whether we are currently in the scope of a function from an /// IncludeFile and if so it prepends the CodeFileAlias of the IncludeFile. /// </summary> /// <param name="memory"></param> /// <param name="identifier">The name of the object (without alias)</param> /// <returns></returns> public static string GetIdentifierBasedOnFunctionScope(ISyneryMemory memory, string identifier) { if (memory.CurrentScope != null) { // check whether the function call comes from a function scope that sits inside of an include file IFunctionScope surroundingFunctionScope = memory.CurrentScope.ResolveFunctionScope(); if (surroundingFunctionScope != null && String.IsNullOrEmpty(surroundingFunctionScope.FunctionData.CodeFileAlias) == false) { // prepend the CodeFileAlias of the current function scope to get the correct FullName of the requested function return(GetFullName(identifier, surroundingFunctionScope.FunctionData.CodeFileAlias)); } } return(identifier); }
public CSCodeGenerationResult Implement(IActivityMonitor monitor, MethodInfo m, ICSCodeGenerationContext codeGenContext, ITypeScope typeBuilder) { IFunctionScope mB = typeBuilder.CreateOverride(m); Debug.Assert(mB.Parent == typeBuilder, "The function is ready to be implemented."); if (_attr.IsLambda) { mB.Append("=> ").Append(_attr.ActualCode).Append(';').NewLine(); } else { mB.Append(_attr.ActualCode).NewLine(); } return(CSCodeGenerationResult.Success); }
public void playing_with_parts() { INamespaceScope g = CodeWorkspace.Create().Global; INamespaceScopePart gSub = g.CreatePart(); INamespaceScopePart gSub2 = gSub.CreatePart(); ITypeScope gSub2Type1 = gSub2.CreateType("class GSub2Type1"); ITypeScope gSub2Type2 = gSub2.CreateType("class GSub2Type2"); ITypeScopePart gSub2Type1Part1 = gSub2Type1.CreatePart(); ITypeScopePart gSub2Type1Part2 = gSub2Type1.CreatePart(); IFunctionScope gSub2Type1Part2F1 = gSub2Type1Part2.CreateFunction("void Action()"); IFunctionScopePart gSub2Type1Part2F1Part1 = gSub2Type1Part2F1.CreatePart(); g.Append("g:"); gSub.Append("gSub:"); gSub2.Append("gSub2:"); gSub2Type1.Append("gSub2Type1:"); gSub2Type2.Append("gSub2Type2:"); gSub2Type1Part1.Append("gSub2Type1Part1:"); gSub2Type1Part2.Append("gSub2Type1Part2:"); gSub2Type1Part2F1.Append("gSub2Type1Part2F1:"); gSub2Type1Part2F1Part1.Append("gSub2Type1Part2F1Part1:"); var s = g.ToString().Trim(); s.Should().Be(@" gSub2: gSub: g: class GSub2Type1 { gSub2Type1Part1: gSub2Type1Part2: gSub2Type1: void Action() { gSub2Type1Part2F1Part1: gSub2Type1Part2F1: } } class GSub2Type2 { gSub2Type2: }".Trim().ReplaceLineEndings()); }
public static Expression Apply(IEnumerable<Type> transformations, Expression expr, IVariableScope variables, IFunctionScope functions) { Expression result = expr; foreach (Type type in transformations) { result = (new EliminateSubtractions(result)).Result; result = (new BinaryToLinear(result)).Result; RuleOrientedTransformation transformation = (RuleOrientedTransformation)Activator.CreateInstance(type); result = transformation.Transform(result, e => Apply(e, variables, functions)); result = (new LinearToBinary(result)).Result; result = (new SimplifyBinary(result, variables, functions)).Result; } return result; }
public void full_run_test() { var f = TestHelper.TestProjectFolder.AppendPart("TestCodeProject"); TestHelper.CleanupFolder(f); ICodeProject project = CodeWorkspace.CreateProject("MyProject"); project.TargetFrameworks.Add("netcoreapp3.1"); project.OutputType = "Exe"; project.Code.Global.EnsureUsing("System"); ITypeScope program = project.Code.Global.CreateType("public static class Program"); IFunctionScope main = program.GeneratedByComment() .CreateFunction("public static int Main()"); main.Append("Console.WriteLine(").AppendSourceString("Hop!").Append(" );").NewLine(); main.Append("return 0;"); var projectFolder = WriteProjectFolder(f, project); Run(projectFolder, "dotnet", "run", out string output); output.Should().Contain("Hop!"); }
public Expression Evaluate(IVariableScope variables, IFunctionScope functions) { return(Evaluate(this, variables, functions)); }
public Expression Differentiate(string var, IVariableScope variables, IFunctionScope functions, IDifferentiationScope derivatives) { return Differentiate(this, var, variables, functions, derivatives); }
public static FunctionScopeAssertions Should(this IFunctionScope functionScope) => new FunctionScopeAssertions(functionScope);
public Calculator(Expression expr, IVariableScope variables = null, IFunctionScope functions = null) : this(variables, functions) { this.result = Calculate(expr); }
/// <summary> /// Generates the <paramref name="scope"/> that is the PocoDirectory_CK class and /// all the factories (<see cref="IPocoFactory"/> implementations) and the Poco class (<see cref="IPoco"/> implementations). /// </summary> /// <param name="monitor">The monitor to use.</param> /// <param name="classType">The <see cref="PocoDirectory"/> type.</param> /// <param name="c">Code generation context.</param> /// <param name="scope">The PocoDirectory_CK type scope.</param> /// <returns>Always <see cref="CSCodeGenerationResult.Success"/>.</returns> public override CSCodeGenerationResult Implement(IActivityMonitor monitor, Type classType, ICSCodeGenerationContext c, ITypeScope scope) { Debug.Assert(scope.FullName == "CK.Core.PocoDirectory_CK", "We can use the PocoDirectory_CK type name to reference the PocoDirectory implementation."); IPocoSupportResult r = c.Assembly.GetPocoSupportResult(); Debug.Assert(r == c.CurrentRun.ServiceContainer.GetService(typeof(IPocoSupportResult)), "The PocoSupportResult is also available at the GeneratedBinPath."); // PocoDirectory_CK class. scope.GeneratedByComment().NewLine() .FindOrCreateFunction("internal PocoDirectory_CK()") .Append("Instance = this;").NewLine(); scope.Append("internal static PocoDirectory_CK Instance;").NewLine() // The _factories field .Append("static readonly Dictionary<string,IPocoFactory> _factoriesN = new Dictionary<string,IPocoFactory>( ").Append(r.NamedRoots.Count).Append(" );").NewLine() .Append("static readonly Dictionary<Type,IPocoFactory> _factoriesT = new Dictionary<Type,IPocoFactory>( ").Append(r.AllInterfaces.Count).Append(" );").NewLine() .Append("public override IPocoFactory Find( string name ) => _factoriesN.GetValueOrDefault( name );").NewLine() .Append("public override IPocoFactory Find( Type t ) => _factoriesT.GetValueOrDefault( t );").NewLine() .Append("internal static void Register( IPocoFactory f )").OpenBlock() .Append("_factoriesN.Add( f.Name, f );").NewLine() .Append("foreach( var n in f.PreviousNames ) _factoriesN.Add( n, f );").NewLine() .Append("foreach( var i in f.Interfaces ) _factoriesT.Add( i, f );").NewLine() .CloseBlock(); if (r.AllInterfaces.Count == 0) { return(CSCodeGenerationResult.Success); } foreach (var root in r.Roots) { // PocoFactory class. var tFB = c.Assembly.FindOrCreateAutoImplementedClass(monitor, root.PocoFactoryClass); tFB.Definition.Modifiers |= Modifiers.Sealed; string factoryClassName = tFB.Definition.Name.Name; // Poco class. var tB = c.Assembly.FindOrCreateAutoImplementedClass(monitor, root.PocoClass); tB.Definition.Modifiers |= Modifiers.Sealed; // The Poco's static _factory field is internal and its type is the exact class: extended code // can refer to the _factory to access the factory extended code without cast. // // This static internal field is an awful shortcut but it makes things simpler and more efficient // than looking up the factory in the DI (and downcasting it) each time we need it. // This simplification has been done for Cris Command implementation: a ICommand exposes // its ICommandModel: we used to inject the ICommandModel (that is the extended PocoFactory) in the ICommand // PocoClass ctor from the factory methods. It worked but it was complex... and, eventually, there // can (today) but most importantly there SHOULD, be only one StObjMap/Concrete generated code in an // assembly. Maybe one day, the StObj instances themselves can be made static (since they are some kind of // "absolute singletons"). // // Note to myself: this "static shortcut" is valid because we are on a "final generation", not on a // local, per-module, intermediate, code generation like .Net 5 Code Generators. // How this kind of shortcuts could be implemented with .Net 5 Code Generators? It seems that it could but // there will be as many "intermediate statics" as there are "levels of assemblies"? Or, there will be only // one static (the first one) and the instance will be replaced by the subsequent assemblies? In all cases, // diamond problem will have to be ultimately resolved at the final leaf... Just like we do! // tB.Append("internal static ").Append(tFB.Name).Append(" _factory;") .NewLine(); tB.Append("IPocoFactory IPocoGeneratedClass.Factory => _factory;").NewLine(); // Always create the constructor so that other code generators // can always find it. // We support the interfaces here: if other participants have already created this type, it is // up to us, here, to handle the "exact" type definition. tB.Definition.BaseTypes.Add(new ExtendedTypeName("IPocoGeneratedClass")); tB.Definition.BaseTypes.AddRange(root.Interfaces.Select(i => new ExtendedTypeName(i.PocoInterface.ToCSharpName()))); IFunctionScope ctorB = tB.CreateFunction($"public {root.PocoClass.Name}()"); foreach (var p in root.PropertyList) { Type propType = p.PropertyType; bool isUnionType = p.PropertyUnionTypes.Any(); var typeName = propType.ToCSharpName(); string fieldName = "_v" + p.Index; tB.Append(typeName).Space().Append(fieldName); if (p.DefaultValueSource == null) { tB.Append(";"); } else { tB.Append(" = ").Append(p.DefaultValueSource).Append(";"); } tB.NewLine(); tB.Append("public ").Append(typeName).Space().Append(p.PropertyName); Debug.Assert(!p.IsReadOnly || p.DefaultValueSource == null, "Readonly with [DefaultValue] has already raised an error."); if (p.IsReadOnly) { // Generates in constructor. r.GenerateAutoInstantiatedNewAssignation(ctorB, fieldName, p.PropertyType); } tB.OpenBlock() .Append("get => ").Append(fieldName).Append(";").NewLine(); if (!p.IsReadOnly) { tB.Append("set") .OpenBlock(); bool isTechnicallyNullable = p.PropertyNullableTypeTree.Kind.IsTechnicallyNullable(); bool isNullable = p.PropertyNullableTypeTree.Kind.IsNullable(); if (isTechnicallyNullable && !isNullable) { tB.Append("if( value == null ) throw new ArgumentNullException();").NewLine(); } if (isUnionType) { if (isNullable) { tB.Append("if( value != null )") .OpenBlock(); } tB.Append("Type tV = value.GetType();").NewLine() .Append("if( !_c").Append(fieldName) .Append(".Any( t => t.IsAssignableFrom( tV ) ))") .OpenBlock() .Append("throw new ArgumentException( $\"Unexpected Type '{tV}' in UnionType. Allowed types are: ") .Append(p.PropertyUnionTypes.Select(tU => tU.ToString()).Concatenate()) .Append(".\");") .CloseBlock(); if (isNullable) { tB.CloseBlock(); } } tB.Append(fieldName).Append(" = value;") .CloseBlock(); } tB.CloseBlock(); if (isUnionType) { tB.Append("static readonly Type[] _c").Append(fieldName).Append("=").AppendArray(p.PropertyUnionTypes.Select(u => u.Type)).Append(";").NewLine(); } } // PocoFactory class. tFB.Append("PocoDirectory IPocoFactory.PocoDirectory => PocoDirectory_CK.Instance;").NewLine(); tFB.Append("public Type PocoClassType => typeof(").Append(root.PocoClass.Name).Append(");") .NewLine(); tFB.Append("public IPoco Create() => new ").Append(root.PocoClass.Name).Append("();") .NewLine(); tFB.Append("public string Name => ").AppendSourceString(root.Name).Append(";") .NewLine(); tFB.Append("public IReadOnlyList<string> PreviousNames => ").AppendArray(root.PreviousNames).Append(";") .NewLine(); tFB.Append("public IReadOnlyList<Type> Interfaces => ").AppendArray(root.Interfaces.Select(i => i.PocoInterface)).Append(";") .NewLine(); tFB.CreateFunction("public " + factoryClassName + "()") .Append("PocoDirectory_CK.Register( this );").NewLine() .Append(tB.Name).Append("._factory = this;"); foreach (var i in root.Interfaces) { tFB.Definition.BaseTypes.Add(new ExtendedTypeName(i.PocoFactoryInterface.ToCSharpName())); tFB.AppendCSharpName(i.PocoInterface, true, true, true) .Space() .AppendCSharpName(i.PocoFactoryInterface, true, true, true) .Append(".Create() => new ").AppendCSharpName(i.Root.PocoClass, true, true, true).Append("();") .NewLine(); } } return(CSCodeGenerationResult.Success); }
public static Expression Apply(Expression expr, IVariableScope variables, IFunctionScope functions) { return(Apply(transformations, expr, variables, functions)); }
public static Expression Evaluate(Expression expr, IVariableScope variables, IFunctionScope functions) { return(Evaluate(transformations, expr, variables, functions)); }
public ServiceSupportCodeGenerator(ITypeScope rootType, IFunctionScope rootCtor) { _rootType = rootType; _infoType = rootType.Namespace.CreateType("public static class SFInfo"); _rootCtor = rootCtor; }
public static Expression Evaluate(IEnumerable<Type> transformations, Expression expr, IVariableScope variables, IFunctionScope functions) { Expression result = (new EliminateSubtractions(expr)).Result; result = (new SimplifyBinary(result, variables, functions)).Result; Expression presult = null; int count = 0; while (!result.Equals(presult) && count < 10) { presult = result; result = Apply(transformations, result, variables, functions); count++; } return (new ReturnSubtractions(result)).Result; }
public SimplifyBinary(Expression expr, IVariableScope variables = null, IFunctionScope functions = null) : this(variables, functions) { this.result = Simplify(expr); }
public SimplifyBinary(IVariableScope variables = null, IFunctionScope functions = null) { this.variables = variables; this.functions = functions; }
public static Expression Apply(Expression expr, IVariableScope variables, IFunctionScope functions) { return Apply(transformations, expr, variables, functions); }
public Expression Evaluate(IVariableScope variables, IFunctionScope functions) { return Evaluate(this, variables, functions); }
public Expression Apply(IEnumerable <Type> transformations, IVariableScope variables, IFunctionScope functions) { return(Apply(transformations, this, variables, functions)); }
public static Expression Differentiate(Expression expr, string var, IVariableScope variables, IFunctionScope functions, IDifferentiationScope derivatives) { Expression derivative = (new Differentiation(expr, var, derivatives)).Result; return(Evaluate(derivative, variables, functions)); }
JsonCodeGenHandler ConfigureAndAddTypeInfoForListSetAndMap(JsonTypeInfo info, IFunctionScope fWrite, IFunctionScope fRead, NullableTypeTree tInterface) { Debug.Assert(!info.Type.Type.IsInterface && tInterface.Type.IsInterface); info.Configure( (ICodeWriter write, string variableName) => { write.Append("PocoDirectory_CK.").Append(fWrite.Definition.MethodName.Name).Append("( w, ").Append(variableName).Append(", options );"); }, (ICodeWriter read, string variableName, bool assignOnly, bool isNullableVariable) => { if (!assignOnly) { if (isNullableVariable) { read.Append("if( ").Append(variableName).Append(" == null )") .OpenBlock() .Append(variableName).Append(" = new ").Append(info.GenCSharpName).Append("();") .CloseBlock(); } else { read.Append(variableName).Append(".Clear();").NewLine(); } } else { read.Append(variableName).Append(" = new ").Append(info.GenCSharpName).Append("();").NewLine(); } // We cast the variable into its type to handle the case where the variable is an 'object' (or // any other base type) since these are regular collections (arrays are not handled here). read.Append("PocoDirectory_CK.") .Append(fRead.Definition.MethodName.Name) .Append("( ref r, (") .Append(info.GenCSharpName) .Append(")") .Append(variableName) .Append(", options );"); }); // The interface maps to the collection type and is its MostAbstractMapping. AllowTypeAlias(tInterface.ToNormalNull(), info, isMostAbstract: true); AllowTypeInfo(info); return(info.NullHandler); }
public static Expression Evaluate(IEnumerable <Type> transformations, Expression expr, IVariableScope variables, IFunctionScope functions) { Expression result = (new EliminateSubtractions(expr)).Result; result = (new SimplifyBinary(result, variables, functions)).Result; Expression presult = null; int count = 0; while (!result.Equals(presult) && count < 10) { presult = result; result = Apply(transformations, result, variables, functions); count++; } return((new ReturnSubtractions(result)).Result); }
public static Expression Apply(IEnumerable <Type> transformations, Expression expr, IVariableScope variables, IFunctionScope functions) { Expression result = expr; foreach (Type type in transformations) { result = (new EliminateSubtractions(result)).Result; result = (new BinaryToLinear(result)).Result; RuleOrientedTransformation transformation = (RuleOrientedTransformation)Activator.CreateInstance(type); result = transformation.Transform(result, e => Apply(e, variables, functions)); result = (new LinearToBinary(result)).Result; result = (new SimplifyBinary(result, variables, functions)).Result; } return(result); }
public static Expression Differentiate(Expression expr, string var, IVariableScope variables, IFunctionScope functions, IDifferentiationScope derivatives) { Expression derivative = (new Differentiation(expr, var, derivatives)).Result; return Evaluate(derivative, variables, functions); }
public Part(IFunctionScope owner) : base(owner) { }
public Expression Differentiate(string var, IVariableScope variables, IFunctionScope functions, IDifferentiationScope derivatives) { return(Differentiate(this, var, variables, functions, derivatives)); }
void OnFunctionCreated(IFunctionScope obj) => FunctionCount++;
public Expression Apply(IEnumerable<Type> transformations, IVariableScope variables, IFunctionScope functions) { return Apply(transformations, this, variables, functions); }