Пример #1
0
        public void visit(FunctionDeclaration that)
        {
            System.Text.StringBuilder mangled = new System.Text.StringBuilder(64);
            that.Encode(mangled);
            string name = mangled.ToString();

            if (!_symbols.Insert(name, that))
            {
                throw new CheckerError(that.Position, "Duplicate name '" + Demangler.Decode(name) + "' detected in function declaration");
            }
            _symbols.EnterScope(name);

            that.Type.visit(this);

            foreach (ParameterDeclaration parameter in that.Parameters)
            {
                // insert each parameter into the current scope so that it becomes visible to the code
                if (!_symbols.Insert(parameter.Name, parameter))
                {
                    throw new CheckerError(parameter.Position, "Duplicate name '" + parameter.Name + "' detected in parameter");
                }

                parameter.visit(this);
            }

            if (that.Body != null)
            {
                that.Body.visit(this);
            }

            _symbols.LeaveScope(name);
        }
Пример #2
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;
        }