Merge "Convert math functions"
This commit is contained in:
@@ -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 {
|
type badExpr struct {
|
||||||
errorLocation ErrorLocation
|
errorLocation ErrorLocation
|
||||||
message string
|
message string
|
||||||
|
@@ -100,6 +100,11 @@ var knownFunctions = map[string]interface {
|
|||||||
"is-vendor-board-qcom": &isVendorBoardQcomCallParser{},
|
"is-vendor-board-qcom": &isVendorBoardQcomCallParser{},
|
||||||
"lastword": &firstOrLastwordCallParser{isLastWord: true},
|
"lastword": &firstOrLastwordCallParser{isLastWord: true},
|
||||||
"notdir": &simpleCallParser{name: baseName + ".notdir", returnType: starlarkTypeString, addGlobals: false},
|
"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{},
|
"my-dir": &myDirCallParser{},
|
||||||
"patsubst": &substCallParser{fname: "patsubst"},
|
"patsubst": &substCallParser{fname: "patsubst"},
|
||||||
"product-copy-files-by-pattern": &simpleCallParser{name: baseName + ".product_copy_files_by_pattern", returnType: starlarkTypeList, addGlobals: false},
|
"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:
|
case *eqExpr:
|
||||||
typedExpr.isEq = !typedExpr.isEq
|
typedExpr.isEq = !typedExpr.isEq
|
||||||
return typedExpr
|
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:
|
default:
|
||||||
return ¬Expr{expr: expr}
|
return ¬Expr{expr: expr}
|
||||||
}
|
}
|
||||||
@@ -1090,6 +1112,13 @@ func (ctx *parseContext) parseCompare(cond *mkparser.Directive) starlarkExpr {
|
|||||||
return otherOperand
|
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}
|
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}
|
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 {
|
func (ctx *parseContext) parseMakeString(node mkparser.Node, mk *mkparser.MakeString) starlarkExpr {
|
||||||
if mk.Const() {
|
if mk.Const() {
|
||||||
return &stringLiteralExpr{mk.Dump()}
|
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_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_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", "")))
|
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
|
||||||
`,
|
`,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user