示例#1
0
        //private void analyzeSharpDim(StringStream st, ScriptPosition position, bool dims)
        //{
        //	//WordCollection wc = LexicalAnalyzer.Analyse(st, LexEndWith.EoL, LexAnalyzeFlag.AllowAssignment);
        //	//UserDefinedVariableData data = UserDefinedVariableData.Create(wc, dims, false, position);
        //	//if (data.Reference)
        //	//	throw new NotImplCodeEE();
        //	//VariableToken var = null;
        //	//if (data.CharaData)
        //	//	var = parentProcess.VEvaluator.VariableData.CreateUserDefCharaVariable(data);
        //	//else
        //	//	var = parentProcess.VEvaluator.VariableData.CreateUserDefVariable(data);
        //	//idDic.AddUseDefinedVariable(var);
        //}

        //1822 #DIMだけまとめておいて後で処理
        private bool analyzeSharpDimLines()
        {
            bool noError  = true;
            bool tryAgain = true;

            while (dimlines.Count > 0)
            {
                int count = dimlines.Count;
                for (int i = 0; i < count; i++)
                {
                    DimLineWC dimline = dimlines.Dequeue();
                    try
                    {
                        UserDefinedVariableData data = UserDefinedVariableData.Create(dimline);
                        if (data.Reference)
                        {
                            throw new NotImplCodeEE();
                        }
                        VariableToken var = null;
                        if (data.CharaData)
                        {
                            var = parentProcess.VEvaluator.VariableData.CreateUserDefCharaVariable(data);
                        }
                        else
                        {
                            var = parentProcess.VEvaluator.VariableData.CreateUserDefVariable(data);
                        }
                        idDic.AddUseDefinedVariable(var);
                    }
                    catch (IdentifierNotFoundCodeEE e)
                    {
                        //繰り返すことで解決する見込みがあるならキューの最後に追加
                        if (tryAgain)
                        {
                            dimline.WC.Pointer = 0;
                            dimlines.Enqueue(dimline);
                        }
                        else
                        {
                            ParserMediator.Warn(e.Message, dimline.SC, 2);
                            noError = true;
                        }
                    }
                    catch (CodeEE e)
                    {
                        ParserMediator.Warn(e.Message, dimline.SC, 2);
                        noError = false;
                    }
                }
                if (dimlines.Count == count)
                {
                    tryAgain = false;
                }
            }
            return(noError);
        }
示例#2
0
        private void analyzeSharpDim(StringStream st, ScriptPosition position, bool dims)
        {
            var wc   = LexicalAnalyzer.Analyse(st, LexEndWith.EoL, LexAnalyzeFlag.AllowAssignment);
            var data = UserDefinedVariableData.Create(wc, dims, false, position);

            if (data.Reference)
            {
                throw new NotImplCodeEE();
            }
            VariableToken var = null;

            if (data.CharaData)
            {
                var = parentProcess.VEvaluator.VariableData.CreateUserDefCharaVariable(data);
            }
            else
            {
                var = parentProcess.VEvaluator.VariableData.CreateUserDefVariable(data);
            }
            idDic.AddUseDefinedVariable(var);
        }
示例#3
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);
        }