Exemplo n.º 1
0
        public CodeBlock CreateStatement(VarDeclarationNode node)
        {
            var output = new CodeBlock();

            foreach (var id in node.Ids)
            {
                var t = NextTemporary;
                var v = new Variable
                {
                    Name  = id.Token.Content,
                    Scope = CurrentScope
                };

                AddTemporary(v, t);

                if (node.Type is SimpleTypeNode)
                {
                    output.Add(CodeLine.Of($"{VarSignature(node, t.Representation)};", id.Token.Content,
                                           id.Token.Line));
                }
                else
                {
                    HasArrays = true;
                    var at = (ArrayTypeNode)node.Type;

                    var size    = -1;
                    var type    = _types[at.SubType];
                    var sizeStr = "";

                    switch (at.Size)
                    {
                    case NoOpNode _:
                        t.Dynamic = true;
                        t.Size    = 0;
                        sizeStr   = "0";
                        break;

                    case ValueNode vn:
                        t.Size  = vn.Value;
                        sizeStr = $"{t.Size}";
                        break;

                    default:
                    {
                        var(sizeTemp, sizeCode) = ComputeTemporary(at.Size);
                        output.Add(sizeCode);
                        sizeStr = sizeTemp.Representation;
                        break;
                    }
                    }
                    // TODO: skip this if value
                    _arrayDefinitions.Add($"typedef _array({type}, {at.SubType});");
                    output.Add(CodeLine.Of($"_array_{at.SubType} {t.Representation};"));
                    output.Add(CodeLine.Of($"_initArray({t.Representation}, {sizeStr});",
                                           $"{id}: array[{(at.Size is NoOpNode ? "" : at.Size.ToString())}] of {at.Type.Token.Content}",
                                           node.Token.Line));
                    AddFreeable(t);
                }
            }

            return(output);
        }
Exemplo n.º 2
0
        public string Generate()
        {
            foreach (var cfg in Cfgs)
            {
                var function = cfg.Function;
                _scopeStack.Push(function.Scope);
                _freeable[function.Scope] = new List <string>();
                var signature = FunctionSignature(function);
                if (!signature.Equals("main"))
                {
                    _forwardDeclarations.Add($"{signature};");
                }

                var cfgCodeBlock = new CodeBlock();
                cfgCodeBlock.Add(CodeLine.Of($"{signature} {{", $"{cfg.Function}"));
                cfgCodeBlock.Indent();

                foreach (var block in cfg.Blocks)
                {
                    var blockCodeBlock = new CodeBlock
                    {
                        Depth = cfgCodeBlock.Depth
                    };
                    blockCodeBlock.Dedent();
                    blockCodeBlock.Add(CodeLine.Of($"L{block.Index}:;"));
                    blockCodeBlock.Indent();

                    foreach (dynamic statement in block.Statements)
                    {
                        var c = CreateStatement(statement);
                        blockCodeBlock.Add(c);
                    }

                    if (block.Child is BranchBlock bb)
                    {
                        var expression = bb.Expression;
                        var(t, code) = ComputeTemporary(expression);

                        var ifBlock = new CodeBlock
                        {
                            Depth = blockCodeBlock.Depth
                        };
                        ifBlock.Add(code);
                        ifBlock.Add(CodeLine.Of($"if ({t.Name}) goto L{bb.TrueBlock.Index};",
                                                $"{bb.Type.ToString().ToLower()} {bb.Expression}",
                                                bb.Expression.Token.Line));
                        ifBlock.Add(CodeLine.Of($"goto L{bb.FalseBlock.Index};", bb.Type == BranchBlockType.If ? "else" : "end while"));

                        blockCodeBlock.Add(ifBlock);
                    }
                    else if (block.Child != null)
                    {
                        if (block.Child.Index != block.Index + 1)
                        {
                            blockCodeBlock.Add(CodeLine.Of($"goto L{block.Child.Index};"));
                        }
                    }
                    else if (blockCodeBlock.Lines.Count > 0 && !blockCodeBlock.Lines[^ 1].Code.StartsWith("return"))
                    {
                        // TODO: default value, main returns 0?
                        blockCodeBlock.Add(CodeLine.Of("return;"));
                    }

                    /*if (blockCodeBlock.Lines.Count == 0 || blockCodeBlock.Lines[^1].Code.StartsWith("return"))
                     *  {
                     *      // BlockCodeBlock.Dedent();
                     *      _code.Add(blockCodeBlock);
                     *      continue;
                     *  }
                     *
                     *  blockCodeBlock.Add(CodeLine.Of("return;"));
                     * }*/

                    cfgCodeBlock.Add(blockCodeBlock);
                }

                cfgCodeBlock.Dedent();
                cfgCodeBlock.Add(CodeLine.Of("}", cfg.Function.ToString()));
                _code.Add(cfgCodeBlock);
                _scopeStack.Pop();
            }

            var output = "";

            if (HasArrays)
            {
                _includes.Add("stdlib.h");
            }
            output += string.Join("\n", _includes.Select(s => $"#include <{s}>")) + "\n\n";

            if (HasArrays)
            {
                output += ArrayMacros;
            }
            if (HasAssert)
            {
                output += AssertionMacro;
            }
            output += string.Join("\n", _arrayDefinitions) + "\n\n";

            output += string.Join("\n", _forwardDeclarations) + "\n\n";

            output += string.Join("\n\n", _code);

            return(output); //string.Join("\n", _code);
        }