private Statement ConvertStatement(TranslationUnit unit, IScope scope, Grammar.Statement stmt, BlockContext context) { if (stmt is Grammar.Block block) { var result = new Block(); unit.AddTask(() => { var sequence = new List <Statement>(); var blockscope = scope; foreach (var sub in block) { if (sub is Declaration decl) { // TODO: Allow CreateSymbol initializer to access the self-defined symbol var err = CreateSymbol(unit, blockscope, decl, out var sym); if (err != CompilerError.None) { return(err); } sym.Kind = SymbolKind.Local; blockscope = new ExtendingScope(blockscope, sym); if (decl.Value != null) { var init = new ExpressionStatement(); unit.AddTask(() => { if (sym.Initializer == null) { return(Error.InvalidExpression(decl.Value)); } init.Expression = sym.Initializer; return(Error.None); }); sequence.Add(init); } } else { var substmt = ConvertStatement(unit, blockscope, sub, context); if (substmt == null) { return(Error.UntranslatableStatement(sub)); } sequence.Add(substmt); } } result.Statements = sequence; return(Error.None); }); return(result); } else if (stmt is Grammar.ExpressionStatement expr) { var exec = new ExpressionStatement(); unit.AddTask(() => { var list = ConvertExpression(unit, scope, expr.Expression); if (list == null) { return(Error.InvalidExpression(expr.Expression)); } if (list.Count > 1) { return(Error.AmbiguousExpression(expr.Expression, list)); } exec.Expression = list.Single(); if (exec.Expression == null) { return(Error.InvalidExpression(expr.Expression)); } return(Error.None); }); return(exec); } else if (stmt is Grammar.FlowBreakStatement flow) { switch (flow.Type) { case FlowBreakType.Return: { var @return = new ReturnStatement(); if (flow.Value != null) { unit.AddTask(() => { var options = ConvertExpression(unit, scope, flow.Value); @return.Result = SelectFitting(options, context.EnclosingType.ReturnType); if (@return.Result == null) { return(Error.InvalidExpression(flow.Value)); } return(Error.None); }); } return(@return); } default: throw new NotSupportedException($"{flow.Type} is not supported yet."); } } else if (stmt is WhileLoopStatement loop) { var s = new WhileLoop(); unit.AddTask(() => { s.Condition = ConvertExpression(unit, scope, loop.Condition).Single(); if (s.Condition == null) { return(Error.InvalidExpression(loop.Condition)); } return(Error.None); }); unit.AddTask(() => { s.Body = ConvertStatement(unit, scope, loop.Body, context); if (s.Body == null) { return(Error.UntranslatableStatement(loop.Body)); } return(Error.None); }); return(s); } else { throw new NotSupportedException($"The statement type {stmt?.GetType()?.Name ?? "?"} is not supported yet."); } }
public CompilerError UntranslatableStatement(Grammar.Statement body) => Add($"The statement {body} was not translatable.");