Example #1
0
func intOp(op token.Token, x, y *BasicLit, combine bool) (*BasicLit, error) {
	out := &BasicLit{
		Kind: x.Kind,
	}
	l, err := strconv.Atoi(x.Value)
	if err != nil {
		return out, err
	}
	r, err := strconv.Atoi(y.Value)
	if err != nil {
		return out, err
	}
	var t int
	switch op {
	case token.ADD:
		t = l + r
	case token.SUB:
		t = l - r
	case token.QUO:
		// Sass division can create floats, so much treat
		// ints as floats then test for fitting inside INT
		fl, fr := float64(l), float64(r)
		if math.Remainder(fl, fr) != 0 {
			return floatOp(op, x, y, combine)
		}
		t = l / r
	case token.MUL:
		t = l * r
	default:
		panic("unsupported intOp" + op.String())
	}
	out.Value = strconv.Itoa(t)
	return out, nil
}
Example #2
0
func stringOp(op token.Token, x, y *BasicLit, combine bool) (*BasicLit, error) {
	kind := token.STRING
	if op == token.ADD {
		return &BasicLit{
			Kind:  kind,
			Value: x.Value + y.Value,
		}, nil
	}

	return &BasicLit{
		Kind:  kind,
		Value: x.Value + op.String() + y.Value,
	}, nil
}
Example #3
0
func otherOp(op token.Token, x, y *BasicLit, combine bool) (*BasicLit, error) {
	if !combine && op == token.QUO {
		return stringOp(op, x, y, combine)
	}

	a, b := x, y
	// Order for non-string operations is not important. Reorder for simpler logic
	switch {
	case x.Kind == token.INT || x.Kind == token.FLOAT:
		a = y
		b = x
	case y.Kind == token.INT || y.Kind == token.FLOAT:
	default:
		if op == token.MUL {
			return nil, fmt.Errorf("unsupported operation: %s %s %s", x, op, y)
		}
	}

	var kind token.Token
	switch a.Kind {
	case token.ILLEGAL:
	default:
		kind = a.Kind
	}

	switch b.Kind {
	case token.ILLEGAL:
	default:
		switch {
		case kind == token.ILLEGAL:
			kind = b.Kind
		case b.Kind == token.INT || b.Kind == token.FLOAT:
		case kind != b.Kind:
			return nil, fmt.Errorf("illegal unit operation %s %s",
				a.Kind, b.Kind)
		}
	}
	xx := &BasicLit{
		Value: strings.TrimSuffix(a.Value, a.Kind.String()),
	}
	yy := &BasicLit{
		Value: strings.TrimSuffix(b.Value, b.Kind.String()),
	}

	f, err := floatOp(op, xx, yy, combine)
	return &BasicLit{
		Kind:  kind,
		Value: f.Value + kind.String(),
	}, err
}
Example #4
0
// colorOpString perform combinations on the string values
func colorOpString(tok token.Token, x, y *BasicLit, combine bool) (*BasicLit, error) {
	fmt.Println("cOpS", tok, x.Value, y.Value)
	lit := &BasicLit{
		Kind:     token.STRING,
		ValuePos: x.Pos(),
	}
	switch tok {
	case token.ADD:
		lit.Value = x.Value + y.Value
	case token.SUB:
		lit.Value = x.Value + tok.String() + y.Value
	case token.QUO:
		lit.Value = x.Value + tok.String() + y.Value
	case token.MUL:
		return nil, fmt.Errorf(`Undefined operation: "%s %s %s".`,
			x.Value, tok, y.Value)
	}
	fmt.Println("out", lit.Value)
	return lit, nil
}
Example #5
0
func floatOp(op token.Token, x, y *BasicLit, combine bool) (*BasicLit, error) {
	out := &BasicLit{
		Kind: token.FLOAT,
	}
	if !combine {
		out.Value = x.Value + op.String() + y.Value
		return out, nil
	}

	l, err := strconv.ParseFloat(x.Value, 64)
	if err != nil {
		return out, err
	}
	r, err := strconv.ParseFloat(y.Value, 64)
	if err != nil {
		return out, err
	}
	var t float64
	switch op {
	case token.ADD:
		t = l + r
	case token.SUB:
		t = l - r
	case token.QUO:
		// Sass division can create floats, so much treat
		// ints as floats then test for fitting inside INT
		t = l / r
	case token.MUL:
		t = l * r
	default:
		panic("unsupported intOp" + op.String())
	}
	out.Value = strconv.FormatFloat(t, 'G', -1, 64)
	if math.Remainder(t, 1) == 0 {
		out.Kind = token.INT
	}
	return out, nil

}