Пример #1
0
        public LocalVariableToken GetNewLocalVariableToken(string subKey, FunctionLabelLine func)
        {
            LocalVariableToken ret = null;
            var newSize            = 0;

            if (varCode == VariableCode.LOCAL)
            {
                newSize = func.LocalLength;
            }
            else if (varCode == VariableCode.LOCALS)
            {
                newSize = func.LocalsLength;
            }
            else if (varCode == VariableCode.ARG)
            {
                newSize = func.ArgLength;
            }
            else if (varCode == VariableCode.ARGS)
            {
                newSize = func.ArgsLength;
            }
            if (newSize > 0)
            {
                if (newSize < size && (varCode == VariableCode.ARG || varCode == VariableCode.ARGS))
                {
                    newSize = size;
                }
                ret = creater(varCode, subKey, newSize);
            }
            else if (newSize == 0)
            {
                ret = creater(varCode, subKey, size);
            }
            else
            {
                ret = creater(varCode, subKey, size);
                var line = GlobalStatic.Process.GetScaningLine();
                if (line != null)
                {
                    if (!func.IsSystem)
                    {
                        ParserMediator.Warn(
                            "関数宣言に引数変数\"" + varCode + "\"が使われていない関数中で\"" + varCode +
                            "\"が使われています(関数の引数以外の用途に使うことは推奨されません。代わりに#DIMの使用を検討してください)", line, 1, false, false);
                    }
                    else
                    {
                        ParserMediator.Warn(
                            "システム関数" + func.LabelName + "中で\"" + varCode +
                            "\"が使われています(関数の引数以外の用途に使うことは推奨されません。代わりに#DIMの使用を検討してください)", line, 1, false, false);
                    }
                }
                //throw new CodeEE("この関数に引数変数\"" + varCode + "\"は定義されていません");
            }
            localVarTokens.Add(subKey, ret);
            return(ret);
        }
Пример #2
0
        /// <summary>
        /// エラーならnullを返す。
        /// </summary>
        public static UserDefinedMethodTerm Create(FunctionLabelLine targetLabel, IOperandTerm[] srcArgs, out string errMes)
        {
            CalledFunction call             = CalledFunction.CreateCalledFunctionMethod(targetLabel, targetLabel.LabelName);
            UserDefinedFunctionArgument arg = call.ConvertArg(srcArgs, out errMes);

            if (arg == null)
            {
                return(null);
            }
            return(new UserDefinedMethodTerm(arg, call.TopLabel.MethodType, call));
        }
Пример #3
0
        /// <summary>
        /// 戻り値と引数の数・型の完全一致が必要
        /// </summary>
        /// <param name="call"></param>
        /// <returns>一致ならtrue</returns>
        internal bool MatchType(CalledFunction call)
        {
            FunctionLabelLine label = call.TopLabel;

            if (label.IsError)
            {
                return(false);
            }
            if (RetType != label.MethodType)
            {
                return(false);
            }
            if (ArgTypeList.Length != label.Arg.Length)
            {
                return(false);
            }
            for (int i = 0; i < ArgTypeList.Length; i++)
            {
                VariableToken vToken = label.Arg[i].Identifier;
                if (vToken.IsReference)
                {
                    UserDifinedFunctionDataArgType type = UserDifinedFunctionDataArgType.__Ref;
                    type += vToken.Dimension;
                    if (vToken.IsInteger)
                    {
                        type |= UserDifinedFunctionDataArgType.Int;
                    }
                    else
                    {
                        type |= UserDifinedFunctionDataArgType.Str;
                    }
                    if (ArgTypeList[i] != type)
                    {
                        return(false);
                    }
                }
                else
                {
                    if (vToken.IsInteger && ArgTypeList[i] != UserDifinedFunctionDataArgType.Int)
                    {
                        return(false);
                    }
                    if (vToken.IsString && ArgTypeList[i] != UserDifinedFunctionDataArgType.Str)
                    {
                        return(false);
                    }
                }
            }
            return(true);
        }
Пример #4
0
 public void AddLabel(FunctionLabelLine point)
 {
     point.Index = count;
     point.FileIndex = currentFileCount;
     count++;
     string id = point.LabelName;
     if (labelAtDic.ContainsKey(id))
     {
         labelAtDic[id].Add(point);
     }
     else
     {
         List<FunctionLabelLine> labelList = new List<FunctionLabelLine>();
         labelList.Add(point);
         labelAtDic.Add(id, labelList);
     }
 }
Пример #5
0
        public List <string> GetOverloadedList(LabelDictionary labelDic)
        {
            List <string> list = new List <string>();

            foreach (KeyValuePair <string, FunctionMethod> pair in methodDic)
            {
                FunctionLabelLine func = labelDic.GetNonEventLabel(pair.Key);
                if (func == null)
                {
                    continue;
                }
                if (!func.IsMethod)
                {
                    continue;
                }
                list.Add(pair.Key);
            }
            return(list);
        }
Пример #6
0
 public LocalVariableToken GetNewLocalVariableToken(string subKey, FunctionLabelLine func)
 {
     LocalVariableToken ret = null;
     int newSize = 0;
     if (varCode == VariableCode.LOCAL)
         newSize = func.LocalLength;
     else if (varCode == VariableCode.LOCALS)
         newSize = func.LocalsLength;
     else if (varCode == VariableCode.ARG)
         newSize = func.ArgLength;
     else if (varCode == VariableCode.ARGS)
         newSize = func.ArgsLength;
     if (newSize > 0)
     {
         if((newSize < size) && ((varCode == VariableCode.ARG) || (varCode == VariableCode.ARGS)))
             newSize = size;
         ret = creater(varCode, subKey, newSize);
     }
     else if (newSize == 0)
         ret = creater(varCode, subKey, size);
     else
     {
         ret = creater(varCode, subKey, size);
         LogicalLine line = GlobalStatic.Process.GetScaningLine();
         if (line != null)
         {
             if (!func.IsSystem)
                 ParserMediator.Warn("関数宣言に引数変数\"" + varCode + "\"が使われていない関数中で\"" + varCode + "\"が使われています(関数の引数以外の用途に使うことは推奨されません)", line, 1, false, false);
             else
                 ParserMediator.Warn("システム関数" + func.LabelName + "中で\"" + varCode + "\"が使われています(関数の引数以外の用途に使うことは推奨されません)", line, 1, false, false);
         }
         //throw new CodeEE("この関数に引数変数\"" + varCode + "\"は定義されていません");
     }
     localVarTokens.Add(subKey, ret);
     return ret;
 }
 public static CalledFunction CreateCalledFunctionMethod(FunctionLabelLine labelline, string label)
 {
     CalledFunction called = new CalledFunction(label);
     called.TopLabel = labelline;
     called.CurrentLabel = labelline;
     called.returnAddress = null;
     return called;
 }
Пример #8
0
        private void parseLabel(FunctionLabelLine label)
        {
            WordCollection wc = label.PopRowArgs();
            string errMes = null;
            SingleTerm[] subNames = new SingleTerm[0];
            VariableTerm[] args = new VariableTerm[0];
            SingleTerm[] defs = new SingleTerm[0];
            int maxArg = -1;
            int maxArgs = -1;
            //1807 非イベント関数のシステム関数については警告レベル低下&エラー解除&引数を設定するように。
            if (label.IsEvent)
            {
                if (!wc.EOL)
                    ParserMediator.Warn("イベント関数@" + label.LabelName + " に引数は設定できません", label, 2, true, false);
                //label.SubNames = subNames;
                label.Arg = args;
                label.Def = defs;
                label.ArgLength = -1;
                label.ArgsLength = -1;
                return;
            }

            if (!wc.EOL)
            {
                if (label.IsSystem)
                    ParserMediator.Warn("システム関数@" + label.LabelName + " に引数が設定されています", label, 1, false, false);
                SymbolWord symbol = wc.Current as SymbolWord;
                wc.ShiftNext();
                if (symbol == null)
                { errMes = "引数の書式が間違っています"; goto err; }
                if (symbol.Type == '[')
                {
                    IOperandTerm[] subNamesRow = ExpressionParser.ReduceArguments(wc, ArgsEndWith.RightBracket, false);
                    if (subNamesRow.Length == 0)
                    { errMes = "関数定義の[]内の引数は空にできません"; goto err; }
                    subNames = new SingleTerm[subNamesRow.Length];
                    for (int i = 0; i < subNamesRow.Length; i++)
                    {
                        if (subNamesRow[i] == null)
                        { errMes = "関数定義の引数は省略できません"; goto err; }
                        IOperandTerm term = subNamesRow[i].Restructure(exm);
                        subNames[i] = term as SingleTerm;
                        if (subNames[i] == null)
                        { errMes = "関数定義の[]内の引数は定数のみ指定できます"; goto err; }
                    }
                    symbol = wc.Current as SymbolWord;
                    if ((!wc.EOL) && (symbol == null))
                    { errMes = "引数の書式が間違っています"; goto err; }
                    wc.ShiftNext();
                }
                if (!wc.EOL)
                {
                    IOperandTerm[] argsRow = null;
                    if (symbol.Type == ',')
                        argsRow = ExpressionParser.ReduceArguments(wc, ArgsEndWith.EoL, true);
                    else if (symbol.Type == '(')
                        argsRow = ExpressionParser.ReduceArguments(wc, ArgsEndWith.RightParenthesis, true);
                    else
                    { errMes = "引数の書式が間違っています"; goto err; }
                    int length = argsRow.Length / 2;
                    args = new VariableTerm[length];
                    defs = new SingleTerm[length];
                    for (int i = 0; i < length; i++)
                    {
                        VariableTerm vTerm = null;
                        SingleTerm def = null;
                        IOperandTerm term = argsRow[i * 2];
                        //引数読み取り時点で判別されないといけない
                        //if (term == null)
                        //{ errMes = "関数定義の引数は省略できません"; goto err; }
                        vTerm = term.Restructure(exm) as VariableTerm;
                        if ((vTerm == null) || (vTerm.Identifier.Readonly))
                        { errMes = "関数定義の引数には代入可能な変数を指定してください"; goto err; }
                        else if (!vTerm.isAllConst)
                        { errMes = "関数定義の引数の添え字には定数を指定してください"; goto err; }
                        if (vTerm.Identifier.Code == VariableCode.ARG)
                        {
                            if (maxArg < vTerm.getEl1forArg + 1)
                                maxArg = vTerm.getEl1forArg + 1;
                        }
                        else if (vTerm.Identifier.Code == VariableCode.ARGS)
                        {
                            if (maxArgs < vTerm.getEl1forArg + 1)
                                maxArgs = vTerm.getEl1forArg + 1;
                        }
                        bool canDef = (vTerm.Identifier.Code == VariableCode.ARG || vTerm.Identifier.Code == VariableCode.ARGS || vTerm.Identifier.IsPrivate);
                        term = argsRow[i * 2 + 1];
                        if (term is NullTerm)
                        {
                            if (canDef)// && label.ArgOptional)
                            {
                                if (vTerm.GetOperandType() == typeof(Int64))
                                    def = new SingleTerm(0);
                                else
                                    def = new SingleTerm("");
                            }
                        }
                        else
                        {
                            def = term.Restructure(exm) as SingleTerm;
                            if (def == null)
                            { errMes = "引数の初期値には定数のみを指定できます"; goto err; }
                            if (!canDef)
                            { errMes = "引数の初期値を定義できるのは\"ARG\"、\"ARGS\"またはプライベート変数のみです"; goto err; }
                            else if (vTerm.Identifier.IsReference)
                            { errMes = "参照渡しの引数に初期値は定義できません"; goto err; }
                            if (vTerm.GetOperandType() != def.GetOperandType())
                            { errMes = "引数の型と初期値の型が一致していません"; goto err; }
                        }
                        args[i] = vTerm;
                        defs[i] = def;
                    }

                }
            }
            if (!wc.EOL)
            { errMes = "引数の書式が間違っています"; goto err; }

            //label.SubNames = subNames;
            label.Arg = args;
            label.Def = defs;
            label.ArgLength = maxArg;
            label.ArgsLength = maxArgs;
            return;
            err:
            ParserMediator.Warn("関数@" + label.LabelName + " の引数のエラー:" + errMes, label, 2, true, false);
            return;
        }
Пример #9
0
        private void nestCheck(FunctionLabelLine label)
        {
            //2周目/3周
            //IF-ELSEIF-ENDIF、REPEAT-RENDの対応チェックなど
            //PRINTDATA系もここでチェック
            LogicalLine nextLine = label;
            List<InstructionLine> tempLineList = new List<InstructionLine>();
            Stack<InstructionLine> nestStack = new Stack<InstructionLine>();
            Stack<InstructionLine> SelectcaseStack = new Stack<InstructionLine>();
            InstructionLine pairLine = null;
            while (true)
            {
                nextLine = nextLine.NextLine;
                parentProcess.scaningLine = nextLine;
                if ((nextLine is NullLine) || (nextLine is FunctionLabelLine))
                    break;
                if (!(nextLine is InstructionLine))
                {
                    if (nextLine is GotoLabelLine)
                    {
                        InstructionLine currentBaseFunc = nestStack.Count == 0 ? null : nestStack.Peek();
                        if (currentBaseFunc != null)
                        {
                            if ((currentBaseFunc.FunctionCode == FunctionCode.PRINTDATA)
                                || (currentBaseFunc.FunctionCode == FunctionCode.PRINTDATAL)
                                || (currentBaseFunc.FunctionCode == FunctionCode.PRINTDATAW)
                                || (currentBaseFunc.FunctionCode == FunctionCode.PRINTDATAD)
                                || (currentBaseFunc.FunctionCode == FunctionCode.PRINTDATADL)
                                || (currentBaseFunc.FunctionCode == FunctionCode.PRINTDATADW)
                                || (currentBaseFunc.FunctionCode == FunctionCode.PRINTDATAK)
                                || (currentBaseFunc.FunctionCode == FunctionCode.PRINTDATAKL)
                                || (currentBaseFunc.FunctionCode == FunctionCode.PRINTDATAKW)
                                || (currentBaseFunc.FunctionCode == FunctionCode.DATALIST)
                                || (currentBaseFunc.FunctionCode == FunctionCode.TRYCALLLIST)
                                || (currentBaseFunc.FunctionCode == FunctionCode.TRYJUMPLIST)
                                || (currentBaseFunc.FunctionCode == FunctionCode.TRYGOTOLIST))
                                //|| (currentBaseFunc.FunctionCode == FunctionCode.SELECTCASE))
                            {
                                ParserMediator.Warn(currentBaseFunc.Function.Name + "構文中に$ラベルを定義することはできません", nextLine, 2, true, false);
                            }
                        }
                    }
                    continue;
                }
                InstructionLine func = (InstructionLine)nextLine;
                pairLine = null;
                InstructionLine baseFunc = nestStack.Count == 0 ? null : nestStack.Peek();
                if (baseFunc != null)
                {
                    if ((baseFunc.FunctionCode == FunctionCode.PRINTDATA)
                        || (baseFunc.FunctionCode == FunctionCode.PRINTDATAL)
                        || (baseFunc.FunctionCode == FunctionCode.PRINTDATAW)
                        || (baseFunc.FunctionCode == FunctionCode.PRINTDATAD)
                        || (baseFunc.FunctionCode == FunctionCode.PRINTDATADL)
                        || (baseFunc.FunctionCode == FunctionCode.PRINTDATADW)
                        || (baseFunc.FunctionCode == FunctionCode.PRINTDATAK)
                        || (baseFunc.FunctionCode == FunctionCode.PRINTDATAKL)
                        || (baseFunc.FunctionCode == FunctionCode.PRINTDATAKW) )
                    {
                        if ((func.FunctionCode != FunctionCode.DATA) && (func.FunctionCode != FunctionCode.DATAFORM) && (func.FunctionCode != FunctionCode.DATALIST)
                            && (func.FunctionCode != FunctionCode.ENDLIST) && (func.FunctionCode != FunctionCode.ENDDATA))
                        {
                            ParserMediator.Warn("PRINTDATA構文に使用できない命令\'" + func.Function.Name + "\'が含まれています", func, 2, true, false);
                            continue;
                        }
                    }
                    else if (baseFunc.FunctionCode == FunctionCode.DATALIST)
                    {
                        if ((func.FunctionCode != FunctionCode.DATA) && (func.FunctionCode != FunctionCode.DATAFORM) && (func.FunctionCode != FunctionCode.ENDLIST))
                        {
                            ParserMediator.Warn("DATALIST構文に使用できない命令\'" + func.Function.Name + "\'が含まれています", func, 2, true, false);
                            continue;
                        }
                    }
                    else if ((baseFunc.FunctionCode == FunctionCode.TRYCALLLIST) || (baseFunc.FunctionCode == FunctionCode.TRYJUMPLIST) || (baseFunc.FunctionCode == FunctionCode.TRYGOTOLIST))
                    {
                        if ((func.FunctionCode != FunctionCode.FUNC) && (func.FunctionCode != FunctionCode.ENDFUNC))
                        {
                            ParserMediator.Warn(baseFunc.Function.Name + "構文に使用できない命令" + func.Function.Name + "が含まれています", func, 2, true, false);
                            continue;
                        }
                    }
                    else if (baseFunc.FunctionCode == FunctionCode.SELECTCASE)
                    {
                        if ((baseFunc.IfCaseList.Count == 0) && (func.FunctionCode != FunctionCode.CASE) && (func.FunctionCode != FunctionCode.CASEELSE) && (func.FunctionCode != FunctionCode.ENDSELECT))
                        {
                            ParserMediator.Warn("SELECTCASE構文の分岐の外に命令" + func.Function.Name + "が含まれています", func, 2, true, false);
                            continue;
                        }
                    }
                }
                switch (func.FunctionCode)
                {
                    case FunctionCode.REPEAT:
                        foreach (InstructionLine iLine in nestStack)
                        {
                            if (iLine.FunctionCode == FunctionCode.REPEAT)
                            {
                                ParserMediator.Warn("REPEAT文が入れ子にされています", func, 2, true, false);
                                break;
                            }
                        }
                        if (func.IsError)
                            break;
                        nestStack.Push(func);
                        break;
                    case FunctionCode.IF:
                        nestStack.Push(func);
                        func.IfCaseList = new List<InstructionLine>();
                        func.IfCaseList.Add(func);
                        break;
                    case FunctionCode.SELECTCASE:
                        nestStack.Push(func);
                        func.IfCaseList = new List<InstructionLine>();
                        SelectcaseStack.Push(func);
                        break;
                    case FunctionCode.FOR:
                    case FunctionCode.WHILE:
                    case FunctionCode.TRYCGOTO:
                    case FunctionCode.TRYCJUMP:
                    case FunctionCode.TRYCCALL:
                    case FunctionCode.TRYCGOTOFORM:
                    case FunctionCode.TRYCJUMPFORM:
                    case FunctionCode.TRYCCALLFORM:
                    case FunctionCode.DO:
                        nestStack.Push(func);
                        break;
                    case FunctionCode.BREAK:
                    case FunctionCode.CONTINUE:
                        InstructionLine[] array = nestStack.ToArray();
                        for (int i = 0; i < array.Length; i++)
                        {
                            if ((array[i].FunctionCode == FunctionCode.REPEAT)
                                || (array[i].FunctionCode == FunctionCode.FOR)
                                || (array[i].FunctionCode == FunctionCode.WHILE)
                                || (array[i].FunctionCode == FunctionCode.DO))
                            {
                                pairLine = array[i];
                                break;
                            }
                        }
                        if (pairLine == null)
                        {
                            ParserMediator.Warn("REPEAT, FOR, WHILE, DOの中以外で" + func.Function.Name + "文が使われました", func, 2, true, false);
                            break;
                        }
                        func.JumpTo = pairLine;
                        break;

                    case FunctionCode.ELSEIF:
                    case FunctionCode.ELSE:
                        {
                            //1.725 Stack<T>.Peek()はStackが空の時はnullを返す仕様だと思いこんでおりました。
                            InstructionLine ifLine = nestStack.Count == 0 ? null : nestStack.Peek();
                            if ((ifLine == null) || (ifLine.FunctionCode != FunctionCode.IF))
                            {
                                ParserMediator.Warn("IF~ENDIFの外で" + func.Function.Name + "文が使われました", func, 2, true, false);
                                break;
                            }
                            if (ifLine.IfCaseList[ifLine.IfCaseList.Count - 1].FunctionCode == FunctionCode.ELSE)
                                ParserMediator.Warn("ELSE文より後で" + func.Function.Name + "文が使われました", func, 1, false, false);
                            ifLine.IfCaseList.Add(func);
                        }
                        break;
                    case FunctionCode.ENDIF:
                        {
                            InstructionLine ifLine = nestStack.Count == 0 ? null : nestStack.Peek();
                            if ((ifLine == null) || (ifLine.FunctionCode != FunctionCode.IF))
                            {
                                ParserMediator.Warn("対応するIFの無いENDIF文です", func, 2, true, false);
                                break;
                            }
                            foreach (InstructionLine ifelseifLine in ifLine.IfCaseList)
                            {
                                ifelseifLine.JumpTo = func;
                            }
                            nestStack.Pop();
                        }
                        break;
                    case FunctionCode.CASE:
                    case FunctionCode.CASEELSE:
                        {
                            InstructionLine selectLine = nestStack.Count == 0 ? null : nestStack.Peek();
                            if ((selectLine == null) || (selectLine.FunctionCode != FunctionCode.SELECTCASE && SelectcaseStack.Count == 0))
                            {
                                ParserMediator.Warn("SELECTCASE~ENDSELECTの外で" + func.Function.Name + "文が使われました", func, 2, true, false);
                                break;
                            }
                            else if (selectLine.FunctionCode != FunctionCode.SELECTCASE && SelectcaseStack.Count > 0)
                            {
                                do
                                {
                                    ParserMediator.Warn(selectLine.Function.Name + "文に対応する" + FunctionIdentifier.getMatchFunction(selectLine.FunctionCode) + "がない状態で" + func.Function.Name + "文に到達しました", func, 2, true, false);
                                    //これを跨いでIF等が閉じられることがないようにする。
                                    nestStack.Pop();
                                    if (nestStack.Count > 0)
                                        selectLine = nestStack.Count == 0 ? null : nestStack.Peek();
                                } while (selectLine != null && selectLine.FunctionCode != FunctionCode.SELECTCASE);
                                break;
                            }
                            if ((selectLine.IfCaseList.Count > 0) &&
                                (selectLine.IfCaseList[selectLine.IfCaseList.Count - 1].FunctionCode == FunctionCode.CASEELSE))
                                ParserMediator.Warn("CASEELSE文より後で" + func.Function.Name + "文が使われました", func, 1, false, false);
                            selectLine.IfCaseList.Add(func);
                        }
                        break;
                    case FunctionCode.ENDSELECT:
                        {
                            InstructionLine selectLine = nestStack.Count == 0 ? null : nestStack.Peek();
                            if ((selectLine == null) || (selectLine.FunctionCode != FunctionCode.SELECTCASE && SelectcaseStack.Count == 0))
                            {
                                ParserMediator.Warn("対応するSELECTCASEの無いENDSELECT文です", func, 2, true, false);
                                break;
                            }
                            else if (selectLine.FunctionCode != FunctionCode.SELECTCASE && SelectcaseStack.Count > 0)
                            {
                                do
                                {
                                    ParserMediator.Warn(selectLine.Function.Name + "文に対応する" + FunctionIdentifier.getMatchFunction(selectLine.FunctionCode) + "がない状態で" + func.Function.Name + "文に到達しました", func, 2, true, false);
                                    //これを跨いでIF等が閉じられることがないようにする。
                                    nestStack.Pop();
                                    if (nestStack.Count > 0)
                                        selectLine = nestStack.Count == 0 ? null : nestStack.Peek();
                                } while (selectLine != null && selectLine.FunctionCode != FunctionCode.SELECTCASE);
                                //とりあえず、対応するSELECTCASE跨ぎは閉じる
                                SelectcaseStack.Pop();
                                break;
                            }
                            nestStack.Pop();
                            SelectcaseStack.Pop();
                            selectLine.JumpTo = func;
                            if (selectLine.IsError)
                                break;
                            IOperandTerm term = ((ExpressionArgument)selectLine.Argument).Term;
                            if (term == null)
                            {
                                ParserMediator.Warn("SELECTCASEの引数がありません", selectLine, 2, true, false);
                                break;
                            }
                            foreach (InstructionLine caseLine in selectLine.IfCaseList)
                            {
                                caseLine.JumpTo = func;
                                if (caseLine.IsError)
                                    continue;
                                if (caseLine.FunctionCode == FunctionCode.CASEELSE)
                                    continue;
                                CaseExpression[] caseExps = ((CaseArgument)caseLine.Argument).CaseExps;
                                if (caseExps.Length == 0)
                                    ParserMediator.Warn("CASEの引数がありません", caseLine, 2, true, false);

                                foreach (CaseExpression exp in caseExps)
                                {
                                    if (exp.GetOperandType() != term.GetOperandType())
                                        ParserMediator.Warn("CASEの引数の型がSELECTCASEと一致しません", caseLine, 2, true, false);
                                }

                            }
                        }
                        break;
                    case FunctionCode.REND:
                    case FunctionCode.NEXT:
                    case FunctionCode.WEND:
                    case FunctionCode.LOOP:
                        FunctionCode parentFunc = FunctionIdentifier.getParentFunc(func.FunctionCode);
                        //if (parentFunc == FunctionCode.__NULL__)
                        //    throw new ExeEE("何か変?");
                        if ((nestStack.Count == 0)
                            || (nestStack.Peek().FunctionCode != parentFunc))
                        {
                            ParserMediator.Warn("対応する" + parentFunc.ToString() + "の無い" + func.Function.Name + "文です", func, 2, true, false);
                            break;
                        }
                        pairLine = nestStack.Pop();//REPEAT
                        func.JumpTo = pairLine;
                        pairLine.JumpTo = func;
                        break;
                    case FunctionCode.CATCH:
                        pairLine = nestStack.Count == 0 ? null : nestStack.Peek();
                        if ((pairLine == null)
                            || ((pairLine.FunctionCode != FunctionCode.TRYCGOTO)
                            && (pairLine.FunctionCode != FunctionCode.TRYCCALL)
                            && (pairLine.FunctionCode != FunctionCode.TRYCJUMP)
                            && (pairLine.FunctionCode != FunctionCode.TRYCGOTOFORM)
                            && (pairLine.FunctionCode != FunctionCode.TRYCCALLFORM)
                            && (pairLine.FunctionCode != FunctionCode.TRYCJUMPFORM)))
                        {
                            ParserMediator.Warn("対応するTRYC系命令がありません", func, 2, true, false);
                            break;
                        }
                        pairLine = nestStack.Pop();//TRYC
                        pairLine.JumpToEndCatch = func;//TRYCにCATCHの位置を教える
                        nestStack.Push(func);
                        break;
                    case FunctionCode.ENDCATCH:
                        if ((nestStack.Count == 0)
                            || (nestStack.Peek().FunctionCode != FunctionCode.CATCH))
                        {
                            ParserMediator.Warn("対応するCATCHのないENDCATCHです", func, 2, true, false);
                            break;
                        }
                        pairLine = nestStack.Pop();//CATCH
                        pairLine.JumpToEndCatch = func;//CATCHにENDCATCHの位置を教える
                        break;
                    case FunctionCode.PRINTDATA:
                    case FunctionCode.PRINTDATAL:
                    case FunctionCode.PRINTDATAW:
                    case FunctionCode.PRINTDATAD:
                    case FunctionCode.PRINTDATADL:
                    case FunctionCode.PRINTDATADW:
                    case FunctionCode.PRINTDATAK:
                    case FunctionCode.PRINTDATAKL:
                    case FunctionCode.PRINTDATAKW:
                        foreach (InstructionLine iLine in nestStack)
                        {
                            if (iLine.FunctionCode == FunctionCode.PRINTDATA || iLine.FunctionCode == FunctionCode.PRINTDATAL || iLine.FunctionCode == FunctionCode.PRINTDATAW
                                || iLine.FunctionCode == FunctionCode.PRINTDATAD || iLine.FunctionCode == FunctionCode.PRINTDATADL || iLine.FunctionCode == FunctionCode.PRINTDATADW
                                || iLine.FunctionCode == FunctionCode.PRINTDATAK || iLine.FunctionCode == FunctionCode.PRINTDATAKL || iLine.FunctionCode == FunctionCode.PRINTDATAKW)
                            {
                                ParserMediator.Warn("PRINTDATA系命令が入れ子にされています", func, 2, true, false);
                                break;
                            }
                        }
                        if (func.IsError)
                            break;
                        func.dataList = new List<List<InstructionLine>>();
                        nestStack.Push(func);
                        break;
                    case FunctionCode.DATALIST:
                        InstructionLine plist = (nestStack.Count == 0) ? null : nestStack.Peek();
                        if ((plist == null)
                           || (plist.FunctionCode != FunctionCode.PRINTDATA && plist.FunctionCode != FunctionCode.PRINTDATAL && plist.FunctionCode != FunctionCode.PRINTDATAW
                               && plist.FunctionCode != FunctionCode.PRINTDATAD && plist.FunctionCode != FunctionCode.PRINTDATADL && plist.FunctionCode != FunctionCode.PRINTDATADW
                               && plist.FunctionCode != FunctionCode.PRINTDATAK && plist.FunctionCode != FunctionCode.PRINTDATAKL && plist.FunctionCode != FunctionCode.PRINTDATAKW))
                        {
                            ParserMediator.Warn("対応するPRINTDATA系命令のないDATALISTです", func, 2, true, false);
                            break;
                        }
                        tempLineList = new List<InstructionLine>();
                        nestStack.Push(func);

                        break;
                    case FunctionCode.ENDLIST:
                        if ((nestStack.Count == 0)
                            || (nestStack.Peek().FunctionCode != FunctionCode.DATALIST))
                        {
                            ParserMediator.Warn("対応するDATALISTのないENDLISTです", func, 2, true, false);
                            break;
                        }
                        if (tempLineList.Count == 0)
                            ParserMediator.Warn("DATALIST命令に表示データが与えられていません(このDATALISTは空文字列を表示します)", func, 1, false, false);
                        nestStack.Pop();
                        nestStack.Peek().dataList.Add(tempLineList);
                        break;
                    case FunctionCode.DATA:
                    case FunctionCode.DATAFORM:
                        InstructionLine pdata = (nestStack.Count == 0) ? null : nestStack.Peek();
                        if ((pdata == null) ||
                        (pdata.FunctionCode != FunctionCode.PRINTDATA && pdata.FunctionCode != FunctionCode.PRINTDATAL && pdata.FunctionCode != FunctionCode.PRINTDATAW
                         && pdata.FunctionCode != FunctionCode.PRINTDATAD && pdata.FunctionCode != FunctionCode.PRINTDATADL && pdata.FunctionCode != FunctionCode.PRINTDATADW
                         && pdata.FunctionCode != FunctionCode.PRINTDATAK && pdata.FunctionCode != FunctionCode.PRINTDATAKL && pdata.FunctionCode != FunctionCode.PRINTDATAKW && pdata.FunctionCode != FunctionCode.DATALIST))
                        {
                            ParserMediator.Warn("対応するPRINTDATA系命令のない" + func.Function.Name + "です", func, 2, true, false);
                            break;
                        }
                        List<InstructionLine> iList = new List<InstructionLine>();
                        if (pdata.FunctionCode != FunctionCode.DATALIST)
                        {
                            iList.Add(func);
                            pdata.dataList.Add(iList);
                        }
                        else
                            tempLineList.Add(func);
                        break;
                    case FunctionCode.ENDDATA:
                        InstructionLine pdataline = (nestStack.Count == 0) ? null : nestStack.Peek();
                        if ((pdataline == null) ||
                            (pdataline.FunctionCode != FunctionCode.PRINTDATA && pdataline.FunctionCode != FunctionCode.PRINTDATAL && pdataline.FunctionCode != FunctionCode.PRINTDATAW
                             && pdataline.FunctionCode != FunctionCode.PRINTDATAD && pdataline.FunctionCode != FunctionCode.PRINTDATADL && pdataline.FunctionCode != FunctionCode.PRINTDATADW
                             && pdataline.FunctionCode != FunctionCode.PRINTDATAK && pdataline.FunctionCode != FunctionCode.PRINTDATAKL && pdataline.FunctionCode != FunctionCode.PRINTDATAKW))
                        {
                            ParserMediator.Warn("対応するPRINTDATA系命令のない" + func.Function.Name + "です", func, 2, true, false);
                            break;
                        }
                        if (pdataline.FunctionCode == FunctionCode.DATALIST)
                            ParserMediator.Warn("DATALISTが閉じられていません", func, 2, true, false);
                        if (pdataline.dataList.Count == 0)
                            ParserMediator.Warn(pdataline.Function.Name + "命令に表示データがありません(この命令は無視されます)", func, 1, false, false);
                        pdataline.JumpTo = func;
                        nestStack.Pop();
                        break;
                    case FunctionCode.TRYCALLLIST:
                    case FunctionCode.TRYJUMPLIST:
                    case FunctionCode.TRYGOTOLIST:
                        foreach (InstructionLine iLine in nestStack)
                        {
                            if (iLine.FunctionCode == FunctionCode.TRYCALLLIST || iLine.FunctionCode == FunctionCode.TRYJUMPLIST || iLine.FunctionCode == FunctionCode.TRYGOTOLIST)
                            {
                                ParserMediator.Warn("TRYCALLLIST系命令が入れ子にされています", func, 2, true, false);
                                break;
                            }
                        }
                        if (func.IsError)
                            break;
                        func.callList = new List<InstructionLine>();
                        nestStack.Push(func);
                        break;
                    case FunctionCode.FUNC:
                        {
                            InstructionLine pFunc = (nestStack.Count == 0) ? null : nestStack.Peek();
                            if ((pFunc == null) ||
                                (pFunc.FunctionCode != FunctionCode.TRYCALLLIST && pFunc.FunctionCode != FunctionCode.TRYJUMPLIST && pFunc.FunctionCode != FunctionCode.TRYGOTOLIST))
                            {
                                ParserMediator.Warn("対応するTRYCALLLIST系命令のない" + func.Function.Name + "です", func, 2, true, false);
                                break;
                            }
                            if (pFunc.FunctionCode == FunctionCode.TRYGOTOLIST)
                            {
                                if (((SpCallArgment)func.Argument).SubNames.Length != 0)
                                {
                                    ParserMediator.Warn("TRYGOTOLISTの呼び出し対象に[~~]が設定されています", func, 2, true, false);
                                    break;
                                }
                                if (((SpCallArgment)func.Argument).RowArgs.Length != 0)
                                {
                                    ParserMediator.Warn("TRYGOTOLISTの呼び出し対象に引数が設定されています", func, 2, true, false);
                                    break;
                                }
                            }
                            pFunc.callList.Add(func);
                            break;
                        }
                    case FunctionCode.ENDFUNC:
                        InstructionLine pf = (nestStack.Count == 0) ? null : nestStack.Peek();
                        if ((pf == null) ||
                            (pf.FunctionCode != FunctionCode.TRYCALLLIST && pf.FunctionCode != FunctionCode.TRYJUMPLIST && pf.FunctionCode != FunctionCode.TRYGOTOLIST))
                        {
                            ParserMediator.Warn("対応するTRYCALLLIST系命令のない" + func.Function.Name + "です", func, 2, true, false);
                            break;
                        }
                        pf.JumpTo = func;
                        nestStack.Pop();
                        break;
                    case FunctionCode.NOSKIP:
                        foreach (InstructionLine iLine in nestStack)
                        {
                            if (iLine.FunctionCode == FunctionCode.NOSKIP)
                            {
                                ParserMediator.Warn("NOSKIP系命令が入れ子にされています", func, 2, true, false);
                                break;
                            }
                        }
                        if (func.IsError)
                            break;
                        nestStack.Push(func);
                        break;
                    case FunctionCode.ENDNOSKIP:
                        InstructionLine pfunc = (nestStack.Count == 0) ? null : nestStack.Peek();
                        if ((pfunc == null) ||
                            (pfunc.FunctionCode != FunctionCode.NOSKIP))
                        {
                            ParserMediator.Warn("対応するNOSKIP系命令のない" + func.Function.Name + "です", func, 2, true, false);
                            break;
                        }
                        //エラーハンドリング用
                        pfunc.JumpTo = func;
                        func.JumpTo = pfunc;
                        nestStack.Pop();
                        break;
                }

            }

            while (nestStack.Count != 0)
            {
                InstructionLine func = nestStack.Pop();
                string funcName = func.Function.Name;
                string funcMatch = FunctionIdentifier.getMatchFunction(func.FunctionCode);
                if (func != null)
                    ParserMediator.Warn(funcName + "に対応する" + funcMatch + "が見つかりません", func, 2, true, false);
                else
                    ParserMediator.Warn("ディフォルトエラー(Emuera設定漏れ)", func, 2, true, false);
            }
            //使ったスタックをクリア
            SelectcaseStack.Clear();
        }
Пример #10
0
 private void checkFunctionWithCatch(FunctionLabelLine label)
 {
     //ここでエラーを捕まえることは本来はないはず。ExeEE相当。
     try
     {
         System.Windows.Forms.Application.DoEvents();
         string filename = label.Position.Filename.ToUpper();
         setArgument(label);
         nestCheck(label);
         setJumpTo(label);
     }
     catch (Exception exc)
     {
         System.Media.SystemSounds.Hand.Play();
         //1756beta2+v6.1 修正の効率化のために何かパース関係でハンドリングできてないエラーが出た場合はスタックトレースを投げるようにした
         string errmes = (exc is EmueraException) ? exc.Message : exc.GetType().ToString() + ":" + exc.Message;
         ParserMediator.Warn("@" + label.LabelName + " の解析中にエラー:" + errmes, label, 2, true, false, !(exc is EmueraException) ? exc.StackTrace : null);
         label.ErrMes = "ロード時に解析に失敗した関数が呼び出されました";
     }
     finally
     {
         parentProcess.scaningLine = null;
     }
 }
Пример #11
0
        private void setJumpTo(FunctionLabelLine label)
        {
            //3周目/3周
            //フロー制御命令のジャンプ先を設定
            LogicalLine nextLine = label;
            int depth = label.Depth;
            if (depth < 0)
                depth = -2;
            while (true)
            {
                string FunctionoNotFoundName = null;
                nextLine = nextLine.NextLine;
                InstructionLine func = nextLine as InstructionLine;
                if (func == null)
                {
                    if ((nextLine is NullLine) || (nextLine is FunctionLabelLine))
                        break;
                    continue;
                }
                if (func.IsError)
                    continue;
                parentProcess.scaningLine = func;

                if (func.Function.Instruction != null)
                {
                    try
                    {
                        func.Function.Instruction.SetJumpTo(ref useCallForm, func, depth, ref FunctionoNotFoundName);
                    }
                    catch (CodeEE e)
                    {
                        ParserMediator.Warn(e.Message, func, 2, true, false);
                        continue;
                    }
                    if (FunctionoNotFoundName != null)
                    {
                        if (!Program.AnalysisMode)
                            printFunctionNotFoundWarning("指定された関数名\"@" + FunctionoNotFoundName + "\"は存在しません", func, 2, true);
                        else
                            printFunctionNotFoundWarning(FunctionoNotFoundName, func, 2, true);
                    }
                    continue;
                }
                if ((func.FunctionCode == FunctionCode.TRYCALLLIST) || (func.FunctionCode == FunctionCode.TRYJUMPLIST))
                    useCallForm = true;
            }
        }
Пример #12
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, false, false);
         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 (label.IsEvent)
                     {
                         ParserMediator.Warn("イベント関数では#" + token + "による" + token.Substring(0, token.Length - 4)+ "のサイズ指定は無視されます", position, 1);
                         break;
                     }
                     if (wc.EOL)
                     {
                         ParserMediator.Warn("#" + token + "の後に有効な数値が指定されていません", position, 2);
                         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 (label.LocalLength > 0)
                             ParserMediator.Warn("この関数にはすでに#LOCALSIZEが定義されています。(以前の定義は無視されます)", position, 1);
                         label.LocalLength = size;
                     }
                     else
                     {
                         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;
 }
Пример #13
0
 internal void AddInvalidLabel(FunctionLabelLine invalidLabelLine)
 {
     invalidList.Add(invalidLabelLine);
 }
Пример #14
0
 public FunctionLabelLine GetSameNameLabel(FunctionLabelLine point)
 {
     string id = point.LabelName;
     if (!labelAtDic.ContainsKey(id))
         return null;
     if (point.IsError)
         return null;
     List<FunctionLabelLine> labelList = labelAtDic[id];
     if (labelList.Count <= 1)
         return null;
     return labelList[0];
 }
Пример #15
0
 public GotoLabelLine GetLabelDollar(string key, FunctionLabelLine labelAtLine)
 {
     foreach (GotoLabelLine label in labelDollarList)
     {
         if ((label.LabelName == key) && (label.ParentLabelLine == labelAtLine))
             return label;
     }
     return null;
 }
Пример #16
0
 private void setArgument(FunctionLabelLine label)
 {
     //1周目/3周
     //引数の解析とか
     LogicalLine nextLine = label;
     bool inMethod = label.IsMethod;
     while (true)
     {
         nextLine = nextLine.NextLine;
         parentProcess.scaningLine = nextLine;
         InstructionLine func = nextLine as InstructionLine;
         if (func == null)
         {
             if ((nextLine is NullLine) || (nextLine is FunctionLabelLine))
                 break;
             continue;
         }
         if (inMethod)
         {
             if (!func.Function.IsMethodSafe())
             {
                 ParserMediator.Warn(func.Function.Name + "命令は#FUNCTION中で使うことはできません", nextLine, 2, true, false);
                 continue;
             }
         }
         if (Config.NeedReduceArgumentOnLoad || Program.AnalysisMode || func.Function.IsForceSetArg())
             ArgumentParser.SetArgumentTo(func);
     }
 }
Пример #17
0
        public IOperandTerm GetFunctionMethod(LabelDictionary labelDic, string codeStr, IOperandTerm[] arguments, bool userDefinedOnly)
        {
            if (Config.ICFunction)
            {
                codeStr = codeStr.ToUpper();
            }
            if (arguments == null)            //引数なし、名前のみの探索
            {
                if (refmethodDic.ContainsKey(codeStr))
                {
                    return(new UserDefinedRefMethodNoArgTerm(refmethodDic[codeStr]));
                }
                return(null);
            }
            if ((labelDic != null) && (labelDic.Initialized))
            {
                if (refmethodDic.ContainsKey(codeStr))
                {
                    return(new UserDefinedRefMethodTerm(refmethodDic[codeStr], arguments));
                }
                FunctionLabelLine func = labelDic.GetNonEventLabel(codeStr);
                if (func != null)
                {
                    if (userDefinedOnly && !func.IsMethod)
                    {
                        throw new CodeEE("#FUNCTIONが指定されていない関数\"@" + func.LabelName + "\"をCALLF系命令で呼び出そうとしました");
                    }
                    if (func.IsMethod)
                    {
                        string       errMes;
                        IOperandTerm ret = UserDefinedMethodTerm.Create(func, arguments, out errMes);
                        if (ret == null)
                        {
                            throw new CodeEE(errMes);
                        }
                        return(ret);
                    }
                    //1.721 #FUNCTIONが定義されていない関数は組み込み関数を上書きしない方向に。 PANCTION.ERBのRANDとか。
                    if (!methodDic.ContainsKey(codeStr))
                    {
                        throw new CodeEE("#FUNCTIONが定義されていない関数(" + func.Position.Filename + ":" + func.Position.LineNo + "行目)を式中で呼び出そうとしました");
                    }
                }
            }
            if (userDefinedOnly)
            {
                return(null);
            }
            FunctionMethod method = null;

            if (!methodDic.TryGetValue(codeStr, out method))
            {
                return(null);
            }
            string errmes = method.CheckArgumentType(codeStr, arguments);

            if (errmes != null)
            {
                throw new CodeEE(errmes);
            }
            return(new FunctionMethodTerm(method, arguments));
        }
Пример #18
0
        public static LogicalLine ParseLabelLine(StringStream stream, ScriptPosition position, EmueraConsole console)
        {
            bool isFunction = (stream.Current == '@');
            int lineNo = position.LineNo;
            string labelName = "";
            string errMes = "";
            try
            {
                int warnLevel = -1;
                stream.ShiftNext();//@か$を除去
                WordCollection wc = LexicalAnalyzer.Analyse(stream, LexEndWith.EoL, false, true);
                if (wc.EOL || !(wc.Current is IdentifierWord))
                {
                    errMes = "関数名が不正であるか存在しません";
                    goto err;
                }
                labelName = ((IdentifierWord)wc.Current).Code;
                wc.ShiftNext();
                if (Config.ICVariable)
                    labelName = labelName.ToUpper();
                GlobalStatic.IdentifierDictionary.CheckUserLabelName(ref errMes, ref warnLevel, isFunction, labelName);
                if (warnLevel >= 0)
                {
                    if (warnLevel >= 2)
                        goto err;
                    ParserMediator.Warn(errMes, position, warnLevel);
                }
                if (!isFunction)//$ならこの時点で終了
                {
                    if (!wc.EOL)
                        ParserMediator.Warn("$で始まるラベルに引数が設定されています", position, 1);
                    return new GotoLabelLine(position, labelName);
                }

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

                ////関数名部分に_renameを使えないように変更
                //if (ParserMediator.RenameDic != null && ((stream.ToString().IndexOf("[[") >= 0) && (stream.ToString().IndexOf("]]") >= 0)))
                //{
                //    string line = stream.ToString();
                //    foreach (KeyValuePair<string, string> pair in ParserMediator.RenameDic)
                //        line = line.Replace(pair.Key, pair.Value);
                //    stream = new StringStream(line);
                //}
                //WordCollection wc = null;
                //wc = LexicalAnalyzer.Analyse(stream, LexEndWith.EoL, false, true);
                if (Program.AnalysisMode)
                    console.PrintC("@" + labelName, false);
                FunctionLabelLine funclabelLine = new FunctionLabelLine(position, labelName, wc);
                if (IdentifierDictionary.IsEventLabelName(labelName))
                {
                    funclabelLine.IsEvent = true;
                    funclabelLine.IsSystem = true;
                    funclabelLine.Depth = 0;
                }
                else if (IdentifierDictionary.IsSystemLabelName(labelName))
                {
                    funclabelLine.IsSystem = true;
                    funclabelLine.Depth = 0;
                }
                return funclabelLine;
            }
            catch (CodeEE e)
            {
                errMes = e.Message;
            }
            err:
            System.Media.SystemSounds.Hand.Play();
            if (isFunction)
            {
                if(labelName.Length == 0)
                    labelName = "<Error>";
                return new InvalidLabelLine(position, labelName, errMes);
            }
            return new InvalidLine(position, errMes);
        }