本文整理汇总了C#中LNode.CallsMin方法的典型用法代码示例。如果您正苦于以下问题:C# LNode.CallsMin方法的具体用法?C# LNode.CallsMin怎么用?C# LNode.CallsMin使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类LNode
的用法示例。
在下文中一共展示了LNode.CallsMin方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C#代码示例。
示例1: AltType
public AltType(VList<LNode> classAttrs, LNode typeName, VList<LNode> baseTypes, AltType parentType)
{
_classAttrs = classAttrs;
TypeName = typeName;
BaseTypes = baseTypes;
ParentType = parentType;
//matchCode (TypeName) {
// case $stem<$(..a)>, $stem:
// _typeNameStem = stem;
// _genericArgs = a;
// default:
// _genericArgs = new WList<LNode>();
//}
{ // Above matchCode expanded:
LNode stem;
VList<LNode> a = default(VList<LNode>);
if (TypeName.CallsMin(CodeSymbols.Of, 1) && (stem = TypeName.Args[0]) != null && (a = new VList<LNode>(TypeName.Args.Slice(1))).IsEmpty | true || (stem = TypeName) != null) {
_typeNameStem = stem;
_genericArgs = a.ToWList();
} else {
_genericArgs = new WList<LNode>();
}
}
if (ParentType != null) {
BaseTypes.Insert(0, ParentType.TypeNameWithoutAttrs);
// Search for all 'where' clauses on the ParentType and make sure OUR generic args have them too.
bool changed = false;
for (int i = 0; i < _genericArgs.Count; i++) {
var arg = _genericArgs[i];
var parentArg = ParentType._genericArgs.FirstOrDefault(a => a.IsIdNamed(arg.Name));
if (parentArg != null) {
var wheres = new HashSet<LNode>(WhereTypes(arg));
int oldCount = wheres.Count;
var parentWheres = WhereTypes(parentArg);
foreach (var where in parentWheres)
wheres.Add(where);
if (wheres.Count > oldCount) {
arg = arg.WithAttrs(arg.Attrs.SmartWhere(a => !a.Calls(S.Where))
.Add(LNode.Call(S.Where, LNode.List(wheres))));
_genericArgs[i] = arg;
changed = true;
}
}
}
if (changed)
TypeName = LNode.Call(CodeSymbols.Of, LNode.List().Add(_typeNameStem).AddRange(_genericArgs)).SetStyle(NodeStyle.Operator);
}
TypeNameWithoutAttrs = TypeName.Select(n => n.WithoutAttrs());
}
示例2: AltType
public AltType(RVList<LNode> typeAttrs, LNode typeName, RVList<LNode> baseTypes, AltType parentType)
{
_typeAttrs = typeAttrs;
TypeName = typeName;
BaseTypes = baseTypes;
ParentType = parentType;
if (ParentType != null)
BaseTypes.Add(ParentType.TypeName);
{
LNode stem;
RVList<LNode> a = default(RVList<LNode>);
if (TypeName.CallsMin(CodeSymbols.Of, 1) && (stem = TypeName.Args[0]) != null && (a = new RVList<LNode>(TypeName.Args.Slice(1))).IsEmpty | true || (stem = TypeName) != null) {
_typeNameStem = stem;
_genericArgs = a;
}
}
}
示例3: AltType
public AltType(VList<LNode> classAttrs, LNode typeName, VList<LNode> baseTypes, AltType parentType)
{
_classAttrs = classAttrs;
TypeName = typeName;
BaseTypes = baseTypes;
ParentType = parentType;
{
LNode stem;
VList<LNode> a = default(VList<LNode>);
if (TypeName.CallsMin(CodeSymbols.Of, 1) && (stem = TypeName.Args[0]) != null && (a = new VList<LNode>(TypeName.Args.Slice(1))).IsEmpty | true || (stem = TypeName) != null) {
_typeNameStem = stem;
_genericArgs = a.ToWList();
} else {
_genericArgs = new WList<LNode>();
}
}
if (ParentType != null) {
BaseTypes.Insert(0, ParentType.TypeNameWithoutAttrs);
bool changed = false;
for (int i = 0; i < _genericArgs.Count; i++) {
var arg = _genericArgs[i];
var parentArg = ParentType._genericArgs.FirstOrDefault(a => a.IsIdNamed(arg.Name));
if (parentArg != null) {
var wheres = new HashSet<LNode>(WhereTypes(arg));
int oldCount = wheres.Count;
var parentWheres = WhereTypes(parentArg);
foreach (var where in parentWheres)
wheres.Add(where);
if (wheres.Count > oldCount) {
arg = arg.WithAttrs(arg.Attrs.Where(a => !a.Calls(S.Where)).Add(LNode.Call(S.Where, LNode.List(wheres))));
_genericArgs[i] = arg;
changed = true;
}
}
}
if (changed)
TypeName = LNode.Call(CodeSymbols.Of, LNode.List().Add(_typeNameStem).AddRange(_genericArgs));
}
TypeNameWithoutAttrs = TypeName.Select(n => n.WithoutAttrs());
}
示例4: IsDefinitionId
// A definition identifier has the form Name or Name!(Id,$Id,...)
// where Id is a simple identifier and Name is either a simple identifier
// or (if dots are allowed) a complex identifier with allowOf=false.
public static bool IsDefinitionId(LNode id, bool allowDots)
{
var args = id.Args;
if (id.CallsMin(S.Of, 1)) {
if (!(allowDots ? IsComplexId(args[0], false) : args[0].IsId))
return false;
for (int i = 1; i < args.Count; i++)
if (!(args[i].IsId || args[i].Calls(S.Substitute, 1) && args[i].Args[0].IsId))
return false;
return true;
} else
return allowDots ? IsComplexId(id, false) : id.IsId;
}
示例5: EliminateSequenceExpressions
public LNode EliminateSequenceExpressions(LNode stmt, bool isDeclContext)
{
LNode retType, name, argList, bases, body, initValue;
if (EcsValidators.SpaceDefinitionKind(stmt, out name, out bases, out body) != null) {
// Space definition: class, struct, etc.
return body == null ? stmt : stmt.WithArgChanged(2, EliminateSequenceExpressions(body, true));
} else if (EcsValidators.MethodDefinitionKind(stmt, out retType, out name, out argList, out body, true) != null) {
// Method definition
return body == null ? stmt : stmt.WithArgChanged(3, EliminateSequenceExpressionsInLambdaExpr(body, retType));
} else if (EcsValidators.IsPropertyDefinition(stmt, out retType, out name, out argList, out body, out initValue)) {
// Property definition
stmt = stmt.WithArgChanged(3,
body.WithArgs(part => {
if (part.ArgCount == 1 && part[0].Calls(S.Braces))
part = part.WithArgChanged(0, EliminateSequenceExpressions(part[0], false));
return part;
}));
if (initValue != null) {
var initMethod = EliminateRunSeqFromInitializer(retType, name, ref initValue);
if (initMethod != null) {
stmt = stmt.WithArgChanged(4, initValue);
return LNode.Call((Symbol) "#runSequence", LNode.List(stmt, initMethod));
}
}
return stmt;
} else if (stmt.Calls(CodeSymbols.Braces)) {
return stmt.WithArgs(EliminateSequenceExpressions(stmt.Args, isDeclContext));
} else if (!isDeclContext) {
return EliminateSequenceExpressionsInExecStmt(stmt);
} else if (stmt.CallsMin(S.Var, 2)) {
// Eliminate blocks from field member
var results = new List<LNode> {
stmt
};
var vars = stmt.Args;
var varType = vars[0];
for (int i = 1; i < vars.Count; i++) {
var @var = vars[i];
if (@var.Calls(CodeSymbols.Assign, 2) && (name = @var.Args[0]) != null && (initValue = @var.Args[1]) != null) {
var initMethod = EliminateRunSeqFromInitializer(varType, name, ref initValue);
if (initMethod != null) {
results.Add(initMethod);
vars[i] = vars[i].WithArgChanged(1, initValue);
}
}
}
if (results.Count > 1) {
results[0] = stmt.WithArgs(vars);
return LNode.List(results).AsLNode(__numrunSequence);
}
return stmt;
} else
return stmt;
}
示例6: KeyNameComponentOf
/// <summary>Retrieves the "key" name component for the nameof(...) macro.</summary>
/// <remarks>
/// The key name component of <c>global::Foo!int.Bar!T(x)</c> (which is
/// is structured <c>((((global::Foo)!int).Bar)!T)(x)</c>) is <c>Bar</c>.
/// </remarks>
public static LNode KeyNameComponentOf(LNode name)
{
// So if #of, get first arg (which cannot itself be #of), then if @`.`, get second arg.
// If it's a call, note that we have to check for #of and @`.` BEFORE stripping off the args.
if (name.CallsMin(S.Of, 1))
name = name.Args[0];
if (name.CallsMin(S.Dot, 1))
name = name.Args.Last;
if (name.IsCall)
return KeyNameComponentOf(name.Target);
return name;
}
示例7: EndMayBeReachable
// Decides whether to add a "break" at the end of a switch case.
internal protected static bool EndMayBeReachable(LNode stmt)
{
// The goal of this code is to avoid the dreaded compiler warning
// "Unreachable code detected". We're conservative, to avoid a compiler
// error about a missing "break". This is just a heuristic since we
// don't have access to proper reachability analysis.
if (stmt.CallsMin(S.Braces, 1))
return EndMayBeReachable(stmt.Args.Last);
if (!stmt.HasSpecialName)
return true;
if (stmt.Calls(S.Goto, 1))
return false;
else if (stmt.Calls(S.Continue) || stmt.Calls(S.Break))
return false;
else if (stmt.Calls(S.Return))
return false;
else if (stmt.Calls(S.GotoCase, 1))
return false;
LNode body;
if (stmt.Calls(S.If, 2))
return true;
else if (stmt.Calls(S.If, 3))
{
return EndMayBeReachable(stmt.Args[1])
|| EndMayBeReachable(stmt.Args[2]);
}
else if (stmt.CallsMin(S.Switch, 2) && (body = stmt.Args[1]).CallsMin(S.Braces, 2))
{
// for a switch statement, assume it exits normally if a break
// statement is the last statement of any of the cases, or if
// there is no "default" case.
bool beforeCase = true;
bool hasDefaultCase = false;
for (int i = body.ArgCount - 1; i > 0; i--)
{
var substmt = body.Args[i];
if (beforeCase && substmt.Calls(S.Break))
return true;
if (substmt.Calls(S.Label, 1) && substmt.Args[0].IsIdNamed(S.Default))
hasDefaultCase = beforeCase = true;
else
beforeCase = substmt.Calls(S.Case);
}
return hasDefaultCase == false;
}
else if (stmt.Calls(S.For) || stmt.Calls(S.While) || stmt.Calls(S.DoWhile))
{
return true;
}
else if (stmt.CallsMin(S.Try, 1))
{
return EndMayBeReachable(stmt.Args[0]);
}
else if (stmt.ArgCount >= 1)
{
Debug.Assert(stmt.HasSpecialName);
return EndMayBeReachable(stmt.Args.Last);
}
return true;
}
示例8: NextStatementMayBeReachable
// quote @{ Hope.For(777, $cash) } => F.Call(F.Dot(F.Id("Hope"), F.Id("For")), F.Literal(777), cash)
// declare_symbols @@Foo @@Bar {...} (braces optional, invoke replace_code)
// replace_code (IntSet.Parse($s) \with ParseSet($s), IntSet \with HashSet!int) {...}
// replace_code_after ($X($Y, -1) \with $X($Y, EOF)) {...}
// with Foo.Bar {...} => replace_code (.($x) \with Foo.Bar.$x) {...}
// include_here "../Util/Util.les"
// specialize $T \in (int, float, double) { def Square!$T(T x) { x*x; }; class Foo!($T,U) {}; }
// run_macros (specialize $T \in (int, float)) (replace Xyz \with Zyx) { ... }
// Bob.Hair?.Brush()
// cons Point(public field X::int, public field Y::int) { }
// def SetX(public X::int) { }
// prop X::int (public field _x) { get; set; };
// def DoSomething(required X::string) { };
// public override def ToString()::string ==> _obj;
// forward_to _obj { def ToString()::string; def GetHashCode()::int; };
// foo ??= Foo();
// x - 0.5;
// x in (1, 2, 3);
// $"The value is {Value,-10:C}." => string.Format("The value is {0,-10:C}", Value)
// save_and_restore _foo { Foo(_foo = true); } => var tmp17 = _foo; try { Foo(_foo = true); } finally { _foo = tmp17; }
/// <summary>Given a statement, this method attempts to decide if the
/// immediately following statement (if any) is reachable.</summary>
/// <returns>true if reachable/unsure, false if definitely unreachable.</returns>
/// <remarks>
/// The goal of this code is to avoid the dreaded compiler warning
/// "Unreachable code detected". This is just a heuristic since we
/// don't have access to proper reachability analysis. In fact, it's
/// no doubt buggy.
/// </remarks>
public static bool NextStatementMayBeReachable(LNode stmt)
{
if (stmt.CallsMin(S.Braces, 1))
return NextStatementMayBeReachable(stmt.Args.Last);
if (!stmt.HasSpecialName)
return true;
if (stmt.Calls(S.Goto, 1))
return false;
else if (stmt.Calls(S.Continue) || stmt.Calls(S.Break))
return false;
else if (stmt.Calls(S.Return))
return false;
else if (stmt.Calls(S.GotoCase, 1))
return false;
bool isFor;
LNode body;
if (stmt.Calls(S.If, 2))
return true;
else if (stmt.Calls(S.If, 3))
{
var r1 = NextStatementMayBeReachable(stmt.Args[1]);
var r2 = NextStatementMayBeReachable(stmt.Args[2]);
return r1 || r2;
}
else if (stmt.CallsMin(S.Switch, 2) && (body = stmt.Args[1]).CallsMin(S.Braces, 2))
{
// for a switch statement, assume it exits normally if a break
// statement is the last statement of any of the cases, or if
// there is no "default" case.
bool beforeCase = true;
bool hasDefaultCase = false;
foreach (var substmt in body.Args.ToFVList())
{
if (beforeCase && substmt.Calls(S.Break))
return true;
if (substmt.Calls(S.Label, 1) && substmt.Args[0].IsIdNamed(S.Default))
hasDefaultCase = beforeCase = true;
else
beforeCase = substmt.Calls(S.Case);
}
return hasDefaultCase == false;
}
else if ((isFor = stmt.Calls(S.For, 4)) || stmt.Calls(S.While, 2) || stmt.Calls(S.DoWhile, 2))
{ // Infinite loop?
var cond = stmt.Args[isFor ? 1 : 0];
if (cond.IsIdNamed(S.Missing) || true.Equals(cond.Value))
return true; // ok, I don't know what to do
return true;
}
else if (stmt.CallsMin(S.Try, 1))
{
return NextStatementMayBeReachable(stmt.Args[0]);
}
else if (stmt.ArgCount >= 1)
{
Debug.Assert(stmt.HasSpecialName);
return NextStatementMayBeReachable(stmt.Args.Last);
}
return true;
}
示例9: CallsMinWPAIH
internal static bool CallsMinWPAIH(LNode self, Symbol name, int argCount, Pedantics p)
{
return self.CallsMin(name, argCount) && HasSimpleHeadWPA(self, p);
}
示例10: MaybeCreateTemporaryForLValue
// Creates a temporary for an LValue (left side of `=`, or `ref` parameter)
// e.g. f(x).Foo becomes f(x_N).Foo, and `var x_N = x` is added to `stmtSequence`,
// where N is a unique integer for the temporary variable.
LNode MaybeCreateTemporaryForLValue(LNode expr, ref VList<LNode> stmtSequence)
{
{
LNode _, lhs;
if (expr.Calls(CodeSymbols.Dot, 2) && (lhs = expr.Args[0]) != null || expr.CallsMin(CodeSymbols.Of, 1) && (lhs = expr.Args[0]) != null)
return expr.WithArgChanged(0, MaybeCreateTemporaryForLValue(lhs, ref stmtSequence));
else if ((_ = expr) != null && !_.IsCall)
return expr;
else {
var args = expr.Args.ToWList();
int i = 0;
if (expr.CallsMin(S.IndexBracks, 1) || expr.CallsMin(S.NullIndexBracks, 1)) {
// Consider foo[i]. We cannot always store `foo` in a temporary, as
// this may change the code's behavior in case `foo` is a struct.
i = 1;
}
for (; i < args.Count; i++) {
if (!args[i].IsLiteral && !args[i].Attrs.Contains(_trivia_isTmpVar)) {
LNode tmpVarName;
stmtSequence.Add(TempVarDecl(Context, args[i], out tmpVarName));
args[i] = tmpVarName.PlusAttr(_trivia_isTmpVar);
}
}
return expr.WithArgs(args.ToVList());
}
}
}
示例11: ConvertVarDeclToRunSequence
LNode ConvertVarDeclToRunSequence(VList<LNode> attrs, LNode varType, LNode varName, LNode initValue)
{
initValue = BubbleUpBlocks(initValue);
varType = varType ?? F.Missing;
LNode @ref;
attrs = attrs.WithoutNodeNamed(S.Ref, out @ref);
var varName_apos = varName.PlusAttr(_trivia_isTmpVar);
if (@ref != null)
varName_apos = varName_apos.PlusAttr(@ref);
{
LNode resultValue;
VList<LNode> stmts;
if (initValue.CallsMin((Symbol) "#runSequence", 1) && (resultValue = initValue.Args[initValue.Args.Count - 1]) != null) {
stmts = initValue.Args.WithoutLast(1);
var newVarDecl = LNode.Call(LNode.List(attrs), CodeSymbols.Var, LNode.List(varType, LNode.Call(CodeSymbols.Assign, LNode.List(varName, resultValue))));
return initValue.WithArgs(stmts.Add(newVarDecl).Add(varName_apos));
} else {
var newVarDecl = LNode.Call(LNode.List(attrs), CodeSymbols.Var, LNode.List(varType, LNode.Call(CodeSymbols.Assign, LNode.List(varName, initValue))));
return LNode.Call((Symbol) "#runSequence", LNode.List(newVarDecl, varName_apos));
}
}
}
示例12: BubbleUp_GeneralCall2
// Bubbles up a call. The returned pair consists of
// 1. A sequence of statements to run before the call
// 2. The call with all (outer) #runSequences removed
Pair<VList<LNode>, LNode> BubbleUp_GeneralCall2(LNode expr)
{
var target = expr.Target;
var args = expr.Args;
var combinedSequence = LNode.List();
// Bubbe up target
target = BubbleUpBlocks(target);
if (target.CallsMin(__numrunSequence, 1)) {
combinedSequence = target.Args.WithoutLast(1);
expr = expr.WithTarget(target.Args.Last);
}
// Bubble up each argument
var isAssignment = EcsValidators.IsAssignmentOperator(expr.Name);
if (isAssignment) {
LNode lhs = BubbleUpBlocks(expr.Args[0]);
LNode rhs = BubbleUpBlocks(expr.Args[1]);
args = LNode.List(lhs, rhs);
} else { // most common case
args = args.SmartSelect(arg => BubbleUpBlocks(arg));
}
int lastRunSeq = args.LastIndexWhere(a => a.CallsMin(__numrunSequence, 1));
if (lastRunSeq >= 0) {
// last index of #runSequence that is not marked pure
int lastRunSeqImpure = args.First(lastRunSeq + 1).LastIndexWhere(a =>
a.CallsMin(__numrunSequence, 1) && a.AttrNamed(_trivia_pure.Name) == null);
if (lastRunSeq > 0 &&
(args.Count == 2 && (target.IsIdNamed(S.And) || target.IsIdNamed(S.Or)) || args.Count == 3 && target.IsIdNamed(S.QuestionMark)))
{
Context.Sink.Error(target,
"#useSequenceExpressions is not designed to support sequences or variable declarations on the right-hand side of the `&&`, `||` or `?` operators. The generated code will be incorrect.");
}
var argsW = args.ToList();
for (int i = 0; i <= lastRunSeq; i++) {
LNode arg = argsW[i];
if (!arg.IsLiteral) {
if (arg.CallsMin(__numrunSequence, 1)) {
combinedSequence.AddRange(arg.Args.WithoutLast(1));
argsW[i] = arg = arg.Args.Last;
}
if (i < lastRunSeqImpure) {
if (i == 0 && (expr.CallsMin(S.IndexBracks, 1) || expr.CallsMin(S.NullIndexBracks, 1))) {
// Consider foo[#runSequence(f(), i)]. In case this appears in
// an lvalue context and `foo` is a struct, we cannot store `foo` in
// a temporary, as this may silently change the code's behavior.
// Better to take the risk of evaluating `foo` after `f()`.
} else {
if (isAssignment || arg.Attrs.Any(a => a.IsIdNamed(S.Ref) || a.IsIdNamed(S.Out)))
argsW[i] = MaybeCreateTemporaryForLValue(arg, ref combinedSequence);
else {
// Create a temporary variable to hold this argument
LNode tmpVarName, tmpVarDecl = TempVarDecl(Context, arg, out tmpVarName);
combinedSequence.Add(tmpVarDecl);
argsW[i] = tmpVarName.PlusAttr(_trivia_isTmpVar);
}
}
}
}
}
expr = expr.WithArgs(LNode.List(argsW));
}
return Pair.Create(combinedSequence, expr);
}
示例13: EliminateRunSeqFromInitializer
/// Eliminates run sequence(s) in a field initializer expression.
/// If any are found, a method is returned to encapsulate the
/// initialization code, e.g.
/// expr on entry: Foo()::foo.x + foo.y
/// return value: static retType fieldName_initializer() {
/// var foo = Foo();
/// return foo.x + foo.y;
/// }
/// expr on exit: fieldName_initializer()
LNode EliminateRunSeqFromInitializer(LNode retType, LNode fieldName, ref LNode expr)
{
expr = BubbleUpBlocks(expr);
if (expr.CallsMin(__numrunSequence, 1)) {
var statements = expr.Args.WithoutLast(1);
var finalResult = expr.Args.Last;
LNode methodName = F.Id(KeyNameComponentOf(fieldName).Name + "_initializer");
expr = LNode.Call(methodName);
return LNode.Call(LNode.List(LNode.Id(CodeSymbols.Static)), CodeSymbols.Fn, LNode.List(retType, methodName, LNode.Call(CodeSymbols.AltList), LNode.Call(CodeSymbols.Braces, LNode.List().AddRange(statements).Add(LNode.Call(CodeSymbols.Return, LNode.List(finalResult)))).SetStyle(NodeStyle.Statement)));
} else
return null; // most common case
}
示例14: EliminateSequenceExpressionsInExecStmt
LNode EliminateSequenceExpressionsInExecStmt(LNode stmt)
{
{
LNode block, collection, cond, init, initValue, loopVar, name, tmp_11, tmp_12, type;
VList<LNode> attrs, incs, inits;
if (stmt.Calls(CodeSymbols.Braces))
return stmt.WithArgs(EliminateSequenceExpressions(stmt.Args, false));
else if (stmt.CallsMin(CodeSymbols.If, 1) || stmt.Calls(CodeSymbols.UsingStmt, 2) || stmt.Calls(CodeSymbols.Lock, 2) || stmt.Calls(CodeSymbols.Switch, 2) && stmt.Args[1].Calls(CodeSymbols.Braces))
return ProcessBlockCallStmt(stmt, 1);
else if ((attrs = stmt.Attrs).IsEmpty | true && stmt.Calls(CodeSymbols.Fixed, 2) && (init = stmt.Args[0]) != null && (block = stmt.Args[1]) != null) {
init = EliminateSequenceExpressionsInExecStmt(init);
block = EliminateSequenceExpressionsInChildStmt(block);
if (init.CallsMin(__numrunSequence, 1)) {
return LNode.Call(LNode.List(attrs), CodeSymbols.Braces, LNode.List().AddRange(init.Args.WithoutLast(1)).Add(LNode.Call(CodeSymbols.Fixed, LNode.List(init.Args.Last, block)))).SetStyle(NodeStyle.Statement);
} else
return stmt.WithArgChanged(1, block);
} else if ((attrs = stmt.Attrs).IsEmpty | true && stmt.Calls(CodeSymbols.While, 2) && (cond = stmt.Args[0]) != null && (block = stmt.Args[1]) != null) {
cond = BubbleUpBlocks(cond);
block = EliminateSequenceExpressionsInChildStmt(block);
if (cond.CallsMin(__numrunSequence, 1)) {
return LNode.Call(LNode.List(attrs), CodeSymbols.For, LNode.List(LNode.Call(CodeSymbols.AltList), LNode.Missing, LNode.Call(CodeSymbols.AltList), LNode.Call(CodeSymbols.Braces, LNode.List().AddRange(cond.Args.WithoutLast(1)).Add(LNode.Call(CodeSymbols.If, LNode.List(cond.Args.Last, block, LNode.Call(CodeSymbols.Break))))).SetStyle(NodeStyle.Statement)));
} else
return stmt.WithArgChanged(1, block);
} else if ((attrs = stmt.Attrs).IsEmpty | true && stmt.Calls(CodeSymbols.DoWhile, 2) && (block = stmt.Args[0]) != null && (cond = stmt.Args[1]) != null) {
block = EliminateSequenceExpressionsInChildStmt(block);
cond = BubbleUpBlocks(cond);
if (cond.CallsMin(__numrunSequence, 1)) {
var continue_N = F.Id(NextTempName(Context, "continue_"));
var bodyStmts = block.AsList(S.Braces);
bodyStmts.AddRange(cond.Args.WithoutLast(1));
bodyStmts.Add(LNode.Call(CodeSymbols.Assign, LNode.List(continue_N, cond.Args.Last)).SetStyle(NodeStyle.Operator));
return LNode.Call(LNode.List(attrs), CodeSymbols.For, LNode.List(LNode.Call(CodeSymbols.AltList, LNode.List(LNode.Call(CodeSymbols.Var, LNode.List(LNode.Id(CodeSymbols.Bool), LNode.Call(CodeSymbols.Assign, LNode.List(continue_N, LNode.Literal(true))))))), continue_N, LNode.Call(CodeSymbols.AltList), LNode.Call(CodeSymbols.Braces, LNode.List(bodyStmts)).SetStyle(NodeStyle.Statement)));
} else
return stmt.WithArgChanged(0, block);
} else if ((attrs = stmt.Attrs).IsEmpty | true && stmt.Calls(CodeSymbols.For, 4) && stmt.Args[0].Calls(CodeSymbols.AltList) && (cond = stmt.Args[1]) != null && stmt.Args[2].Calls(CodeSymbols.AltList) && (block = stmt.Args[3]) != null) {
inits = stmt.Args[0].Args;
incs = stmt.Args[2].Args;
return ESEInForLoop(stmt, attrs, inits, cond, incs, block);
} else if ((attrs = stmt.Attrs).IsEmpty | true && stmt.Calls(CodeSymbols.ForEach, 3) && (tmp_11 = stmt.Args[0]) != null && tmp_11.Calls(CodeSymbols.Var, 2) && (type = tmp_11.Args[0]) != null && (loopVar = tmp_11.Args[1]) != null && (collection = stmt.Args[1]) != null && (block = stmt.Args[2]) != null) {
block = EliminateSequenceExpressionsInChildStmt(block);
collection = BubbleUpBlocks(collection);
if (collection.CallsMin(__numrunSequence, 1)) {
return LNode.Call(LNode.List(attrs), CodeSymbols.Braces, LNode.List().AddRange(collection.Args.WithoutLast(1)).Add(LNode.Call(CodeSymbols.ForEach, LNode.List(LNode.Call(CodeSymbols.Var, LNode.List(type, loopVar)), collection.Args.Last, block)))).SetStyle(NodeStyle.Statement);
} else {
return stmt.WithArgChanged(stmt.Args.Count - 1, block);
}
} else if ((attrs = stmt.Attrs).IsEmpty | true && stmt.Calls(CodeSymbols.Var, 2) && (type = stmt.Args[0]) != null && (tmp_12 = stmt.Args[1]) != null && tmp_12.Calls(CodeSymbols.Assign, 2) && (name = tmp_12.Args[0]) != null && (initValue = tmp_12.Args[1]) != null) {
var initValue_apos = BubbleUpBlocks(initValue);
if (initValue_apos != initValue) {
{
LNode last;
VList<LNode> stmts;
if (initValue_apos.CallsMin((Symbol) "#runSequence", 1) && (last = initValue_apos.Args[initValue_apos.Args.Count - 1]) != null) {
stmts = initValue_apos.Args.WithoutLast(1);
return LNode.Call((Symbol) "#runSequence", LNode.List().AddRange(stmts).Add(LNode.Call(LNode.List(attrs), CodeSymbols.Var, LNode.List(type, LNode.Call(CodeSymbols.Assign, LNode.List(name, last))))));
} else
return LNode.Call(LNode.List(attrs), CodeSymbols.Var, LNode.List(type, LNode.Call(CodeSymbols.Assign, LNode.List(name, initValue_apos))));
}
}
} else if (stmt.CallsMin(S.Try, 2)) {
return ESEInTryStmt(stmt);
} else if (stmt.HasSpecialName && stmt.ArgCount >= 1 && stmt.Args.Last.Calls(S.Braces)) {
return ProcessBlockCallStmt(stmt, stmt.ArgCount - 1);
} else {
// Ordinary expression statement
return BubbleUpBlocks(stmt, stmtContext: true);
}
}
return stmt;
}
示例15: CoreName
LNode CoreName(LNode complexId)
{
if (complexId.IsId)
return complexId;
if (complexId.CallsMin(S.Of, 1))
return CoreName(complexId.Args[0]);
if (complexId.CallsMin(S.Dot, 1))
return complexId.Args.Last;
if (complexId.CallsMin(S.Substitute, 1))
return complexId;
Debug.Fail("Not a complex identifier");
return complexId.Target;
}