private void CheckForReadonlyAssignments(ASTAssign n) { if (n.LValue.Descriptor is FormalDescriptor) { FormalDescriptor descriptor = (FormalDescriptor)n.LValue.Descriptor; if (String.Compare(descriptor.Modifier, READONLY_MODIFIER, true) == 0) { ReportError(n.Location, "Parameter '{0}' is marked as readonly and can not be assigned.", descriptor.Name); } } bool isDerefField = (n.LValue is ASTDereferenceField && ((ASTDereferenceField)n.LValue).Object is ASTIdentifier); bool isDerefArray = (n.LValue is ASTDereferenceArray && ((ASTDereferenceArray)n.LValue).Array is ASTIdentifier); if (isDerefArray || isDerefField) { var item = isDerefField ? ((ASTDereferenceField)n.LValue).Object : ((ASTDereferenceArray)n.LValue).Array; var id = ((ASTIdentifier)item).ID; var curMethDesc = _scopeMgr.Find(_currentMethod.Name, d => d is MethodDescriptor) as MethodDescriptor; var formalMatch = curMethDesc.Formals.Where(p => p.Name.Equals(id, StringComparison.OrdinalIgnoreCase)).SingleOrDefault(); if (formalMatch != null) { if (!string.IsNullOrEmpty(formalMatch.Modifier) && formalMatch.Modifier.Equals(READONLY_MODIFIER, StringComparison.OrdinalIgnoreCase)) { ReportError(n.Location, "Parameter '{0}' passed to method '{1}' is marked as readonly and cannot be assigned.", formalMatch.Name, _currentMethod.Name); } } } }
private VisitResult VisitAssign(ASTAssign node) { var value = Visit(node.Right); switch (node.Left) { case ASTVariable variable: if (variable.ArrayIndexFrom != null) { var index = Visit(variable.ArrayIndexFrom).Value; ((List <dynamic>)_callStack.Top[variable.Name])[(int)index] = value.Value; } else { _callStack.Top[variable.Name] = value.Value; } return(null); case ASTVariablesDeclarations variablesDeclarations: Visit(variablesDeclarations); foreach (var variable in variablesDeclarations.Children) { _callStack.Top[variable.Variable.Name] = value.Value; } return(null); } throw new ArgumentException($"Invalid AST node type {node.GetType()}"); }
public override void VisitAssign(ASTAssign n) { n.LValue.Visit(this); n.Expr.Visit(this); /* Our action here depends on whether or not we visited a local variable, member variable, or argument, * so when we visit the LValue, that method will specify a callback with the correct IL output after we * visit the right hand side. */ ApplyAssignmentCallback(); }
/// <summary> /// Makes sure the left hand side of the assignment is a supertype of the right hand side. /// </summary> /// <param name="n"></param> public override void VisitAssign(ASTAssign n) { n.LValue.IsLeftHandSide = true; //this is needed when we generate the IL. CFlatType lhs = CheckSubTree(n.LValue); CFlatType rhs = CheckSubTree(n.Expr); if (IsValidAssignment(lhs, rhs)) { //check if the assignment is to a readonly method parameter CheckForReadonlyAssignments(n); //I believe we don't really do anything when the source code is correct in this case. n.CFlatType = new TypeVoid(); _lastSeenType = n.CFlatType; } else { ReportError(n.Location, "Invalid assignment, type mismatch. Expected: {0} Got: {1}", TypeToFriendlyName(lhs), TypeToFriendlyName(rhs)); } }
public bool Visit(ASTAssign node) { throw new NotImplementedException(); }