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)); }
public static string NotDeclareFunction(DispatchNode node, string name) { return($"(line: {node.line}, column: {node.column})" + $" El nombre '{name}' no existe en este contexto." ); }
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; }