Esempio n. 1
0
        public Type Visit(WhileStatement whileStatement, FunctionGeneratorEnvironment arg)
        {
            var labelno_while = arg.GetNextLabelNumber();
            var labelno_end   = arg.GetNextLabelNumber();
            var _while        = $"{arg.FunctionName}_LABEL{labelno_while}";
            var end           = $"{arg.FunctionName}_LABEL{labelno_end}";

            Program.Emit(T42Instruction.LABEL(_while));
            whileStatement.expr.Accept(this, arg);
            Program.Emit(T42Instruction.BRF(end));

            whileStatement.stmt.Accept(this, arg);

            Program.Emit(T42Instruction.BRA(_while));
            Program.Emit(T42Instruction.LABEL(end));

            return(null);
        }
Esempio n. 2
0
        public Type Visit(IfElseStatement ifElseStatement, FunctionGeneratorEnvironment arg)
        {
            var labelno_else = arg.GetNextLabelNumber();
            var labelno_end  = arg.GetNextLabelNumber();
            var _else        = $"{arg.FunctionName}_LABEL{labelno_else}";
            var end          = $"{arg.FunctionName}_LABEL{labelno_end}";

            ifElseStatement.expr.Accept(this, arg);
            Program.Emit(T42Instruction.BRF(_else));

            ifElseStatement.stmt1.Accept(this, arg);
            Program.Emit(T42Instruction.BRA(end));

            Program.Emit(T42Instruction.LABEL(_else));
            ifElseStatement.stmt2.Accept(this, arg);

            Program.Emit(T42Instruction.LABEL(end));

            return(null);
        }
Esempio n. 3
0
        public Type Visit(BinOperatorStatement binOperatorStatement, FunctionGeneratorEnvironment arg)
        {
            var left   = binOperatorStatement.left;
            var right  = binOperatorStatement.right;
            var type   = binOperatorStatement.type;
            var opType = MapOpExpr[binOperatorStatement.type];

            switch (opType)
            {
            case OperatorExpression.INTEGER:
                left.Accept(this, arg);
                right.Accept(this, arg);
                switch (type)
                {
                case BinOperatorStatement.Type.ADD:
                    Program.Emit(T42Instruction.ADD);
                    break;

                case BinOperatorStatement.Type.SUB:
                    Program.Emit(T42Instruction.SUB);
                    break;

                case BinOperatorStatement.Type.MUL:
                    Program.Emit(T42Instruction.MUL);
                    break;

                case BinOperatorStatement.Type.DIV:
                    Program.Emit(T42Instruction.DIV);
                    break;
                }
                break;

            case OperatorExpression.LOGICAL:
                var labelno_next = arg.GetNextLabelNumber();
                var labelno_end  = arg.GetNextLabelNumber();
                var end          = $"{arg.FunctionName}_LABEL{labelno_end}";
                var next         = $"{arg.FunctionName}_LABEL{labelno_next}";
                switch (binOperatorStatement.type)
                {
                case BinOperatorStatement.Type.OR:

                    left.Accept(this, arg);
                    Program.Emit(T42Instruction.BRF(next));
                    Program.Emit(T42Instruction.PUSHBOOL(1));
                    Program.Emit(T42Instruction.BRA(end));
                    Program.Emit(T42Instruction.LABEL(next));
                    right.Accept(this, arg);
                    Program.Emit(T42Instruction.LABEL(end));

                    break;

                case BinOperatorStatement.Type.AND:

                    left.Accept(this, arg);
                    Program.Emit(T42Instruction.BRF(next));
                    right.Accept(this, arg);
                    Program.Emit(T42Instruction.BRA(end));
                    Program.Emit(T42Instruction.LABEL(next));
                    Program.Emit(T42Instruction.PUSHBOOL(0));
                    Program.Emit(T42Instruction.LABEL(end));

                    break;
                }
                break;

            case OperatorExpression.INEQUALITY:
                left.Accept(this, arg);
                right.Accept(this, arg);
                switch (type)
                {
                case BinOperatorStatement.Type.LE:
                case BinOperatorStatement.Type.GEQ:
                    Program.Emit(T42Instruction.LTINT);
                    if (type == BinOperatorStatement.Type.GEQ)
                    {
                        Program.Emit(T42Instruction.NOT);
                    }
                    break;

                case BinOperatorStatement.Type.GR:
                case BinOperatorStatement.Type.LEQ:
                    Program.Emit(T42Instruction.GTINT);
                    if (type == BinOperatorStatement.Type.LEQ)
                    {
                        Program.Emit(T42Instruction.NOT);
                    }
                    break;
                }

                break;

            case OperatorExpression.EQUALITY:
                var t = left.Accept(this, arg);
                right.Accept(this, arg);

                if (t.GetType() == typeof(IntType))
                {
                    Program.Emit(T42Instruction.EQINT);
                }
                else
                {
                    Program.Emit(T42Instruction.EQBOOL);
                }

                if (type == BinOperatorStatement.Type.NEQ)
                {
                    Program.Emit(T42Instruction.NOT);
                }

                break;

            default:
                throw new Exception();
            }


            return(new BoolType());
        }