Merge "Convert math functions"
This commit is contained in:
commit
4cfd37e617
3 changed files with 178 additions and 0 deletions
|
@ -728,6 +728,36 @@ func (f *foreachExpr) transform(transformer func(expr starlarkExpr) starlarkExpr
|
|||
}
|
||||
}
|
||||
|
||||
type binaryOpExpr struct {
|
||||
left, right starlarkExpr
|
||||
op string
|
||||
returnType starlarkType
|
||||
}
|
||||
|
||||
func (b *binaryOpExpr) emit(gctx *generationContext) {
|
||||
b.left.emit(gctx)
|
||||
gctx.write(" " + b.op + " ")
|
||||
b.right.emit(gctx)
|
||||
}
|
||||
|
||||
func (b *binaryOpExpr) typ() starlarkType {
|
||||
return b.returnType
|
||||
}
|
||||
|
||||
func (b *binaryOpExpr) emitListVarCopy(gctx *generationContext) {
|
||||
b.emit(gctx)
|
||||
}
|
||||
|
||||
func (b *binaryOpExpr) transform(transformer func(expr starlarkExpr) starlarkExpr) starlarkExpr {
|
||||
b.left = b.left.transform(transformer)
|
||||
b.right = b.right.transform(transformer)
|
||||
if replacement := transformer(b); replacement != nil {
|
||||
return replacement
|
||||
} else {
|
||||
return b
|
||||
}
|
||||
}
|
||||
|
||||
type badExpr struct {
|
||||
errorLocation ErrorLocation
|
||||
message string
|
||||
|
|
|
@ -100,6 +100,11 @@ var knownFunctions = map[string]interface {
|
|||
"is-vendor-board-qcom": &isVendorBoardQcomCallParser{},
|
||||
"lastword": &firstOrLastwordCallParser{isLastWord: true},
|
||||
"notdir": &simpleCallParser{name: baseName + ".notdir", returnType: starlarkTypeString, addGlobals: false},
|
||||
"math_max": &mathMaxOrMinCallParser{function: "max"},
|
||||
"math_min": &mathMaxOrMinCallParser{function: "min"},
|
||||
"math_gt_or_eq": &mathComparisonCallParser{op: ">="},
|
||||
"math_gt": &mathComparisonCallParser{op: ">"},
|
||||
"math_lt": &mathComparisonCallParser{op: "<"},
|
||||
"my-dir": &myDirCallParser{},
|
||||
"patsubst": &substCallParser{fname: "patsubst"},
|
||||
"product-copy-files-by-pattern": &simpleCallParser{name: baseName + ".product_copy_files_by_pattern", returnType: starlarkTypeList, addGlobals: false},
|
||||
|
@ -1068,6 +1073,23 @@ func (ctx *parseContext) parseCompare(cond *mkparser.Directive) starlarkExpr {
|
|||
case *eqExpr:
|
||||
typedExpr.isEq = !typedExpr.isEq
|
||||
return typedExpr
|
||||
case *binaryOpExpr:
|
||||
switch typedExpr.op {
|
||||
case ">":
|
||||
typedExpr.op = "<="
|
||||
return typedExpr
|
||||
case "<":
|
||||
typedExpr.op = ">="
|
||||
return typedExpr
|
||||
case ">=":
|
||||
typedExpr.op = "<"
|
||||
return typedExpr
|
||||
case "<=":
|
||||
typedExpr.op = ">"
|
||||
return typedExpr
|
||||
default:
|
||||
return ¬Expr{expr: expr}
|
||||
}
|
||||
default:
|
||||
return ¬Expr{expr: expr}
|
||||
}
|
||||
|
@ -1090,6 +1112,13 @@ func (ctx *parseContext) parseCompare(cond *mkparser.Directive) starlarkExpr {
|
|||
return otherOperand
|
||||
}
|
||||
}
|
||||
if intOperand, err := strconv.Atoi(strings.TrimSpace(stringOperand)); err == nil && otherOperand.typ() == starlarkTypeInt {
|
||||
return &eqExpr{
|
||||
left: otherOperand,
|
||||
right: &intLiteralExpr{literal: intOperand},
|
||||
isEq: isEq,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return &eqExpr{left: xLeft, right: xRight, isEq: isEq}
|
||||
|
@ -1625,6 +1654,68 @@ func (p *firstOrLastwordCallParser) parse(ctx *parseContext, node mkparser.Node,
|
|||
return &indexExpr{&callExpr{object: arg, name: "split", returnType: starlarkTypeList}, index}
|
||||
}
|
||||
|
||||
func parseIntegerArguments(ctx *parseContext, node mkparser.Node, args *mkparser.MakeString, expectedArgs int) ([]starlarkExpr, error) {
|
||||
parsedArgs := make([]starlarkExpr, 0)
|
||||
for _, arg := range args.Split(",") {
|
||||
expr := ctx.parseMakeString(node, arg)
|
||||
if expr.typ() == starlarkTypeList {
|
||||
return nil, fmt.Errorf("argument to math argument has type list, which cannot be converted to int")
|
||||
}
|
||||
if s, ok := maybeString(expr); ok {
|
||||
intVal, err := strconv.Atoi(strings.TrimSpace(s))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
expr = &intLiteralExpr{literal: intVal}
|
||||
} else if expr.typ() != starlarkTypeInt {
|
||||
expr = &callExpr{
|
||||
name: "int",
|
||||
args: []starlarkExpr{expr},
|
||||
returnType: starlarkTypeInt,
|
||||
}
|
||||
}
|
||||
parsedArgs = append(parsedArgs, expr)
|
||||
}
|
||||
if len(parsedArgs) != expectedArgs {
|
||||
return nil, fmt.Errorf("function should have %d arguments", expectedArgs)
|
||||
}
|
||||
return parsedArgs, nil
|
||||
}
|
||||
|
||||
type mathComparisonCallParser struct {
|
||||
op string
|
||||
}
|
||||
|
||||
func (p *mathComparisonCallParser) parse(ctx *parseContext, node mkparser.Node, args *mkparser.MakeString) starlarkExpr {
|
||||
parsedArgs, err := parseIntegerArguments(ctx, node, args, 2)
|
||||
if err != nil {
|
||||
return ctx.newBadExpr(node, err.Error())
|
||||
}
|
||||
return &binaryOpExpr{
|
||||
left: parsedArgs[0],
|
||||
right: parsedArgs[1],
|
||||
op: p.op,
|
||||
returnType: starlarkTypeBool,
|
||||
}
|
||||
}
|
||||
|
||||
type mathMaxOrMinCallParser struct {
|
||||
function string
|
||||
}
|
||||
|
||||
func (p *mathMaxOrMinCallParser) parse(ctx *parseContext, node mkparser.Node, args *mkparser.MakeString) starlarkExpr {
|
||||
parsedArgs, err := parseIntegerArguments(ctx, node, args, 2)
|
||||
if err != nil {
|
||||
return ctx.newBadExpr(node, err.Error())
|
||||
}
|
||||
return &callExpr{
|
||||
object: nil,
|
||||
name: p.function,
|
||||
args: parsedArgs,
|
||||
returnType: starlarkTypeInt,
|
||||
}
|
||||
}
|
||||
|
||||
func (ctx *parseContext) parseMakeString(node mkparser.Node, mk *mkparser.MakeString) starlarkExpr {
|
||||
if mk.Const() {
|
||||
return &stringLiteralExpr{mk.Dump()}
|
||||
|
|
|
@ -1279,6 +1279,63 @@ def init(g, handle):
|
|||
g["NATIVE_BRIDGE_PRODUCT_PACKAGES"] = "libnative_bridge_vdso.native_bridge native_bridge_guest_app_process.native_bridge native_bridge_guest_linker.native_bridge"
|
||||
g["NATIVE_BRIDGE_MODIFIED_GUEST_LIBS"] = "libaaudio libamidi libandroid libandroid_runtime"
|
||||
g["NATIVE_BRIDGE_PRODUCT_PACKAGES"] += " " + " ".join(rblf.addsuffix(".native_bridge", g.get("NATIVE_BRIDGE_ORIG_GUEST_LIBS", "")))
|
||||
`,
|
||||
},
|
||||
{
|
||||
desc: "Math functions",
|
||||
mkname: "product.mk",
|
||||
in: `
|
||||
# Test the math functions defined in build/make/common/math.mk
|
||||
ifeq ($(call math_max,2,5),5)
|
||||
endif
|
||||
ifeq ($(call math_min,2,5),2)
|
||||
endif
|
||||
ifeq ($(call math_gt_or_eq,2,5),true)
|
||||
endif
|
||||
ifeq ($(call math_gt,2,5),true)
|
||||
endif
|
||||
ifeq ($(call math_lt,2,5),true)
|
||||
endif
|
||||
ifeq ($(call math_gt_or_eq,2,5),)
|
||||
endif
|
||||
ifeq ($(call math_gt,2,5),)
|
||||
endif
|
||||
ifeq ($(call math_lt,2,5),)
|
||||
endif
|
||||
ifeq ($(call math_gt_or_eq,$(MY_VAR), 5),true)
|
||||
endif
|
||||
ifeq ($(call math_gt_or_eq,$(MY_VAR),$(MY_OTHER_VAR)),true)
|
||||
endif
|
||||
ifeq ($(call math_gt_or_eq,100$(MY_VAR),10),true)
|
||||
endif
|
||||
`,
|
||||
expected: `# Test the math functions defined in build/make/common/math.mk
|
||||
load("//build/make/core:product_config.rbc", "rblf")
|
||||
|
||||
def init(g, handle):
|
||||
cfg = rblf.cfg(handle)
|
||||
if max(2, 5) == 5:
|
||||
pass
|
||||
if min(2, 5) == 2:
|
||||
pass
|
||||
if 2 >= 5:
|
||||
pass
|
||||
if 2 > 5:
|
||||
pass
|
||||
if 2 < 5:
|
||||
pass
|
||||
if 2 < 5:
|
||||
pass
|
||||
if 2 <= 5:
|
||||
pass
|
||||
if 2 >= 5:
|
||||
pass
|
||||
if int(g.get("MY_VAR", "")) >= 5:
|
||||
pass
|
||||
if int(g.get("MY_VAR", "")) >= int(g.get("MY_OTHER_VAR", "")):
|
||||
pass
|
||||
if int("100%s" % g.get("MY_VAR", "")) >= 10:
|
||||
pass
|
||||
`,
|
||||
},
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue