Example #1
0
        public void VisitFunctionDefinition(FunctionDefinition functionDefinition)
        {
            if (_functionContext != null)
            {
                _context.Error(
                    functionDefinition.Identifier.Span,
                    "cannot define a function inside o`f another function");
            }

            if (functionDefinition.Identifier.Lexeme == "main")
            {
                _astContext.AddMangledName(functionDefinition.NodeId, "wire_main__");
            }

            var(parameterTypes, allParamsOk) = GetFunctionParameterTypes(functionDefinition);
            if (!allParamsOk)
            {
                return;
            }

            var returnType = GetFunctionReturnType(functionDefinition);

            if (returnType != null)
            {
                var functionType = new FunctionType(parameterTypes, returnType);
                _astContext.AddNodeType(functionDefinition.NodeId, functionType);
                var wasRedefined = !_currentScope.DefineSymbol(functionDefinition, functionType);
                if (wasRedefined)
                {
                    _context.Error(
                        functionDefinition.Identifier.Span,
                        $"redefinition of function \"{functionDefinition.Identifier}\"");
                }
            }

            _functionContext = functionDefinition;
            _currentScope    = new Scope(_currentScope);

            foreach (var parameter in functionDefinition.Parameters)
            {
                var parameterType = _astContext.GetNodeType(parameter.Node.NodeId);
                _currentScope.DefineSymbol(parameter.Node, parameterType);
            }

            AnalyzeBlock(functionDefinition.Body);

            _currentScope    = _currentScope.Outer;
            _functionContext = null;
        }