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); }
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), });
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); }
public override object Visit(NumberLiteralExpression ex) { return(ex.Value); }
public virtual object Visit(NumberLiteralExpression ex) { return(null); }
private void Visit(NumberLiteralExpression expr) { LoadBitsValue(expr.Value); }
public override object Visit(NumberLiteralExpression ex) { return(DataType.Number); }