Ejemplo n.º 1
0
        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.");
            }
        }
Ejemplo n.º 2
0
 public CompilerError UntranslatableStatement(Grammar.Statement body) => Add($"The statement {body} was not translatable.");