コード例 #1
0
ファイル: Assembly.cs プロジェクト: Semperia/miniC-compiler
 public override void OnCodeGenVisit(AssemblyGenerator assembler)
 {
     Test.OnCodeGenVisit(assembler);
     assembler.EmitCode($"\tcmpl $0,%eax");
     assembler.EmitCode($"\tje _SEM_ENDIF{count}");
     Block.OnCodeGenVisit(assembler);
     assembler.EmitCode($"_SEM_ENDIF{count}:");
     count++;
 }
コード例 #2
0
ファイル: Assembly.cs プロジェクト: Semperia/miniC-compiler
 public override void OnCodeGenVisit(AssemblyGenerator assembler)
 {
     ReturnValue.OnCodeGenVisit(assembler);
     if (ShouldPause)
     {
         //assembler.EmitCode($"\tpushl %eax");
         assembler.EmitCode($"\tmovl $SL{assembler.StringConstants.Count}, (%esp)");
         assembler.EmitCode($"\tcall _system");
         //assembler.EmitCode($"\tpopl %eax");
     }
     assembler.EmitCode($"\tleave");
     assembler.EmitCode($"\tret");
 }
コード例 #3
0
ファイル: Assembly.cs プロジェクト: Semperia/miniC-compiler
 public override void OnCodeGenVisit(AssemblyGenerator assembler)
 {
     Init.OnCodeGenVisit(assembler);
     assembler.EmitCode($"_SEM_FOR{count}:");
     Test.OnCodeGenVisit(assembler);
     assembler.EmitCode($"\tcmpl $0,%eax");
     assembler.EmitCode($"\tje _SEM_ENDFOR{count}");
     Block.OnCodeGenVisit(assembler);
     Update.OnCodeGenVisit(assembler);
     assembler.EmitCode($"\tjmp _SEM_FOR{count}");
     assembler.EmitCode($"_SEM_ENDFOR{count}:");
     count++;
 }
コード例 #4
0
ファイル: Assembly.cs プロジェクト: Semperia/miniC-compiler
        public override void OnCodeGenVisit(AssemblyGenerator assembler)
        {
            int offset = assembler.GetVariableOffset(Identifier);

            Value.OnCodeGenVisit(assembler);
            if (Identifier.isVariable())
            {
                assembler.EmitCode($"\tmovl %eax, {offset}(%ebp)");
            }
            else
            {
                assembler.EmitCode($"\tmovl %eax, {offset}(%ebp)");
            }
        }
コード例 #5
0
ファイル: Assembly.cs プロジェクト: Semperia/miniC-compiler
 public override void OnCodeGenVisit(AssemblyGenerator assembler)
 {
     assembler.AllocMemory(Identifier);
     if (Init != null)
     {
         Init.OnCodeGenVisit(assembler);
         string postfix = ((VariableSymbol)symbol).VariableType == VariableType.Char ? "b" : "l";
         string target  = ((VariableSymbol)symbol).VariableType == VariableType.Char ? "%al" : "%eax";
         assembler.EmitCode($"\tmov{postfix} {target}, {assembler.GetVariableOffset(this.Identifier)}(%ebp)");
     }
 }
コード例 #6
0
ファイル: Assembly.cs プロジェクト: Semperia/miniC-compiler
        public override void OnCodeGenVisit(AssemblyGenerator assembler)
        {
            Stack <Expression> parameters = new Stack <Expression>();
            //assembler.EmitCode($"\tpushl %edx");
            int count = 0;

            foreach (Expression arg in Arguments)
            {
                parameters.Push(arg);
            }
            while (parameters.Count != 0)
            {
                Expression arg = parameters.Pop();
                arg.OnCodeGenVisit(assembler);
                assembler.EmitCode($"\tpushl %eax");
                count++;
            }
            assembler.EmitCode($"\tcall {Symbol.AsmLabel}");
            assembler.EmitCode($"\taddl ${count * 4},%esp");
            //assembler.EmitCode($"\tpopl %edx");
        }
コード例 #7
0
ファイル: Assembly.cs プロジェクト: Semperia/miniC-compiler
        public override void OnCodeGenVisit(AssemblyGenerator assembler)
        {
            foreach (FormalArgument arg in ArgumentList)
            {
                assembler.AllocMemory(Block.BlockId, arg);
            }
            assembler.EmitCode($"{this.symbol.AsmLabel}:");
            assembler.EmitCode($"\tpushl %ebp");
            assembler.EmitCode($"\tmovl %esp, %ebp");
            assembler.EmitCode($"\tandl $-16, %esp");
            int TotalBytes = assembler.GetParameterBytes(Block.BlockId);

            if (TotalBytes != 0)
            {
                assembler.EmitCode($"\tsubl ${(TotalBytes >= 16 ? TotalBytes : 16)}, %esp");
            }
            if (Identifier.IdentifierName == "main")
            {
                assembler.EmitCode($"\tcall ___main");
                foreach (Statement s in Block.Statements.Where(s => s.Type == SyntaxNodeType.ReturnStatement))
                {
                    ((ReturnStatement)s).ShouldPause = true;
                }
            }
            Block.OnCodeGenVisit(assembler);
            //assembler.EmitCode($"\tleave");
            //assembler.EmitCode($"\tret");
        }
コード例 #8
0
ファイル: Assembly.cs プロジェクト: Semperia/miniC-compiler
        public override void OnCodeGenVisit(AssemblyGenerator assembler)
        {
            Expression.OnCodeGenVisit(assembler);
            switch (Operator)
            {
            case UnaryOperator.Not:
                assembler.EmitCode($"\tsete %al");
                break;

            case UnaryOperator.Address:
                if (Expression.Type != SyntaxNodeType.Identifier)
                {
                    throw new SemanticError("Cannot address rvalue");
                }
                Identifier addrVariable = Expression.As <Identifier>();
                assembler.EmitCode($"\tleal {assembler.GetVariableOffset(addrVariable)}(%ebp),%eax");
                break;

            case UnaryOperator.Dereference:
                assembler.EmitCode($"\tmovl (%eax),%eax");
                break;
            }
        }
コード例 #9
0
ファイル: Assembly.cs プロジェクト: Semperia/miniC-compiler
        // This is only visited while appears alone
        public override void OnCodeGenVisit(AssemblyGenerator assembler)
        {
            switch (Type)
            {
            case SyntaxNodeType.CharLiteral:
                uint val = Convert.ToUInt32((char)Value);
                assembler.EmitCode($"\tmovl {val}, %eax");
                break;

            case SyntaxNodeType.IntegerLiteral:
                assembler.EmitCode($"\tmovl ${Value}, %eax");
                break;

            case SyntaxNodeType.NullLiteral:
                assembler.EmitCode($"\tmovl $0, %eax");
                break;

            case SyntaxNodeType.BooleanLiteral:
                if (Value == "true")
                {
                    assembler.EmitCode($"\tmovl $-1, %eax");
                }
                else if (Value == "false")
                {
                    assembler.EmitCode($"\t movl $0, %eax");
                }
                break;

            case SyntaxNodeType.FloatLiteral:
                break;

            case SyntaxNodeType.StringLiteral:
                assembler.EmitCode($"\tmovl ${assembler.GetLiteralLabel(this)}, %eax");
                break;
            }
        }
コード例 #10
0
ファイル: Assembly.cs プロジェクト: Semperia/miniC-compiler
        public override void OnCodeGenVisit(AssemblyGenerator assembler)
        {
            Right.OnCodeGenVisit(assembler);
            //assembler.EmitCode($"\tmovl %eax,%edx");
            assembler.EmitCode($"\tpushl %eax");
            Left.OnCodeGenVisit(assembler);
            assembler.EmitCode($"\tpopl %edx");
            ReturnType leftType = Left.GetReturnType(), rightType = Right.GetReturnType();
            string     postfix = "", regA = "", regB = "";

            switch (Cast(leftType, rightType))
            {
            case ReturnType.Char:
                postfix = "b";
                regA    = "%al";
                regB    = "%dl";
                Return  = ReturnType.Char;
                break;

            case ReturnType.Float:
                postfix = "l";
                regA    = "%eax";
                regB    = "%edx";
                Return  = ReturnType.Float;
                break;

            case ReturnType.Int:
                postfix = "l";
                regA    = "%eax";
                regB    = "%edx";
                Return  = ReturnType.Int;
                break;
            }
            switch (this.Operator)
            {
            case BinaryOperator.Plus:
                assembler.EmitCode($"\tadd{postfix} {regB},{regA}");
                break;

            case BinaryOperator.Minus:
                assembler.EmitCode($"\tsub{postfix} {regB},{regA}");
                break;

            case BinaryOperator.Multiply:
                assembler.EmitCode($"\timul{postfix} {regB},{regA}");
                break;

            case BinaryOperator.Divide:
                assembler.EmitCode($"\tpushl %edx");
                assembler.EmitCode($"\tcltd");
                assembler.EmitCode($"\tidivl (%esp)");
                assembler.EmitCode($"\taddl $4,%esp");
                break;

            case BinaryOperator.And:
                assembler.EmitCode($"\tcmp{postfix} $0,{regB}");
                assembler.EmitCode($"\tjz LGF{LogicCount}");
                assembler.EmitCode($"\tcmp{postfix} $0,{regA}");
                assembler.EmitCode($"\tjz LGF{LogicCount}");
                assembler.EmitCode($"\tmovl $1,%eax");
                assembler.EmitCode($"\tjmp LGE{LogicCount}");
                assembler.EmitCode($"LGF{LogicCount}:");
                assembler.EmitCode($"\tmovl $0,%eax");
                assembler.EmitCode($"LGE{LogicCount}:");
                LogicCount++;
                break;

            case BinaryOperator.Or:
                assembler.EmitCode($"\tcmp{postfix} $0,{regB}");
                assembler.EmitCode($"\tjnz LGT{LogicCount}");
                assembler.EmitCode($"\tcmp{postfix} $0,{regA}");
                assembler.EmitCode($"\tjnz LGT{LogicCount}");
                assembler.EmitCode($"\tmovl $0,%eax");
                assembler.EmitCode($"\tjmp LGE{LogicCount}");
                assembler.EmitCode($"LGT{LogicCount}:");
                assembler.EmitCode($"\tmovl $1,%eax");
                assembler.EmitCode($"LGE{LogicCount}:");
                LogicCount++;
                break;

            case BinaryOperator.Equal:
                assembler.EmitCode($"\tcmp{postfix} {regB},{regA}");
                assembler.EmitCode($"\tsete %al");
                assembler.EmitCode($"\tmovzbl %al,%eax");
                break;

            case BinaryOperator.GreaterEqual:
                assembler.EmitCode($"\tcmp{postfix} {regB},{regA}");
                assembler.EmitCode($"\tsetge %al");
                if (postfix == "l")
                {
                    assembler.EmitCode($"\tmovzbl %al,%eax");
                }
                break;

            case BinaryOperator.GreaterThan:
                assembler.EmitCode($"\tcmp{postfix} {regB},{regA}");
                assembler.EmitCode($"\tsetg %al");
                if (postfix == "l")
                {
                    assembler.EmitCode($"\tmovzbl %al,%eax");
                }
                break;

            case BinaryOperator.LessEqual:
                assembler.EmitCode($"\tcmp{postfix} {regB},{regA}");
                assembler.EmitCode($"\tsetle %al");
                if (postfix == "l")
                {
                    assembler.EmitCode($"\tmovzbl %al,%eax");
                }
                break;

            case BinaryOperator.LessThan:
                assembler.EmitCode($"\tcmp{postfix} {regB},{regA}");
                assembler.EmitCode($"\tsetl %al");
                if (postfix == "l")
                {
                    assembler.EmitCode($"\tmovzbl %al,%eax");
                }
                break;

            case BinaryOperator.NotEqual:
                assembler.EmitCode($"\tcmp{postfix} {regB},{regA}");
                assembler.EmitCode($"\tsetne %al");
                if (postfix == "l")
                {
                    assembler.EmitCode($"\tmovzbl %al,%eax");
                }
                break;
            }
        }