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); }
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); }
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()); }