Exemple #1
0
		/// <summary>
		/// Parses an unary operator expression
		/// </summary>
		/// <param name="funcCall">Indicates if the primary is parsed in a function call</param>
		/// <returns>An expression syntax tree</returns>
		private ExpressionSyntaxTree ParseUnary(bool funcCall = false)
		{
			//If the current token is not an operator, it must be a primary expression
			CharacterToken charToken = this.currentToken as CharacterToken;

			if (charToken == null)
			{
				return this.ParsePrimary(funcCall);
			}

			if (charToken != null && (charToken.Value == '(' || charToken.Value == ')' || charToken.Value == ','))
			{
				return this.ParsePrimary(funcCall);
			}

			charToken = this.currentToken as CharacterToken;
			char op = charToken.Value;
			this.NextToken();

			ExpressionSyntaxTree operand = this.ParseUnary(funcCall);

			if (operand == null)
			{
				return null;
			}

			return new UnaryExpressionSyntaxTree(op, operand);
		}
Exemple #2
0
 /// <summary>
 /// Creates a new for expression syntax tree
 /// </summary>
 /// <param name="variableName">The name of the loop variable</param>
 /// <param name="start">The start value</param>
 /// <param name="end">The stop value</param>
 /// <param name="step">The step</param>
 /// <param name="body">The body</param>
 public ForExpressionSyntaxTree(string variableName, ExpressionSyntaxTree start, ExpressionSyntaxTree end, ExpressionSyntaxTree step, ExpressionSyntaxTree body)
 {
     this.variableName = variableName;
     this.start        = start;
     this.end          = end;
     this.step         = step;
     this.body         = body;
 }
Exemple #3
0
		/// <summary>
		/// Parses an expression
		/// </summary>
		/// <param name="funcCall">Indicates if the primary is parsed in a function call</param>
		/// <returns>An expression syntax tree</returns>
		private ExpressionSyntaxTree ParseExpression(bool funcCall = false)
		{
			ExpressionSyntaxTree leftHandSide = this.ParseUnary(funcCall);

			if (leftHandSide == null)
			{
				return null;
			}

			return this.ParseBinaryOpRHS(0, leftHandSide);
		}
Exemple #4
0
		/// <summary>
		/// Parses a top level expression
		/// </summary>
		/// <returns>An expression syntax tree</returns>
		private ExpressionSyntaxTree ParseTopLevelExpression()
		{
			ExpressionSyntaxTree expression = this.ParseExpression();

			if (expression != null)
			{
				//Make an anonymous prototype
				PrototypeSyntaxTree prototype = new PrototypeSyntaxTree("", new List<string>());
				return new FunctionSyntaxTree(prototype, expression);
			}

			return null;
		}
Exemple #5
0
		/// <summary>
		/// Parses the right hand side of binary operator expression
		/// </summary>
		/// <param name="expressionPrecedence">The expression precedence</param>
		/// <param name="leftHandSide">The left hand side</param>
		/// <returns>An expression syntax tree</returns>
		private ExpressionSyntaxTree ParseBinaryOpRHS(int expressionPrecedence, ExpressionSyntaxTree leftHandSide)
		{
			//If this is a binop, find its precedence
			while (true)
			{
				int tokenPrec = this.GetTokenPrecedence();

				//If this is a binop that binds at least as tightly as the current binop,
				//consume it, otherwise we are done.

				if (tokenPrec < expressionPrecedence)
				{
					return leftHandSide;
				}

				//Okay, we know this is a binop.
				CharacterToken opToken = this.currentToken as CharacterToken;
				this.NextToken(); //Consume the binop

				//Parse the primary expression after the binary operator.
				ExpressionSyntaxTree rightHandSide = this.ParseUnary();

				if (rightHandSide == null)
				{
					return null;
				}

				if (rightHandSide == null)
				{
					return null;
				}

				//If the bin op binds less tightly with RHS than the operator after RHS, let
				//the pending operator take RHS as its LHS.
				int nextPrec = this.GetTokenPrecedence();
				if (tokenPrec < nextPrec)
				{
					rightHandSide = this.ParseBinaryOpRHS(tokenPrec + 1, rightHandSide);

					if (rightHandSide == null)
					{
						return null;
					}
				}

				//Merge the left and right hand side
				leftHandSide = new BinaryExpressionSyntaxTree(opToken.Value, leftHandSide, rightHandSide);
			}
		}
Exemple #6
0
		/// <summary>
		/// Parses a identifier expression
		/// </summary>
		/// <returns>An expression syntax tree</returns>
		private ExpressionSyntaxTree ParseIdentifierExpression()
		{
			string identifierName = ((IdentifierToken)this.currentToken).Value;

			this.NextToken(); //Consume the identifier

			CharacterToken charToken = this.currentToken as CharacterToken;

			//Simple variable ref
			if ((charToken != null && charToken.Value != '(') || charToken == null)
			{
				return new VariableExpressionSyntaxTree(identifierName);
			}

			//Call
			this.NextToken(); //Consume the (
			List<ExpressionSyntaxTree> args = new List<ExpressionSyntaxTree>();

			if (charToken != null && charToken.Value != ')')
			{
				while (true)
				{
					ExpressionSyntaxTree arg = this.ParseExpression(true);

					if (arg != null)
					{
						args.Add(arg);
					}

					charToken = this.currentToken as CharacterToken;

					if (charToken != null && charToken.Value == ')')
					{
						break;
					}

					if ((charToken != null && charToken.Value != ',') || charToken == null)
					{
						throw new ParserException("Expected ')' or ',' in argument list");
					}

					this.NextToken();
				}
			}

			this.NextToken(); //Consume the )

			return new CallExpressionSyntaxTree(identifierName, args);
		}
Exemple #7
0
		/// <summary>
		/// Parses an if expression
		/// </summary>
		/// <returns>An expression syntax tree</returns>
		private ExpressionSyntaxTree ParseIfExpression()
		{
			this.NextToken(); //Consume the if

			//Condition
			ExpressionSyntaxTree cond = this.ParseExpression();

			if (cond == null)
			{
				return null;
			}

			if (this.currentToken.Type != TokenType.Then)
			{
				throw new ParserException("expected then");
			}

			this.NextToken(); //Consume the then

			ExpressionSyntaxTree thenBody = this.ParseExpression();

			if (thenBody == null)
			{
				return null;
			}

			if (this.currentToken.Type != TokenType.Else)
			{
				throw new ParserException("expected else");
			}

			this.NextToken(); //Consume the else

			ExpressionSyntaxTree elseBody = this.ParseExpression();

			if (elseBody == null)
			{
				return null;
			}

			return new IfExpressionSyntaxTree(cond, thenBody, elseBody);
		}
Exemple #8
0
		/// <summary>
		/// Parses a function definition
		/// </summary>
		/// <returns>A function syntax tree</returns>
		private FunctionSyntaxTree ParseDefinition()
		{
			this.NextToken(); //Consume the def
			PrototypeSyntaxTree prototype = this.ParsePrototype();

			if (prototype == null)
			{
				return null;
			}

			//Parse the body
			ExpressionSyntaxTree bodyExpression = this.ParseExpression();

			if (bodyExpression != null)
			{
				return new FunctionSyntaxTree(prototype, bodyExpression);
			}

			return null;
		}
Exemple #9
0
		/// <summary>
		/// Parses a parenthese expression
		/// </summary>
		/// <returns>An expression syntax tree</returns>
		private ExpressionSyntaxTree ParseParentheseExpression()
		{
			this.NextToken(); //Consume (
			ExpressionSyntaxTree expr = this.ParseExpression();

			if (expr == null)
			{
				return null;
			}

			CharacterToken charToken = this.currentToken as CharacterToken;

			if ((charToken != null && charToken.Value != ')') ||charToken == null)
			{
				Console.WriteLine("expected ')'");
				return null;
			}

			this.NextToken(); //Consume )

			return expr;
		}
		/// <summary>
		/// Creates a new binary expression syntax tree
		/// </summary>
		/// <param name="op">The operator</param>
		/// <param name="leftHandSide">The left hand side</param>
		/// <param name="rightHandSide">The right hand side</param>
		public BinaryExpressionSyntaxTree(char op, ExpressionSyntaxTree leftHandSide, ExpressionSyntaxTree rightHandSide)
		{
			this.op = op;
			this.leftHandSide = leftHandSide;
			this.rightHandSide = rightHandSide;
		}
Exemple #11
0
        /// <summary>
        /// Parses a for expression
        /// </summary>
        /// <returns>An expression syntax tree</returns>
        private ExpressionSyntaxTree ParseForExpression()
        {
            this.NextToken(); //Consume the for

            if (this.currentToken.Type != TokenType.Identifier)
            {
				throw new ParserException("expected identifier after for");
            }

            string varName = ((IdentifierToken)this.currentToken).Value;

            this.NextToken(); //Consume the identifier

            CharacterToken charToken = this.currentToken as CharacterToken;

            if ((charToken != null && charToken.Value != '=') ||charToken == null)
            {
				throw new ParserException("expected '=' after for");
            }

            this.NextToken(); //Consume the '='

            ExpressionSyntaxTree startExpression = this.ParseExpression();

            if (startExpression == null)
            {
                return null;
            }

            charToken = this.currentToken as CharacterToken;

            if ((charToken != null && charToken.Value != ',') ||charToken == null)
            {
				throw new ParserException("expected ',' after for start value");
            }

            this.NextToken(); //Consume the ','

            ExpressionSyntaxTree endExpression = this.ParseExpression();

            if (endExpression == null)
            {
                return null;
            }

            //The step value is optional
            ExpressionSyntaxTree stepExpression = null;

            charToken = this.currentToken as CharacterToken;

            if ((charToken != null && charToken.Value == ',') ||charToken == null)
            {
                this.NextToken(); //Consume the ','
                stepExpression = this.ParseExpression();

                if (stepExpression == null)
                {
                    return null;
                }
            }

            if (this.currentToken.Type != TokenType.In)
            {
				throw new ParserException("expected 'in' after for");
            }

            this.NextToken(); //Consume the 'in'

            ExpressionSyntaxTree bodyExpression = this.ParseExpression();

            if (bodyExpression == null)
            {
                return null;
            }

            return new ForExpressionSyntaxTree(varName, startExpression, endExpression, stepExpression, bodyExpression);
        }
		/// <summary>
		/// Creates a new function syntax tree
		/// </summary>
		/// <param name="name">The prototype</param>
		/// <param name="arguments">The body</param>
		public FunctionSyntaxTree(PrototypeSyntaxTree prototype, ExpressionSyntaxTree body)
		{
			this.prototype = prototype;
			this.body = body;
		}
Exemple #13
0
 /// <summary>
 /// Creates a new if expression syntax tree
 /// </summary>
 /// <param name="condition">The condition</param>
 /// <param name="thenBody">The then body</param>
 /// <param name="elseBody">The else body</param>
 public IfExpressionSyntaxTree(ExpressionSyntaxTree condition, ExpressionSyntaxTree thenBody, ExpressionSyntaxTree elseBody)
 {
     this.condition = condition;
     this.thenBody  = thenBody;
     this.elseBody  = elseBody;
 }
		/// <summary>
		/// Creates a new unary expression syntax tree
		/// </summary>
		/// <param name="op">The operator</param>
		/// <param name="operand">The operand</param>
		public UnaryExpressionSyntaxTree(char op, ExpressionSyntaxTree operand)
		{
			this.op = op;
			this.operand = operand;
		}
Exemple #15
0
 /// <summary>
 /// Creates a new function syntax tree
 /// </summary>
 /// <param name="name">The prototype</param>
 /// <param name="arguments">The body</param>
 public FunctionSyntaxTree(PrototypeSyntaxTree prototype, ExpressionSyntaxTree body)
 {
     this.prototype = prototype;
     this.body      = body;
 }
Exemple #16
0
 /// <summary>
 /// Creates a new unary expression syntax tree
 /// </summary>
 /// <param name="op">The operator</param>
 /// <param name="operand">The operand</param>
 public UnaryExpressionSyntaxTree(char op, ExpressionSyntaxTree operand)
 {
     this.op      = op;
     this.operand = operand;
 }
Exemple #17
0
 /// <summary>
 /// Creates a new binary expression syntax tree
 /// </summary>
 /// <param name="op">The operator</param>
 /// <param name="leftHandSide">The left hand side</param>
 /// <param name="rightHandSide">The right hand side</param>
 public BinaryExpressionSyntaxTree(char op, ExpressionSyntaxTree leftHandSide, ExpressionSyntaxTree rightHandSide)
 {
     this.op            = op;
     this.leftHandSide  = leftHandSide;
     this.rightHandSide = rightHandSide;
 }
 /// <summary>
 /// Creates a new for expression syntax tree
 /// </summary>
 /// <param name="variableName">The name of the loop variable</param>
 /// <param name="start">The start value</param>
 /// <param name="end">The stop value</param>
 /// <param name="step">The step</param>
 /// <param name="body">The body</param>
 public ForExpressionSyntaxTree(string variableName, ExpressionSyntaxTree start, ExpressionSyntaxTree end, ExpressionSyntaxTree step, ExpressionSyntaxTree body)
 {
     this.variableName = variableName;
     this.start = start;
     this.end = end;
     this.step = step;
     this.body = body;
 }
		/// <summary>
		/// Creates a new if expression syntax tree
		/// </summary>
		/// <param name="condition">The condition</param>
		/// <param name="thenBody">The then body</param>
		/// <param name="elseBody">The else body</param>
		public IfExpressionSyntaxTree(ExpressionSyntaxTree condition, ExpressionSyntaxTree thenBody, ExpressionSyntaxTree elseBody)
		{
			this.condition = condition;
			this.thenBody = thenBody;
			this.elseBody = elseBody;
		}