Beispiel #1
0
 private string getValueString(string str)
 {
     if ((emuera == null) || (GlobalStatic.EMediator == null))
     {
         return("");
     }
     if (string.IsNullOrEmpty(str))
     {
         return("");
     }
     mainConsole.RunERBFromMemory = true;
     try
     {
         StringStream   st    = new StringStream(str);
         WordCollection wc    = LexicalAnalyzer.Analyse(st, LexEndWith.EoL, LexAnalyzeFlag.None);
         IOperandTerm   term  = ExpressionParser.ReduceExpressionTerm(wc, TermEndWith.EoL);
         SingleTerm     value = term.GetValue(GlobalStatic.EMediator);
         return(value.ToString());
     }
     catch (CodeEE e)
     {
         return(e.Message);
     }
     catch (Exception e)
     {
         return(e.GetType().ToString() + ":" + e.Message);
     }
     finally
     {
         mainConsole.RunERBFromMemory = false;
     }
 }
Beispiel #2
0
        public SingleTerm GetValue(SuperUserDefinedMethodTerm udmt)
        {
            methodStack++;
            if (methodStack > 100)
            {
                //StackOverflowExceptionはcatchできない上に再現性がないので発生前に一定数で打ち切る。
                //環境によっては100以前にStackOverflowExceptionがでるかも?
                throw new CodeEE("関数の呼び出しスタックが溢れました(無限に再帰呼び出しされていませんか?)");
            }
            SingleTerm ret          = null;
            int        temp_current = state.currentMin;

            state.currentMin = state.functionCount;
            udmt.Call.updateRetAddress(state.CurrentLine);
            try
            {
                state.IntoFunction(udmt.Call, udmt.Argument, exm);
                //do whileの中でthrow されたエラーはここではキャッチされない。
                //#functionを全て抜けてDoScriptでキャッチされる。
                runScriptProc();
                ret = state.MethodReturnValue;
            }
            finally
            {
                if (udmt.Call.TopLabel.hasPrivDynamicVar)
                {
                    udmt.Call.TopLabel.Out();
                }
                //1756beta2+v3:こいつらはここにないとデバッグコンソールで式中関数が事故った時に大事故になる
                state.currentMin = temp_current;
                methodStack--;
            }
            return(ret);
        }
Beispiel #3
0
        public SingleTerm GetValue(SuperUserDefinedMethodTerm udmt)
        {
            methodStack++;
            if (methodStack > 100)
            {
                throw new CodeEE("関数の呼び出しスタックが溢れました(無限に再帰呼び出しされていませんか?)");
            }
            SingleTerm ret          = null;
            var        temp_current = getCurrentState.currentMin;

            getCurrentState.currentMin = getCurrentState.functionCount;
            udmt.Call.updateRetAddress(getCurrentState.CurrentLine);
            try
            {
                getCurrentState.IntoFunction(udmt.Call, udmt.Argument, exm);
                //do whileの中でthrow されたエラーはここではキャッチされない。
                //#functionを全て抜けてDoScriptでキャッチされる。
                runScriptProc();
                ret = getCurrentState.MethodReturnValue;
            }
            finally
            {
                if (udmt.Call.TopLabel.hasPrivDynamicVar)
                {
                    udmt.Call.TopLabel.Out();
                }
                //1756beta2+v3:こいつらはここにないとデバッグコンソールで式中関数が事故った時に大事故になる
                getCurrentState.currentMin = temp_current;
                methodStack--;
            }
            return(ret);
        }
        public override string GetStrValue(ExpressionMediator exm)
        {
            SingleTerm term = exm.Process.GetValue(this);

            if (term == null)
            {
                return("");
            }
            return(term.Str);
        }
        public override long GetIntValue(ExpressionMediator exm)
        {
            SingleTerm term = exm.Process.GetValue(this);

            if (term == null)
            {
                return(0);
            }
            return(term.Int);
        }
Beispiel #6
0
 public virtual void SetValue(SingleTerm value, ExpressionMediator exm)
 {
     if (Identifier.VariableType == typeof(long))
     {
         SetValue(value.Int, exm);
     }
     else
     {
         SetValue(value.Str, exm);
     }
 }
        public override SingleTerm GetValue(ExpressionMediator exm)
        {
            SingleTerm term = exm.Process.GetValue(this);

            if (term == null)
            {
                if (GetOperandType() == typeof(Int64))
                {
                    return(new SingleTerm(0));
                }
                else
                {
                    return(new SingleTerm(""));
                }
            }
            return(term);
        }
Beispiel #8
0
 public void ReturnF(SingleTerm ret)
 {
     //読み込み時のチェック済みのはず
     //if (!IsFunctionMethod)
     //    throw new ExeEE("ReturnFと#FUNCTIONのチェックがおかしい");
     //sequential = false;//いずれにしろ順列ではない。
     //呼び出し元はRETURNFコマンドか関数終了時のみ
     //if (functionList.Count == 0)
     //    throw new ExeEE("実行中の関数が存在しません");
     //非イベント呼び出しなので、これは起こりえない
     //else if (functionList.Count != 1)
     //    throw new ExeEE("関数が複数ある");
     if (Program.DebugMode)
     {
         console.DebugRemoveTraceLog();
     }
     //OutはGetValue側で行う
     //functionList[0].TopLabel.Out();
     CurrentLine = functionList[functionList.Count - 1].ReturnAddress;
     functionList.RemoveAt(functionList.Count - 1);
     //nextLine = null;
     MethodReturnValue = ret;
 }
Beispiel #9
0
        public SingleTerm GetConfigValueInERB(string text, ref string errMes)
        {
            AConfigItem item = ConfigData.Instance.GetItem(text);

            if (item == null)
            {
                errMes = "文字列\"" + text + "\"は適切なコンフィグ名ではありません";
                return(null);
            }
            SingleTerm term;

            switch (item.Code)
            {
            //<bool>
            case ConfigCode.AutoSave:                    //"オートセーブを行なう"
            case ConfigCode.MoneyFirst:                  //"単位の位置"
                if (item.GetValue <bool>())
                {
                    term = new SingleTerm(1);
                }
                else
                {
                    term = new SingleTerm(0);
                }
                break;

            //<int>
            case ConfigCode.WindowX:                    // "ウィンドウ幅"
            case ConfigCode.PrintCPerLine:              // "PRINTCを並べる数"
            case ConfigCode.PrintCLength:               // "PRINTCの文字数"
            case ConfigCode.FontSize:                   // "フォントサイズ"
            case ConfigCode.LineHeight:                 // "一行の高さ"
            case ConfigCode.SaveDataNos:                // "表示するセーブデータ数"
            case ConfigCode.MaxShopItem:                // "販売アイテム数"
            case ConfigCode.ComAbleDefault:             // "COM_ABLE初期値"
                term = new SingleTerm(item.GetValue <int>());
                break;

            //<Color>
            case ConfigCode.ForeColor:                   //"文字色"
            case ConfigCode.BackColor:                   //"背景色"
            case ConfigCode.FocusColor:                  //"選択中文字色"
            case ConfigCode.LogColor:                    //"履歴文字色"
            {
                Color color = item.GetValue <Color>();
                term = new SingleTerm(((color.R * 256) + color.G) * 256 + color.B);
            }
            break;

            //<Int64>
            case ConfigCode.pbandDef:                    // "PBANDの初期値"
            case ConfigCode.RelationDef:                 // "RELATIONの初期値"
                term = new SingleTerm(item.GetValue <Int64>());
                break;

            //<string>
            case ConfigCode.FontName:                    // "フォント名"
            case ConfigCode.MoneyLabel:                  // "お金の単位"
            case ConfigCode.LoadLabel:                   // "起動時簡略表示"
            case ConfigCode.DrawLineString:              // "DRAWLINE文字"
            case ConfigCode.TitleMenuString0:            // "システムメニュー0"
            case ConfigCode.TitleMenuString1:            // "システムメニュー1"
            case ConfigCode.TimeupLabel:                 // "時間切れ表示"
                term = new SingleTerm(item.GetValue <string>());
                break;

            //<char>
            case ConfigCode.BarChar1:                    // "BAR文字1"
            case ConfigCode.BarChar2:                    // "BAR文字2"
                term = new SingleTerm(item.GetValue <char>().ToString());
                break;

            //<TextDrawingMode>
            case ConfigCode.TextDrawingMode:                    // "描画インターフェース"
                term = new SingleTerm(item.GetValue <TextDrawingMode>().ToString());
                break;

            default:
            {
                errMes = "コンフィグ文字列\"" + text + "\"の値の取得は許可されていません";
                return(null);
            }
            }
            return(term);
        }
Beispiel #10
0
        public static StrForm FromWordToken(StrFormWord wt)
        {
            StrForm ret = new StrForm();

            ret.strs = wt.Strs;
            IOperandTerm[] termArray = new IOperandTerm[wt.SubWords.Length];
            for (int i = 0; i < wt.SubWords.Length; i++)
            {
                SubWord             SWT     = wt.SubWords[i];
                TripleSymbolSubWord tSymbol = SWT as TripleSymbolSubWord;
                if (tSymbol != null)
                {
                    switch (tSymbol.Code)
                    {
                    case '*':
                        termArray[i] = NameTarget;
                        continue;

                    case '+':
                        termArray[i] = CallnameMaster;
                        continue;

                    case '=':
                        termArray[i] = CallnamePlayer;
                        continue;

                    case '/':
                        termArray[i] = NameAssi;
                        continue;

                    case '$':
                        termArray[i] = CallnameTarget;
                        continue;
                    }
                    throw new ExeEE("何かおかしい");
                }
                WordCollection wc      = null;
                IOperandTerm   operand = null;
                YenAtSubWord   yenat   = SWT as YenAtSubWord;
                if (yenat != null)
                {
                    wc = yenat.Words;
                    if (wc != null)
                    {
                        operand = ExpressionParser.ReduceIntegerTerm(wc, TermEndWith.EoL);
                        if (!wc.EOL)
                        {
                            throw new CodeEE("三項演算子\\@の第一オペランドが異常です");
                        }
                    }
                    else
                    {
                        operand = new SingleTerm(0);
                    }
                    IOperandTerm left  = new StrFormTerm(StrForm.FromWordToken(yenat.Left));
                    IOperandTerm right = null;
                    if (yenat.Right == null)
                    {
                        right = new SingleTerm("");
                    }
                    else
                    {
                        right = new StrFormTerm(StrForm.FromWordToken(yenat.Right));
                    }
                    termArray[i] = new FunctionMethodTerm(formatYenAt, new IOperandTerm[] { operand, left, right });
                    continue;
                }
                wc      = SWT.Words;
                operand = ExpressionParser.ReduceExpressionTerm(wc, TermEndWith.Comma);
                if (operand == null)
                {
                    if (SWT is CurlyBraceSubWord)
                    {
                        throw new CodeEE("{}の中に式が存在しません");
                    }
                    else
                    {
                        throw new CodeEE("%%の中に式が存在しません");
                    }
                }
                IOperandTerm second = null;
                SingleTerm   third  = null;
                wc.ShiftNext();
                if (!wc.EOL)
                {
                    second = ExpressionParser.ReduceIntegerTerm(wc, TermEndWith.Comma);

                    wc.ShiftNext();
                    if (!wc.EOL)
                    {
                        IdentifierWord id = wc.Current as IdentifierWord;
                        if (id == null)
                        {
                            throw new CodeEE("','の後にRIGHT又はLEFTがありません");
                        }
                        if (string.Equals(id.Code, "LEFT", Config.SCVariable))//標準RIGHT
                        {
                            third = new SingleTerm(1);
                        }
                        else if (!string.Equals(id.Code, "RIGHT", Config.SCVariable))
                        {
                            throw new CodeEE("','の後にRIGHT又はLEFT以外の単語があります");
                        }
                        wc.ShiftNext();
                    }
                    if (!wc.EOL)
                    {
                        throw new CodeEE("RIGHT又はLEFTの後に余分な文字があります");
                    }
                }
                if (SWT is CurlyBraceSubWord)
                {
                    if (operand.GetOperandType() != typeof(Int64))
                    {
                        throw new CodeEE("{}の中の式が数式ではありません");
                    }
                    termArray[i] = new FunctionMethodTerm(formatCurlyBrace, new IOperandTerm[] { operand, second, third });
                    continue;
                }
                if (operand.GetOperandType() != typeof(string))
                {
                    throw new CodeEE("%%の中の式が文字列式ではありません");
                }
                termArray[i] = new FunctionMethodTerm(formatPercent, new IOperandTerm[] { operand, second, third });
            }
            ret.terms = termArray;
            return(ret);
        }
Beispiel #11
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);
        }
Beispiel #12
0
 public override void SetValue(SingleTerm value, ExpressionMediator exm)
 {
     throw new CodeEE("変数" + Identifier.Name + "に必要な引数が不足しています");
 }
Beispiel #13
0
        public static bool ParseSharpLine(FunctionLabelLine label, StringStream st, ScriptPosition position, List <string> OnlyLabel)
        {
            st.ShiftNext();                                          //'#'を飛ばす
            string 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
            {
                WordCollection 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(Int64) && token == "FUNCTION") || (label.MethodType == typeof(string) && token == "FUNCTIONS"))
                        {
                            ParserMediator.Warn("関数" + label.LabelName + "にはすでに#" + token + "が宣言されています(この行は無視されます)", position, 1);
                            return(false);
                        }
                        if (label.MethodType == typeof(Int64) && 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(Int64);
                    }
                    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;
                    }
                    IOperandTerm arg      = ExpressionParser.ReduceIntegerTerm(wc, TermEndWith.EoL);
                    SingleTerm   sizeTerm = arg.Restructure(null) as SingleTerm;
                    if ((sizeTerm == null) || (sizeTerm.GetOperandType() != typeof(Int64)))
                    {
                        ParserMediator.Warn("#" + token + "の後に有効な定数式が指定されていません", position, 2);
                        break;
                    }
                    if (sizeTerm.Int <= 0)
                    {
                        ParserMediator.Warn("#" + token + "に0以下の値(" + sizeTerm.Int.ToString() + ")が与えられました。設定は無視されます", position, 1);
                        break;
                    }
                    if (sizeTerm.Int >= Int32.MaxValue)
                    {
                        ParserMediator.Warn("#" + token + "に大きすぎる値(" + sizeTerm.Int.ToString() + ")が与えられました。設定は無視されます", position, 1);
                        break;
                    }
                    int 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":
                {
                    UserDefinedVariableData 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);
        }
Beispiel #14
0
 public static void Initialize()
 {
     ZeroTerm = new SingleTerm(0);
     IOperandTerm[] zeroArgs = { ZeroTerm };
     TARGET = new VariableTerm(GlobalStatic.VariableData.GetSystemVariableToken("TARGET"), zeroArgs);
 }