Exemplo n.º 1
0
        public void visit(FunctionExpression that)
        {
            // let the arguments resolve their types
            foreach (Expression argument in that.Arguments)
            {
                argument.visit(this);
            }

            // mangle the parameter list so as to be able to look up the mangled symbol
            System.Text.StringBuilder mangled = new System.Text.StringBuilder(64);
            that.Encode(mangled);
            string name = mangled.ToString();

            // look up the function declaration
            Declaration declaration = _symbols.Lookup(name);

            if (declaration == null)
            {
                throw new CheckerError(that.Position, "Unknown function name '" + Demangler.Decode(name) + "' in function call");
            }

            // check that the symbol is actually a function
            switch (declaration.Kind)
            {
            case SymbolKind.Constant:
                throw new CheckerError(that.Position, "Cannot call constant");

            case SymbolKind.Function:
                break;

            case SymbolKind.Parameter:
                throw new CheckerError(that.Position, "Cannot call parameter");

            case SymbolKind.Variable:
                throw new CheckerError(that.Position, "Cannot call variable");

            default:
                throw new CheckerError(declaration.Position, "Unknown symbol kind: " + declaration.Kind.ToString());
            }

            // check that the number of arguments match the number of parameters
            FunctionDeclaration function = (FunctionDeclaration)declaration;

            if (that.Arguments.Length != function.Parameters.Length)
            {
                throw new CheckerError(that.Position, "Incorrect number of parameters in function call");
            }

            // check that the argument types match the parameter types
            for (int i = 0; i < that.Arguments.Length; i++)
            {
                if (that.Arguments[i].Type.Kind != function.Parameters[i].Type.Kind)
                {
                    throw new CheckerError(that.Arguments[i].Position, "Type mismatch in argument to function");
                }
            }

            that.Type = declaration.Type;
        }