From 70cc9bf9cd1cdd8ae92eaec5092d22203c7cda88 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Grubbstr=C3=B6m=20=28Grubba=29?= <grubba@grubba.org> Date: Sat, 1 Nov 2014 11:29:41 +0100 Subject: [PATCH] Optimizer [treeopt]: Support operator call short-hand. A short-hand notation may now be used to match operator calls. Eg the following fragment: F_APPLY(F_CONSTANT[TYPEOF($$->u.sval) == T_FUNCTION] [SUBTYPEOF($$->u.sval) == FUNCTION_BUILTIN] [$$->u.sval.u.efun->function == f_ge], F_ARG_LIST(X, Y)) can now be written as: F_GE(X, Y) --- bin/mktreeopt.pike | 59 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 58 insertions(+), 1 deletion(-) diff --git a/bin/mktreeopt.pike b/bin/mktreeopt.pike index 60d1a6c853..60d9bf4b02 100644 --- a/bin/mktreeopt.pike +++ b/bin/mktreeopt.pike @@ -529,6 +529,27 @@ void read_car_cdr(object(node) res, array(string) linepos) } } +constant f_op_name_lookup = ([ + "F_LT": "f_lt", + "F_GT": "f_gt", + "F_LE": "f_le", + "F_GE": "f_ge", + "F_EQ": "f_eq", + "F_NE": "f_ne", + "F_ADD": "f_add", + "F_SUBTRACT": "f_subtract", + "F_DIVIDE": "f_divide", + "F_MULTIPLY": "f_multiply", + "F_MOD": "f_mod", + "F_LSH": "f_lsh", + "F_RSH": "f_rsh", + "F_OR": "f_or", + "F_AND": "f_and", + "F_XOR": "f_xor", + "F_NOT": "f_not", + "F_COMPL": "f_compl", +]); + object(node) read_node(array(string) linepos) { object(node) res = node(); @@ -612,7 +633,43 @@ object(node) read_node(array(string) linepos) c = data[pos]; } - read_car_cdr(res, linepos); + string f_op_name = f_op_name_lookup[token]; + if (f_op_name) { + // We need to convert the short-hand notation to + // an actual operator call node. + + res->token = "F_APPLY"; + + // Match the corresponding constant efun value. + node match = node(); + match->token = "F_CONSTANT"; + res->car = res->real_car = match; + string otpos = tpos; + tpos = "A" + tpos; + match->extras = + map(({ + "TYPEOF($$->u.sval) == T_FUNCTION", + "SUBTYPEOF($$->u.sval) == FUNCTION_BUILTIN", + "$$->u.sval.u.efun->function == " + f_op_name, + }), fix_extras); + tpos = "D" + otpos; + + // Read the arguments (if any) into an F_ARG_LIST node. + node args = node(); + args->token = "F_ARG_LIST"; + res->cdr = res->real_cdr = args; + + read_car_cdr(args, linepos); + + tpos = otpos; + + if (!args->car && !args->cdr) { + // No argument matching needed. + res->cdr = 0; + } + } else { + read_car_cdr(res, linepos); + } if ((res->token == "*") && !sizeof(res->extras) && !res->car && !res->cdr) { -- GitLab