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); } }
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); }
protected virtual void VisitAssignmentSyntax(AssignmentSyntax pNode) { foreach (var v in pNode.Variables) { Visit(v); } Visit(pNode.Value); }
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); }
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))); }
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); }