// TODO: at the end we need to add to stack new function public bool Visit(CallableDeclNode node) { node.Header.Accept(this); var existedCallable = _symStack.FindFunc(node.Header.CallableSymbol.Ident, new List <SymType>(from type in node.Header.CallableSymbol.ParametersTypes select type.Item2)); if (existedCallable != null) { if (!existedCallable.IsForward) { throw new Exception(string.Format( "({0}, {1}) semantic error: overloaded functions have the same parameter list", node.Header.Name.Token.Line, node.Header.Name.Token.Column)); } var modifiersAreSame = true; for (var i = 0; i < existedCallable.ParametersTypes.Count; ++i) { if (existedCallable.ParametersTypes[i].Item1 == node.Header.CallableSymbol.ParametersTypes[i].Item1) { continue; } modifiersAreSame = false; break; } if (!modifiersAreSame) { throw new Exception(string.Format( "({0}, {1}) semantic error: function does not match the previous declaration", node.Header.Name.Token.Line, node.Header.Name.Token.Column)); } } else { _symStack.PrepareFunction(node.Header.CallableSymbol); } if (node.Block != null) { _symStack.Push(node.Header.CallableSymbol.Local); node.Header.CallableSymbol.IsForward = false; _inLastNamespace = true; node.Block.Accept(this); _inLastNamespace = false; node.Header.CallableSymbol.Local = _symStack.Pop(); _symStack.AddFunction(node.Header.CallableSymbol); } else if (existedCallable != null) { throw new Exception(string.Format( "({0}, {1}) semantic error: function is already declared", node.Header.Name.Token.Line, node.Header.Name.Token.Column)); } return(true); }