示例#1
0
        /// <summary>
        /// 関数をシステムに追加する
        /// </summary>
        /// <param name="name">関数の名前</param>
        /// <param name="argdef">引数の定義</param>
        /// <param name="resultType">関数の戻り値</param>
        /// <param name="f">実際に処理を行うC#のdelegate</param>
        /// <param name="desc">関数の説明</param>
        /// <param name="kana">命令のよみがな</param>
        protected void addFunc(string name, string argdef, NakoVarType resultType, SysCallDelegate f, string desc, string kana)
        {
            name = NakoToken.TrimOkurigana(name);
            NakoAPIFunc s = new NakoAPIFunc(name, argdef, resultType, f);

            NakoAPIFuncBank.Instance.AddFunc(s);
        }
示例#2
0
 /// <summary>
 /// ユーザー関数を登録する
 /// </summary>
 protected void RegisterUserCall()
 {
     // tokenでDEFINE FUNKが見つかったらEOLまでを最上部に追加
     if (tokens != null)
     {
         tokens.MoveTop();
         while (!tokens.IsEOF())
         {
             NakoToken tok = tokens.CurrentToken;
             if (tok.Type == NakoTokenType.DEF_FUNCTION)
             {
                 int index = 0;
                 while (tok.Type != NakoTokenType.SCOPE_BEGIN)
                 {
                     NakoToken insertToken = new NakoToken(tok.Type, tok.LineNo, tok.IndentLevel, tok.Value);
                     if (tok.Type == NakoTokenType.DEF_FUNCTION)
                     {
                         insertToken.Type = NakoTokenType.DEF_FUNCTION_ALIASE;
                     }
                     tokens.Insert(index, insertToken);
                     index++;
                     tokens.MoveNext();
                     tokens.MoveNext();
                     tok = tokens.CurrentToken;
                 }
                 tokens.Insert(index, tok);
             }
             tokens.MoveNext();
         }
         tokens.MoveTop();
     }
 }
示例#3
0
        /// <summary>
        /// 関数を追加
        /// </summary>
        /// <param name="name"></param>
        /// <param name="argdef"></param>
        /// <param name="resultType"></param>
        /// <param name="f"></param>
        /// <param name="desc"></param>
        /// <param name="kana"></param>
        public void AddFunc(string name, string argdef, NakoVarType resultType, NakoPlugin.SysCallDelegate f, string desc, string kana)
        {
            name = NakoToken.TrimOkurigana(name);
            NakoAPIFunc s = new NakoAPIFunc(name, argdef, resultType, f);

            s.PluginInstance = PluginInstance;
            this.AddFuncToList(s);
        }
示例#4
0
        //> _for     : WORD _value _value FOR _scope_or_statement
        //>          ;
        private bool _for()
        {
            NakoToken tokVar = null;

            TokenTry();

            // local variable
            if (!Accept(NakoTokenType.WORD))
            {
                return(false);
            }
            tokVar = tok.CurrentToken;
            if (!(tokVar.Josi == "を" || tokVar.Josi == "で"))
            {
                return(false);
            }
            tok.MoveNext();

            // get argument * 2
            if (!_value())
            {
                TokenBack();
                return(false);
            }
            if (!_value())
            {
                TokenBack();
                return(false);
            }

            NakoNodeFor      fornode = new NakoNodeFor();
            NakoNodeVariable v       = new NakoNodeVariable();

            fornode.loopVar = v;
            v.scope         = NakoVariableScope.Local;
            v.Token         = tokVar;
            v.varNo         = localVar.CreateVar(tokVar.Value);

            fornode.nodeTo   = calcStack.Pop();
            fornode.nodeFrom = calcStack.Pop();

            if (!Accept(NakoTokenType.FOR))
            {
                TokenBack();
                return(false);
            }
            TokenFinally();
            tok.MoveNext();

            fornode.nodeBlocks = _scope_or_statement();
            this.parentNode.AddChild(fornode);
            lastNode = fornode;
            return(true);
        }
示例#5
0
        //> _callfunc : { [{_value}] FUNCTION_NAME }
        //>           ;
        private bool _callfunc_stmt()
        {
            NakoToken startToken = tok.CurrentToken;

            TokenTry();
            while (!tok.IsEOF())
            {
                WriteLog(tok.CurrentToken.ToStringForDebug());
                if (Accept(NakoTokenType.EOL))
                {
                    tok.MoveNext();
                    break;
                }
                if (!_value())
                {
                    TokenBack();
                    return(false);
                }
            }
            TokenFinally();
            //TODO: _callfunc_stmt
            // 計算用スタックの管理
            if (calcStack.Count > 0)
            {
                while (calcStack.Count > 0)
                {
                    NakoNode n = calcStack.Shift();
                    if (!(n is NakoNodeCallFunction))
                    {
                        // 余剰スタックの値を得る
                        string r = "";
                        for (int i = 0; i < calcStack.Count; i++)
                        {
                            if (i != 0)
                            {
                                r += ",";
                            }
                            NakoNode n0 = calcStack[i];
                            r += n0.ToTypeString();
                        }
                        throw new NakoParserException(
                                  "無効な式か値があります。(余剰スタックのチェック):" + r,
                                  startToken);
                    }
                    parentNode.AddChild(n);
                    parentNode.AddChild(new NakoNodePop());
                }
            }
            // ここで本来ならば
            // スタックを空にする or 余剰なスタックがあればエラーにするのが筋だが...
            // 連続関数呼び出しに対応するためエラーにしない
            return(true);
        }
示例#6
0
        //> _arglist : '(' { _value } ')'
        //>          ;
        private bool _arglist(NakoNodeCallFunction node)
        {
            NakoToken firstT = tok.CurrentToken;
            int       nest   = 0;

            // '(' から始まるかチェック
            if (!Accept(NakoTokenType.PARENTHESES_L))
            {
                return(false);
            }
            tok.MoveNext(); // skip '('
            nest++;

            // '(' .. ')' の間を取りだして別トークンとする
            NakoTokenList par_list = new NakoTokenList();

            while (!tok.IsEOF())
            {
                if (Accept(NakoTokenType.PARENTHESES_R))
                {
                    nest--;
                    if (nest == 0)
                    {
                        tok.MoveNext();
                        break;
                    }
                }
                else if (Accept(NakoTokenType.PARENTHESES_L))
                {
                    nest++;
                }
                par_list.Add(tok.CurrentToken);
                tok.MoveNext();
            }
            // 現在のトークン位置を保存
            tok.Save();
            NakoTokenList tmp_list = tok;

            tok = par_list;
            tok.MoveTop();
            while (!tok.IsEOF())
            {
                if (!_value())
                {
                    throw new NakoParserException("関数の引数の配置エラー。", firstT);
                }
            }
            // トークンリストを復元
            tok = tmp_list;
            tok.Restore();
            return(true);
        }
示例#7
0
        //> _variable_elements : '[' _value ']'
        //>                    | '\' _value
        //>                    ;
        private bool _variable_elements(NakoNodeVariable n)
        {
            NakoToken firstT = tok.CurrentToken;

            // 配列アクセス?
            if (!Accept(NakoTokenType.BRACKETS_L) && !Accept(NakoTokenType.YEN))
            {
                return(false);
            }
            NakoTokenType t;

            while (!tok.IsEOF())
            {
                t = tok.CurrentTokenType;

                if (t == NakoTokenType.BRACKETS_L)
                {
                    tok.MoveNext(); // skip ']'
                    if (!_value())
                    {
                        throw new NakoParserException("変数要素へのアクセスで要素式にエラー。", firstT);
                    }
                    if (!Accept(NakoTokenType.BRACKETS_R))
                    {
                        throw new NakoParserException("変数要素へのアクセスで閉じ角カッコがありません。", firstT);
                    }
                    tok.MoveNext(); // skip ']'
                    n.AddChild(calcStack.Pop());
                }
                else // t == NakoTokenType.YEN
                {
                    tok.MoveNext(); // skip '\'
                    if (!_value_nojfunc())
                    {
                        throw new NakoParserException("変数要素へのアクセスで要素式にエラー。", firstT);
                    }
                    n.AddChild(calcStack.Pop());
                }
                // 引き続き、変数要素へのアクセスがあるかどうか
                if (Accept(NakoTokenType.BRACKETS_L))
                {
                    continue;
                }
                if (Accept(NakoTokenType.YEN))
                {
                    continue;
                }
                break;
            }
            return(true);
        }
示例#8
0
        //> _if_stmt : IF _value THEN [EOL] _scope_or_statement [ ELSE _scope_or_statement ]
        //>          ;
        private bool _if_stmt()
        {
            if (!Accept(NakoTokenType.IF))
            {
                return(false);
            }
            tok.MoveNext(); // skip IF

            NakoNodeIf ifnode = new NakoNodeIf();

            // _value
            NakoToken t = tok.CurrentToken;

            if (!_value())
            {
                throw new NakoParserException("もし文で比較式がありません。", t);
            }
            ifnode.nodeCond = calcStack.Pop();

            // THEN (日本語では、助詞なのでたぶんないはずだが...)
            if (Accept(NakoTokenType.THEN))
            {
                tok.MoveNext();
            }
            while (Accept(NakoTokenType.EOL))
            {
                tok.MoveNext();
            }

            // TRUE
            ifnode.nodeTrue = _scope_or_statement();
            while (Accept(NakoTokenType.EOL))
            {
                tok.MoveNext();
            }

            // FALSE
            if (Accept(NakoTokenType.ELSE))
            {
                tok.MoveNext(); // skip ELSE
                while (Accept(NakoTokenType.EOL))
                {
                    tok.MoveNext();
                }
                ifnode.nodeFalse = _scope_or_statement();
            }
            this.parentNode.AddChild(ifnode);
            this.lastNode = ifnode;
            return(true);
        }
示例#9
0
        //> _def_function_args : empty
        //>                    | '(' { WORD } ')' FUNCTION_NAME
        //>                    | { WORD } FUNCTION_NAME
        //>                    | FUNCTION_NAME '(' { WORD } ')'
        //>                    ;
        private bool _def_function_args(NakoFunc func)
        {
            NakoToken     firstT    = tok.CurrentToken;
            NakoTokenList argTokens = new NakoTokenList();
            bool          argMode   = false;
            NakoToken     funcName  = null;

            // 関数の引数宣言を取得する
            while (!tok.IsEOF())
            {
                // '(' .. ')' の中は全部、関数の引数です
                if (argMode)
                {
                    if (Accept(NakoTokenType.PARENTHESES_R))
                    {
                        argMode = false;
                        tok.MoveNext();
                        continue;
                    }
                    argTokens.Add(tok.CurrentToken);
                    tok.MoveNext();
                    continue;
                }
                if (Accept(NakoTokenType.PARENTHESES_L))
                {
                    tok.MoveNext();
                    argMode = true;
                    continue;
                }
                if (Accept(NakoTokenType.SCOPE_BEGIN))
                {
                    break;
                }
                if (Accept(NakoTokenType.FUNCTION_NAME))
                {
                    funcName = tok.CurrentToken;
                    tok.MoveNext();
                    continue;
                }
                argTokens.Add(tok.CurrentToken);
                tok.MoveNext();
            }
            if (funcName == null)
            {
                throw new NakoParserException("関数名がありません。", firstT);
            }
            func.name = funcName.GetValueAsName();            //TODO: check namespace and class name
            func.args.analizeArgTokens(argTokens);
            return(true);
        }
示例#10
0
        private bool _try_stmt()
        {
            if (!Accept(NakoTokenType.TRY))
            {
                return(false);
            }
            tok.MoveNext();             // skip IF

            NakoNodeTry trynode = new NakoNodeTry();

            NakoToken t = tok.CurrentToken;

            while (Accept(NakoTokenType.EOL))
            {
                tok.MoveNext();
            }

            // TRY
            trynode.nodeTry = _scope_or_statement();
            while (Accept(NakoTokenType.EOL))
            {
                tok.MoveNext();
            }

            // CATCH
            //TODO ○○のエラーならば〜☆☆のエラーならば〜への対応
            //TODO ○○や☆☆のエラーならばへの対応
            while (Accept(NakoTokenType.CATCH))
            {
                //TODO:catchの例外種別を取得
                tok.MoveNext();                //skip catch
                while (Accept(NakoTokenType.EOL))
                {
                    tok.MoveNext();
                }
                //while (calcStack.Count > 0) {
                //	calcStack.Pop ();
                //}
                NakoNode nodeCatch = _scope_or_statement();                //TODO Add
                trynode.nodeCatch = nodeCatch;
            }
            //TODO set finally
            this.parentNode.AddChild(trynode);
            this.lastNode = trynode;
            return(true);
        }
示例#11
0
        //> _def_function : DEF_FUNCTION _def_function_args _scope
        //>               ;
        private bool _def_function()
        {
            if (!Accept(NakoTokenType.DEF_FUNCTION))
            {
                return(false);
            }
            NakoToken t = tok.CurrentToken;

            tok.MoveNext(); // '*'

            NakoFunc userFunc = new NakoFunc();

            userFunc.funcType = NakoFuncType.UserCall;

            // 引数 + 関数名の取得
            _def_function_args(userFunc);

            // ブロックの取得
            PushFrame();
            NakoNodeDefFunction funcNode = new NakoNodeDefFunction();

            funcNode.func = userFunc;
            parentNode    = funcNode.funcBody = new NakoNode();
            funcNode.RegistArgsToLocalVar();
            localVar = funcNode.localVar;
            if (!_scope())
            {
                throw new NakoParserException("関数定義中のエラー。", t);
            }
            PopFrame();
            // グローバル変数に登録
            NakoVariable v = new NakoVariable();

            v.SetBody(funcNode, NakoVarType.UserFunc);
            globalVar.CreateVar(userFunc.name, v);
            // 関数の宣言は、ノードのトップ直下に追加する
            if (!this.topNode.hasChildren())
            {
                this.topNode.AddChild(new NakoNode());
            }
            this.topNode.Children.Insert(0, funcNode);
            return(true);
        }
示例#12
0
        //> _blocks : empty
        //>         | { _statement | _eol }
        //>         ;
        private bool _blocks()
        {
            if (tok.IsEOF())
            {
                return(true);
            }

            NakoToken tBlockTop = tok.CurrentToken;
            NakoToken t;

            while (!tok.IsEOF())
            {
                // ブロックを抜けるキーワードをチェック
                if (Accept(NakoTokenType.SCOPE_END))
                {
                    return(true);
                }
                if (Accept(NakoTokenType.KOKOMADE))
                {
                    return(true);
                }

                // ブロック要素を繰り返し評価
                t = tok.CurrentToken;
                if (_statement())
                {
                    continue;
                }
                if (_eol())
                {
                    continue;
                }

                throw new NakoParserException("ブロックの解析エラー", t);
            }
            return(true);
        }
示例#13
0
        /// <summary>
        /// 引数の定義文字列を読んで、関数の引数として登録する
        /// </summary>
        public void analizeArgTokens(NakoTokenList tokens)
        {
            bool   optMode = false;
            ArgOpt argOpt  = new ArgOpt();

            for (int i = 0; i < tokens.Count; i++)
            {
                NakoToken   tok = tokens[i];
                NakoFuncArg arg = null;
                // オプション指定モード(optMode) の on/off
                if (tok.Type == NakoTokenType.BRACES_L)
                {
                    // オプションの初期化
                    optMode = true;
                    argOpt.Init();
                    continue;
                }
                if (tok.Type == NakoTokenType.BRACES_R)
                {
                    optMode = false;
                    continue;
                }
                if (optMode)
                {
                    if (tok.Type == NakoTokenType.WORD)
                    {
                        string opt = (string)tok.Value;
                        if (opt == "参照渡し")
                        {
                            argOpt.varBy = VarByType.ByRef;
                        }
                        if (opt == "整数")  //TODO:数値
                        {
                            NakoToken checkToken = tokens [i + 1];
                            if (checkToken.Type == NakoTokenType.EQ)
                            {
                                checkToken = tokens [i + 2];
                                if (checkToken.Type == NakoTokenType.INT)
                                {
                                    argOpt.defaultValue = int.Parse(checkToken.Value);
                                }
                            }
                        }
                        if (opt == "文字列")
                        {
                            NakoToken checkToken = tokens [i + 1];
                            if (checkToken.Type == NakoTokenType.EQ)
                            {
                                checkToken = tokens [i + 2];
                                if (checkToken.Type == NakoTokenType.STRING || checkToken.Type == NakoTokenType.STRING_EX || checkToken.Type == NakoTokenType.WORD)
                                {
                                    argOpt.defaultValue = (string)checkToken.Value;
                                }
                            }
                        }
                    }
                    else
                    {
                        //find type
                        string type  = (string)tok.Value;
                        int    index = NakoAPIFuncBank.Instance.FuncList.FindIndex(delegate(NakoAPIFunc obj) {
                            return(obj.PluginInstance.Name == type);
                        });
                        if (index > 0)
                        {
                            argOpt.type = type;
                        }
                    }
                    continue;
                }

                // WORD
                if (tok.Type == NakoTokenType.WORD)
                {
                    int idx = indexOfName(tok.Value);
                    if (idx < 0)
                    {
                        arg              = new NakoFuncArg();
                        arg.name         = tok.Value;
                        arg.varBy        = argOpt.varBy;
                        arg.defaultValue = argOpt.defaultValue;
                        arg.type         = argOpt.type;
                        arg.AddJosi(tok.Josi);
                        this.Add(arg);
                        argOpt.Init();
                    }
                    else
                    {
                        arg = this[idx];
                        arg.AddJosi(tok.Josi);
                    }
                }
                if (tok.Type == NakoTokenType.OR || tok.Type == NakoTokenType.OR_OR)
                {
                    continue;
                }
            }
        }
示例#14
0
 /// <summary>
 /// 変数を追加
 /// </summary>
 /// <param name="name"></param>
 /// <param name="value"></param>
 /// <param name="desc"></param>
 /// <param name="kana"></param>
 public void AddVar(string name, object value, string desc, string kana)
 {
     name = NakoToken.TrimOkurigana(name);
     this.AddVarToList(name, value);
 }
示例#15
0
        //> _callfunc : FUNCTION_NAME
        //>           | FUNCTION_NAME _arglist
        //>           ;
        private bool _callfunc()
        {
            NakoToken t = tok.CurrentToken;

            if (!Accept(NakoTokenType.FUNCTION_NAME))
            {
                return(false);
            }
            tok.MoveNext(); // skip FUNCTION_NAME

            string       fname = t.GetValueAsName();
            NakoVariable var   = globalVar.GetVar(fname);

            if (var == null)
            {
                throw new NakoParserException("関数『" + fname + "』が見あたりません。", t);
            }

            //
            NakoNodeCallFunction callNode = new NakoNodeCallFunction();
            NakoFunc             func     = null;

            callNode.Token = t;

            if (var.Type == NakoVarType.SystemFunc)
            {
                int funcNo = (int)var.Body;
                func          = NakoAPIFuncBank.Instance.FuncList[funcNo];
                callNode.func = func;
            }
            else
            {
                NakoNodeDefFunction defNode = (NakoNodeDefFunction)var.Body;
                func           = callNode.func = defNode.func;
                callNode.value = defNode;
            }

            // ---------------------------------
            if (Accept(NakoTokenType.PARENTHESES_L))
            {
                _arglist(callNode);
                // TODO ここで引数の数をチェックする処理
            }
            // 引数の数だけノードを取得
            for (int i = 0; i < func.ArgCount; i++)
            {
                NakoFuncArg arg = func.args[func.ArgCount - i - 1];
                NakoNode    argNode;
                if (arg.defaultValue != null && calcStack.Count < (func.ArgCount - i))                  //初期値があって引数が無い場合に引数に初期値を与える
                {
                    argNode       = new NakoNodeConst();
                    argNode.value = arg.defaultValue;
                    if (arg.defaultValue is int)
                    {
                        argNode.type  = NakoNodeType.INT;
                        argNode.Token = new NakoToken(NakoTokenType.INT);
                    }
                    else if (arg.defaultValue is string)
                    {
                        argNode.type  = NakoNodeType.STRING;
                        argNode.Token = new NakoToken(NakoTokenType.STRING);
                    }
                }
                else
                {
                    argNode = calcStack.Pop(arg);
                }
                if (arg.varBy == VarByType.ByRef)
                {
                    if (argNode.type == NakoNodeType.LD_VARIABLE)
                    {
                        ((NakoNodeVariable)argNode).varBy = VarByType.ByRef;
                    }
                }
                callNode.AddChild(argNode);
            }

            // ---------------------------------
            // 計算スタックに関数の呼び出しを追加
            calcStack.Push(callNode);
            this.lastNode = callNode;

            return(true);
        }
示例#16
0
 /// <summary>
 /// 構文解析エラーを出す
 /// </summary>
 /// <param name="message"></param>
 /// <param name="tok"></param>
 public NakoParserException(string message, NakoToken tok) : base(message + ":" + tok.ToStringForDebug())
 {
 }
示例#17
0
        /// <summary>
        /// 引数の定義文字列を読んで、関数の引数として登録する
        /// </summary>
        public void analizeArgTokens(NakoTokenList tokens)
        {
            bool   optMode = false;
            ArgOpt argOpt  = new ArgOpt();

            for (int i = 0; i < tokens.Count; i++)
            {
                NakoToken   tok = tokens[i];
                NakoFuncArg arg = null;
                // オプション指定モード(optMode) の on/off
                if (tok.Type == NakoTokenType.BRACES_L)
                {
                    // オプションの初期化
                    optMode = true;
                    argOpt.Init();
                    continue;
                }
                if (tok.Type == NakoTokenType.BRACES_R)
                {
                    optMode = false;
                    continue;
                }
                if (optMode)
                {
                    if (tok.Type == NakoTokenType.DIM_INT)   //ユーザー定義関数の「整数」はDIM INTと判定されるので、WORDに直す
                    {
                        tok.Type = NakoTokenType.WORD;
                    }
                    if (tok.Type == NakoTokenType.WORD)
                    {
                        string opt = (string)tok.Value;
                        if (opt == "参照渡し")
                        {
                            argOpt.varBy = VarByType.ByRef;
                        }
                        if (opt == "整数")  //TODO:数値
                        {
                            NakoToken checkToken = tokens [i + 1];
                            if (checkToken.Type == NakoTokenType.EQ)
                            {
                                checkToken = tokens [i + 2];
                                if (checkToken.Type == NakoTokenType.INT)
                                {
                                    argOpt.defaultValue = int.Parse(checkToken.Value);
                                }
                            }
                        }
                        if (opt == "文字列")
                        {
                            NakoToken checkToken = tokens [i + 1];
                            if (checkToken.Type == NakoTokenType.EQ)
                            {
                                checkToken = tokens [i + 2];
                                if (checkToken.Type == NakoTokenType.STRING || checkToken.Type == NakoTokenType.STRING_EX || checkToken.Type == NakoTokenType.WORD)
                                {
                                    argOpt.defaultValue = (string)checkToken.Value;
                                }
                            }
                        }
                        if (opt == "関数")  //関数定義が引数の場合。{関数(2)}とか表記(n)はn個引数があるという意味。初期値は無いはずなので、引数の個数をdefaultValueプロパティに入れているが、その点は修正の必要があるかもしれない。
                        {
                            argOpt.defaultValue = 0;
                            argOpt.type         = NakoFuncType.UserCall.ToString();
                            for (int j = i + 1; j < tokens.Count; j++)
                            {
                                if (tokens [j].Type == NakoTokenType.PARENTHESES_L)
                                {
                                    j++;
                                    NakoToken argCountToken = tokens [j];
                                    argOpt.defaultValue = int.Parse(argCountToken.Value);
                                    j++;
                                }
                                if (tokens [j].Type == NakoTokenType.BRACES_R)
                                {
                                    break;
                                }
                            }
                        }
                    }
                    else
                    {
                        //find type
                        string type  = (string)tok.Value;
                        int    index = NakoAPIFuncBank.Instance.FuncList.FindIndex(delegate(NakoAPIFunc obj) {
                            return(obj.PluginInstance.Name == type);
                        });
                        if (index > 0)
                        {
                            argOpt.type = type;
                        }
                    }
                    continue;
                }

                // WORD
                if (tok.Type == NakoTokenType.WORD)
                {
                    int idx = indexOfName(tok.Value);
                    if (idx < 0)
                    {
                        arg              = new NakoFuncArg();
                        arg.name         = tok.Value;
                        arg.varBy        = argOpt.varBy;
                        arg.defaultValue = argOpt.defaultValue;
                        arg.type         = argOpt.type;
                        arg.AddJosi(tok.Josi);
                        this.Add(arg);
                        argOpt.Init();
                    }
                    else
                    {
                        arg = this[idx];
                        arg.AddJosi(tok.Josi);
                    }
                }
                if (tok.Type == NakoTokenType.OR || tok.Type == NakoTokenType.OR_OR)
                {
                    continue;
                }
            }
        }
示例#18
0
 protected void addVar(string name, Object value, string desc, string kana)
 {
     name = NakoToken.TrimOkurigana(name);
     NakoAPIFuncBank.Instance.AddVar(name, value);
 }
示例#19
0
        //> _def_variable : WORD (DIM_VARIABLE|DIM_NUMBER|DIM_INT|DIM_STRING|DIM_ARRAY) [=_value]
        //>               ;
        private bool _def_variable()
        {
            if (!Accept(NakoTokenType.WORD))
            {
                return(false);
            }
            NakoVarType st = NakoVarType.Object;

            switch (tok.NextTokenType)
            {
            case NakoTokenType.DIM_VARIABLE:
                st = NakoVarType.Object;
                break;

            case NakoTokenType.DIM_NUMBER:
                st = NakoVarType.Double;
                break;

            case NakoTokenType.DIM_INT:
                st = NakoVarType.Int;
                break;

            case NakoTokenType.DIM_STRING:
                st = NakoVarType.String;
                break;

            case NakoTokenType.DIM_ARRAY:
                st = NakoVarType.Array;
                break;

            default:
                return(false);
            }
            NakoToken    t     = tok.CurrentToken;
            int          varNo = localVar.CreateVar(t.GetValueAsName());
            NakoVariable v     = localVar.GetVar(varNo);

            v.SetBody(null, st);
            tok.MoveNext(); // skip WORD
            tok.MoveNext(); // skip DIM_xxx

            // 変数の初期化があるか?
            if (!Accept(NakoTokenType.EQ))
            {
                return(true); // なければ正常値として戻る
            }
            tok.MoveNext();   // skip EQ

            if (!_value())
            {
                throw new NakoParserException("変数の初期化文でエラー。", t);
            }
            // 代入文を作る
            NakoNodeLet let = new NakoNodeLet();

            let.VarNode       = new NakoNodeVariable();
            let.VarNode.varNo = varNo;
            let.VarNode.scope = NakoVariableScope.Local;
            let.ValueNode.AddChild(calcStack.Pop());
            this.parentNode.AddChild(let);
            return(true);
        }