private SyntaxTree ParseFactorOrFunctionCall() { SyntaxTree factor = null; Token token = CurrentToken; if (token.TokenType == TokenType.Identifier) { Match(TokenType.Identifier); if (CurrentToken.TokenType == TokenType.OpenParenthesis) { Match(TokenType.OpenParenthesis); FunctionCallTree functionCall = new FunctionCallTree(token); functionCall.Arguments = ParseArgumentList(); Match(TokenType.CloseParenthesis); factor = functionCall; } else { factor = new FactorTree(token); } } else if (CurrentToken.TokenType == TokenType.Scalar) { Match(TokenType.Scalar); factor = new FactorTree(token); } else { throw new ParserException(token, TokenType.Identifier, TokenType.Scalar); } return(factor); }
protected virtual string EmitFactor(FactorTree factor) { StandardFunctionResolver resolver = new StandardFunctionResolver(); string src = string.Empty; if (factor.Token.TokenType == TokenType.Identifier) { if (resolver.IsStandardVariable(factor.Token.Value)) { src = resolver.ResolveToStandardVariableName(factor.Token.Value); } else if (factor.Token.Value == FunctionParameterName) { // refers to actual parameter of function, which will always be emitted as ___x src = "___x"; } else { src = string.Format( "MathContext.Variables[\"{0}\"]", factor.Token.Value ); } } else { src = factor.Token.Value; } return(src); }
protected virtual List <CodeErrorException> TypeCheckFactor(FactorTree factorTree) { List <CodeErrorException> errors = new List <CodeErrorException>(); // if identifier is function parameter then it's okay, otherwise make sure it's defined in variable // context if (factorTree.Token.TokenType == TokenType.Identifier) { if (factorTree.Token.Value != FunctionParameterName) { if (!MathContext.Variables.ContainsVariable(factorTree.Token.Value)) { errors.Add( new CodeErrorException( factorTree.Token.Line, factorTree.Token.StartPosition, factorTree.Token.EndPosition, string.Format( "The variable '{0}' is not defined in math context", factorTree.Token.Value ) ) ); } } } return(errors); }