/// <summary> /// 二項演算のコンパイル /// </summary> /// <param name="ilgen">IL Generator</param> /// <param name="expr">二項演算</param> static void CompileBinOpExpr(ILGenerator ilgen, MBinOpExpr expr) { CompileExpr(ilgen, expr.Lhs); CompileExpr(ilgen, expr.Rhs); switch (expr.OpType) { case BinOpType.Add: ilgen.Emit(OpCodes.Add); break; case BinOpType.Sub: ilgen.Emit(OpCodes.Sub); break; case BinOpType.Mul: ilgen.Emit(OpCodes.Mul); break; case BinOpType.Div: ilgen.Emit(OpCodes.Div); break; case BinOpType.Gt: CompileGtExpr(ilgen); break; case BinOpType.Eq: CompileEqExpr(ilgen); break; default: throw new NotImplementedException(); } }
/// <summary> /// +, - で構成される式の構文解析 /// </summary> /// <returns>式</returns> MExpr ParseAddExpr() { var lhs = ParseMulExpr(); for ( ; ; ) { var pos = _tkn.Pos; BinOpType op_type; if (_tkn.Type == TokenType.PLS) { op_type = BinOpType.Add; } else if (_tkn.Type == TokenType.MNS) { op_type = BinOpType.Sub; } else { break; } NextToken(); var rhs = ParseMulExpr(); lhs = new MBinOpExpr(pos, op_type, lhs, rhs); } return lhs; }
/// <summary> /// 比較演算子で構成される式の構文解析 /// </summary> /// <returns>式</returns> MExpr ParseLtExpr() { var lhs = ParseAddExpr(); BinOpType op_type; if (_tkn.Type == TokenType.GT) { var pos = _tkn.Pos; op_type = BinOpType.Gt; NextToken(); var rhs = ParseMulExpr(); lhs = new MBinOpExpr(pos, op_type, lhs, rhs); } else if (_tkn.Type == TokenType.EQEQ) { var pos = _tkn.Pos; op_type = BinOpType.Eq; NextToken(); var rhs = ParseMulExpr(); lhs = new MBinOpExpr(pos, op_type, lhs, rhs); } return lhs; }
/// <summary> /// 二項演算の型推論 /// </summary> /// <param name="expr">二項演算</param> static void TypeinfBinOpExpr(MBinOpExpr expr) { TypeinfExpr(expr.Lhs); TypeinfExpr(expr.Rhs); switch (expr.OpType) { case BinOpType.Add: case BinOpType.Sub: case BinOpType.Mul: case BinOpType.Div: Unification(expr.Pos, expr.Lhs.Type, new DotNetType(typeof(int))); Unification(expr.Pos, expr.Rhs.Type, new DotNetType(typeof(int))); expr.Type = new DotNetType(typeof(int)); break; case BinOpType.Gt: case BinOpType.Eq: Unification(expr.Pos, expr.Lhs.Type, new DotNetType(typeof(int))); Unification(expr.Pos, expr.Rhs.Type, new DotNetType(typeof(int))); expr.Type = new DotNetType(typeof(bool)); break; default: throw new NotImplementedException(); } }