Ejemplo n.º 1
0
        static void Main(string[] args)
        {
            foreach (var fn in args)
            {
                if (!File.Exists(fn))
                {
                    Console.WriteLine("cannot find file: {0}", fn);
                }
                string src = File.ReadAllText(fn);

                /// Stage 1: lexer.
                ReadOnlyCollection <T> tokens;
                try {
                    tokens = new ReadOnlyCollection <T>(Lexer.Instance.Scan(src));
                } catch (LexerException e) {
                    Console.WriteLine(e.Message);
                    return;
                }


                /// Stage 2: parser.
                Parser.Env.Clear();
                var stream  = new TokenStream <T>(tokens);
                var results = P.TranslationUnit().End()(stream);
                if (results.Count() == 0)
                {
                    Console.WriteLine("Parser Error: parsing failed");
                    return;
                }
                if (results.Count() > 1)
                {
                    Console.WriteLine("Parser Error: ambiguity");
                    return;
                }

                /// Stage 3: type check and build ast.
                AST.Node ast = null;
                try {
                    ast = results.First().Value.ToAST(new SyntaxTree.Env());
                } catch (Error e) {
                    Console.WriteLine(e.Message);
                    return;
                }

                /// Stage 4: code generation and write to file.
                var gen = new X86Gen();
                ast.ToX86(gen);
                if (fn.Length > 2 && fn.Substring(fn.Length - 2) == ".c")
                {
                    File.WriteAllText(fn.Substring(0, fn.Length - 2) + ".s", gen.ToString());
                }
                else
                {
                    File.WriteAllText(fn + ".s", gen.ToString());
                }
            }
        }
Ejemplo n.º 2
0
        public override void ToX86(X86Gen gen)
        {
            gen.Comment(X86Gen.Seg.TEXT, "if");
            gen.Branch(expr, other != null ? elseLabel : endIfLabel, false);

            /// Generate code for then branch.
            /// Remember to jump to endif label since
            /// "If the first substatement is reached via a label, the second substatement is not executed.
            gen.Comment(X86Gen.Seg.TEXT, "then");
            then.ToX86(gen);
            gen.Inst(X86Gen.jmp, endIfLabel);
            if (other != null)
            {
                gen.Comment(X86Gen.Seg.TEXT, "else");
                gen.Tag(X86Gen.Seg.TEXT, elseLabel);
                other.ToX86(gen);
            }
            gen.Tag(X86Gen.Seg.TEXT, endIfLabel);
        }
Ejemplo n.º 3
0
        public override void ToX86(X86Gen gen)
        {
            var ret = expr.ToX86Expr(gen);

            switch (expr.Type.Kind)
            {
            case TKind.INT:
            case TKind.LONG:

                /// Move the result to ecx.
                if (ret == X86Gen.Ret.PTR)
                {
                    gen.Inst(X86Gen.mov, X86Gen.ecx, X86Gen.eax.Addr());
                }
                else
                {
                    gen.Inst(X86Gen.mov, X86Gen.ecx, X86Gen.eax);
                }

                /// For each case.
                foreach (var c in cases)
                {
                    var cRet = c.Item2.ToX86Expr(gen);
                    Debug.Assert(cRet == X86Gen.Ret.REG);
                    gen.Inst(X86Gen.cmp, X86Gen.eax, X86Gen.ecx);
                    gen.Inst(X86Gen.je, c.Item1);
                }

                /// Jump to default label.
                gen.Inst(X86Gen.jmp, defaultLabel);
                break;

            default: throw new NotImplementedException();
            }

            /// Lay the code for the body.
            stmt.ToX86(gen);

            /// Lay down the break label.
            gen.Tag(X86Gen.Seg.TEXT, breakLabel);
        }
Ejemplo n.º 4
0
        /// <summary>
        /// The basic structure is like:
        ///
        ///     # init
        ///     jmp first_label
        /// second_plus_label:
        ///     # iter
        /// first_label:
        ///     # pred
        ///     je break_label
        ///     # body
        ///     jmp second_plus_label
        /// break_label:
        ///
        /// </summary>
        /// <param name="gen"></param>
        public override void ToX86(X86Gen gen)
        {
            /// Generate the initialize code.
            /// Jump to first_label if iter is not omitted.
            gen.Comment(X86Gen.Seg.TEXT, "for init");
            if (init != null)
            {
                init.ToX86(gen);
                if (iter != null)
                {
                    gen.Inst(X86Gen.jmp, firstLabel);
                }
            }

            /// Generate the iterate code.
            gen.Comment(X86Gen.Seg.TEXT, "for iter");
            if (iter != null)
            {
                gen.Tag(X86Gen.Seg.TEXT, secondPlusLabel);
                iter.ToX86(gen);
            }

            /// Generate the controlling (predicating) code.
            gen.Comment(X86Gen.Seg.TEXT, "for pred");
            gen.Tag(X86Gen.Seg.TEXT, firstLabel);
            gen.Branch(pred, breakLabel, false);

            /// Generate body code.
            gen.Comment(X86Gen.Seg.TEXT, "for body");
            body.ToX86WithLabel(gen, continueLabel);
            gen.Inst(X86Gen.jmp, iter != null ? secondPlusLabel : firstLabel);

            /// Generate break labe.
            gen.Comment(X86Gen.Seg.TEXT, "for end");
            gen.Tag(X86Gen.Seg.TEXT, breakLabel);
        }
Ejemplo n.º 5
0
 public override void ToX86(X86Gen gen)
 {
     gen.Tag(X86Gen.Seg.TEXT, label);
     stmt.ToX86(gen);
 }