示例#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
        internal bool AddPrivateVariable(UserDefinedVariableData data)
        {
            if (privateVar.ContainsKey(data.Name))
            {
                return(false);
            }
            UserDefinedVariableToken var = GlobalStatic.VariableData.CreatePrivateVariable(data);

            privateVar.Add(data.Name, var);
            //静的な変数のみの場合は関数呼び出し時に何もする必要がない
            if (!data.Static)
            {
                hasPrivDynamicVar = true;
            }
            return(true);
        }
示例#3
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);
        }
示例#4
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);
        }
示例#5
0
        public static UserDefinedVariableData Create(WordCollection wc, bool dims, bool isPrivate, ScriptPosition sc)
        {
            string dimtype = dims ? "#DIM" : "#DIMS";
            UserDefinedVariableData ret = new UserDefinedVariableData();

            ret.TypeIsStr = dims;

            IdentifierWord idw           = null;
            bool           staticDefined = false;

            ret.Const = false;
            string        keyword  = dimtype;
            List <string> keywords = new List <string>();

            while (!wc.EOL && (idw = wc.Current as IdentifierWord) != null)
            {
                wc.ShiftNext();
                keyword = idw.Code;
                if (Config.ICVariable)
                {
                    keyword = keyword.ToUpper();
                }
                //TODO ifの数があたまわるい なんとかしたい
                switch (keyword)
                {
                case "CONST":
                    if (ret.CharaData)
                    {
                        throw new CodeEE(keyword + "とCHARADATAキーワードは同時に指定できません", sc);
                    }
                    if (ret.Global)
                    {
                        throw new CodeEE(keyword + "とGLOBALキーワードは同時に指定できません", sc);
                    }
                    if (ret.Save)
                    {
                        throw new CodeEE(keyword + "とSAVEDATAキーワードは同時に指定できません", sc);
                    }
                    if (ret.Reference)
                    {
                        throw new CodeEE(keyword + "とREFキーワードは同時に指定できません", sc);
                    }
                    if (!ret.Static)
                    {
                        throw new CodeEE(keyword + "とDYNAMICキーワードは同時に指定できません", sc);
                    }
                    if (ret.Const)
                    {
                        throw new CodeEE(keyword + "キーワードが二重に指定されています", sc);
                    }
                    ret.Const = true;
                    break;

                case "REF":
                    //throw new CodeEE("未実装の機能です", sc);
                    //if (!isPrivate)
                    //	throw new CodeEE("広域変数の宣言に" + keyword + "キーワードは指定できません", sc);
                    if (staticDefined && ret.Static)
                    {
                        throw new CodeEE(keyword + "とSTATICキーワードは同時に指定できません", sc);
                    }
                    if (ret.CharaData)
                    {
                        throw new CodeEE(keyword + "とCHARADATAキーワードは同時に指定できません", sc);
                    }
                    if (ret.Global)
                    {
                        throw new CodeEE(keyword + "とGLOBALキーワードは同時に指定できません", sc);
                    }
                    if (ret.Save)
                    {
                        throw new CodeEE(keyword + "とSAVEDATAキーワードは同時に指定できません", sc);
                    }
                    if (ret.Const)
                    {
                        throw new CodeEE(keyword + "とCONSTキーワードは同時に指定できません", sc);
                    }
                    if (ret.Reference)
                    {
                        throw new CodeEE(keyword + "キーワードが二重に指定されています", sc);
                    }
                    ret.Reference = true;
                    ret.Static    = true;
                    break;

                case "DYNAMIC":
                    if (!isPrivate)
                    {
                        throw new CodeEE("広域変数の宣言に" + keyword + "キーワードは指定できません", sc);
                    }
                    if (ret.CharaData)
                    {
                        throw new CodeEE(keyword + "とCHARADATAキーワードは同時に指定できません", sc);
                    }
                    if (ret.Const)
                    {
                        throw new CodeEE(keyword + "とCONSTキーワードは同時に指定できません", sc);
                    }
                    if (staticDefined)
                    {
                        if (ret.Static)
                        {
                            throw new CodeEE("STATICとDYNAMICキーワードは同時に指定できません", sc);
                        }
                        else
                        {
                            throw new CodeEE(keyword + "キーワードが二重に指定されています", sc);
                        }
                    }
                    staticDefined = true;
                    ret.Static    = false;
                    break;

                case "STATIC":
                    if (!isPrivate)
                    {
                        throw new CodeEE("広域変数の宣言に" + keyword + "キーワードは指定できません", sc);
                    }
                    if (ret.CharaData)
                    {
                        throw new CodeEE(keyword + "とCHARADATAキーワードは同時に指定できません", sc);
                    }
                    if (staticDefined)
                    {
                        if (!ret.Static)
                        {
                            throw new CodeEE("STATICとDYNAMICキーワードは同時に指定できません", sc);
                        }
                        else
                        {
                            throw new CodeEE(keyword + "キーワードが二重に指定されています", sc);
                        }
                    }
                    if (ret.Reference)
                    {
                        throw new CodeEE(keyword + "とREFキーワードは同時に指定できません", sc);
                    }
                    staticDefined = true;
                    ret.Static    = true;
                    break;

                case "GLOBAL":
                    if (isPrivate)
                    {
                        throw new CodeEE("ローカル変数の宣言に" + keyword + "キーワードは指定できません", sc);
                    }
                    if (ret.CharaData)
                    {
                        throw new CodeEE(keyword + "とCHARADATAキーワードは同時に指定できません", sc);
                    }
                    if (ret.Reference)
                    {
                        throw new CodeEE(keyword + "とREFキーワードは同時に指定できません", sc);
                    }
                    if (ret.Const)
                    {
                        throw new CodeEE(keyword + "とCONSTキーワードは同時に指定できません", sc);
                    }
                    if (staticDefined)
                    {
                        if (ret.Static)
                        {
                            throw new CodeEE("STATICとGLOBALキーワードは同時に指定できません", sc);
                        }
                        else
                        {
                            throw new CodeEE("DYNAMICとGLOBALキーワードは同時に指定できません", sc);
                        }
                    }
                    ret.Global = true;
                    break;

                case "SAVEDATA":
                    if (isPrivate)
                    {
                        throw new CodeEE("ローカル変数の宣言に" + keyword + "キーワードは指定できません", sc);
                    }
                    if (staticDefined)
                    {
                        if (ret.Static)
                        {
                            throw new CodeEE("STATICとSAVEDATAキーワードは同時に指定できません", sc);
                        }
                        else
                        {
                            throw new CodeEE("DYNAMICとSAVEDATAキーワードは同時に指定できません", sc);
                        }
                    }
                    if (ret.Reference)
                    {
                        throw new CodeEE(keyword + "とREFキーワードは同時に指定できません", sc);
                    }
                    if (ret.Const)
                    {
                        throw new CodeEE(keyword + "とCONSTキーワードは同時に指定できません", sc);
                    }
                    if (ret.Save)
                    {
                        throw new CodeEE(keyword + "キーワードが二重に指定されています", sc);
                    }
                    ret.Save = true;
                    break;

                case "CHARADATA":
                    if (isPrivate)
                    {
                        throw new CodeEE("ローカル変数の宣言に" + keyword + "キーワードは指定できません", sc);
                    }
                    if (ret.Reference)
                    {
                        throw new CodeEE(keyword + "とREFキーワードは同時に指定できません", sc);
                    }
                    if (ret.Const)
                    {
                        throw new CodeEE(keyword + "とCONSTキーワードは同時に指定できません", sc);
                    }
                    if (staticDefined)
                    {
                        if (ret.Static)
                        {
                            throw new CodeEE(keyword + "とSTATICキーワードは同時に指定できません", sc);
                        }
                        else
                        {
                            throw new CodeEE(keyword + "とDYNAMICキーワードは同時に指定できません", sc);
                        }
                    }
                    if (ret.Global)
                    {
                        throw new CodeEE(keyword + "とGLOBALキーワードは同時に指定できません", sc);
                    }
                    if (ret.CharaData)
                    {
                        throw new CodeEE(keyword + "キーワードが二重に指定されています", sc);
                    }
                    ret.CharaData = true;
                    break;

                default:
                    ret.Name = keyword;
                    goto whilebreak;
                }
            }
whilebreak:
            if (ret.Name == null)
            {
                throw new CodeEE(keyword + "の後に有効な変数名が指定されていません", sc);
            }
            string errMes   = "";
            int    errLevel = -1;

            if (isPrivate)
            {
                GlobalStatic.IdentifierDictionary.CheckUserPrivateVarName(ref errMes, ref errLevel, ret.Name);
            }
            else
            {
                GlobalStatic.IdentifierDictionary.CheckUserVarName(ref errMes, ref errLevel, ret.Name);
            }
            if (errLevel >= 0)
            {
                if (errLevel >= 2)
                {
                    throw new CodeEE(errMes, sc);
                }
                ParserMediator.Warn(errMes, sc, errLevel);
            }


            List <int> sizeNum = new List <int>();

            if (wc.EOL)            //サイズ省略
            {
                if (ret.Const)
                {
                    throw new CodeEE("CONSTキーワードが指定されていますが初期値が設定されていません");
                }
                sizeNum.Add(1);
            }
            else if (wc.Current.Type == ',')            //サイズ指定
            {
                while (!wc.EOL)
                {
                    if (wc.Current.Type == '=')                    //サイズ指定解読完了&初期値指定
                    {
                        break;
                    }
                    if (wc.Current.Type != ',')
                    {
                        throw new CodeEE("書式が間違っています", sc);
                    }
                    wc.ShiftNext();
                    if (ret.Reference)                    //参照型の場合は要素数不要
                    {
                        sizeNum.Add(0);
                        if (wc.EOL)
                        {
                            break;
                        }
                        if (wc.Current.Type == ',')
                        {
                            continue;
                        }
                    }
                    if (wc.EOL)
                    {
                        throw new CodeEE("カンマの後に有効な定数式が指定されていません", sc);
                    }
                    IOperandTerm arg      = ExpressionParser.ReduceIntegerTerm(wc, TermEndWith.Comma_Assignment);
                    SingleTerm   sizeTerm = arg.Restructure(null) as SingleTerm;
                    if ((sizeTerm == null) || (sizeTerm.GetOperandType() != typeof(Int64)))
                    {
                        throw new CodeEE("カンマの後に有効な定数式が指定されていません", sc);
                    }
                    if (ret.Reference)                    //参照型には要素数指定不可(0にするか書かないかどっちか
                    {
                        if (sizeTerm.Int != 0)
                        {
                            throw new CodeEE("参照型変数にはサイズを指定できません(サイズを省略するか0を指定してください)", sc);
                        }

                        continue;
                    }
                    else if ((sizeTerm.Int <= 0) || (sizeTerm.Int > 1000000))
                    {
                        throw new CodeEE("ユーザー定義変数のサイズは1以上1000000以下でなければなりません", sc);
                    }
                    sizeNum.Add((int)sizeTerm.Int);
                }
            }


            if (wc.Current.Type != '=')            //初期値指定なし
            {
                if (ret.Const)
                {
                    throw new CodeEE("CONSTキーワードが指定されていますが初期値が設定されていません");
                }
            }
            else            //初期値指定あり
            {
                if (((OperatorWord)wc.Current).Code != OperatorCode.Assignment)
                {
                    throw new CodeEE("予期しない演算子を発見しました");
                }
                if (ret.Reference)
                {
                    throw new CodeEE("参照型変数には初期値を設定できません");
                }
                if (sizeNum.Count >= 2)
                {
                    throw new CodeEE("多次元変数には初期値を設定できません");
                }
                if (ret.CharaData)
                {
                    throw new CodeEE("キャラ型変数には初期値を設定できません");
                }
                int size = 0;
                if (sizeNum.Count == 1)
                {
                    size = sizeNum[0];
                }
                wc.ShiftNext();
                IOperandTerm[] terms = ExpressionParser.ReduceArguments(wc, ArgsEndWith.EoL, false);
                if (terms.Length == 0)
                {
                    throw new CodeEE("配列の初期値は省略できません");
                }
                if (size > 0)
                {
                    if (terms.Length > size)
                    {
                        throw new CodeEE("初期値の数が配列のサイズを超えています");
                    }
                    if (ret.Const && terms.Length != size)
                    {
                        throw new CodeEE("定数の初期値の数が配列のサイズと一致しません");
                    }
                }
                if (dims)
                {
                    ret.DefaultStr = new string[terms.Length];
                }
                else
                {
                    ret.DefaultInt = new Int64[terms.Length];
                }

                for (int i = 0; i < terms.Length; i++)
                {
                    if (terms[i] == null)
                    {
                        throw new CodeEE("配列の初期値は省略できません");
                    }
                    terms[i] = terms[i].Restructure(GlobalStatic.EMediator);
                    SingleTerm sTerm = terms[i] as SingleTerm;
                    if (sTerm == null)
                    {
                        throw new CodeEE("配列の初期値には定数のみ指定できます");
                    }
                    if (dims != sTerm.IsString)
                    {
                        throw new CodeEE("変数の型と初期値の型が一致していません");
                    }
                    if (dims)
                    {
                        ret.DefaultStr[i] = sTerm.Str;
                    }
                    else
                    {
                        ret.DefaultInt[i] = sTerm.Int;
                    }
                }
                if (sizeNum.Count == 0)
                {
                    sizeNum.Add(terms.Length);
                }
            }
            if (!wc.EOL)
            {
                throw new CodeEE("書式が間違っています", sc);
            }

            if (sizeNum.Count == 0)
            {
                sizeNum.Add(1);
            }

            ret.Private   = isPrivate;
            ret.Dimension = sizeNum.Count;
            if (ret.Const && ret.Dimension > 1)
            {
                throw new CodeEE("CONSTキーワードが指定された変数を多次元配列にはできません");
            }
            if (ret.CharaData && ret.Dimension > 2)
            {
                throw new CodeEE("3次元以上のキャラ型変数を宣言することはできません", sc);
            }
            if (ret.Dimension > 3)
            {
                throw new CodeEE("4次元以上の配列変数を宣言することはできません", sc);
            }
            ret.Lengths = new int[sizeNum.Count];
            if (ret.Reference)
            {
                return(ret);
            }
            Int64 totalBytes = 1;

            for (int i = 0; i < sizeNum.Count; i++)
            {
                ret.Lengths[i] = sizeNum[i];
                totalBytes    *= ret.Lengths[i];
            }
            if ((totalBytes <= 0) || (totalBytes > 1000000))
            {
                throw new CodeEE("ユーザー定義変数のサイズは1以上1000000以下でなければなりません", sc);
            }
            if (!isPrivate && ret.Save && !Config.SystemSaveInBinary)
            {
                if (dims && ret.Dimension > 1)
                {
                    throw new CodeEE("文字列型の多次元配列変数にSAVEDATAフラグを付ける場合には「バイナリ型セーブ」オプションが必須です", sc);
                }
                else if (ret.CharaData)
                {
                    throw new CodeEE("キャラ型変数にSAVEDATAフラグを付ける場合には「バイナリ型セーブ」オプションが必須です", sc);
                }
            }
            return(ret);
        }
        public static UserDefinedVariableData Create(WordCollection wc, bool dims, bool isPrivate, ScriptPosition sc)
        {
            string dimtype = dims ? "#DIM" : "#DIMS";
            UserDefinedVariableData ret = new UserDefinedVariableData();
            ret.TypeStr = dims;

            IdentifierWord idw = null;
            bool staticDefined = false;
            string keyword = dimtype;
            while (!wc.EOL && (idw = wc.Current as IdentifierWord) != null)
            {
                wc.ShiftNext();
                keyword = idw.Code;
                if (Config.ICVariable)
                    keyword = keyword.ToUpper();
                switch (keyword)
                {
                    case "REF":
                        //TODO 1808beta009
                        throw new CodeEE("未実装の機能です", sc);
                        if (!isPrivate)
                            throw new CodeEE("広域変数の宣言に" + keyword + "キーワードは指定できません", sc);
                        if (staticDefined && ret.Static)
                            throw new CodeEE("STATICとREFキーワードは同時に指定できません", sc);
                        if (ret.Reference)
                            throw new CodeEE(keyword + "キーワードが二重に指定されています", sc);
                        ret.Reference = true;
                        ret.Static = true;
                        break;
                    case "DYNAMIC":
                        if (!isPrivate)
                            throw new CodeEE("広域変数の宣言に" + keyword + "キーワードは指定できません", sc);
                        if (staticDefined)
                            if (ret.Static)
                                throw new CodeEE("STATICとDYNAMICキーワードは同時に指定できません", sc);
                            else
                                throw new CodeEE(keyword + "キーワードが二重に指定されています", sc);
                        staticDefined = true;
                        ret.Static = false;
                        break;
                    case "STATIC":
                        if (!isPrivate)
                            throw new CodeEE("広域変数の宣言に" + keyword + "キーワードは指定できません", sc);
                        if (staticDefined)
                            if (!ret.Static)
                                throw new CodeEE("STATICとDYNAMICキーワードは同時に指定できません", sc);
                            else
                                throw new CodeEE(keyword + "キーワードが二重に指定されています", sc);
                        if (ret.Reference)
                            throw new CodeEE("STATICとREFキーワードは同時に指定できません", sc);
                        staticDefined = true;
                        ret.Static = true;
                        break;
                    case "GLOBAL":
                        if (isPrivate)
                            throw new CodeEE("ローカル変数の宣言に" + keyword + "キーワードは指定できません", sc);
                        if (ret.Global)
                            throw new CodeEE(keyword + "キーワードが二重に指定されています", sc);
                        ret.Global = true;
                        break;
                    case "SAVEDATA":
                        if (isPrivate)
                            throw new CodeEE("ローカル変数の宣言に" + keyword + "キーワードは指定できません", sc);
                        if (ret.Save)
                            throw new CodeEE(keyword + "キーワードが二重に指定されています", sc);
                        ret.Save = true;
                        break;
                    case "CHARDATA":
                        throw new CodeEE("キャラ変数の宣言は実装されていません", sc);
                    default:
                        ret.Name = keyword;
                        goto whilebreak;
                }
            }
            whilebreak:
            if (ret.Name == null)
                throw new CodeEE(keyword + "の後に有効な変数名が指定されていません", sc);
            string errMes = "";
            int errLevel = -1;
            if (isPrivate)
                GlobalStatic.IdentifierDictionary.CheckUserPrivateVarName(ref errMes, ref errLevel, ret.Name);
            else
                GlobalStatic.IdentifierDictionary.CheckUserVarName(ref errMes, ref errLevel, ret.Name);
            if (errLevel >= 0)
            {
                if (errLevel >= 2)
                    throw new CodeEE(errMes, sc);
                ParserMediator.Warn(errMes, sc, errLevel);
            }
            List<int> sizeNum = new List<int>();
            while (!wc.EOL)
            {
                if (wc.Current.Type != ',')
                    throw new CodeEE("書式が間違っています", sc);
                wc.ShiftNext();
                if (ret.Reference)//参照型の場合は要素数不要
                {
                    if (wc.EOL)
                        break;
                    if (wc.Current.Type == ',')
                    {
                        sizeNum.Add(0);
                        continue;
                    }
                }
                if (wc.EOL)
                    throw new CodeEE("カンマの後に有効な定数式が指定されていません", sc);
                IOperandTerm arg = ExpressionParser.ReduceIntegerTerm(wc, TermEndWith.Comma);
                SingleTerm sizeTerm = arg.Restructure(null) as SingleTerm;
                if ((sizeTerm == null) || (sizeTerm.GetOperandType() != typeof(Int64)))
                    throw new CodeEE("カンマの後に有効な定数式が指定されていません", sc);
                if (ret.Reference)//参照型には要素数指定不可(0にするか書かないかどっちか
                {
                    if (sizeTerm.Int != 0)
                        throw new CodeEE("参照型変数にはサイズを指定できません(サイズを省略するか0を指定してください)", sc);
                    continue;
                }
                else if ((sizeTerm.Int <= 0) || (sizeTerm.Int > 1000000))
                    throw new CodeEE("ユーザー定義変数のサイズは1以上1000000以下でなければなりません", sc);
                sizeNum.Add((int)sizeTerm.Int);
            }
            if (sizeNum.Count == 0)
                sizeNum.Add(1);
            ret.Private = isPrivate;
            ret.Dimension = sizeNum.Count;
            if (ret.Dimension > 3)
                throw new CodeEE("4次元以上の配列変数を宣言することはできません", sc);
            ret.Lengths = new int[sizeNum.Count];
            if (ret.Reference)
                return ret;
            Int64 totalBytes = 1;
            for (int i = 0; i < sizeNum.Count; i++)
            {
                ret.Lengths[i] = sizeNum[i];
                totalBytes *= ret.Lengths[i];
            }
            if ((totalBytes <= 0) || (totalBytes > 1000000))
                throw new CodeEE("ユーザー定義変数のサイズは1以上1000000以下でなければなりません", sc);
            if (!isPrivate && dims && ret.Dimension > 1 && ret.Save && !Config.SystemSaveInBinary)
                throw new CodeEE("文字列型の多次元配列変数にSAVEDATAフラグを付ける場合には「バイナリ型セーブ」オプションが必要です", sc);

            return ret;
        }
示例#7
0
 public StaticStr3DVariableToken(UserDefinedVariableData data)
     : base(VariableCode.VARS3D, data)
 {
     CanRestructure = false;
     int[] sizes = data.Lengths;
     IsStatic = true;
     array = new string[sizes[0], sizes[1], sizes[2]];
 }
示例#8
0
 protected ReferenceToken(VariableCode varCode, UserDefinedVariableData data)
     : base(varCode, data)
 {
     CanRestructure = false;
     IsStatic = !data.Private;
     IsReference = true;
     arrayList = new List<Array>();
 }
示例#9
0
 public StaticInt2DVariableToken(UserDefinedVariableData data)
     : base(VariableCode.VAR2D, data)
 {
     CanRestructure = false;
     int[] sizes = data.Lengths;
     IsStatic = true;
     array = new Int64[sizes[0], sizes[1]];
 }
示例#10
0
 public ReferenceStr3DToken(UserDefinedVariableData data)
     : base(VariableCode.REFS3D, data)
 {
     CanRestructure = false;
     IsStatic = !data.Private;
 }
示例#11
0
 public PrivateStr3DVariableToken(UserDefinedVariableData data)
     : base(VariableCode.VARS3D, data)
 {
     CanRestructure = false;
     int[] sizes = data.Lengths;
     IsStatic = false;
     arrayList = new List<string[, ,]>();
 }
示例#12
0
 protected UserDefinedVariableToken(VariableCode varCode, UserDefinedVariableData data)
     : base(varCode, null)
 {
     varName = data.Name;
     IsPrivate = data.Private;
     this.sizes = data.Lengths;
     this.IsGlobal = data.Global;
     this.IsSavedata = data.Save;
     //Dimension = sizes.Length;
     totalSize = 1;
     for (int i = 0; i < sizes.Length; i++)
         totalSize *= sizes[i];
 }
示例#13
0
 public PrivateInt2DVariableToken(UserDefinedVariableData data)
     : base(VariableCode.VAR2D, data)
 {
     CanRestructure = false;
     int[] sizes = data.Lengths;
     IsStatic = false;
     arrayList = new List<Int64[,]>();
 }