コード例 #1
0
ファイル: PropertyRule.cs プロジェクト: InspiringCode/DX.CQRS
 public override StatementSyntax GetAssignmentStatement(AssignmentTarget target, SourceProperty p, IdentifierNameSyntax sourceObjectVariableName)
 {
     return(target switch
     {
         AssignmentTarget.SourceClass =>
         GetSourceMethodCallAssignmentStatement(p, sourceObjectVariableName, "ToImmutable"),
         AssignmentTarget.SourceToSource =>
         p.GetAssignmentStatement(p.GetAccessExpression(sourceObjectVariableName)),
         _ => GetTargetMethodCallAssignmentStatement(p, sourceObjectVariableName, "AddRange")
     });
コード例 #2
0
        internal static string AnalysisDictionaryKey(VariableExpressionAst varExprAst)
        {
            if (varExprAst == null)
            {
                return(String.Empty);
            }

            return(String.Format(CultureInfo.CurrentCulture,
                                 "{0}s{1}e{2}",
                                 AssignmentTarget.GetUnaliasedVariableName(varExprAst.VariablePath),
                                 varExprAst.Extent.StartOffset,
                                 varExprAst.Extent.EndOffset
                                 ));
        }
コード例 #3
0
 private void AnalyzeBlock(BitArray assignedBitArray, Block block)
 {
     foreach (Ast ast in block._asts)
     {
         VariableExpressionAst ast2 = ast as VariableExpressionAst;
         if (ast2 != null)
         {
             VariablePath variablePath = ast2.VariablePath;
             if (variablePath.IsAnyLocal())
             {
                 string unaliasedVariableName    = GetUnaliasedVariableName(variablePath);
                 VariableAnalysisDetails details = this._variables[unaliasedVariableName];
                 if (details.Automatic)
                 {
                     ast2.TupleIndex = details.LocalTupleIndex;
                     ast2.Automatic  = true;
                 }
                 else
                 {
                     ast2.TupleIndex = (assignedBitArray[details.BitIndex] && !details.PreferenceVariable) ? details.LocalTupleIndex : -2;
                 }
             }
         }
         else
         {
             AssignmentTarget target = ast as AssignmentTarget;
             if (target != null)
             {
                 if (target._targetAst != null)
                 {
                     this.CheckLHSAssign(target._targetAst, assignedBitArray);
                 }
                 else
                 {
                     this.CheckLHSAssignVar(target._variableName, assignedBitArray, target._type);
                 }
             }
             else
             {
                 DataStatementAst item = ast as DataStatementAst;
                 if (item != null)
                 {
                     VariableAnalysisDetails details2 = this.CheckLHSAssignVar(item.Variable, assignedBitArray, typeof(object));
                     item.TupleIndex = details2.LocalTupleIndex;
                     details2.AssociatedAsts.Add(item);
                 }
             }
         }
     }
 }
コード例 #4
0
        /// <summary>
        /// Visit variable expression ast
        /// </summary>
        /// <param name="variableExpressionAst"></param>
        /// <returns></returns>
        public override object VisitVariableExpression(VariableExpressionAst variableExpressionAst)
        {
            if (variableExpressionAst == null)
            {
                return(null);
            }

            var varPath = variableExpressionAst.VariablePath;

            if (_variables.ContainsKey(AssignmentTarget.GetUnaliasedVariableName(varPath)))
            {
                var details = _variables[AssignmentTarget.GetUnaliasedVariableName(varPath)];
                Current.AddAst(new VariableTarget(variableExpressionAst));
                details.AssociatedAsts.Add(variableExpressionAst);
            }

            return(base.VisitVariableExpression(variableExpressionAst));
        }
コード例 #5
0
        /// <summary>
        /// Visit assignment statement
        /// </summary>
        /// <param name="assignmentStatementAst"></param>
        /// <returns></returns>
        public override object VisitAssignmentStatement(AssignmentStatementAst assignmentStatementAst)
        {
            if (assignmentStatementAst == null)
            {
                return(null);
            }

            base.VisitAssignmentStatement(assignmentStatementAst);

            foreach (var assignTarget in GetAssignmentTargets(assignmentStatementAst.Left))
            {
                var leftAst = assignTarget;
                while (leftAst is AttributedExpressionAst)
                {
                    leftAst = ((AttributedExpressionAst)leftAst).Child;
                }

                if (leftAst is VariableExpressionAst)
                {
                    var varPath = ((VariableExpressionAst)leftAst).VariablePath;

                    if (_variables.ContainsKey(AssignmentTarget.GetUnaliasedVariableName(varPath)))
                    {
                        var details = _variables[AssignmentTarget.GetUnaliasedVariableName(varPath)];
                        details.AssignedBlocks.Add(Current);
                    }

                    Current.AddAst(new AssignmentTarget(assignmentStatementAst));
                }
                else
                {
                    // We skip things like $a.test = 3. In this case we will just test
                    // for variable $a
                    assignTarget.Visit(this.Decorator);
                }
            }

            return(null);
        }
コード例 #6
0
ファイル: Compiler.cs プロジェクト: wmltogether/yukatool2
        protected DataElement CreateTargetElement(AssignmentTarget target)
        {
            switch (target)
            {
            case AssignmentTarget.Variable variable:
                return(_dataSet.CreateVariable(variable.VariableType, variable.VariableId));

            case AssignmentTarget.VariablePointer pointer:
                return(_dataSet.CreateVariablePointer(pointer.VariableType, pointer.PointerId));

            case AssignmentTarget.SpecialString sstr:
                return(_dataSet.CreateVariable(sstr.Id, 0));

            case AssignmentTarget.Local local:
                throw new FormatException($"Unexpected local variable in assignment: {local.Id}");

            case AssignmentTarget.IntPointer pointer:
                return(_dataSet.CreateIntPointer(pointer.PointerId));

            default:
                throw new FormatException($"Invalid assignment target: {target.GetType().Name}");
            }
        }
コード例 #7
0
        /// <summary>
        /// pre-run for emitting the needed entities before emitting the real code
        /// - emits sequence variable declarations (only once for every variable, declaration only possible at assignment targets)
        /// </summary>
        private void EmitNeededVarEntities(AssignmentTarget tgt, SourceBuilder source)
        {
            source.AppendFront(COMP_HELPER.DeclareResultVar(tgt));

            switch (tgt.AssignmentTargetType)
            {
            case AssignmentTargetType.Var:
            {
                AssignmentTargetVar var = (AssignmentTargetVar)tgt;
                EmitVarIfNew(var.DestVar, source);
                break;
            }

            case AssignmentTargetType.YieldingToVar:
            {
                AssignmentTargetYieldingVar var = (AssignmentTargetYieldingVar)tgt;
                EmitVarIfNew(var.DestVar, source);
                break;
            }

            default:
                break;
            }
        }
コード例 #8
0
        private void ProcessParameters(IEnumerable <ParameterAst> parameters)
        {
            foreach (var parameter in parameters)
            {
                var  variablePath        = parameter.Name.VariablePath;
                bool isSwitchOrMandatory = false;
                Type type = null;
                foreach (var paramAst in parameter.Attributes)
                {
                    if (paramAst is TypeConstraintAst)
                    {
                        if (type == null)
                        {
                            type = paramAst.TypeName.GetReflectionType();
                        }

                        if (String.Equals(paramAst.TypeName.FullName, "switch", StringComparison.OrdinalIgnoreCase))
                        {
                            isSwitchOrMandatory = true;
                        }
                    }
                    else if (paramAst is AttributeAst)
                    {
                        var args = (paramAst as AttributeAst).NamedArguments;
                        if (args != null)
                        {
                            foreach (NamedAttributeArgumentAst arg in args)
                            {
                                if (String.Equals(arg.ArgumentName, "mandatory", StringComparison.OrdinalIgnoreCase) &&
                                    String.Equals(arg.Argument.Extent.Text, "$true", StringComparison.OrdinalIgnoreCase))
                                {
                                    isSwitchOrMandatory = true;
                                }
                            }
                        }
                    }
                }

                var varName = AssignmentTarget.GetUnaliasedVariableName(variablePath);
                var details = _variables[varName];
                details.Type = type ?? details.Type ?? typeof(object);

                if (parameter.DefaultValue != null)
                {
                    var assignTarget = new AssignmentTarget(varName, type);

                    if (parameter.DefaultValue is ConstantExpressionAst)
                    {
                        assignTarget.Constant = (parameter.DefaultValue as ConstantExpressionAst).Value;
                        assignTarget.Type     = assignTarget.Constant == null ? typeof(object) : assignTarget.Constant.GetType();
                    }

                    Entry.AddAst(assignTarget);
                }
                else if (isSwitchOrMandatory)
                {
                    // Consider switch or mandatory parameter as already initialized
                    Entry.AddAst(new AssignmentTarget(varName, type));
                }
                else
                {
                    VariableTarget varTarget = new VariableTarget(parameter.Name);
                    varTarget.Type = details.Type;
                    Entry.AddAst(varTarget);
                }
            }
        }
コード例 #9
0
 public ParameterGenerator AddPropertyAssignmentBlock(AssignmentTarget target)
 {
     _constructor.Statements.AddRange(GeneratePropertyAssignmentBlock(target));
     return(this);
 }
コード例 #10
0
 protected abstract IEnumerable <StatementSyntax> GeneratePropertyAssignmentBlock(AssignmentTarget target);
コード例 #11
0
 protected override IEnumerable <StatementSyntax> GeneratePropertyAssignmentBlock(AssignmentTarget target)
 => SourceType.GenerateConditionalPropertyAssginmentBlock(target, Name);
コード例 #12
0
        /// <summary>
        /// Used to analyze scriptbloct, functionmemberast or functiondefinitionast
        /// </summary>
        /// <param name="ast"></param>
        /// <returns></returns>
        public void AnalyzeImpl(Ast ast, VariableAnalysis outerAnalysis)
        {
            if (!(ast is ScriptBlockAst || ast is FunctionMemberAst || ast is FunctionDefinitionAst))
            {
                return;
            }

            _variables = FindAllVariablesVisitor.Visit(ast);

            Init();

            if (ast is FunctionMemberAst || ast is FunctionDefinitionAst)
            {
                IEnumerable <ParameterAst> parameters = FindParameters(ast, ast.GetType());
                if (parameters != null)
                {
                    ProcessParameters(parameters);
                }
            }
            else
            {
                ScriptBlockAst sbAst = ast as ScriptBlockAst;
                if (sbAst != null && sbAst.ParamBlock != null && sbAst.ParamBlock.Parameters != null)
                {
                    ProcessParameters(sbAst.ParamBlock.Parameters);
                }
            }

            if (ast is FunctionMemberAst)
            {
                (ast as FunctionMemberAst).Body.Visit(this.Decorator);
            }
            else if (ast is FunctionDefinitionAst)
            {
                (ast as FunctionDefinitionAst).Body.Visit(this.Decorator);
            }
            else
            {
                ast.Visit(this.Decorator);
            }

            Ast parent = ast;

            while (parent.Parent != null)
            {
                parent = parent.Parent;
            }

            List <TypeDefinitionAst> classes = parent.FindAll(item =>
                                                              item is TypeDefinitionAst && (item as TypeDefinitionAst).IsClass, true)
                                               .Cast <TypeDefinitionAst>().ToList();

            if (outerAnalysis != null)
            {
                // Initialize the variables from outside
                var outerDictionary = outerAnalysis.InternalVariablesDictionary;
                foreach (var details in outerDictionary.Values)
                {
                    if (details.DefinedBlock != null)
                    {
                        var assignTarget = new AssignmentTarget(details.RealName, details.Type);
                        assignTarget.Constant = details.Constant;
                        if (!_variables.ContainsKey(assignTarget.Name))
                        {
                            _variables.Add(assignTarget.Name, new VariableAnalysisDetails
                            {
                                Name     = assignTarget.Name,
                                RealName = assignTarget.Name,
                                Type     = assignTarget.Type
                            });
                        }
                        Entry.AddFirstAst(assignTarget);
                    }
                }

                foreach (var key in _variables.Keys)
                {
                    if (outerDictionary.ContainsKey(key))
                    {
                        var outerItem = outerDictionary[key];
                        var innerItem = _variables[key];
                        innerItem.Constant = outerItem.Constant;
                        innerItem.Name     = outerItem.Name;
                        innerItem.RealName = outerItem.RealName;
                        innerItem.Type     = outerItem.Type;
                    }
                }
            }

            var dictionaries = Block.SparseSimpleConstants(_variables, Entry, classes);

            VariablesDictionary         = dictionaries.Item1;
            InternalVariablesDictionary = new Dictionary <string, VariableAnalysisDetails>(StringComparer.OrdinalIgnoreCase);

            foreach (var KVP in dictionaries.Item2)
            {
                var analysis = KVP.Value;
                if (analysis == null)
                {
                    continue;
                }

                if (!InternalVariablesDictionary.ContainsKey(analysis.RealName))
                {
                    InternalVariablesDictionary.Add(analysis.RealName, analysis);
                }
                else
                {
                    InternalVariablesDictionary[analysis.RealName] = analysis;
                }
            }
        }
コード例 #13
0
 public IEnumerable <StatementSyntax> GenerateConditionalPropertyAssginmentBlock(AssignmentTarget target, IdentifierNameSyntax sourceObjectVariableName) =>
 new StatementSyntax[]
 {
     IfStatement(
         condition: BinaryExpression(
             SyntaxKind.NotEqualsExpression,
             left: sourceObjectVariableName,
             right: LiteralExpression(SyntaxKind.NullLiteralExpression)),
         statement: Block(GeneratePropertyAssginmentBlock(target, sourceObjectVariableName)))
 };
コード例 #14
0
        protected void SetAssignmentTarget(TargetInstruction instruction)
        {
            if (_currentAssignmentTarget != null)
            {
                throw new FormatException("Assignment target already set");
            }
            switch (instruction.Target)
            {
            // special strings
            case DataElement.SStr sstr:
                _currentAssignmentTarget = new AssignmentTarget.SpecialString(sstr.FlagType.StringValue);
                break;



            // integer variable pointers
            case DataElement.VInt vint when vint.FlagId.IsPointer:
                _currentAssignmentTarget = new AssignmentTarget.VariablePointer(vint.FlagType.StringValue, vint.FlagId.PointerId);
                break;



            // integer variables
            case DataElement.VInt vint:
                // range checks
                if (vint.FlagId.IntValue < 0)
                {
                    throw new ArgumentOutOfRangeException(nameof(vint.FlagId.IntValue), vint.FlagId.IntValue, "Flag index must be positive");
                }
                if (vint.FlagId.IntValue >= GlobalFlagTableSize && vint.FlagType.StringValue == YksFormat.GlobalFlag)
                {
                    throw new ArgumentOutOfRangeException(nameof(vint.FlagId.IntValue), vint.FlagId.IntValue, "Global flag index must be smaller than " + GlobalFlagTableSize);
                }
                if (vint.FlagId.IntValue >= LocalFlagTableSize && vint.FlagType.StringValue == YksFormat.Flag)
                {
                    throw new ArgumentOutOfRangeException(nameof(vint.FlagId.IntValue), vint.FlagId.IntValue, "Local flag index must be smaller than " + LocalFlagTableSize);
                }

                _currentAssignmentTarget = new AssignmentTarget.Variable(vint.FlagType.StringValue, vint.FlagId.IntValue);
                break;



            // string variable pointers
            case DataElement.VStr vstr when vstr.FlagId.IsPointer:
                _currentAssignmentTarget = new AssignmentTarget.VariablePointer(vstr.FlagType.StringValue, vstr.FlagId.PointerId);
                break;



            // integer variables
            case DataElement.VStr vstr:
                // range checks
                if (vstr.FlagId.IntValue < 0)
                {
                    throw new ArgumentOutOfRangeException(nameof(vstr.FlagId.IntValue), vstr.FlagId.IntValue, "String index must be positive");
                }
                if (vstr.FlagId.IntValue >= GlobalStringTableSize && vstr.FlagType.StringValue == YksFormat.GlobalString)
                {
                    throw new ArgumentOutOfRangeException(nameof(vstr.FlagId.IntValue), vstr.FlagId.IntValue, "String flag index must be smaller than " + GlobalStringTableSize);
                }
                if (vstr.FlagId.IntValue >= LocalStringTableSize && vstr.FlagType.StringValue == YksFormat.String)
                {
                    throw new ArgumentOutOfRangeException(nameof(vstr.FlagId.IntValue), vstr.FlagId.IntValue, "String flag index must be smaller than " + LocalStringTableSize);
                }

                _currentAssignmentTarget = new AssignmentTarget.Variable(vstr.FlagType.StringValue, vstr.FlagId.IntValue);
                break;



            // local variables
            case DataElement.VLoc vloc:
                if (vloc.Id >= Script.InstructionList.MaxLocals)
                {
                    throw new ArgumentOutOfRangeException(nameof(vloc.Id), vloc.Id, "Local variable id must be smaller than local variable pool size (" + Script.InstructionList.MaxLocals + ")");
                }
                _currentAssignmentTarget = new AssignmentTarget.Local(vloc.Id);
                break;



            // int pointers
            case DataElement.CInt cint:
                cint.Value.PointerId     = _flagPointerId++;
                _currentAssignmentTarget = new AssignmentTarget.IntPointer(cint.Value.PointerId);
                break;



            default:
                throw new ArgumentOutOfRangeException(nameof(instruction), "Invalid assignment target: " + instruction);
            }
        }
コード例 #15
0
        protected Statement ReadStatement()
        {
            var instruction = ReadInstruction();

            switch (instruction)
            {
            case LabelInstruction label:
                Debug.Assert(label.Name != "else" && label.Name != "}");
                if (label.Name == "{")
                {
                    return(ReadBlockStatement());
                }
                return(new JumpLabelStmt {
                    Name = label.Name.EscapeIdentifier()
                });

            case CallInstruction func:

                #region Handle assignments
                if (func.Name == "=")
                {
                    if (_currentAssignmentTarget == null)
                    {
                        throw new FormatException("No assignment target set");
                    }

                    Expression expr;
                    if (func.Arguments.Length == 0)
                    {
                        // a call to =() with no arguments means the result of the following function call is assigned
                        if (CurrentInstruction is CallInstruction callInstruction)
                        {
                            expr = new FunctionCallExpr {
                                CallStmt = new FunctionCallStmt {
                                    MethodName = callInstruction.Name, Arguments = MapToExpressions(callInstruction.Arguments)
                                }
                            };
                            _currentInstructionOffset++;
                        }
                        else
                        {
                            throw new FormatException("A parameterless call to =() must be followed by a function call, found " + CurrentInstruction);
                        }
                    }
                    else
                    {
                        // otherwise, the arguments are alternating operands and operators
                        expr = ToExpression(func.Arguments);
                    }

                    if (_currentAssignmentTarget is AssignmentTarget.Local local)
                    {
                        _locals[local.Id]        = expr;
                        _currentAssignmentTarget = null;
                        return(null);
                    }

                    var assigment = new AssignmentStmt {
                        Target = _currentAssignmentTarget, Expression = expr
                    };
                    _currentAssignmentTarget = null;
                    return(assigment);
                }
                #endregion

                var callStatement = new FunctionCallStmt {
                    MethodName = func.Name, Arguments = MapToExpressions(func.Arguments)
                };

                #region Handle body functions

                if (CurrentInstruction is LabelInstruction startLabel && startLabel.Name == "{")
                {
                    _currentInstructionOffset++;                             // skip opening brace

                    var body = ReadBlockStatement();

                    #region Handle if statements

                    if (callStatement.MethodName.ToLower() == "if")
                    {
                        if (Script.InstructionList.Count <= _currentInstructionOffset ||
                            !(Script.InstructionList[_currentInstructionOffset] is LabelInstruction elseKeyword) ||
                            elseKeyword.Name != "else")
                        {
                            // no else block
                            return new IfStmt {
                                       Function = callStatement, Body = body
                            }
                        }
                        ;

                        BlockStmt elseBody;
                        // skip else keyword
                        _currentInstructionOffset++;
                        if (Script.InstructionList[_currentInstructionOffset] is LabelInstruction elseStart && elseStart.Name == "{")
                        {
                            // skip opening brace
                            _currentInstructionOffset++;

                            elseBody = ReadBlockStatement();
                        }
                        else
                        {
                            // "Kimi o Aogi Otome wa Hime ni" has these bodyless else keywords in data01:system/selectjumpstart.yks
                            Console.WriteLine("Warning: Loose else keyword without body");
                            elseBody = new BlockStmt();
                            //throw new FormatException("Else keyword must be followed by an opening brace");
                        }

                        return(new IfStmt {
                            Function = callStatement, Body = body, ElseBody = elseBody
                        });
                    }

                    #endregion

                    return(new BodyFunctionStmt {
                        Function = callStatement, Body = body
                    });
                }

                #endregion

                return(callStatement);

            case TargetInstruction target:
                SetAssignmentTarget(target);
                return(null);

            default:
                throw new FormatException("Invalid statement instruction: " + instruction);
            }
        }
コード例 #16
0
ファイル: Compiler.cs プロジェクト: wmltogether/yukatool2
 protected TargetInstruction CreateTargetInstruction(AssignmentTarget target)
 {
     return(new TargetInstruction(CreateTargetElement(target), _instructions));
 }
コード例 #17
0
ファイル: PropertyRule.cs プロジェクト: InspiringCode/DX.CQRS
 public abstract StatementSyntax GetAssignmentStatement(
     AssignmentTarget target,
     SourceProperty p,
     IdentifierNameSyntax sourceObjectVariableName);
コード例 #18
0
 private IEnumerable <StatementSyntax> GeneratePropertyAssginmentBlock(AssignmentTarget target, IdentifierNameSyntax sourceObjectVariableName) =>
 Properties.Select(p =>
                   PropertyRule.GetRule(p).GetAssignmentStatement(target, p, sourceObjectVariableName));
コード例 #19
0
 public IEnumerable <StatementSyntax> GeneratePropertyAssginmentBlockWithNullCheck(AssignmentTarget target, IdentifierNameSyntax sourceObjectVariableName) =>
 new[] { GenerateNullCheck(sourceObjectVariableName) }.Concat(GeneratePropertyAssginmentBlock(target, sourceObjectVariableName));