//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); }
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); }
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); }
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); }
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; }
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]]; }
protected ReferenceToken(VariableCode varCode, UserDefinedVariableData data) : base(varCode, data) { CanRestructure = false; IsStatic = !data.Private; IsReference = true; arrayList = new List<Array>(); }
public StaticInt2DVariableToken(UserDefinedVariableData data) : base(VariableCode.VAR2D, data) { CanRestructure = false; int[] sizes = data.Lengths; IsStatic = true; array = new Int64[sizes[0], sizes[1]]; }
public ReferenceStr3DToken(UserDefinedVariableData data) : base(VariableCode.REFS3D, data) { CanRestructure = false; IsStatic = !data.Private; }
public PrivateStr3DVariableToken(UserDefinedVariableData data) : base(VariableCode.VARS3D, data) { CanRestructure = false; int[] sizes = data.Lengths; IsStatic = false; arrayList = new List<string[, ,]>(); }
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]; }
public PrivateInt2DVariableToken(UserDefinedVariableData data) : base(VariableCode.VAR2D, data) { CanRestructure = false; int[] sizes = data.Lengths; IsStatic = false; arrayList = new List<Int64[,]>(); }