00001
00002
00003 #include "ptree_util.h"
00004 #include "ptree_util_i.h"
00005
00006
00007 #line 94 "ptree_util.cpp"
00008 static Ptree*
00009 do_function(Ptree* lhs, Ptree* lpar, Ptree* args, Ptree* rpar);
00010
00011 #line 48 "ptree_util.cpp"
00012
00013 void
00014 flatten_specifier_list(Ptree* tree, std::vector<Ptree*>* nodes)
00015 {
00016 Flat_maker(nodes).visit(tree);
00017 }
00018
00019 #line 54 "ptree_util.cpp"
00020
00021 void
00022 flatten_ptree(Ptree* tree, std::vector<Ptree*>* nodes)
00023 {
00024 if (!tree) {
00025
00026 } else if (tree->IsLeaf()) {
00027 nodes->push_back(tree);
00028 } else {
00029 while (tree) {
00030 flatten_ptree(tree->Car(), nodes);
00031 tree = tree->Cdr();
00032 }
00033 }
00034 }
00035
00036 #line 69 "ptree_util.cpp"
00037
00040 bool
00041 ptree_is_name(Ptree* tree)
00042 {
00043 return tree->IsA(ntName) || dynamic_cast<LeafName*>(tree);
00044 }
00045
00046 #line 77 "ptree_util.cpp"
00047
00052 Ptree*
00053 convert_comma_expr_to_list(Ptree* input)
00054 {
00055 Ptree* out = 0;
00056 while (PtreeCommaExpr* cx = dynamic_cast<PtreeCommaExpr*>(input)) {
00057 out = Ptree::Cons(cx->Second(), Ptree::Cons(cx->Third(), out));
00058 input = cx->First();
00059 }
00060 out = Ptree::Cons(input, out);
00061 return out;
00062 }
00063
00064 #line 93 "ptree_util.cpp"
00065
00066 static Ptree*
00067 do_function(Ptree* lhs, Ptree* lpar, Ptree* args, Ptree* rpar)
00068 {
00069 Ptree* args_in = args;
00070 Ptree* args_out = 0;
00071 for (Ptree* p = args_in; p != 0; p = p->Cdr()) {
00072 if (p->Car()->Eq(',')) {
00073 args_out = Ptree::Snoc(args_out, p->Car());
00074 } else {
00075 Ptree* pair = p->Car();
00076 assert(pair->Length() == 2);
00077 args_out = Ptree::Snoc(args_out, convert_decl_to_expr(pair->First(), pair->Second()));
00078 }
00079 }
00080 return new PtreeFuncallExpr(lhs, Ptree::List(lpar, args_out, rpar));
00081 }
00082
00083 #line 110 "ptree_util.cpp"
00084
00085 Ptree*
00086 convert_node_to_name(Ptree* p)
00087 {
00088 if (p->IsLeaf()) {
00089 Token tmp_tok = { p->GetPosition(), p->GetLength(), ntName };
00090 return new LeafName(tmp_tok);
00091 } else {
00092 Encoding tmp_enc;
00093 return new PtreeName(p, tmp_enc);
00094 }
00095 }
00096
00097 #line 122 "ptree_util.cpp"
00098
00101 Ptree*
00102 convert_decl_to_expr(Ptree* lhs, Ptree* rhs)
00103 {
00104
00105
00106
00107
00108 lhs = convert_node_to_name(lhs);
00109
00110
00111 std::vector<Ptree*> binop_list;
00112
00113 Ptree* dlist = rhs;
00114 while (dlist && dlist->Car()) {
00115 Ptree* ele = dlist->Car();
00116 if (ele->Eq('*') || ele->Eq('&')) {
00117
00118 if (!dlist->Cdr() || !dlist->Second())
00119 compile_error("don't understand this expression");
00120 Ptree* name = dlist->Second();
00121 if (name->IsLeaf() &&
00122 (name->Eq('(') || name->Eq('[') || name->Eq(':') || name->Eq('=') || name->Eq('*') || name->Eq(')')
00123 || name->IsA(CONST) || name->IsA(VOLATILE) || name->Eq("restrict")))
00124 compile_error("don't understand this expression");
00125
00126 binop_list.push_back(lhs);
00127 binop_list.push_back(ele);
00128 lhs = convert_node_to_name(name);
00129 dlist = dlist->Cdr()->Cdr();
00130 } else if (ele->Eq('[')) {
00131
00132 expect_ptree(dlist->Third(), ']');
00133 if (!dlist->Second())
00134 compile_error("don't understand this array expression");
00135 lhs = new PtreeArrayExpr(lhs,
00136 Ptree::List(ele,
00137 dlist->Second(),
00138 dlist->Third()));
00139 dlist = dlist->Cdr()->Cdr()->Cdr();
00140 } else if (ele->Eq('(')) {
00141
00142 expect_ptree(dlist->Third(), ')');
00143 lhs = do_function(lhs, ele, dlist->Second(), dlist->Third());
00144 dlist = dlist->Cdr()->Cdr()->Cdr();
00145 } else if (!ele->IsLeaf() && ele->Car()->Eq('(')) {
00146
00147 expect_ptree(ele->Third(), ')');
00148 lhs = do_function(lhs, ele->Car(), ele->Second(), ele->Third());
00149 dlist = dlist->Cdr();
00150 } else {
00151 dlist->Display();
00152 compile_error("don't understand this funky expression");
00153 }
00154 }
00155
00156
00157 while (!binop_list.empty()) {
00158 Ptree* op = binop_list.back(); binop_list.pop_back();
00159 Ptree* arg = binop_list.back(); binop_list.pop_back();
00160 lhs = new PtreeInfixExpr(arg, Ptree::List(op, lhs));
00161 }
00162 return lhs;
00163 }