Esempio n. 1
0
        /// <summary>
        /// Interpret CatExpression
        /// </summary>
        /// <param name="expression">CatExpression to interpret</param>
        public override void Visit(CatExpression expression)
        {
            //Concatenate two expressions
            String tempExpressionText = "";

            //Visit left
            expression.GetLeftExpression().AcceptVisitor(this);
            tempExpressionText += TextValue;

            //Visit right
            expression.GetRightExpression().AcceptVisitor(this);
            tempExpressionText += TextValue;

            TextValue = tempExpressionText;
        }
Esempio n. 2
0
        /// <summary>
        /// Parse an CatExpression
        /// </summary>
        /// <param name="expression">Expression which is already parsed</param>
        /// <returns></returns>
        public Expression ParseCatExpression(Expression expression)
        {
            CatExpression catExpression = new CatExpression();

            //Left part of catenation expression
            catExpression.SetLeftExpression(expression);

            //Skip + token
            NextToken("+", "expression + expression", '+');

            //Parse right part of token
            catExpression.SetRightExpression(ParseExpression());

            return(catExpression);
        }
Esempio n. 3
0
        public void ParseCatExpressionTest()
        {
            //Create parser and parse tokens
            ExpressionParser expressionParser = new ExpressionParser(Init("expression+'symbol"));
            Expression       expression       = expressionParser.ParseExpression();

            //Check type of expression
            Assert.AreEqual(typeof(CatExpression), expression.GetType());
            CatExpression parsedCatExpression = (CatExpression)expression;

            //Check expressions in catexpression
            Assert.AreEqual(typeof(VarExpression), parsedCatExpression.GetLeftExpression().GetType());
            Assert.AreEqual(typeof(SymExpression), parsedCatExpression.GetRightExpression().GetType());

            VarExpression left  = (VarExpression)parsedCatExpression.GetLeftExpression();
            SymExpression right = (SymExpression)parsedCatExpression.GetRightExpression();

            Assert.AreEqual("expression", left.GetVariableIdentifier());
            Assert.AreEqual("symbol", right.GetSym());
        }
 public void Visit(CatExpression x)
 {
 }
Esempio n. 5
0
 public AbstractType Visit(CatExpression x)
 {
     return(OpExpressionType(x));
 }
		public void Visit(CatExpression x)
		{
			
		}
		public ISymbolValue Visit(CatExpression x)
		{
			return E_MathOp(x);
		}
		ISymbolValue EvalConcatenation(CatExpression x, ISymbolValue lValue)
		{
			// In the (not unusual) case that more than 2 arrays/strings shall be concat'ed - process them more efficiently
			var catQueue = new Queue<ISymbolValue>();
			
			var catEx = (x as CatExpression);
			
			catQueue.Enqueue(lValue);
			
			catEx = catEx.RightOperand as CatExpression;
			ISymbolValue r;
			while(catEx != null)
			{
				r = TryGetValue(catEx.LeftOperand != null ? catEx.LeftOperand.Accept(this) : null);
				if(r == null || r is NullValue)
				{
					EvalError(catEx.LeftOperand, "Couldn't be evaluated.");
					return null;
				}
				catQueue.Enqueue(r);
				if(catEx.RightOperand is CatExpression)
					catEx = catEx.RightOperand as CatExpression;
				else
					break;
			}

			var rightOp = (catEx ?? x).RightOperand;
			r = TryGetValue(rightOp != null ? rightOp.Accept(this) : null);
			if(r == null)
			{
				EvalError((catEx ?? x).LeftOperand, "Couldn't be evaluated.");
				return null;
			}
			catQueue.Enqueue(r);
			
			// Notable: If one element is of the value type of the array, the element is added (either at the front or at the back) to the array
			// myString ~ 'a' will append an 'a' to the string
			// 'a' ~ myString inserts 'a' at index 0
			
			// Determine whether we have to build up a string OR a normal list of atomic elements
			bool isString = true;
			ArrayType lastArrayType = null;
			
			foreach(var e in catQueue)
			{
				if(e is AssociativeArrayValue)
				{
					EvalError(x, "Can't concatenate associative arrays", e);
					return null;
				}
				else if(e is ArrayValue)
				{
					if(lastArrayType != null && !ResultComparer.IsEqual(lastArrayType, e.RepresentedType))
					{
						EvalError(x, "Both arrays must be of same type", new[]{lastArrayType, e.RepresentedType});
						return null;
					}
					lastArrayType = e.RepresentedType as ArrayType;
					
					if((e as ArrayValue).IsString)
						continue;
				}
				else if(e is PrimitiveValue)
				{
					var btt = (e as PrimitiveValue).BaseTypeToken;
					if(btt == DTokens.Char || btt == DTokens.Dchar || btt == DTokens.Wchar)
						continue;
				}
				
				isString = false;
			}
			
			if(lastArrayType == null)
			{
				EvalError(x, "At least one operand must be an (non-associative) array. If so, the other operand must be of the array's element type.", catQueue.ToArray());
				return null;
			}
			
			if(isString)
			{
				var sb = new StringBuilder();
				
				while(catQueue.Count != 0)
				{
					var e = catQueue.Dequeue();
					if(e is ArrayValue)
						sb.Append((e as ArrayValue).StringValue);
					else if(e is PrimitiveValue)
						sb.Append((char)((e as PrimitiveValue).Value));
				}
				return new ArrayValue(GetStringType(LiteralSubformat.Utf8), sb.ToString());
			}
			
			
			var elements = new List<ISymbolValue>();
			while(catQueue.Count != 0)
			{
				var e = catQueue.Dequeue();
				
				var av = e as ArrayValue;
				if(av != null)
				{
					if(av.IsString)
						elements.Add(av);
					else if(av.Elements != null)
						elements.AddRange(av.Elements);
					continue;
				}
				
				if(!ResultComparer.IsImplicitlyConvertible(e.RepresentedType, lastArrayType.ValueType, ctxt))
				{
					EvalError(x, "Element with type " + (e.RepresentedType != null ? e.RepresentedType.ToCode() : "") + " doesn't fit into array with type "+lastArrayType.ToCode(), catQueue.ToArray());
					return null;
				}
				
				elements.Add(e);
			}
			
			return new ArrayValue(lastArrayType, elements.ToArray());
		}
Esempio n. 9
0
        /// <summary>
        /// Note: Add, Multiply as well as Cat Expressions are parsed in this method.
        /// </summary>
        IExpression AddExpression(IBlockNode Scope = null)
        {
            var left = UnaryExpression(Scope);

            OperatorBasedExpression ae = null;

            switch (laKind)
            {
                case Plus:
                case Minus:
                    ae = new AddExpression(laKind == Minus);
                    break;
                case Tilde:
                    ae = new CatExpression();
                    break;
                case Times:
                case Div:
                case Mod:
                    ae = new MulExpression(laKind);
                    break;
                default:
                    return left;
            }

            Step();

            ae.LeftOperand = left;
            ae.RightOperand = AddExpression(Scope);
            return ae;
        }
        ISymbolValue EvalConcatenation(CatExpression x, ISymbolValue lValue)
        {
            // In the (not unusual) case that more than 2 arrays/strings shall be concat'ed - process them more efficiently
            var catQueue = new Queue <ISymbolValue>();

            var catEx = (x as CatExpression);

            catQueue.Enqueue(lValue);

            catEx = catEx.RightOperand as CatExpression;
            ISymbolValue r;

            while (catEx != null)
            {
                r = TryGetValue(E(catEx.LeftOperand));
                if (r == null)
                {
                    EvalError(catEx.LeftOperand, "Couldn't be evaluated.");
                    return(null);
                }
                catQueue.Enqueue(r);
                if (catEx.RightOperand is CatExpression)
                {
                    catEx = catEx.RightOperand as CatExpression;
                }
                else
                {
                    break;
                }
            }

            r = TryGetValue(E((catEx ?? x).RightOperand));
            if (r == null)
            {
                EvalError(catEx.LeftOperand, "Couldn't be evaluated.");
                return(null);
            }
            catQueue.Enqueue(r);

            // Notable: If one element is of the value type of the array, the element is added (either at the front or at the back) to the array
            // myString ~ 'a' will append an 'a' to the string
            // 'a' ~ myString inserts 'a' at index 0

            // Determine whether we have to build up a string OR a normal list of atomic elements
            bool      isString      = true;
            ArrayType lastArrayType = null;

            foreach (var e in catQueue)
            {
                if (e is AssociativeArrayValue)
                {
                    EvalError(x, "Can't concatenate associative arrays", e);
                    return(null);
                }
                else if (e is ArrayValue)
                {
                    if (lastArrayType != null && !ResultComparer.IsEqual(lastArrayType, e.RepresentedType))
                    {
                        EvalError(x, "Both arrays must be of same type", new[] { lastArrayType, e.RepresentedType });
                        return(null);
                    }
                    lastArrayType = e.RepresentedType as ArrayType;

                    if ((e as ArrayValue).IsString)
                    {
                        continue;
                    }
                }
                else if (e is PrimitiveValue)
                {
                    var btt = (e as PrimitiveValue).BaseTypeToken;
                    if (btt == DTokens.Char || btt == DTokens.Dchar || btt == DTokens.Wchar)
                    {
                        continue;
                    }
                }

                isString = false;
            }

            if (lastArrayType == null)
            {
                EvalError(x, "At least one operand must be an (non-associative) array. If so, the other operand must be of the array's element type.", catQueue.ToArray());
                return(null);
            }

            if (isString)
            {
                var sb = new StringBuilder();

                while (catQueue.Count != 0)
                {
                    var e = catQueue.Dequeue();
                    if (e is ArrayValue)
                    {
                        sb.Append((e as ArrayValue).StringValue);
                    }
                    else if (e is PrimitiveValue)
                    {
                        sb.Append((char)((e as PrimitiveValue).Value));
                    }
                }
                return(new ArrayValue(GetStringType(LiteralSubformat.Utf8), sb.ToString()));
            }


            var elements = new List <ISymbolValue>();

            while (catQueue.Count != 0)
            {
                var e = catQueue.Dequeue();

                var av = e as ArrayValue;
                if (av != null)
                {
                    if (av.IsString)
                    {
                        elements.Add(av);
                    }
                    else if (av.Elements != null)
                    {
                        elements.AddRange(av.Elements);
                    }
                    continue;
                }

                if (!ResultComparer.IsImplicitlyConvertible(e.RepresentedType, lastArrayType.ValueType, ctxt))
                {
                    EvalError(x, "Element with type " + e.RepresentedType.ToCode() + " doesn't fit into array with type " + lastArrayType.ToCode(), catQueue.ToArray());
                    return(null);
                }

                elements.Add(e);
            }

            return(new ArrayValue(lastArrayType, elements.ToArray()));
        }
Esempio n. 11
0
 public virtual void Visit(CatExpression expression)
 {
     VisitSubNodes(expression);
 }
 public ISymbolValue Visit(CatExpression x)
 {
     return(E_MathOp(x));
 }