Пример #1
0
        public override Expression VisitExprSlice([NotNull] LogicScriptParser.ExprSliceContext context)
        {
            // Create a new unbounded expression visitor, since we only care about the slice length, not the operand's
            var operand = new ExpressionVisitor(Context).Visit(context.expression());
            var start   = context.indexer().lr?.Text switch
            {
                ">" => IndexStart.Right,
                "<" or null => IndexStart.Left,
                _ => throw new ParseException("Unknown index start position", context.indexer().Span())
            };

            Expression offset;

            if (context.indexer().offset == null)
            {
                Context.Errors.AddError("Missing indexer offset", context.indexer().Span());
                offset = new NumberLiteralExpression(context.indexer().Span(), BitsValue.Zero);
            }
            else
            {
                offset = new ExpressionVisitor(Context).Visit(context.indexer().offset);
            }

            var length    = context.indexer().len == null ? 1 : context.indexer().len.GetConstantValue(Context.Outer);
            var sliceExpr = new SliceExpression(context.Span(), operand, start, offset, length);

            if (length == 0)
            {
                Context.Errors.AddError("Slice length cannot be zero", context.indexer().len.Span());
            }

            if (offset.IsConstant)
            {
                //TODO Figure out the logic for left-indexed slices
                var offsetValue = (int)offset.GetConstantValue().Number;

                if (offsetValue >= operand.BitSize)
                {
                    Context.Errors.AddError("Offset is out of bounds", context.indexer().offset.Span());
                }

                if (offsetValue + length > operand.BitSize)
                {
                    Context.Errors.AddError("Slice is out of bounds", context.indexer().Span());
                }
            }

            if (MaxBitSize != 0 && length > MaxBitSize)
            {
                Context.Errors.AddError($"Cannot fit a {length} bits long number into {MaxBitSize} bits", sliceExpr);
            }

            return(sliceExpr);
        }
Пример #2
0
 public BitsValue Visit(Expression expr)
 {
     return(expr switch
     {
         NumberLiteralExpression lit => lit.Value,
         BinaryOperatorExpression binOp => Visit(binOp),
         ReferenceExpression refExpr => Visit(refExpr),
         TernaryOperatorExpression tern => Visit(tern),
         UnaryOperatorExpression unary => Visit(unary),
         TruncateExpression trunc => Visit(trunc),
         SliceExpression slice => Visit(slice),
         _ => throw new InterpreterException("Unknown expression", expr.Span.Start),
     });
Пример #3
0
        private Expression DoExpression(bool doOperator = true)
        {
            Expression ret = null;

            if (Take(LexemeKind.LeftParenthesis, out _))
            {
                ret = DoExpression();

                if (Take(LexemeKind.QuestionMark, out _))
                {
                    ret = DoTernaryOperator(ret);
                }

                Take(LexemeKind.RightParenthesis, "closing parentheses");
            }
            else if (Take(LexemeKind.String, out var str))
            {
                if (float.TryParse(str.Content, NumberStyles.Float, CultureInfo.InvariantCulture, out var f))
                {
                    ret = new NumberLiteralExpression(f);
                }
                else if (Current.Kind == LexemeKind.Exclamation)
                {
                    ret = DoFunctionCall(str.Content);
                }
                else
                {
                    if (Current.Kind == LexemeKind.LeftParenthesis)
                    {
                        ret = DoCommandExpression(str.Content);
                    }
                    else
                    {
                        Error($"unxpected string '{str.Content}' found");
                    }
                }
            }
            else if (Take(LexemeKind.QuotedString, out var quotedStr))
            {
                ret = new StringLiteralExpression(quotedStr.Content);
            }
            else if (Take(LexemeKind.Exclamation, out _))
            {
                ret = DoNegateOperator();
            }
            else if (Take(LexemeKind.Keyword, out var keyword))
            {
                if (keyword.Content == "null")
                {
                    ret = new NullExpression();
                }
                else if (keyword.Content == "true")
                {
                    ret = new BooleanLiteralExpression(true);
                }
                else if (keyword.Content == "false")
                {
                    ret = new BooleanLiteralExpression(false);
                }
                else
                {
                    Error($"unexpected keyword: '{keyword.Content}'");
                }
            }
            else if (Take(LexemeKind.Dollar, out _))
            {
                Push();

                if (Take(LexemeKind.String, out _) && Take(LexemeKind.EqualsAssign, out _))
                {
                    Pop();

                    ret = DoVariableAssign();
                }
                else
                {
                    Pop();

                    string name = Take(LexemeKind.String, "variable name").Content;

                    ret = new VariableAccessExpression(name);

                    if (Take(LexemeKind.Increment, out _))
                    {
                        ret = new UnaryOperatorExpression(Operator.IncrementByOne, ret);
                    }
                    else if (Take(LexemeKind.Decrement, out _))
                    {
                        ret = new UnaryOperatorExpression(Operator.DecrementByOne, ret);
                    }
                }
            }

            while (Take(LexemeKind.Dot, out _))
            {
                ret = new MemberAccessExpression(ret, Take(LexemeKind.String, "member name").Content);

                if (Take(LexemeKind.Exclamation, out _))
                {
                    ret = DoMemberCall(ret);
                }
            }

            if (ret != null && doOperator)
            {
                ret = Take(LexemeKind.QuestionMark, out _)
                    ? DoTernaryOperator(ret)
                    : (DoOperatorChain(ret) ?? ret);
            }

            return(ret);
        }
Пример #4
0
 public override object Visit(NumberLiteralExpression ex)
 {
     return(ex.Value);
 }
Пример #5
0
 public virtual object Visit(NumberLiteralExpression ex)
 {
     return(null);
 }
Пример #6
0
 private void Visit(NumberLiteralExpression expr)
 {
     LoadBitsValue(expr.Value);
 }
Пример #7
0
 public override object Visit(NumberLiteralExpression ex)
 {
     return(DataType.Number);
 }