From 444196a5d9790de63a664c233d9f5098cca7692d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Grubbstr=C3=B6m=20=28Grubba=29?= <grubba@grubba.org> Date: Mon, 8 Nov 1999 01:00:26 +0100 Subject: [PATCH] First version. The rules for F_FOR aren't fully ported yet. Rev: src/treeopt.in:1.1 --- .gitattributes | 1 + src/treeopt.in | 424 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 425 insertions(+) create mode 100644 src/treeopt.in diff --git a/.gitattributes b/.gitattributes index 461ec7d7e0..1c2546c2d3 100644 --- a/.gitattributes +++ b/.gitattributes @@ -487,6 +487,7 @@ testfont binary /src/threads.c foreign_ident /src/threads.h foreign_ident /src/time_stuff.h foreign_ident +/src/treeopt.in foreign_ident /src/version.c foreign_ident /src/version.h foreign_ident /tutorial/manpages foreign_ident diff --git a/src/treeopt.in b/src/treeopt.in new file mode 100644 index 0000000000..3556d54174 --- /dev/null +++ b/src/treeopt.in @@ -0,0 +1,424 @@ +// -*- c-mode -*- +// +// $Id: treeopt.in,v 1.1 1999/11/08 00:00:26 grubba Exp $ +// +// The tree optimizer +// +// Henrik Grubbström 1999-11-06 + +0 = F_APPLY(1 = F_CONSTANT + [u.sval.type == T_FUNCTION] + [u.sval.subtype == FUNCTION_BUILTIN] + [u.sval.u.efun->optimize], *): + +{ + if ((tmp = $1->u.sval.u.efun->optimize($0))) { + $$ = tmp; + } +} +; + +F_CAST(-,*): + -; + +F_CAST[type == void_type_string](F_CONSTANT, *): + -; + +F_CAST[type == void_type_string](F_COMMA_EXPR(0, F_CONSTANT), *): +{ + $$ = mkcastnode(void_type_string, $0); +} +; + +F_CAST[type == void_type_string] + (F_APPLY(F_CONSTANT[(node_info & OPT_SIDE_EFFECT| + OPT_ASSIGNMENT| + OPT_TRY_OPTIMIZE) == OPT_TRY_OPTIMIZE], + F_ARG_LIST(1, 2)), *): +{ + $$ = mkcastnode(void_type_string, + mknode(F_COMMA_EXPR, $1, $2)); +} +; + +F_CAST[type == void_type_string] + (F_APPLY(F_CONSTANT[(node_info & OPT_SIDE_EFFECT| + OPT_ASSIGNMENT| + OPT_TRY_OPTIMIZE) == OPT_TRY_OPTIMIZE], + 0), *): + $0; + +// FCAST[0 = type](1 = *[0], *): 1; + +F_RANGE(*, F_ARG_LIST(*, F_CONSTANT[u.sval.type == T_INT] + [u.sval.u.integer <= 0])): +{ + yywarning("Range end is not positive."); +} +; + +F_RANGE(*, F_ARG_LIST(*, F_CONSTANT[u.sval.type == T_FLOAT] + [u.sval.u.float_number <= 0.0])): +{ + yywarning("Range end is not positive."); +} +; + +F_COMMA_EXPR(-, 0): + $0; + +F_COMMA_EXPR(0, -): + $0; + +F_COMMA_EXPR(F_CONSTANT, 0): + $0; + +F_COMMA_EXPR(F_COMMA_EXPR(0, F_CONSTANT), 1): + F_COMMA_EXPR($0, $1); + +F_COMMA_EXPR(F_ARG_LIST(0, 1), 2): + F_COMMA_EXPR(F_COMMA_EXPR($0, $1), $2); + +// Ensure that the result value is at the top-node, to ensure +// proper optimization. +F_COMMA_EXPR(0, F_COMMA_EXPR(1, 2)): + F_COMMA_EXPR(F_COMMA_EXPR($0, $1), $2); + +// Is really the OPT_CASE needded for the following three? +F_COMMA_EXPR(0 = F_RETURN, *[!(tree_info & OPT_CASE)]): + $0; + +F_COMMA_EXPR(0 = F_CONTINUE, *[!(tree_info & OPT_CASE)]): + $0; + +F_COMMA_EXPR(0 = F_BREAK, *[!(tree_info & OPT_CASE)]): + $0; + +F_COMMA_EXPR(0 = F_COMMA_EXPR(*, F_RETURN), *[!(tree_info & OPT_CASE)]): + $0; + +F_COMMA_EXPR(0 = F_COMMA_EXPR(*, F_CONSTANT), *[!(tree_info & OPT_CASE)]): + $0; + +F_COMMA_EXPR(0 = F_COMMA_EXPR(*, F_BREAK), *[!(tree_info & OPT_CASE)]): + $0; + + +F_ARG_LIST(-, 0): + $0; + +F_ARG_LIST(0, -): + $0; + +// Is really the OPT_CASE needded for the following three? +F_ARG_LIST(0 = F_RETURN, *[!(tree_info & OPT_CASE)]): + $0; + +F_ARG_LIST(0 = F_CONTINUE, *[!(tree_info & OPT_CASE)]): + $0; + +F_ARG_LIST(0 = F_BREAK, *[!(tree_info & OPT_CASE)]): + $0; + +F_ARG_LIST(0 = F_COMMA_EXPR(*, F_RETURN), *[!(tree_info & OPT_CASE)]): + $0; + +F_ARG_LIST(0 = F_COMMA_EXPR(*, F_CONSTANT), *[!(tree_info & OPT_CASE)]): + $0; + +F_ARG_LIST(0 = F_COMMA_EXPR(*, F_BREAK), *[!(tree_info & OPT_CASE)]): + $0; + + +F_LVALUE_LIST(-, 0): + $0; + +F_LVALUE_LIST(0, -): + $0; + +// Is really the OPT_CASE needded for the following three? +F_LVALUE_LIST(0 = F_RETURN, *[!(tree_info & OPT_CASE)]): + $0; + +F_LVALUE_LIST(0 = F_CONTINUE, *[!(tree_info & OPT_CASE)]): + $0; + +F_LVALUE_LIST(0 = F_BREAK, *[!(tree_info & OPT_CASE)]): + $0; + +F_LVALUE_LIST(0 = F_COMMA_EXPR(*, F_RETURN), *[!(tree_info & OPT_CASE)]): + $0; + +F_LVALUE_LIST(0 = F_COMMA_EXPR(*, F_CONSTANT), *[!(tree_info & OPT_CASE)]): + $0; + +F_LVALUE_LIST(0 = F_COMMA_EXPR(*, F_BREAK), *[!(tree_info & OPT_CASE)]): + $0; + + +F_LOR(-, 0): + $0; + +F_LOR(0, -): + $0; + +F_LOR(F_NOT(0, *), F_NOT(1, *)): + F_NOT(F_LAND($0, $1), -); + +F_LOR(0 = F_ASSIGN(*, 1), 2): +{ + if (node_is_false($1)) { + $$ = mknode(F_COMMA_EXPR, $0, $2); + } + if (node_is_true($1)) { + $$ = $0; + } +} +; + +F_LOR(0, 1 = F_CONSTANT): +{ + if (node_is_false($1)) { + $$ = $0; + } +} +; + +F_LOR(0, 1): +{ + if (node_is_false($0)) { + $$ = $1; + } + if (node_is_true($0)) { + $$ = $0; + } +} +; + + +F_LAND(-, 0): + -; + +F_LAND(0, -): + F_COMMA_EXPR($0, 0); + +F_LAND(F_NOT(0, *), F_NOT(1, *)): + F_NOT(F_LOR($0, $1), -); + +F_LAND(0 = F_ASSIGN(*, 1), 2): +{ + if (node_is_true($1)) { + $$ = mknode(F_COMMA_EXPR, $0, $2); + } + if (node_is_false($1)) { + $$ = $0; + } +} +; + +F_LAND(0, 1): +{ + if (node_is_true($0)) { + $$ = $1; + } + if (node_is_false($0)) { + $$ = $0; + } + if (node_is_false($1)) { + $$ = mknode(F_COMMA_EXPR, $0, $1); + } +} +; + + +'?'(F_NOT(0, *), ':'(1, 2)): + '?'($0, ':'($2, $1)); + +'?'(0, ':'(1, 2)): +{ + if (node_is_true($0)) { + $$ = $1; + } + if (node_is_false($0)) { + $$ = $2; + } +} +; + + +F_NOT(-, *): + 1; + +F_NOT(F_LT(0, 1), *): + F_GE($0, $1); + +F_NOT(F_GT(0, 1), *): + F_LE($0, $1); + +F_NOT(F_LE(0, 1), *): + F_GT($0, $1); + +F_NOT(F_GE(0, 1), *): + F_LT($0, $1); + +F_NOT(F_EQ(0, 1), *): + F_NE($0, $1); + +F_NOT(F_NE(0, 1), *): + F_EQ($0, $1); + + +F_ADD_EQ(0, 1 = F_CONSTANT[u.sval.type == T_INT]): +{ + /* a += 0 -> a */ + if (!$1->u.sval.u.integer) { + $$ = $0; + } + + /* a += 1 -> ++a */ + if ($1->u.sval.u.integer == 1) { + $$ = mknode(F_INC, $0, 0); + } + + /* a += -1 -> --a */ + if ($1->u.sval.u.integer == -1) { + $$ = mknode(F_DEC, $0, 0); + } +} +; + +F_SUB_EQ(0, 1 = F_CONSTANT[u.sval.type == T_INT]): +{ + /* a -= 0 -> a */ + if (!$1->u.sval.u.integer) { + $$ = $0; + } + + /* a -= 1 -> --a */ + if ($1->u.sval.u.integer == 1) { + $$ = mknode(F_DEC, $0, 0); + } + + /* a -= -1 -> ++a */ + if ($1->u.sval.u.integer == -1) { + $$ = mknode(F_INC, $0, 0); + } +} +; + +F_ARROW(0 = F_CONSTANT[u.sval.type == T_OBJECT] + [u.sval.u.object->prog], + 1 = F_CONSTANT[u.sval.type == T_STRING]): +{ + if (find_identifier("`->", $0->u.sval.u.object->prog) == -1) { + int i = find_shared_string_identifier($1->u.sval.u.string, + $0->u.sval.u.object->prog); + if (i) { + struct identifier *id = ID_FROM_INT($0->u.sval.u.object->prog, i); + if (IDENTIFIER_IS_VARIABLE(id->identifier_flags)) break; + } + ref_push_object($0->u.sval.u.object); + ref_push_string($1->u.sval.u.string); + f_index(2); + tmp = mksvaluenode(sp-1); + pop_stack(); + $$ = tmp; + } +} +; + +F_FOR(-, *): + -; + +F_FOR(0, ':'(-, -)): + F_FOR($0, -); + +F_FOR(0, -): +{ + if (node_is_true($0)) { + $$ = mknode(F_FOR($0, mknode(':', + mkefuncallnode("sleep", mkintnode(255)), + 0))); + } + if (node_is_false($0)) { + $$ = 0; + } +} +; + +F_FOR(0, *): +{ + if (node_is_false($0)) { + $$ = 0; + } +} +; + +F_FOR(F_INC(0, *), -): + F_INC_NEQ_LOOP(F_VAL_LVAL(0, $0), -); +F_FOR(F_INC(0, *), ':'(-, 1[!(tree_info & OPT_CONTINUE)])): + F_INC_NEQ_LOOP(F_VAL_LVAL(0, $0), $1); +F_FOR(F_INC(0, *), ':'(1[!(tree_info & OPT_CONTINUE)], -)): + F_INC_NEQ_LOOP(F_VAL_LVAL(0, $0), $1); +F_FOR(F_INC(0, *), ':'(1[!(tree_info & OPT_CONTINUE)], + 2[!(tree_info & OPT_CONTINUE)])): + F_INC_NEQ_LOOP(F_VAL_LVAL(0, $0), F_COMMA_EXPR($1, $2)); + +F_FOR(F_POST_INC(0, *), -): + F_INC_NEQ_LOOP(F_VAL_LVAL(1, $0), -); +F_FOR(F_POST_INC(0, *), ':'(-, 1[!(tree_info & OPT_CONTINUE)])): + F_INC_NEQ_LOOP(F_VAL_LVAL(1, $0), $1); +F_FOR(F_POST_INC(0, *), ':'(1[!(tree_info & OPT_CONTINUE)], -)): + F_INC_NEQ_LOOP(F_VAL_LVAL(1, $0), $1); +F_FOR(F_POST_INC(0, *), ':'(1[!(tree_info & OPT_CONTINUE)], + 2[!(tree_info & OPT_CONTINUE)])): + F_INC_NEQ_LOOP(F_VAL_LVAL(1, $0), F_COMMA_EXPR($1, $2)); + +F_FOR(F_DEC(0, *), -): + F_DEC_NEQ_LOOP(F_VAL_LVAL(0, $0), -); +F_FOR(F_DEC(0, *), ':'(-, 1[!(tree_info & OPT_CONTINUE)])): + F_DEC_NEQ_LOOP(F_VAL_LVAL(0, $0), $1); +F_FOR(F_DEC(0, *), ':'(1[!(tree_info & OPT_CONTINUE)], -)): + F_DEC_NEQ_LOOP(F_VAL_LVAL(0, $0), $1); +F_FOR(F_DEC(0, *), ':'(1[!(tree_info & OPT_CONTINUE)], + 2[!(tree_info & OPT_CONTINUE)])): + F_DEC_NEQ_LOOP(F_VAL_LVAL(0, $0), F_COMMA_EXPR($1, $2)); + +F_FOR(F_POST_DEC(0, *), -): + F_DEC_NEQ_LOOP(F_VAL_LVAL(F_NEG(1, -), $0), -); +F_FOR(F_POST_DEC(0, *), ':'(-, 1[!(tree_info & OPT_CONTINUE)])): + F_DEC_NEQ_LOOP(F_VAL_LVAL(F_NEG(1, -), $0), $1); +F_FOR(F_POST_DEC(0, *), ':'(1[!(tree_info & OPT_CONTINUE)], -)): + F_DEC_NEQ_LOOP(F_VAL_LVAL(F_NEG(1, -), $0), $1); +F_FOR(F_POSTDEC(0, *), ':'(1[!(tree_info & OPT_CONTINUE)], + 2[!(tree_info & OPT_CONTINUE)])): + F_DEC_NEQ_LOOP(F_VAL_LVAL(F_NEG(1, -), $0), F_COMMA_EXPR($1, $2)); + +F_FOR(0, ':'(1, F_CAST[type == void_type_string](2, *))): + F_FOR($0, ':'($1, $2)); + +F_FOR(F_APPLY(0 = F_CONSTANT[u.sval.type == T_FUNCTION] + [u.sval.subtype == FUNCTION_BUILTIN], + 1), + ':'(2, 3)): +{ + int oper; + if ($0->u.sval.u.efun->function == f_gt) + oper = F_GT; + else if ($0->u.sval.u.efun->function == f_ge) + oper = F_GE; + else if ($0->u.sval.u.efun->function == f_lt) + oper = F_LT; + else if ($0->u.sval.u.efun->function == f_le) + oper = F_LE; + else if ($0->u.sval.u.efun->function == f_ne) + oper = F_NE; + else + goto end_for_apply; + + if (count_args($1) != 2) goto end_for_apply; + + +end_for_apply: +} +; -- GitLab