Beispiel #1
0
func (v *Codegen) genBinaryExpr(n *parser.BinaryExpr) llvm.Value {
	if n.Op.Category() == parser.OP_LOGICAL {
		return v.genLogicalBinop(n)
	}

	lhand := v.genExpr(n.Lhand)
	rhand := v.genExpr(n.Rhand)

	return v.genBinop(n.Op, n.GetType(), n.Lhand.GetType(), n.Rhand.GetType(), lhand, rhand)
}
Beispiel #2
0
func (v *Codegen) genBinaryExpr(n *parser.BinaryExpr) llvm.Value {
	var res llvm.Value

	lhand := v.genExpr(n.Lhand)
	rhand := v.genExpr(n.Rhand)

	if lhand.IsNil() || rhand.IsNil() {
		v.err("invalid binary expr")
	} else {
		switch n.Op {
		// Arithmetic
		case parser.BINOP_ADD:
			if n.GetType().IsFloatingType() {
				return v.builder.CreateFAdd(lhand, rhand, "")
			} else {
				return v.builder.CreateAdd(lhand, rhand, "")
			}
		case parser.BINOP_SUB:
			if n.GetType().IsFloatingType() {
				return v.builder.CreateFSub(lhand, rhand, "")
			} else {
				return v.builder.CreateSub(lhand, rhand, "")
			}
		case parser.BINOP_MUL:
			if n.GetType().IsFloatingType() {
				return v.builder.CreateFMul(lhand, rhand, "")
			} else {
				return v.builder.CreateMul(lhand, rhand, "")
			}
		case parser.BINOP_DIV:
			if n.GetType().IsFloatingType() {
				return v.builder.CreateFDiv(lhand, rhand, "")
			} else {
				if n.GetType().(parser.PrimitiveType).IsSigned() {
					return v.builder.CreateSDiv(lhand, rhand, "")
				} else {
					return v.builder.CreateUDiv(lhand, rhand, "")
				}
			}
		case parser.BINOP_MOD:
			if n.GetType().IsFloatingType() {
				return v.builder.CreateFRem(lhand, rhand, "")
			} else {
				if n.GetType().(parser.PrimitiveType).IsSigned() {
					return v.builder.CreateSRem(lhand, rhand, "")
				} else {
					return v.builder.CreateURem(lhand, rhand, "")
				}
			}

		// Comparison
		case parser.BINOP_GREATER, parser.BINOP_LESS, parser.BINOP_GREATER_EQ, parser.BINOP_LESS_EQ, parser.BINOP_EQ, parser.BINOP_NOT_EQ:
			if n.Lhand.GetType().IsFloatingType() {
				return v.builder.CreateFCmp(comparisonOpToFloatPredicate(n.Op), lhand, rhand, "")
			} else {
				return v.builder.CreateICmp(comparisonOpToIntPredicate(n.Op, n.Lhand.GetType().IsSigned()), lhand, rhand, "")
			}

		// Bitwise
		case parser.BINOP_BIT_AND:
			return v.builder.CreateAnd(lhand, rhand, "")
		case parser.BINOP_BIT_OR:
			return v.builder.CreateOr(lhand, rhand, "")
		case parser.BINOP_BIT_XOR:
			return v.builder.CreateXor(lhand, rhand, "")
		case parser.BINOP_BIT_LEFT:
			return v.builder.CreateShl(lhand, rhand, "")
		case parser.BINOP_BIT_RIGHT:
			// TODO make sure both operands are same type (create type cast here?)
			// TODO in semantic.go, make sure rhand is *unsigned* (LLVM always treats it that way)
			// TODO doc this
			if n.Lhand.GetType().IsSigned() {
				return v.builder.CreateAShr(lhand, rhand, "")
			} else {
				return v.builder.CreateLShr(lhand, rhand, "")
			}

		// Logical
		case parser.BINOP_LOG_AND:
			return v.builder.CreateAnd(lhand, rhand, "")
		case parser.BINOP_LOG_OR:
			return v.builder.CreateOr(lhand, rhand, "")

		default:
			panic("umimplented binop")
		}
	}

	return res
}
Beispiel #3
0
func (v *Codegen) genBinaryExpr(n *parser.BinaryExpr) llvm.Value {
	lhand := v.genExpr(n.Lhand)
	rhand := v.genExpr(n.Rhand)

	return v.genBinop(n.Op, n.GetType(), n.Lhand.GetType(), n.Rhand.GetType(), lhand, rhand)
}