예제 #1
0
        /// <summary>
        /// Builds call statement
        /// </summary>
        /// <param name="callNode">Call statement node</param>
        private void BuildCallStatement(ASTCallStatementNode callNode)
        {
            int argCnt = 0;

            //push arguments
            if (callNode.Arguments != null)
            {
                argCnt = callNode.Arguments.Expressions.Count;
                foreach (var e in callNode.Arguments.Expressions)
                {
                    BuildExpression(e);
                    _emitter.Box();
                }
            }
            //get symbol
            var symbol = (ISubroutine)_symbols.FindSymbol(callNode.ProcedureName);

            if (symbol is NativeSubroutine nativeSub)
            {
                _emitter.Call(nativeSub.NativeMethod);
            }
            if (symbol is UserSubroutine userSub)
            {
                var m = _builtSubs[callNode.ProcedureName].Builder;
                _emitter.UnwrapCall(m);
                //hand handling because type not built
                _emitter.StackPop(userSub.ArgumentsCount);
                if (userSub.Return)
                {
                    _emitter.StackPush(typeof(object));
                }
            }
        }
예제 #2
0
 //Pop call arguments
 public override void ExitSubCallStatement([NotNull] CmanParser.SubCallStatementContext context)
 {
     if (_nodes.Peek() is ASTExprListNode exprListNode)
     {
         _nodes.Pop();
         ASTCallStatementNode callStmtNode = (ASTCallStatementNode)_nodes.Peek();
         callStmtNode.Arguments = exprListNode;
     }
 }
예제 #3
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="callNode">AST node of subroutine call</param>
        /// <param name="requireReturn">Requires subroutine return value</param>
        private void CheckSubCall(ASTCallStatementNode callNode, bool requireReturn)
        {
            //check define
            ISubroutine sub = (ISubroutine)_symbolTable.FindSymbol(callNode.ProcedureName);

            if (sub == null)
            {
                _messages.Add(new MessageRecord(
                                  MsgCode.UndefinedSub,
                                  callNode.SourcePath,
                                  callNode.StartLine,
                                  callNode.StartPos,
                                  callNode.ProcedureName
                                  ));
            }
            else
            {
                //check return value
                if (requireReturn)
                {
                    if (!sub.Return)
                    {
                        _messages.Add(new MessageRecord(
                                          MsgCode.ReturnNotFound,
                                          callNode.SourcePath,
                                          callNode.StartLine,
                                          callNode.StartPos,
                                          callNode.ProcedureName
                                          ));
                    }
                }

                //check arguments count
                int argCnt = sub.ArgumentsCount;
                if (callNode.Arguments != null)
                {
                    if (argCnt > callNode.Arguments.Children.Count)
                    {
                        _messages.Add(new MessageRecord(
                                          MsgCode.TooFewArguments,
                                          callNode.SourcePath,
                                          callNode.StartLine,
                                          callNode.StartPos,
                                          argCnt,
                                          callNode.Arguments.Children.Count
                                          ));
                    }
                    if (argCnt < callNode.Arguments.Children.Count)
                    {
                        _messages.Add(new MessageRecord(
                                          MsgCode.TooManyArguments,
                                          callNode.SourcePath,
                                          callNode.StartLine,
                                          callNode.StartPos,
                                          argCnt,
                                          callNode.Arguments.Children.Count
                                          ));
                    }
                    //check arguments
                    foreach (var a in callNode.Arguments.Expressions)
                    {
                        CheckExpression(a);
                    }
                }
                else //no arguments
                {
                    if (argCnt != 0)
                    {
                        _messages.Add(new MessageRecord(
                                          MsgCode.TooFewArguments,
                                          callNode.SourcePath,
                                          callNode.StartLine,
                                          callNode.StartPos,
                                          argCnt,
                                          0
                                          ));
                    }
                }
            }
        }