예제 #1
0
        public Type Visit(Argument argument, FunctionGeneratorEnvironment arg)
        {
            arg.AllocateVariable(argument.id, (Type)argument.type);
            Program.Emit(T42Instruction.DECL(1));

            return((Type)argument.type);
        }
예제 #2
0
        public Type Visit(RegularStatement regularStatement, FunctionGeneratorEnvironment arg)
        {
            regularStatement.expr.Accept(this, arg);
            Program.Emit(T42Instruction.POP(1));

            return(null);
        }
예제 #3
0
        public Type Visit(BoolStatement boolStatement, FunctionGeneratorEnvironment arg)
        {
            var val = (boolStatement.value == true) ? 1 : 0;

            Program.Emit(T42Instruction.PUSHBOOL(val));

            return(new BoolType());
        }
예제 #4
0
        public void Emit(T42Instruction inst)
        {
            if (inst.opcode == T42Instruction.OPCODE.LABEL)
            {
                AddressMap[inst.target] = Instructions.Count;
            }

            Instructions.Add(inst);
        }
예제 #5
0
        public T42Program Generate(Statement stmt)
        {
            var globalEnvironment = new FunctionGeneratorEnvironment();

            Program.Emit(T42Instruction.DECL(1));
            Program.Emit(T42Instruction.BSR("main"));
            Program.Emit(T42Instruction.END);
            stmt.Accept(this, globalEnvironment);
            Program.Link();
            return(Program);
        }
예제 #6
0
        public Type Visit(IfStatement ifStatement, FunctionGeneratorEnvironment arg)
        {
            var labelno_end = arg.GetNextLabelNumber();
            var end         = $"{arg.FunctionName}_LABEL{labelno_end}";

            ifStatement.expr.Accept(this, arg);
            Program.Emit(T42Instruction.BRF(end));

            ifStatement.stmt.Accept(this, arg);

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

            return(null);
        }
예제 #7
0
        public Type Visit(AssignStatement assignStatement, FunctionGeneratorEnvironment arg)
        {
            var type   = arg.GetIdentifierType(assignStatement.id);
            var offset = arg.GetIdentifierOffset(assignStatement.id);

            Program.Emit(T42Instruction.LVAL(offset));
            assignStatement.s.Accept(this, arg);

            if (type.GetType() == typeof(IntType))
            {
                Program.Emit(T42Instruction.ASSINT);
                Program.Emit(T42Instruction.RVALINT(offset));
            }
            else
            {
                Program.Emit(T42Instruction.ASSBOOL);
                Program.Emit(T42Instruction.RVALBOOL(offset));
            }

            return(type);
        }
예제 #8
0
 public Type Visit(IdentifierStatement identifierStatement, FunctionGeneratorEnvironment arg)
 {
     if (identifierStatement.list == null)
     {
         var type   = arg.GetIdentifierType(identifierStatement.id);
         var offset = arg.GetIdentifierOffset(identifierStatement.id);
         if (type.GetType() == typeof(IntType))
         {
             Program.Emit(T42Instruction.RVALINT(offset));
             return(new IntType());
         }
         else
         {
             Program.Emit(T42Instruction.RVALBOOL(offset));
             return(new BoolType());
         }
     }
     else
     {
         // CALL STATEMENT
         return(new BoolType());
     }
 }
예제 #9
0
        public Type Visit(NumStatement numStatement, FunctionGeneratorEnvironment arg)
        {
            Program.Emit(T42Instruction.PUSHINT(numStatement.num));

            return(new IntType());
        }
예제 #10
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());
        }