public override void WriteBlock(Context context, Scope scope, TextWriter writer, TextWriter metaWriter, IStatement statement) { if (!(statement is FunctionStatement funcDefStt)) { throw new InvalidOperationException(); } var functionName = funcDefStt.Name; if (scope.IsIdentifierExists(functionName)) { throw new IdentifierNameExistsCompilerException(functionName, funcDefStt.Info); } var funcScope = scope.BeginNewScope(ScopeType.MethodRoot); IStatement inlinedStatement = null; funcScope.SetConfig(c => c.ExplicitEchoStream, context.Flags.DefaultExplicitEchoStream); if (context.Flags.UseComments && context.Flags.CommentParameterInfos) { BashTranspilerHelpers.WriteComment(writer, $"! {funcDefStt.TypeDescriptor} {functionName}"); } if (funcDefStt.Parameters != null && funcDefStt.Parameters.Length > 0) { for (var i = 0; i < funcDefStt.Parameters.Length; i++) { var param = funcDefStt.Parameters[i]; var paramMappedName = (i + 1).ToString(CultureInfo.InvariantCulture); funcScope.ReserveNewParameter(param.TypeDescriptor, param.Name, paramMappedName); if (context.Flags.UseComments && context.Flags.CommentParameterInfos) { BashTranspilerHelpers.WriteComment(writer, $"\\param ${paramMappedName} {param.TypeDescriptor} - {param.Name}"); } } } writer.WriteLine($"function {functionName}() {{"); BashBlockStatementTranspiler.WriteBlockStatement(context, funcScope, writer, metaWriter, funcDefStt.Statement, ScopeType.MethodRoot, false, typeof(ReturnStatement)); TryGetInlinedStatement(context, funcScope, funcDefStt, out inlinedStatement); var func = new FunctionInfo(funcDefStt.TypeDescriptor, functionName, null, null, funcDefStt.IsParams, funcDefStt.Parameters, inlinedStatement); scope.ReserveNewFunction(func); writer.WriteLine("}"); scope.IncrementStatements(); }
public static void WriteIf(Context context, Scope scope, TextWriter writer, TextWriter nonInlinePartWriter, TextWriter metaWriter, IfElseStatement ifElseStatement) { var ifEscaped = false; var skipElse = false; var condition = EvaluationStatementTranspilerBase.ProcessEvaluation(context, scope, ifElseStatement.MainIf.Condition); if (StatementHelpers.IsAbsoluteBooleanValue(condition, out var isTrue)) { if (isTrue) { BashBlockStatementTranspiler.WriteBlockStatement(context, scope, writer, metaWriter, ifElseStatement.MainIf.Statement, ScopeType.Block, true); return; } ifEscaped = true; } else { writer.Write("if "); WriteCondition(context, scope, writer, metaWriter, nonInlinePartWriter, ifElseStatement, condition); writer.WriteLine(); writer.WriteLine("then"); BashBlockStatementTranspiler.WriteBlockStatement(context, scope, writer, metaWriter, ifElseStatement.MainIf.Statement, ScopeType.IfMainBlock, true); } if (ifElseStatement.ElseIfs != null) { foreach (var elseIf in ifElseStatement.ElseIfs) { condition = EvaluationStatementTranspilerBase.ProcessEvaluation(context, scope, elseIf.Condition); if (StatementHelpers.IsAbsoluteBooleanValue(condition, out isTrue)) { if (isTrue) { if (!ifEscaped) { writer.WriteLine("else"); } BashBlockStatementTranspiler.WriteBlockStatement(context, scope, writer, metaWriter, elseIf.Statement, ScopeType.IfElseBlock, true); skipElse = true; break; } } else { if (ifEscaped) { writer.Write("if "); ifEscaped = false; } else { writer.Write("elif "); } WriteCondition(context, scope, writer, metaWriter, nonInlinePartWriter, ifElseStatement, condition); writer.WriteLine(); writer.WriteLine("then"); BashBlockStatementTranspiler.WriteBlockStatement(context, scope, writer, metaWriter, elseIf.Statement, ScopeType.IfIfElseBlock, true); } } } if (!skipElse && ifElseStatement.Else != null) { if (ifEscaped) { BashBlockStatementTranspiler.WriteBlockStatement(context, scope, writer, metaWriter, ifElseStatement.Else, ScopeType.IfMainBlock, true); } else { writer.WriteLine("else"); BashBlockStatementTranspiler.WriteBlockStatement(context, scope, writer, metaWriter, ifElseStatement.Else, ScopeType.IfElseBlock, true); } } if (!ifEscaped) { writer.WriteLine("fi"); scope.IncrementStatements(); } }