Exemple #1
0
        public void Dispatch(DispatchNode node, string className)
        {
            string method = node.IdMethod.Text;

            if (className == "Int" || className == "Bool" || className == "String")
            {
                if (method == "abort")
                {
                    codeLines.Add(new ICCallLabel(new ICLabel("Object", "abort")));
                }

                else if (method == "type_name")
                {
                    codeLines.Add(new ICAssignStrToVar(variableManager.PeekCounter(), className));
                }

                else if (method == "copy")
                {
                    codeLines.Add(new ICPushParams(variableManager.PeekCounter()));
                    codeLines.Add(new ICCallLabel(new ICLabel("_wrapper", className), variableManager.PeekCounter()));
                    codeLines.Add(new ICPopParams(1));
                }
            }
            else
            {
                variableManager.PushCounter();

                int fAddress = variableManager.IncreaseCounter();
                int offset   = virtualTable.getOffset(className, method);

                List <int>    parameters = new List <int>();
                List <string> types      = virtualTable.getParamTypes(className, method);

                for (int i = 0; i < node.Arguments.Count; i++)
                {
                    variableManager.IncreaseCounter();
                    variableManager.PushCounter();
                    parameters.Add(variableManager.VarCount);
                    node.Arguments[i].GetIntCode(this);

                    if (types[i] == "Object" && (node.Arguments[i].StaticType.Text == "Int" ||
                                                 node.Arguments[i].StaticType.Text == "String" || node.Arguments[i].StaticType.Text == "Bool"))
                    {
                        codeLines.Add(new ICPushParams(variableManager.PeekCounter()));
                        codeLines.Add(new ICCallLabel(new ICLabel("_wrapper", node.Arguments[i].StaticType.Text), variableManager.PeekCounter()));
                        codeLines.Add(new ICPopParams(1));
                    }

                    variableManager.PopCounter();
                }

                variableManager.PopCounter();

                if (className != "String")
                {
                    codeLines.Add(new ICAssignMemToVar(fAddress, variableManager.PeekCounter(), offset));
                }

                codeLines.Add(new ICPushParams(variableManager.PeekCounter()));

                foreach (var param in parameters)
                {
                    codeLines.Add(new ICPushParams(param));
                }

                if (className != "String")
                {
                    codeLines.Add(new ICCallAddress(fAddress, variableManager.PeekCounter()));
                }
                else
                {
                    codeLines.Add(new ICCallLabel(new ICLabel(className, method), variableManager.PeekCounter()));
                }

                if (special_object_return_type)
                {
                    SetReturnType(node.StaticType.Text);
                }

                codeLines.Add(new ICPopParams(parameters.Count + 1));
            }
        }
 public static string NotDeclareFunction(DispatchNode node, string name)
 {
     return($"({node.Line}, {node.Column}) - Semantic Error:" +
            $" The name '{name}' does not exist in the current context."
            );
 }
        void DispatchVisit(DispatchNode node, string cclass)
        {
            string method = node.IdMethod.Text;

            if (method == "abort" && (cclass == "Int" || cclass == "String" || cclass == "Bool"))
            {
                IC.Add(new CallLabel(new LabelLine("Object", "abort")));
                return;
            }

            if (method == "type_name")
            {
                if (cclass == "Int" || cclass == "Bool" || cclass == "String")
                {
                    IC.Add(new AssignmentStringToVariable(VariableManager.PeekVariableCounter(), cclass));
                    return;
                }
            }

            //important for define
            if (method == "copy")
            {
                if (cclass == "Int" || cclass == "Bool" || cclass == "String")
                {
                    IC.Add(new PushParam(VariableManager.PeekVariableCounter()));
                    IC.Add(new CallLabel(new LabelLine("_wrapper", cclass), VariableManager.PeekVariableCounter()));
                    IC.Add(new PopParam(1));
                    return;
                }
            }

            VariableManager.PushVariableCounter();

            //int t = VariableManager.IncrementVariableCounter();
            int function_address = VariableManager.IncrementVariableCounter();
            //int offset = IntermediateCode.GetMethodOffset(cclass, method);
            int offset = VirtualTable.GetOffset(cclass, method);

            List <int>    parameters       = new List <int>();
            List <string> parameters_types = VirtualTable.GetParametersTypes(cclass, method);

            for (int i = 0; i < node.Arguments.Count; ++i)
            {
                VariableManager.IncrementVariableCounter();
                VariableManager.PushVariableCounter();
                parameters.Add(VariableManager.VariableCounter);
                node.Arguments[i].Accept(this);

                if (parameters_types[i] == "Object" && (
                        node.Arguments[i].StaticType.Text == "Int" ||
                        node.Arguments[i].StaticType.Text == "Bool" ||
                        node.Arguments[i].StaticType.Text == "String"))
                {
                    IC.Add(new PushParam(VariableManager.PeekVariableCounter()));
                    IC.Add(new CallLabel(new LabelLine("_wrapper", node.Arguments[i].StaticType.Text), VariableManager.PeekVariableCounter()));
                    IC.Add(new PopParam(1));
                }

                VariableManager.PopVariableCounter();
            }

            VariableManager.PopVariableCounter();

            if (cclass != "String")
            {
                IC.Add(new CommentLine("get method: " + cclass + "." + method));
                IC.Add(new AssignmentMemoryToVariable(function_address, VariableManager.PeekVariableCounter(), offset));
            }

            IC.Add(new PushParam(VariableManager.PeekVariableCounter()));

            foreach (var p in parameters)
            {
                IC.Add(new PushParam(p));
            }

            if (cclass != "String")
            {
                IC.Add(new CallAddress(function_address, VariableManager.PeekVariableCounter()));
            }
            else
            {
                IC.Add(new CallLabel(new LabelLine(cclass, method), VariableManager.PeekVariableCounter()));
            }

            if (special_object_return_type)
            {
                SetReturnType(node.StaticType.Text);
            }

            IC.Add(new PopParam(parameters.Count + 1));
        }
        public void Visit(DispatchNode node, string @class)
        {
            string method = node.Id.text;

            if (@class == "Int" || @class == "String" || @class == "Bool")
            {
                switch (method)
                {
                case "abort":
                    Code.Add(new CallLblCodeLine(new LabelCodeLine("Object", "abort")));
                    return;

                case "type_name":
                    Code.Add(new AssignStrToVarCodeLine(VariableManager.PeekVariableCounter(), @class));
                    return;

                case "copy":
                    Code.Add(new PushParamCodeLine(VariableManager.PeekVariableCounter()));
                    Code.Add(new CallLblCodeLine(new LabelCodeLine("_wrapper", @class), VariableManager.PeekVariableCounter()));
                    Code.Add(new PopParamCodeLine(1));
                    return;

                default:
                    break;
                }
            }

            VariableManager.PushVariableCounter();

            int f_address = VariableManager.IncrementVariableCounter();
            int offset    = ClassManager.GetOffset(@class, method);

            List <int>    parameters       = new List <int>();
            List <string> parameters_types = ClassManager.GetParametersTypes(@class, method);

            for (int i = 0; i < node.paramFormal.Count; ++i)
            {
                VariableManager.IncrementVariableCounter();
                VariableManager.PushVariableCounter();
                parameters.Add(VariableManager.VariableCounter);

                node.paramFormal[i].Accept(this);
                var static_type = node.paramFormal[i].staticType.Text;

                if (parameters_types[i] == "Object")
                {
                    if (static_type == "Int" || static_type == "Bool" || static_type == "String")
                    {
                        Code.Add(new PushParamCodeLine(VariableManager.PeekVariableCounter()));
                        Code.Add(new CallLblCodeLine(new LabelCodeLine("_wrapper", static_type), VariableManager.PeekVariableCounter()));
                        Code.Add(new PopParamCodeLine(1));
                    }
                }

                VariableManager.PopVariableCounter();
            }

            VariableManager.PopVariableCounter();

            if (@class != "String")
            {
                Code.Add(new AssignMemToVarCodeLine(f_address, VariableManager.PeekVariableCounter(), offset));
            }

            Code.Add(new PushParamCodeLine(VariableManager.PeekVariableCounter()));

            foreach (var param in parameters)
            {
                Code.Add(new PushParamCodeLine(param));
            }

            if (@class != "String")
            {
                Code.Add(new CallAddrCodeLine(f_address, VariableManager.PeekVariableCounter()));
            }
            else
            {
                Code.Add(new CallLblCodeLine(new LabelCodeLine(@class, method), VariableManager.PeekVariableCounter()));
            }

            if (object_return_type)
            {
                var s_type = node.staticType.Text;

                if (s_type == "Int" || s_type == "Bool" || s_type == "String")
                {
                    Code.Add(new AssignStrToVarCodeLine(return_type, s_type));
                }
                else
                {
                    Code.Add(new AssignStrToVarCodeLine(return_type, "Object"));
                }
            }

            Code.Add(new PopParamCodeLine(parameters.Count + 1));
        }
Exemple #5
0
 public static string NotDeclareFunction(DispatchNode node, string name)
 {
     return($"(line: {node.line}, column: {node.column})" +
            $" El nombre '{name}' no existe en este contexto."
            );
 }
Exemple #6
0
        public void Register(string name, Type commandType)
        {
            if (RegisteredCommands.ContainsKey(name))
            {
                throw new InvalidOperationException($"Command '{name}' is registered");
            }

            var methods = (from method in commandType.GetTypeInfo().DeclaredMethods
                           let handlerAttribute = method.GetCustomAttribute <CommandHandlerAttribute>()
                                                  where handlerAttribute != null
                                                  orderby handlerAttribute.ArgumentRegex == null, handlerAttribute.Order
                           select(method, handlerAttribute)).ToArray();

            if (methods.Length == 0)
            {
                throw new InvalidOperationException($"There's no any command handlers in type '{commandType.Name}'");
            }

            var usedRegex = new HashSet <string?>();

            DispatchNode?rootNode = null;
            DispatchNode?node     = null;

            var forbidPrivateChat = commandType.IsDefined(typeof(GroupChatOnlyAttribute), false);
            var forbidGroupChat   = commandType.IsDefined(typeof(PrivateChatOnlyAttribute), false);

            foreach (var(method, handlerAttribute) in methods)
            {
                if (!usedRegex.Add(handlerAttribute.ArgumentRegex))
                {
                    throw new InvalidOperationException($"There're duplicated command handler attributes in type '{commandType.Name}'");
                }

                if (method.ReturnType != typeof(MessageResponse) && method.ReturnType != typeof(Task <MessageResponse>) && method.ReturnType != typeof(IAsyncEnumerable <MessageResponse>))
                {
                    throw new InvalidOperationException("The return type of handler should be of type 'MessageResponse', 'Task<MessageResponse>' or 'IAsyncEnumerable<MessageResponse>'");
                }

                var parameters = method.GetParameters();

                if (handlerAttribute.ArgumentRegex == null && parameters.Length > 1 || parameters.Length != 0 && parameters[0].ParameterType != typeof(Message))
                {
                    throw new InvalidOperationException("Fallback handler should have no arguments or only one parameter of type 'Message'");
                }

                var argumentMatcher = handlerAttribute.ArgumentRegex switch
                {
                    null => null,
                    "$" => new Regex(@"^\s*$", RegexOptions.Compiled),
                    _ => new Regex(@"^\s+" + handlerAttribute.ArgumentRegex, RegexOptions.Compiled),
                };

                var currentNode = new DispatchNode(CompileHandler(commandType, method, parameters), argumentMatcher)
                {
                    ForbidPrivateChat = forbidPrivateChat || method.IsDefined(typeof(GroupChatOnlyAttribute), false),
                    ForbidGroupChat   = forbidGroupChat || method.IsDefined(typeof(PrivateChatOnlyAttribute), false),
                };

                if (node == null)
                {
                    node     = currentNode;
                    rootNode = currentNode;
                }
                else
                {
                    node.Next = currentNode;
                    node      = currentNode;
                }
            }

            Debug.Assert(rootNode != null);

            RegisteredCommands[name] = rootNode;
        }