private CodeStatementCollection GenerateImperativeStatement(SwitchExpression node) { var condition = GenerateImperativeExpression(node.Expression); CodeConditionStatement switchStatement = null; CodeConditionStatement rootSwitchStatement = null; Action<CodeConditionStatement> setSwitchStmt = x => { if (switchStatement != null) { switchStatement.FalseStatements.Add(x); switchStatement = x; } else { rootSwitchStatement = switchStatement = x; } }; foreach (var c in node.Cases) { var caseChecks = c.Cases .Cast<IdentifierExpression>() .Select(x => x.Identifier) .Select(x => IsTokenType(x) ? (CodeExpression)GetTokenTypeRef(x) : CodeHelper.VarRef(x)) .Select(x => CodeHelper.BinOpExp(condition, CodeBinaryOperatorType.ValueEquality, x)) .ToArray(); var exp = CodeHelper.BinOpExpJoin(caseChecks, CodeBinaryOperatorType.BooleanOr); var body = GenerateImperativeStatements(c.Body); //var body = c.Body // .SelectMany(x => GenerateImperativeStatement(x).OfType<CodeStatement>()) // .ToArray(); setSwitchStmt(new CodeConditionStatement(exp, body.Cast<CodeStatement>().ToArray())); } if (node.DefaultCase != null && node.DefaultCase.Any()) { if (setSwitchStmt == null) { throw new NotImplementedException(); } //var defaultStmts = node.DefaultCase // .SelectMany(x => GenerateImperativeStatement(x).OfType<CodeStatement>()) // .ToArray(); var defaultStmts = GenerateImperativeStatements(node.DefaultCase) .OfType<CodeStatement>() .ToArray(); switchStatement.FalseStatements.AddRange(defaultStmts); } return new CodeStatementCollection(new[] { rootSwitchStatement }); }
private void InterpretSwitchExpression(SwitchExpression expression) { var exp = (AphidObject)InterpretExpression(expression.Expression); foreach (var c in expression.Cases) { foreach (var c2 in c.Cases) { var caseValue = (AphidObject)InterpretExpression(c2); if (!exp.Value.Equals(caseValue.Value)) { continue; } EnterChildScope(); Interpret(c.Body, resetIsReturning: false); LeaveChildScope(bubbleReturnValue: true); return; } } if (expression.DefaultCase != null) { EnterChildScope(); Interpret(expression.DefaultCase, resetIsReturning: false); LeaveChildScope(bubbleReturnValue: true); } }
private AphidExpression ParseSwitchExpression() { NextToken(); Match(AphidTokenType.LeftParenthesis); var exp = ParseExpression(); Match(AphidTokenType.RightParenthesis); Match(AphidTokenType.LeftBrace); var switchExp = new SwitchExpression() { Expression = exp, Cases = new List<SwitchCase>(), }; while (_currentToken.TokenType != AphidTokenType.RightBrace) { if (_currentToken.TokenType != AphidTokenType.defaultKeyword) { var caseTuple = ParseTuple(); Match(AphidTokenType.ColonOperator); var block = ParseBlock(); switchExp.Cases.Add(new SwitchCase() { Cases = caseTuple, Body = block, }); } else { NextToken(); Match(AphidTokenType.ColonOperator); switchExp.DefaultCase = ParseBlock(); } } NextToken(); return switchExp; }