pike.git / bin / mktreeopt.pike

version» Context lines:

pike.git/bin/mktreeopt.pike:224:    * if (cdr(n)) {    * ANY_X:    * // Code for ANY-X    * // Code for ANY-PLUS    * }    * }    * // Code for ANY-ANY    */      constant header = - "/* Tree transformation code.\n" - " *\n" - " * This file was generated from %O.\n" - " *\n" - " * Do NOT edit!\n" - " */\n" - "\n"; + #"/* Tree transformation code. +  * +  * This file was generated from %O. +  * +  * Do NOT edit! +  */    -  + #ifdef PIKE_DEBUG + #define DBG(X) if (l_flag>4) { fprintf(stderr, (X)); } + #else + #define DBG(X) + #endif +  + "; +    mapping(string: array(object(node))) rules = ([]);      void fail(string msg, mixed ... args)   {    werror(msg, @args);    exit(7); /* distinctive error... */   }      string fname;   string data = "";
pike.git/bin/mktreeopt.pike:456:    }    if (sizeof(pos)) {    a[i] = sprintf("C%sR(n)", pos) + a[i];    } else {    a[i] = "n" + a[i];    }    }    return a * "";   }    + void read_car_cdr(object(node) res, array(string) linepos) + { +  int c = data[pos]; +  +  if (c == '(') { +  string otpos = tpos; +  pos++; +  +  tpos = "A"+otpos; +  +  if (data[pos] == '$') { +  // FIXME: Support for recurring nodes. +  // Useful for common subexpression elimination. +  pos++; +  int tag = read_int(); +  string ntpos; +  if (!(ntpos = marks[tag])) { +  fail("%s:%d: Tag $%d used before being defined.\n", +  fname, line, tag); +  } else if (ntpos == "") { +  fail("%s:%d: Tag $%d is the root, and can't be used for " +  "exact matching.\n", +  fname, line, tag); +  } else { +  // FIXME: Ought to check that the tag isn't for one of our parents. +  res->car = res->real_car = sprintf("C%sR(n)", ntpos); +  } +  eat_whitespace(); +  } else { +  res->car = res->real_car = read_node(linepos); +  } +  +  expect(','); +  eat_whitespace(); +  +  tpos = "D"+otpos; +  +  if (data[pos] == '$') { +  // FIXME: Support for recurring nodes. +  // Useful for common subexpression elimination. +  pos++; +  int tag = read_int(); +  string ntpos; +  if (!(ntpos = marks[tag])) { +  fail("%s:%d: Tag $%d used before being defined.\n", +  fname, line, tag); +  } else if (ntpos == "") { +  fail("%s:%d: Tag $%d is the root, and can't be used for " +  "exact matching.\n", +  fname, line, tag); +  } else { +  // FIXME: Ought to check that the tag isn't for one of our parents. +  res->cdr = res->real_cdr = sprintf("C%sR(n)", ntpos); +  } +  eat_whitespace(); +  } else { +  res->cdr = res->real_cdr = read_node(linepos); +  } +  +  tpos = otpos; +  expect(')'); +  +  eat_whitespace(); +  } + } +  + 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();       eat_whitespace();    int c = data[pos];       if (c == '#') {    // Line number information holder.    linepos[0] = tpos;
pike.git/bin/mktreeopt.pike:538:    } else if (c == ']') {    cnt--;    } else if (c == '\n') {    line++;    }    }    res->extras += ({ fix_extras(data[start..pos-2]) });    eat_whitespace();    c = data[pos];    } -  if (c == '(') { -  string otpos = tpos; -  pos++; +     -  tpos = "A"+otpos; +  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.    -  if (data[pos] == '$') { -  // FIXME: Support for recurring nodes. -  // Useful for common subexpression elimination. -  pos++; -  int tag = read_int(); -  string ntpos; -  if (!(ntpos = marks[tag])) { -  fail("%s:%d: Tag $%d used before being defined.\n", -  fname, line, tag); -  } else if (ntpos == "") { -  fail("%s:%d: Tag $%d is the root, and can't be used for " -  "exact matching.\n", -  fname, line, tag); -  } else { -  // FIXME: Ought to check that the tag isn't for one of our parents. -  res->car = res->real_car = sprintf("C%sR(n)", ntpos); -  } -  eat_whitespace(); -  } else { -  res->car = res->real_car = read_node(linepos); -  } +  res->token = "F_APPLY";    -  expect(','); -  eat_whitespace(); +  // 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;    -  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;    -  if (data[pos] == '$') { -  // FIXME: Support for recurring nodes. -  // Useful for common subexpression elimination. -  pos++; -  int tag = read_int(); -  string ntpos; -  if (!(ntpos = marks[tag])) { -  fail("%s:%d: Tag $%d used before being defined.\n", -  fname, line, tag); -  } else if (ntpos == "") { -  fail("%s:%d: Tag $%d is the root, and can't be used for " -  "exact matching.\n", -  fname, line, tag); -  } else { -  // FIXME: Ought to check that the tag isn't for one of our parents. -  res->cdr = res->real_cdr = sprintf("C%sR(n)", ntpos); -  } -  eat_whitespace(); -  } else { -  res->cdr = res->real_cdr = read_node(linepos); -  } +  read_car_cdr(args, linepos);       tpos = otpos; -  expect(')'); +     -  eat_whitespace(); +  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) {    // No need to consider this node.    return 0;    }    }    return res;   }   
pike.git/bin/mktreeopt.pike:649:    }       new_node = b * "";       string pre_cleanup = "\n";    string post_cleanup = "\n";       if (sizeof(used_nodes)) {    pre_cleanup = "\n";    post_cleanup = "\n "; -  foreach(indices(used_nodes), string used_node) { +  foreach(sort(indices(used_nodes)), string used_node) {    pre_cleanup += (" ADD_NODE_REF2(" + used_node + ",\n")*    used_nodes[used_node];    post_cleanup += ")" * used_nodes[used_node];    }    pre_cleanup += " ";    post_cleanup += ";\n";    }    a[i] = pre_cleanup +    " tmp1" + new_node +    post_cleanup +
pike.git/bin/mktreeopt.pike:812:    cnt--;    } else if (c == '\n') {    line++;    }    }       action = fix_action(data[start..pos-1]);    } else if (data[pos] != ';') {    object(node) n2 = read_node2();    // werror(sprintf("\t%s;\n\n", n2)); -  array(string) t = [array(string)]Array.uniq(n2->used_nodes()); +  array(string) t = [array(string)]n2->used_nodes();       string expr = n2->generate_code();       // Some optimizations for common cases    switch(expr) {    case "0":    action = "goto zap_node;";    break;    case "CAR(n)":    action = "goto use_car;";
pike.git/bin/mktreeopt.pike:847:    "%s"    " tmp1 = %s;\n"    "%s"    " goto use_tmp1;\n"    "}",    pre_fix_refs,    expr,    post_fix_refs);    break;    } -  action = sprintf("#ifdef PIKE_DEBUG\n" -  " if (l_flag > 4) {\n" -  " fprintf(stderr, \"=> \"%O\"\\n\");\n" -  " }\n" -  "#endif /* PIKE_DEBUG */\n", sprintf("%s", n2)) + +  action = sprintf("DBG(\"=> \"%O\"\\n\");\n", sprintf("%s", n2)) +    action;    } else {    // Null action.    // Used to force code generation for eg NULL-detection.    // Obsolete.    action = "";    }       if (linepos[0] != "") {    // Update with linenumber information.
pike.git/bin/mktreeopt.pike:876:    " C%sR(n)->current_file->str,\n"    " (long)C%sR(n)->line_number);\n"    " }\n"    "#endif /* PIKE_DEBUG */\n"    "c->lex.current_line = C%sR(n)->line_number;\n"    "c->lex.current_file = C%sR(n)->current_file;\n",    linepos[0], linepos[0], linepos[0], linepos[0]) +    action;    }    -  action = sprintf("#ifdef PIKE_DEBUG\n" -  " if (l_flag > 4) {\n" -  " fprintf(stderr, \"Match: \"%O\"\\n\");\n" -  " }\n" -  "#endif /* PIKE_DEBUG */\n", sprintf("%s", n)) + +  action = sprintf("DBG(\"Match: \"%O\"\\n\");\n", sprintf("%s", n)) +    action;       n->action = action;       eat_whitespace();    expect(';');    eat_whitespace();    }   }   
pike.git/bin/mktreeopt.pike:928:   constant NULL_CDR = 2;   constant MATCH_CAR = 3;   constant NOT_NULL_CAR = 4;   constant EXACT_CDR = 5;   constant MATCH_CDR = 6;   constant NOT_NULL_CDR = 7;   constant ANY = 8;   constant ANY_CAR = 9;   constant ANY_CDR = 10;    - static int label_cnt; + protected int label_cnt;      int debug;      string generate_match(array(object(node)) rule_set, string indent)   {    string res = "";       if (debug) {    werror(indent + sprintf("generate_match(%s)\n",    rule_set->_sprintf() * ", "));
pike.git/bin/mktreeopt.pike:1055:    foreach(node_classes[EXACT_CAR], object(node) n) {    exacts[n->car] += ({ n });    }    zap_car(node_classes[EXACT_CAR]);    foreach(indices(exacts), string expr) {    if (last_was_if) {    res += " else ";    } else {    res += indent;    } -  res += -  sprintf("if ((CA%sR(n) == %s)\n" -  "#ifdef SHARED_NODES_MK2\n" + indent + -  " || (CA%sR(n) && %s &&\n" + indent + -  " ((CA%sR(n)->master?CA%sR(n)->master:CA%sR(n))==\n" + -  indent + " (%s->master?%s->master:%s)))\n" -  "#endif /* SHARED_NODES_MK2 */\n" + -  indent + " ) {\n", -  tpos, expr, -  tpos, expr, -  tpos, tpos, tpos, -  expr, expr, expr); +  res += sprintf("if (CA%sR(n) == %s) {\n", tpos, expr);    res += generate_match(exacts[expr], indent + " ");    res += indent + "}";    }    res += "\n";    last_was_if = 0;    }       if (sizeof(node_classes[NULL_CDR]) ||    sizeof(node_classes[MATCH_CDR]) ||    sizeof(node_classes[NOT_NULL_CDR])) {
pike.git/bin/mktreeopt.pike:1120:    res += indent;    }    res += "{\n";    indent += " ";    last_was_if = 0;    mapping(string:array(object(node))) exacts = ([]);    foreach(node_classes[EXACT_CDR], object(node) n) {    exacts[n->cdr] += ({ n });    }    zap_cdr(node_classes[EXACT_CDR]); -  foreach(indices(exacts), string expr) { +  foreach(sort(indices(exacts)), string expr) {    if (last_was_if) {    res += " else ";    } else {    res += indent;    } -  res+= -  sprintf("if ((CD%sR(n) == %s)\n" -  "#ifdef SHARED_NODES_MK2\n" + indent + -  " || (CD%sR(n) && %s &&\n" + indent + -  " ((CD%sR(n)->master?CD%sR(n)->master:CD%sR(n))==\n" + -  indent + " (%s->master?%s->master:%s)))\n" -  "#endif /* SHARED_NODES_MK2 */\n" + -  indent + " ) {\n", -  tpos, expr, -  tpos, expr, -  tpos, tpos, tpos, -  expr, expr, expr); +  res += sprintf("if (CD%sR(n) == %s) {\n", tpos, expr);    res += generate_match(exacts[expr], indent + " ");    res += indent + "}";    }    res += "\n";    last_was_if = 0;    }       if (sizeof(node_classes[MATCH_CAR]) || sizeof(node_classes[NOT_NULL_CAR]) ||    sizeof(node_classes[MATCH_CDR]) || sizeof(node_classes[NOT_NULL_CDR])) {    if (last_was_if) {
pike.git/bin/mktreeopt.pike:1326:    fname = argv[1];       if (fname[sizeof(fname)-3..] != ".in") {    fail("Filename %O doesn't end with \".in\"\n", fname);    }       data = Stdio.File(fname, "r")->read();       parse_data();    -  foreach(values(rules), array(object(node)) nodes) { +  foreach(indices(rules), string rule) { +  array(object(node)) nodes = rules[rule];    foreach(nodes, object(node) n) {    generate_parent(n , 0, "");    }    }       string result = sprintf(header, fname) + generate_code();       object(Stdio.File) dest = Stdio.File();       fname = fname[..sizeof(fname)-4] + ".h";       if ((!dest->open(fname, "wct")) ||    (dest->write(result) != sizeof(result))) {    fail("Failed to write file %O\n", fname);    }    exit(0);   }