private Type DoCoalesceAssignment(NyaParser.AssignmentContext context) { string sLocal = context.identifier().GetText(); Variable local = _scopeManager.FindVariable(sLocal); Label nullOp = _ilg.DefineLabel(); local.Load(_ilg); _stackDepth++; _ilg.Emit(OpCodes.Dup); _ilg.Emit(OpCodes.Brtrue_S, nullOp); _ilg.Emit(OpCodes.Pop); Type src = (Type)Visit(context.expression()); Type dst = local.Type; if (!TypeHelper.TryConvert(_ilg, src, local.Type)) { throw new Exception("Shit's whacked, yo"); } _ilg.MarkLabel(nullOp); local.Store(_ilg); _stackDepth -= 2; return(local.Type); }
public override object VisitAssignment([NotNull] NyaParser.AssignmentContext context) { switch (context.assignment_operator().GetText()) { case "=": return(DoBasicAssignment(context)); case "?=": return(DoCoalesceAssignment(context)); default: return(DoArithmenticAssignment(context)); } }
private Type DoArithmenticAssignment(NyaParser.AssignmentContext context) { string sOperator = context.assignment_operator().GetText(); string sLocal = context.identifier().GetText(); Variable local = _scopeManager.FindVariable(sLocal); local.Load(_ilg); _stackDepth++; Type src = (Type)Visit(context.expression()); Type dst = local.Type; switch (sOperator) { case "+=": TypeHelper.DoMath(_ilg, dst, src, OpCodes.Add, "op_Addition"); break; case "-=": TypeHelper.DoMath(_ilg, dst, src, OpCodes.Sub, "op_Subtraction"); break; case "*=": TypeHelper.DoMath(_ilg, dst, src, OpCodes.Mul, "op_Multiply"); break; case "/=": TypeHelper.DoMath(_ilg, dst, src, OpCodes.Div, "op_Division"); break; case "%=": TypeHelper.DoMath(_ilg, dst, src, OpCodes.Rem, "op_Modulus"); break; case "&=": TypeHelper.DoMath(_ilg, dst, src, OpCodes.And, "op_BitwiseAnd"); break; case "|=": TypeHelper.DoMath(_ilg, dst, src, OpCodes.Or, "op_BitwiseOr"); break; case "^=": TypeHelper.DoMath(_ilg, dst, src, OpCodes.Xor, "op_ExclusiveOr"); break; case "<<=": TypeHelper.DoMath(_ilg, dst, src, OpCodes.Shl, "op_LeftShift"); break; case ">>=": TypeHelper.DoMath(_ilg, dst, src, OpCodes.Shr, "op_RightShift"); break; } local.Store(_ilg); _stackDepth -= 2; return(local.Type); }
private Type DoBasicAssignment(NyaParser.AssignmentContext context) { string sLocal = context.identifier().GetText(); Variable local = _scopeManager.FindVariable(sLocal); Type src = (Type)Visit(context.expression()); Type dst = null; if (local != null) { dst = local.Type; } else { if (context.type_descriptor() != null) { dst = ParseTypeDescriptor(context.type_descriptor()); } else { dst = src; } // Someone did an untyped null assignment... if (dst == null) { dst = typeof(object); } local = _ilg.DeclareLocal(dst); _scopeManager.AddVariable(sLocal, local); } local.Store(_ilg); _stackDepth--; return(local.Type); }