Пример #1
0
        public static CalledFunction CallFunction(Process parent, string label, LogicalLine retAddress)
        {
            CalledFunction called = new CalledFunction(label);

            called.Finished = false;
            FunctionLabelLine labelline = parent.LabelDictionary.GetNonEventLabel(label);

            if (labelline == null)
            {
                if (parent.LabelDictionary.GetEventLabels(label) != null)
                {
                    throw new CodeEE("イベント関数@" + label + "に対し通常のCALLが行われました(このエラーは互換性オプション「" + Config.GetConfigName(ConfigCode.CompatiCallEvent) + "」により無視できます)");
                }
                return(null);
            }
            else if (labelline.IsMethod)
            {
                throw new CodeEE("#FUCNTION(S)が定義された関数@" + labelline.LabelName + "(" + labelline.Position.Filename + ":" + labelline.Position.LineNo.ToString() + "行目)に対し通常のCALLが行われました");
            }
            called.TopLabel      = labelline;
            called.CurrentLabel  = labelline;
            called.returnAddress = retAddress;
            called.IsEvent       = false;
            return(called);
        }
Пример #2
0
        public FunctionLabelLine GetNonEventLabel(string key)
        {
            FunctionLabelLine ret = null;

            noneventLabelDic.TryGetValue(key, out ret);
            return(ret);
        }
Пример #3
0
        public static CalledFunction CreateCalledFunctionMethod(FunctionLabelLine labelline, string label)
        {
            var called = new CalledFunction(label);

            called.TopLabel      = labelline;
            called.CurrentLabel  = labelline;
            called.ReturnAddress = null;
            called.IsEvent       = false;
            return(called);
        }
Пример #4
0
 public GotoLabelLine GetLabelDollar(string key, FunctionLabelLine labelAtLine)
 {
     foreach (GotoLabelLine label in labelDollarList)
     {
         if ((label.LabelName == key) && (label.ParentLabelLine == labelAtLine))
         {
             return(label);
         }
     }
     return(null);
 }
Пример #5
0
        public void AddLabel(FunctionLabelLine point)
        {
            point.Index     = count;
            point.FileIndex = currentFileCount;
            count++;
            string id = point.LabelName;
            List <FunctionLabelLine> function_label_line_list = null;

            if (!labelAtDic.TryGetValue(id, out function_label_line_list))
            {
                function_label_line_list = new List <FunctionLabelLine>();
                labelAtDic.Add(id, function_label_line_list);
            }
            function_label_line_list.Add(point);
        }
Пример #6
0
        public void AddLabel(FunctionLabelLine point)
        {
            point.Index     = count;
            point.FileIndex = currentFileCount;
            count++;
            string id = point.LabelName;

            if (labelAtDic.ContainsKey(id))
            {
                labelAtDic[id].Add(point);
            }
            else
            {
                List <FunctionLabelLine> labelList = new List <FunctionLabelLine>();
                labelList.Add(point);
                labelAtDic.Add(id, labelList);
            }
        }
Пример #7
0
        public FunctionLabelLine GetSameNameLabel(FunctionLabelLine point)
        {
            string id = point.LabelName;

            if (!labelAtDic.ContainsKey(id))
            {
                return(null);
            }
            if (point.IsError)
            {
                return(null);
            }
            List <FunctionLabelLine> labelList = labelAtDic[id];

            if (labelList.Count <= 1)
            {
                return(null);
            }
            return(labelList[0]);
        }
Пример #8
0
        public static CalledFunction CallEventFunction(Process parent, string label, LogicalLine retAddress)
        {
            CalledFunction           called       = new CalledFunction(label);
            List <FunctionLabelLine> newLabelList = new List <FunctionLabelLine>();

            called.Finished       = false;
            called.eventLabelList = parent.LabelDictionary.GetEventLabels(label);
            if (called.eventLabelList == null)
            {
                FunctionLabelLine line = parent.LabelDictionary.GetNonEventLabel(label);
                if (parent.LabelDictionary.GetNonEventLabel(label) != null)
                {
                    throw new CodeEE("イベント関数でない関数@" + label + "(" + line.Position.Filename + ":" + line.Position.LineNo + "行目)に対しEVENT呼び出しが行われました");
                }
                return(null);
            }
            called.counter = -1;
            called.group   = 0;
            called.ShiftNext();
            called.TopLabel      = called.CurrentLabel;
            called.returnAddress = retAddress;
            called.IsEvent       = true;
            return(called);
        }
Пример #9
0
        public static LogicalLine ParseLabelLine(StringStream stream, ScriptPosition position, EmueraConsole console)
        {
            var isFunction = stream.Current == '@';
            var lineNo     = position.LineNo;
            var labelName  = "";
            var errMes     = "";

            try
            {
                var warnLevel = -1;
                stream.ShiftNext(); //@か$を除去
                var wc = LexicalAnalyzer.Analyse(stream, LexEndWith.EoL, LexAnalyzeFlag.AllowAssignment);
                if (wc.EOL || !(wc.Current is IdentifierWord))
                {
                    errMes = "関数名が不正であるか存在しません";
                    goto err;
                }
                labelName = ((IdentifierWord)wc.Current).Code;
                wc.ShiftNext();
                if (Config.ICVariable)
                {
                    labelName = labelName.ToUpper();
                }
                GlobalStatic.IdentifierDictionary.CheckUserLabelName(ref errMes, ref warnLevel, isFunction, labelName);
                if (warnLevel >= 0)
                {
                    if (warnLevel >= 2)
                    {
                        goto err;
                    }
                    ParserMediator.Warn(errMes, position, warnLevel);
                }
                if (!isFunction) //$ならこの時点で終了
                {
                    if (!wc.EOL)
                    {
                        ParserMediator.Warn("$で始まるラベルに引数が設定されています", position, 1);
                    }
                    return(new GotoLabelLine(position, labelName));
                }


                //labelName = LexicalAnalyzer.ReadString(stream, StrEndWith.LeftParenthesis_Bracket_Comma_Semicolon);
                //labelName = labelName.Trim();
                //if (Config.ICVariable)
                //    labelName = labelName.ToUpper();
                //GlobalStatic.IdentifierDictionary.CheckUserLabelName(ref errMes, ref warnLevel, isFunction, labelName);
                //if(warnLevel >= 0)
                //{
                //    if (warnLevel >= 2)
                //        goto err;
                //    ParserMediator.Warn(errMes, position, warnLevel);
                //}
                //if (!isFunction)//$ならこの時点で終了
                //{
                //    LexicalAnalyzer.SkipWhiteSpace(stream);
                //    if (!stream.EOS)
                //        ParserMediator.Warn("$で始まるラベルに引数が設定されています", position, 1);
                //    return new GotoLabelLine(position, labelName);
                //}

                ////関数名部分に_renameを使えないように変更
                //if (ParserMediator.RenameDic != null && ((stream.ToString().IndexOf("[[") >= 0) && (stream.ToString().IndexOf("]]") >= 0)))
                //{
                //    string line = stream.ToString();
                //    foreach (KeyValuePair<string, string> pair in ParserMediator.RenameDic)
                //        line = line.Replace(pair.Key, pair.Value);
                //    stream = new StringStream(line);
                //}
                //WordCollection wc = null;
                //wc = LexicalAnalyzer.Analyse(stream, LexEndWith.EoL, LexAnalyzeFlag.AllowAssignment);
                if (Program.AnalysisMode)
                {
                    console.PrintC("@" + labelName, false);
                }
                var funclabelLine = new FunctionLabelLine(position, labelName, wc);
                if (IdentifierDictionary.IsEventLabelName(labelName))
                {
                    funclabelLine.IsEvent  = true;
                    funclabelLine.IsSystem = true;
                    funclabelLine.Depth    = 0;
                }
                else if (IdentifierDictionary.IsSystemLabelName(labelName))
                {
                    funclabelLine.IsSystem = true;
                    funclabelLine.Depth    = 0;
                }
                return(funclabelLine);
            }
            catch (CodeEE e)
            {
                errMes = e.Message;
            }
err:
            SystemSounds.Hand.Play();
            if (isFunction)
            {
                if (labelName.Length == 0)
                {
                    labelName = "<Error>";
                }
                return(new InvalidLabelLine(position, labelName, errMes));
            }
            return(new InvalidLine(position, errMes));
        }
Пример #10
0
        public static bool ParseSharpLine(FunctionLabelLine label, StringStream st, ScriptPosition position,
                                          List <string> OnlyLabel)
        {
            st.ShiftNext();                                       //'#'を飛ばす
            var token = LexicalAnalyzer.ReadSingleIdentifier(st); //#~自体にはマクロ非適用

            if (Config.ICFunction)
            {
                token = token.ToUpper();
            }
            //#行として不正な行でもAnalyzeに行って引っかかることがあるので、先に存在しない#~は弾いてしまう
            if (token == null || token != "SINGLE" && token != "LATER" && token != "PRI" && token != "ONLY" &&
                token != "FUNCTION" && token != "FUNCTIONS" &&
                token != "LOCALSIZE" && token != "LOCALSSIZE" && token != "DIM" && token != "DIMS")
            {
                ParserMediator.Warn("解釈できない#行です", position, 1);
                return(false);
            }
            try
            {
                var wc = LexicalAnalyzer.Analyse(st, LexEndWith.EoL, LexAnalyzeFlag.AllowAssignment);
                switch (token)
                {
                case "SINGLE":
                    if (label.IsMethod)
                    {
                        ParserMediator.Warn("式中関数では#SINGLEは機能しません", position, 1);
                        break;
                    }
                    else if (!label.IsEvent)
                    {
                        ParserMediator.Warn("イベント関数以外では#SINGLEは機能しません", position, 1);
                        break;
                    }
                    else if (label.IsSingle)
                    {
                        ParserMediator.Warn("#SINGLEが重複して使われています", position, 1);
                        break;
                    }
                    else if (label.IsOnly)
                    {
                        ParserMediator.Warn("#ONLYが指定されたイベント関数では#SINGLEは機能しません", position, 1);
                        break;
                    }
                    label.IsSingle = true;
                    break;

                case "LATER":
                    if (label.IsMethod)
                    {
                        ParserMediator.Warn("式中関数では#LATERは機能しません", position, 1);
                        break;
                    }
                    else if (!label.IsEvent)
                    {
                        ParserMediator.Warn("イベント関数以外では#LATERは機能しません", position, 1);
                        break;
                    }
                    else if (label.IsLater)
                    {
                        ParserMediator.Warn("#LATERが重複して使われています", position, 1);
                        break;
                    }
                    else if (label.IsOnly)
                    {
                        ParserMediator.Warn("#ONLYが指定されたイベント関数では#LATERは機能しません", position, 1);
                        break;
                    }
                    else if (label.IsPri)
                    {
                        ParserMediator.Warn("#PRIと#LATERが重複して使われています(この関数は2度呼ばれます)", position, 1);
                    }
                    label.IsLater = true;
                    break;

                case "PRI":
                    if (label.IsMethod)
                    {
                        ParserMediator.Warn("式中関数では#PRIは機能しません", position, 1);
                        break;
                    }
                    else if (!label.IsEvent)
                    {
                        ParserMediator.Warn("イベント関数以外では#PRIは機能しません", position, 1);
                        break;
                    }
                    else if (label.IsPri)
                    {
                        ParserMediator.Warn("#PRIが重複して使われています", position, 1);
                        break;
                    }
                    else if (label.IsOnly)
                    {
                        ParserMediator.Warn("#ONLYが指定されたイベント関数では#PRIは機能しません", position, 1);
                        break;
                    }
                    else if (label.IsLater)
                    {
                        ParserMediator.Warn("#PRIと#LATERが重複して使われています(この関数は2度呼ばれます)", position, 1);
                    }
                    label.IsPri = true;
                    break;

                case "ONLY":
                    if (label.IsMethod)
                    {
                        ParserMediator.Warn("式中関数では#ONLYは機能しません", position, 1);
                        break;
                    }
                    else if (!label.IsEvent)
                    {
                        ParserMediator.Warn("イベント関数以外では#ONLYは機能しません", position, 1);
                        break;
                    }
                    else if (label.IsOnly)
                    {
                        ParserMediator.Warn("#ONLYが重複して使われています", position, 1);
                        break;
                    }
                    else if (OnlyLabel.Contains(label.LabelName))
                    {
                        ParserMediator.Warn("このイベント関数\"@" + label.LabelName + "\"にはすでに#ONLYが宣言されています(この関数は実行されません)",
                                            position, 1);
                    }
                    OnlyLabel.Add(label.LabelName);
                    label.IsOnly = true;
                    if (label.IsPri)
                    {
                        ParserMediator.Warn("このイベント関数には#PRIが宣言されていますが無視されます", position, 1);
                        label.IsPri = false;
                    }
                    if (label.IsLater)
                    {
                        ParserMediator.Warn("このイベント関数には#LATERが宣言されていますが無視されます", position, 1);
                        label.IsLater = false;
                    }
                    if (label.IsSingle)
                    {
                        ParserMediator.Warn("このイベント関数には#SINGLEが宣言されていますが無視されます", position, 1);
                        label.IsSingle = false;
                    }
                    break;

                case "FUNCTION":
                case "FUNCTIONS":
                    if (!string.IsNullOrEmpty(label.LabelName) && char.IsDigit(label.LabelName[0]))
                    {
                        ParserMediator.Warn("#" + token + "属性は関数名が数字で始まる関数には指定できません", position, 1);
                        label.IsError = true;
                        label.ErrMes  = "関数名が数字で始まっています";
                        break;
                    }
                    if (label.IsMethod)
                    {
                        if (label.MethodType == typeof(long) && token == "FUNCTION" ||
                            label.MethodType == typeof(string) && token == "FUNCTIONS")
                        {
                            ParserMediator.Warn("関数" + label.LabelName + "にはすでに#" + token + "が宣言されています(この行は無視されます)",
                                                position, 1);
                            return(false);
                        }
                        if (label.MethodType == typeof(long) && token == "FUNCTIONS")
                        {
                            ParserMediator.Warn("関数" + label.LabelName + "にはすでに#FUNCTIONが宣言されています", position, 2);
                        }
                        else if (label.MethodType == typeof(string) && token == "FUNCTION")
                        {
                            ParserMediator.Warn("関数" + label.LabelName + "にはすでに#FUNCTIONSが宣言されています", position, 2);
                        }
                        return(false);
                    }
                    if (label.Depth == 0)
                    {
                        ParserMediator.Warn("システム関数に#" + token + "が指定されています", position, 2);
                        return(false);
                    }
                    label.IsMethod = true;
                    label.Depth    = 0;
                    if (token == "FUNCTIONS")
                    {
                        label.MethodType = typeof(string);
                    }
                    else
                    {
                        label.MethodType = typeof(long);
                    }
                    if (label.IsPri)
                    {
                        ParserMediator.Warn("式中関数では#PRIは機能しません", position, 1);
                        label.IsPri = false;
                    }
                    if (label.IsLater)
                    {
                        ParserMediator.Warn("式中関数では#LATERは機能しません", position, 1);
                        label.IsLater = false;
                    }
                    if (label.IsSingle)
                    {
                        ParserMediator.Warn("式中関数では#SINGLEは機能しません", position, 1);
                        label.IsSingle = false;
                    }
                    if (label.IsOnly)
                    {
                        ParserMediator.Warn("式中関数では#ONLYは機能しません", position, 1);
                        label.IsOnly = false;
                    }
                    break;

                case "LOCALSIZE":
                case "LOCALSSIZE":
                {
                    if (wc.EOL)
                    {
                        ParserMediator.Warn("#" + token + "の後に有効な数値が指定されていません", position, 2);
                        break;
                    }
                    //イベント関数では指定しても無視される
                    if (label.IsEvent)
                    {
                        ParserMediator.Warn(
                            "イベント関数では#" + token + "による" + token.Substring(0, token.Length - 4) + "のサイズ指定は無視されます",
                            position, 1);
                        break;
                    }
                    var arg      = ExpressionParser.ReduceIntegerTerm(wc, TermEndWith.EoL);
                    var sizeTerm = arg.Restructure(null) as SingleTerm;
                    if (sizeTerm == null || sizeTerm.GetOperandType() != typeof(long))
                    {
                        ParserMediator.Warn("#" + token + "の後に有効な定数式が指定されていません", position, 2);
                        break;
                    }
                    if (sizeTerm.Int <= 0)
                    {
                        ParserMediator.Warn("#" + token + "に0以下の値(" + sizeTerm.Int + ")が与えられました。設定は無視されます",
                                            position, 1);
                        break;
                    }
                    if (sizeTerm.Int >= int.MaxValue)
                    {
                        ParserMediator.Warn("#" + token + "に大きすぎる値(" + sizeTerm.Int + ")が与えられました。設定は無視されます",
                                            position, 1);
                        break;
                    }
                    var size = (int)sizeTerm.Int;
                    if (token == "LOCALSIZE")
                    {
                        if (GlobalStatic.IdentifierDictionary.getLocalIsForbid("LOCAL"))
                        {
                            ParserMediator.Warn("#" + token + "が指定されていますが変数LOCALは使用禁止されています", position, 2);
                            break;
                        }
                        if (label.LocalLength > 0)
                        {
                            ParserMediator.Warn("この関数にはすでに#LOCALSIZEが定義されています。(以前の定義は無視されます)", position, 1);
                        }
                        label.LocalLength = size;
                    }
                    else
                    {
                        if (GlobalStatic.IdentifierDictionary.getLocalIsForbid("LOCALS"))
                        {
                            ParserMediator.Warn("#" + token + "が指定されていますが変数LOCALSは使用禁止されています", position, 2);
                            break;
                        }
                        if (label.LocalsLength > 0)
                        {
                            ParserMediator.Warn("この関数にはすでに#LOCALSSIZEが定義されています。(以前の定義は無視されます)", position, 1);
                        }
                        label.LocalsLength = size;
                    }
                }
                break;

                case "DIM":
                case "DIMS":
                {
                    var data = UserDefinedVariableData.Create(wc, token == "DIMS", true, position);
                    if (!label.AddPrivateVariable(data))
                    {
                        ParserMediator.Warn("変数名" + data.Name + "は既に使用されています", position, 2);
                        return(false);
                    }
                    break;
                }

                default:
                    ParserMediator.Warn("解釈できない#行です", position, 1);
                    break;
                }
                if (!wc.EOL)
                {
                    ParserMediator.Warn("#の識別子の後に余分な文字があります", position, 1);
                }
            }
            catch (Exception e)
            {
                ParserMediator.Warn(e.Message, position, 2);
                goto err;
            }
            return(true);

err:
            return(false);
        }
Пример #11
0
 internal void AddInvalidLabel(FunctionLabelLine invalidLabelLine)
 {
     invalidList.Add(invalidLabelLine);
 }
Пример #12
0
 public void IntoFunction(CalledFunction call, UserDefinedFunctionArgument srcArgs, ExpressionMediator exm)
 {
     if (call.IsEvent)
     {
         foreach (CalledFunction called in functionList)
         {
             if (called.IsEvent)
             {
                 throw new CodeEE("EVENT関数の解決前にCALLEVENT命令が行われました");
             }
         }
     }
     if (Program.DebugMode)
     {
         FunctionLabelLine label = call.CurrentLabel;
         if (call.IsJump)
         {
             console.DebugAddTraceLog("JUMP :@" + label.LabelName + ":" + label.Position.ToString() + "行目");
         }
         else
         {
             console.DebugAddTraceLog("CALL :@" + label.LabelName + ":" + label.Position.ToString() + "行目");
         }
     }
     if (srcArgs != null)
     {
         //引数の値を確定させる
         srcArgs.SetTransporter(exm);
         //プライベート変数更新
         if (call.TopLabel.hasPrivDynamicVar)
         {
             call.TopLabel.In();
         }
         //更新した変数へ引数を代入
         for (int i = 0; i < call.TopLabel.Arg.Length; i++)
         {
             if (srcArgs.Arguments[i] != null)
             {
                 if (call.TopLabel.Arg[i].Identifier.IsReference)
                 {
                     ((ReferenceToken)(call.TopLabel.Arg[i].Identifier)).SetRef(srcArgs.TransporterRef[i]);
                 }
                 else if (srcArgs.Arguments[i].GetOperandType() == typeof(Int64))
                 {
                     call.TopLabel.Arg[i].SetValue(srcArgs.TransporterInt[i], exm);
                 }
                 else
                 {
                     call.TopLabel.Arg[i].SetValue(srcArgs.TransporterStr[i], exm);
                 }
             }
         }
     }
     else//こっちに来るのはシステムからの呼び出し=引数は存在しない関数のみ ifネストの外に出していい気もしないでもないがはてさて
     {
         //プライベート変数更新
         if (call.TopLabel.hasPrivDynamicVar)
         {
             call.TopLabel.In();
         }
     }
     functionList.Add(call);
     //sequential = false;
     currentLine = call.CurrentLabel;
     lineCount++;
     //ShfitNextLine();
 }
Пример #13
0
        public void Return(Int64 ret)
        {
            if (IsFunctionMethod)
            {
                ReturnF(null);
                return;
            }
            //sequential = false;//いずれにしろ順列ではない。
            //呼び出し元は全部スクリプト処理
            //if (functionList.Count == 0)
            //{
            //    throw new ExeEE("実行中の関数が存在しません");
            //}
            CalledFunction called = functionList[functionList.Count - 1];

            if (called.IsJump)
            {            //JUMPした場合。即座にRETURN RESULTする。
                if (called.TopLabel.hasPrivDynamicVar)
                {
                    called.TopLabel.Out();
                }
                functionList.Remove(called);
                if (Program.DebugMode)
                {
                    console.DebugRemoveTraceLog();
                }
                Return(ret);
                return;
            }
            if (!called.IsEvent)
            {
                if (called.TopLabel.hasPrivDynamicVar)
                {
                    called.TopLabel.Out();
                }
                currentLine = null;
            }
            else
            {
                if (called.CurrentLabel.hasPrivDynamicVar)
                {
                    called.CurrentLabel.Out();
                }
                //#Singleフラグ付き関数で1が返された。
                //1752 非0ではなく1と等価であることを見るように修正
                //1756 全てを終了ではなく#PRIや#LATERのグループごとに修正
                if (called.IsOnly)
                {
                    called.FinishEvent();
                }
                else if ((called.HasSingleFlag) && (ret == 1))
                {
                    called.ShiftNextGroup();
                }
                else
                {
                    called.ShiftNext();            //次の同名関数に進む。
                }
                currentLine = called.CurrentLabel; //関数の始点(@~~)へ移動。呼ぶべき関数が無ければnull
                if (called.CurrentLabel != null)
                {
                    lineCount++;
                    if (called.CurrentLabel.hasPrivDynamicVar)
                    {
                        called.CurrentLabel.In();
                    }
                }
            }
            if (Program.DebugMode)
            {
                console.DebugRemoveTraceLog();
            }
            //関数終了
            if (currentLine == null)
            {
                currentLine = called.ReturnAddress;
                functionList.RemoveAt(functionList.Count - 1);
                if (currentLine == null)
                {
                    //この時点でfunctionListは空のはず
                    //functionList.Clear();//全て終了。stateEndProcessに処理を返す
                    if (begintype != BeginType.NULL)                    //BEGIN XXが行なわれていれば
                    {
                        Begin();
                    }
                    return;
                }
                lineCount++;
                //ShfitNextLine();
                return;
            }
            else if (Program.DebugMode)
            {
                FunctionLabelLine label = called.CurrentLabel;
                console.DebugAddTraceLog("CALL :@" + label.LabelName + ":" + label.Position.ToString() + "行目");
            }
            lineCount++;
            //ShfitNextLine();
            return;
        }
Пример #14
0
        /// <summary>
        /// 1803beta005 予め引数の数を合わせて規定値を代入しておく
        /// 1806+v6.99 式中関数の引数に無効な#DIM変数を与えている場合に例外になるのを修正
        /// 1808beta009 REF型に対応
        /// </summary>
        public UserDefinedFunctionArgument ConvertArg(IOperandTerm[] srcArgs, out string errMes)
        {
            errMes = null;
            if (TopLabel.IsError)
            {
                errMes = TopLabel.ErrMes;
                return(null);
            }
            FunctionLabelLine func = TopLabel;

            IOperandTerm[] convertedArg = new IOperandTerm[func.Arg.Length];
            if (convertedArg.Length < srcArgs.Length)
            {
                errMes = "引数の数が関数\"@" + func.LabelName + "\"に設定された数を超えています";
                return(null);
            }
            IOperandTerm term     = null;
            VariableTerm destArg  = null;
            bool         isString = false;

            for (int i = 0; i < func.Arg.Length; i++)
            {
                term     = (i < srcArgs.Length) ? srcArgs[i] : null;
                destArg  = func.Arg[i];
                isString = destArg.IsString;
                if (destArg.Identifier.IsReference)                //参照渡しの場合
                {
                    if (term == null)
                    {
                        errMes = "\"@" + func.LabelName + "\"の" + (i + 1).ToString() + "番目の引数は参照渡しのため省略できません";
                        return(null);
                    }
                    VariableTerm vTerm = term as VariableTerm;
                    if (vTerm == null || vTerm.Identifier.Dimension == 0)
                    {
                        errMes = "\"@" + func.LabelName + "\"の" + (i + 1).ToString() + "番目の引数は参照渡しのための配列変数でなければなりません";
                        return(null);
                    }
                    //TODO 1810alpha007 キャラ型を認めるかどうかはっきりしたい 今のところ認めない方向
                    //型チェック
                    if (!((ReferenceToken)destArg.Identifier).MatchType(vTerm.Identifier, false, out errMes))
                    {
                        errMes = "\"@" + func.LabelName + "\"の" + (i + 1).ToString() + "番目の引数:" + errMes;
                        return(null);
                    }
                }
                else if (term == null)                //引数が省略されたとき
                {
                    term = func.Def[i];               //デフォルト値を代入
                    //1808beta001 デフォルト値がない場合はエラーにする
                    //一応逃がす
                    if (term == null && !Config.CompatiFuncArgOptional)
                    {
                        errMes = "\"@" + func.LabelName + "\"の" + (i + 1).ToString() + "番目の引数は省略できません(この警告は互換性オプション「" + Config.GetConfigName(ConfigCode.CompatiFuncArgOptional) + "」により無視できます)";
                        return(null);
                    }
                }
                else if (term.GetOperandType() != destArg.GetOperandType())
                {
                    if (term.GetOperandType() == typeof(string))
                    {
                        errMes = "\"@" + func.LabelName + "\"の" + (i + 1).ToString() + "番目の引数を文字列型から整数型に変換できません";
                        return(null);
                    }
                    else
                    {
                        if (!Config.CompatiFuncArgAutoConvert)
                        {
                            errMes = "\"@" + func.LabelName + "\"の" + (i + 1).ToString() + "番目の引数を整数型から文字列型に変換できません(この警告は互換性オプション「" + Config.GetConfigName(ConfigCode.CompatiFuncArgAutoConvert) + "」により無視できます)";
                            return(null);
                        }
                        if (tostrMethod == null)
                        {
                            tostrMethod = FunctionMethodCreator.GetMethodList()["TOSTR"];
                        }
                        term = new FunctionMethodTerm(tostrMethod, new IOperandTerm[] { term });
                    }
                }
                convertedArg[i] = term;
            }
            return(new UserDefinedFunctionArgument(convertedArg, func.Arg));
        }