public override void VisitAssign(AssignStatement assign) { TypeData lhsType; Argument arg = currentRoutine.GetArgument(assign.Name); if (arg != null) { if (arg.NodeType.IsByRef) lhsType = arg.NodeType.ElementType; else lhsType = arg.NodeType; } else { LocalVariable local = localVariableStack.GetLocal(assign.Name); if (local != null) { if (local.IsTypecaseVariable) { report.Error(assign.Location, "it is illegal " + "to assign to the typecase variable"); return; } lhsType = local.LocalType; } else { Expression self = new SelfExpression(assign.Location); ModalExpression arg1 = new ModalExpression(ArgumentMode.In, assign.Value, assign.Value.Location); TypedNodeList args = new TypedNodeList(arg1); assign.Call = new CallExpression(self, assign.Name, args, assign.Location); assign.Call.HasValue = false; assign.Call.Accept(this); if (assign.Call.NodeType == null) return; ParameterInfo[] parameters = typeManager.GetParameters(assign.Call.Method); lhsType = typeManager.GetTypeData(parameters[0].ParameterType); } } if (assign.Value is VoidExpression) { assign.Value.NodeType = lhsType; } else { // NodeType may be already set by DeclarationStatement if (assign.Value.NodeType == null) assign.Value.Accept(this); if (assign.Value.NodeType == null) return; if (!assign.Value.NodeType.IsSubtypeOf(lhsType)) { report.Error(assign.Location, "{0} is not a subtype of {1}", assign.Value.NodeType.FullName, lhsType.FullName); return; } } }
protected virtual void SetupIter(IterCallExpression iter, MethodData method, TypeData receiverType) { if (!method.MethodInfo.IsPublic && currentClass.TypeData != receiverType) { report.Error(iter.Location, "cannot call private iterator {0}", iter.Name); return; } iter.IsBuiltin = method.IsBuiltin; MethodData creator = method.IterCreator; iter.Method = creator.MethodInfo; iter.NodeType = method.ReturnType; if (iter.Receiver == null && (iter.IsBuiltin || !method.MethodInfo.IsStatic)) { iter.Receiver = new VoidExpression(iter.Location); iter.Receiver.NodeType = receiverType; } TypeData iterType = creator.ReturnType; string localName = getTemporallyName(); iter.Local = localVariableStack.AddLocal(localName, iterType); iter.CreatorArguments = new TypedNodeList(); TypedNodeList moveNextArguments = new TypedNodeList(); ModalExpression receiver = new ModalExpression(ArgumentMode.In, (Expression) iter.Receiver.Clone(), iter.Receiver.Location); ParameterInfo[] parameters = typeManager.GetParameters(method.MethodInfo); int i; if (iter.IsBuiltin) i = 1; else i = 0; foreach (ModalExpression arg in iter.Arguments) { ParameterInfo param = parameters[i++]; if (arg.NodeType == null) // void expression arg.NodeType = typeManager.GetTypeData(param.ParameterType); ArgumentMode mode = typeManager.GetArgumentMode(param); if (mode == ArgumentMode.Once) { ModalExpression me = (ModalExpression) arg.Clone(); me.Mode = ArgumentMode.In; iter.CreatorArguments.Append(me); } else { moveNextArguments.Append((ModalExpression) arg.Clone()); } } LocalExpression moveNextReceiver = new LocalExpression(iter.Local.Name, iter.Location); iter.MoveNext = new CallExpression(moveNextReceiver, "MoveNext", moveNextArguments, iter.Location); iter.MoveNext.Accept(this); if (!iter.NodeType.IsVoid) { LocalExpression getCurrentReceiver = new LocalExpression(iter.Local.Name, iter.Location); iter.GetCurrent = new CallExpression(getCurrentReceiver, "GetCurrent", new TypedNodeList(), iter.Location); iter.GetCurrent.Accept(this); } }
public override void VisitModalExpression(ModalExpression modalExpr) { modalExpr.Expression.Accept(this); if (modalExpr.Mode == ArgumentMode.Out || modalExpr.Mode == ArgumentMode.InOut) { LocalExpression local = modalExpr.Expression as LocalExpression; if (local == null || local.Call != null) { report.Error(modalExpr.Location, "out/inout argument must be " + "a local variable or an argument"); return; } } modalExpr.NodeType = modalExpr.Expression.NodeType; }
public override void VisitCase(CaseStatement caseStmt) { caseStmt.Test.Accept(this); caseStmt.TestName = getTemporallyName(); localVariableStack.AddLocal(caseStmt.TestName, caseStmt.Test.NodeType); foreach (CaseWhen when in caseStmt.WhenPartList) { foreach (Expression value in when.ValueList) { LocalExpression test = new LocalExpression(caseStmt.TestName, value.Location); ModalExpression arg = new ModalExpression(ArgumentMode.In, value, value.Location); TypedNodeList args = new TypedNodeList(arg); CallExpression call = new CallExpression(test, "is_eq", args, value.Location); call.Accept(this); if (call.NodeType == typeManager.BoolType) { when.TestCallList.Append(call); } else { if (call.NodeType != null) { report.Error(value.Location, "no match for {0}::is_eq({1}):BOOL", caseStmt.Test.NodeType.FullName, value.NodeType.FullName); } } } when.ThenPart.Accept(this); } if (caseStmt.ElsePart != null) caseStmt.ElsePart.Accept(this); }
public override void VisitModalExpression(ModalExpression modalExpr) { if (modalExpr.Mode == ArgumentMode.Out || modalExpr.Mode == ArgumentMode.InOut) { LocalExpression localExpr = modalExpr.Expression as LocalExpression; Argument arg = currentRoutine.GetArgument(localExpr.Name); if (arg != null) { ilGenerator.Emit(OpCodes.Ldarga, arg.Index); return; } LocalVariable local = localVariableStack.GetLocal(localExpr.Name); local.EmitLoadAddress(ilGenerator); } else { modalExpr.Expression.Accept(this); } }
public virtual void VisitModalExpression(ModalExpression modalExpr) { }