public LocalBuilderInfo AddLocal(string name, LocalBuilder builder) { LocalBuilderInfo info = new LocalBuilderInfo(Locals.Count, name, builder); Locals.Add(name, info); return(info); }
public override void VisitIdentifier(ASTIdentifier n) { _lastWalkedIdentifier = n.ID; //yeah this gets a bit messy, but I kinda do need to check all 3 possibilities where an identifier could //be declared (we're not doing globals in the language). if (n.IsLeftHandSide) { if (IsIdentifierLocal(n.ID)) { LocalBuilderInfo localInfo = _currentMethodBuilder.Locals[n.ID]; _assignmentCallback = gen => gen.Emit(OpCodes.Stloc, localInfo.Index); } else if (IsIdentifierField(n.ID)) { FieldBuilder field = _currentTypeBuilder.FieldMap[n.ID]; //push the "this" argument _gen.Emit(OpCodes.Ldarg_0); _assignmentCallback = gen => gen.Emit(OpCodes.Stfld, field); } else if (IsIdentifierArgument(n.ID)) { _assignmentCallback = gen => gen.Emit(OpCodes.Starg, _currentMethodBuilder.Arguments[n.ID].Index); } else { throw new Exception(String.Format("Identifier '{0}' is not a local, argument, or member variable of the current class.", n.ID)); } } else { if (IsIdentifierLocal(n.ID)) { var info = _currentMethodBuilder.Locals[n.ID]; _gen.Emit(OpCodes.Ldloc, info.Index); _lastWalkedType = info.Builder.LocalType; } else if (IsIdentifierField(n.ID)) { FieldBuilder field = _currentTypeBuilder.FieldMap[n.ID]; _gen.Emit(OpCodes.Ldarg_0); _gen.Emit(OpCodes.Ldfld, field); _lastWalkedType = field.FieldType; } else if (IsIdentifierArgument(n.ID)) { ArgumentInfo info = _currentMethodBuilder.Arguments[n.ID]; int index = info.Index; if (!_currentMethodBuilder.Method.IsStatic) { index++; } _gen.Emit(OpCodes.Ldarg, index); _lastWalkedType = info.CilType; } } }
public override void VisitDeclLocal(ASTDeclarationLocal n) { //Get type n.Type.Visit(this); LocalBuilder builder = _gen.DeclareLocal(_lastWalkedType); //keep track of the LocalBuilder LocalBuilderInfo info = _currentMethodBuilder.AddLocal(n.ID, builder); //set value if needed if (n.InitialValue != null) { n.InitialValue.Visit(this); //store it to the local _gen.Emit(OpCodes.Stloc, info.Index); } }