protected override void VisitAssignmentSyntax(AssignmentSyntax pNode)
        {
            base.VisitAssignmentSyntax(pNode);
            if (pNode.Value.Type == SmallTypeCache.NoValue)
            {
                CompilerErrors.ExpressionNoValue(pNode.Value.Span);
            }

            var isTuple = pNode.Value.Type.IsTuple;

            for (int i = 0; i < pNode.Variables.Count; i++)
            {
                //Check if we are assigning to a const variable
                if (_locals.TryGetVariable(pNode.Variables[i].Value, out LocalDefinition ld) && ld.IsConst)
                {
                    CompilerErrors.CannotAssignCost(pNode.Variables[i], pNode.Variables[i].Span);
                }

                var t = isTuple ? pNode.Value.Type.GetFieldType(i) : pNode.Value.Type;

                //We have to set the type of discards so the tuple is created properly
                if (SyntaxHelper.IsDiscard(pNode.Variables[i]))
                {
                    ((DiscardSyntax)pNode.Variables[i]).SetType(t);
                }
            }
        }
 protected override void VisitAssignmentSyntax(AssignmentSyntax pNode)
 {
     using (var ia = Store.AddValue("InAssignment", true))
     {
         base.VisitAssignmentSyntax(pNode);
     }
 }
Esempio n. 3
0
        private bool TryCompileAssignment(AssignmentSyntax assignment, BasicBlockBuilder builder)
        {
            Debug.Assert(_methodInProgress != null);

            // Get the target variable
            if (!_variableMap.TryGetVariable(assignment.Variable.Name, out var targetIndex))
            {
                _diagnostics.Add(DiagnosticCode.VariableNotFound, assignment.Variable.Position, assignment.Variable.Name);
                return(false);
            }
            var expectedType = _methodInProgress.Values[targetIndex].Type;

            // Compile the expression
            var sourceIndex = ExpressionCompiler.TryCompileExpression(assignment.Value,
                                                                      expectedType, _methodInProgress, builder, this, _diagnostics);

            if (sourceIndex == -1)
            {
                return(false);
            }

            // Emit a copy operation
            builder.AppendInstruction(Opcode.CopyValue, (ushort)sourceIndex, 0, (ushort)targetIndex);
            return(true);
        }
Esempio n. 4
0
 protected virtual void VisitAssignmentSyntax(AssignmentSyntax pNode)
 {
     foreach (var v in pNode.Variables)
     {
         Visit(v);
     }
     Visit(pNode.Value);
 }
Esempio n. 5
0
        private bool TryParseStatementStartingWithIdentifier([NotNullWhen(true)] out StatementSyntax?statement)
        {
            // This method handles
            //   - assignments ("name = expression;")
            //   - standalone method calls ("name(...);")
            statement = null;

            // Read the identifier
            // TODO: Assignments may target array elements or struct fields
            var startPosition = _lexer.Position;

            Debug.Assert(_lexer.PeekTokenType() == TokenType.Identifier);
            if (!TryReadAndValidateIdentifier(out var identifier, allowReservedTypeNames: false))
            {
                return(false);
            }

            // Depending on the next token, decide what to do
            switch (_lexer.PeekTokenType())
            {
            case TokenType.Equals:
                // Eat the '=' and read the new value
                _lexer.GetToken();
                if (!TryParseExpression(out var newValue))
                {
                    return(false);
                }
                Debug.Assert(newValue != null);

                statement = new AssignmentSyntax(identifier, newValue, startPosition);
                break;

            case TokenType.OpenParen:
                // A standalone function call
                if (!TryParseFunctionCall(identifier, out var callExpression))
                {
                    return(false);
                }
                else
                {
                    Debug.Assert(callExpression != null);
                    statement = new FunctionCallStatementSyntax(callExpression, startPosition);
                    break;
                }

            default:
                // Note: the diagnostic is intentionally emitted at expected statement start position
                _diagnosticSink.Add(DiagnosticCode.ExpectedStatement, startPosition, ReadTokenIntoString());
                return(false);
            }

            // This check is shared by all valid cases of the above switch
            if (!ExpectToken(TokenType.Semicolon, DiagnosticCode.ExpectedSemicolon))
            {
                return(false);
            }
            return(true);
        }
Esempio n. 6
0
        protected virtual SyntaxNode VisitAssignmentSyntax(AssignmentSyntax pNode)
        {
            List <IdentifierSyntax> variables = new List <IdentifierSyntax>(pNode.Variables.Count);

            foreach (var v in pNode.Variables)
            {
                variables.Add((IdentifierSyntax)Visit(v));
            }
            return(SyntaxFactory.Assignment(variables, pNode.Operator, Visit(pNode.Value)));
        }
Esempio n. 7
0
        protected override void VisitAssignmentSyntax(AssignmentSyntax pNode)
        {
            var isTuple = pNode.Value.Type.IsTuple;

            for (int i = 0; i < pNode.Variables.Count; i++)
            {
                var valueType = isTuple ? pNode.Value.Type.GetFieldType(i) : pNode.Value.Type;

                if (!CanCast(pNode.Variables[i].Type, valueType))
                {
                    CompilerErrors.TypeCastError(pNode.Variables[i].Type, valueType, pNode.Span);
                }
            }
            base.VisitAssignmentSyntax(pNode);
        }