static void ctrycatchfinally(JF, js_Ast *trystm, js_Ast *catchvar, js_Ast *catchstm, js_Ast *finallystm) { int L1, L2, L3; L1 = emitjump(J, F, OP_TRY); { /* if we get here, we have caught an exception in the try block */ L2 = emitjump(J, F, OP_TRY); { /* if we get here, we have caught an exception in the catch block */ cstm(J, F, finallystm); /* inline finally block */ emit(J, F, OP_THROW); /* rethrow exception */ } label(J, F, L2); if (J->strict) { if (!strcmp(catchvar->string, "arguments")) jsC_error(J, catchvar, "redefining 'arguments' is not allowed in strict mode"); if (!strcmp(catchvar->string, "eval")) jsC_error(J, catchvar, "redefining 'eval' is not allowed in strict mode"); } emitstring(J, F, OP_CATCH, catchvar->string); cstm(J, F, catchstm); emit(J, F, OP_ENDCATCH); L3 = emitjump(J, F, OP_JUMP); /* skip past the try block to the finally block */ } label(J, F, L1); cstm(J, F, trystm); emit(J, F, OP_ENDTRY); label(J, F, L3); cstm(J, F, finallystm); }
static void cexit(JF, enum js_AstType T, js_Ast *node, js_Ast *target) { js_Ast *prev; do { prev = node, node = node->parent; switch (node->type) { default: /* impossible */ break; case STM_WITH: emit(J, F, OP_ENDWITH); break; case STM_FOR_IN: case STM_FOR_IN_VAR: /* pop the iterator if leaving the loop */ if (F->script) { if (T == STM_RETURN || T == STM_BREAK || (T == STM_CONTINUE && target != node)) { /* pop the iterator, save the return or exp value */ emit(J, F, OP_ROT2); emit(J, F, OP_POP); } if (T == STM_CONTINUE) emit(J, F, OP_ROT2); /* put the iterator back on top */ } else { if (T == STM_RETURN) { /* pop the iterator, save the return value */ emit(J, F, OP_ROT2); emit(J, F, OP_POP); } if (T == STM_BREAK || (T == STM_CONTINUE && target != node)) emit(J, F, OP_POP); /* pop the iterator */ } break; case STM_TRY: /* came from try block */ if (prev == node->a) { emit(J, F, OP_ENDTRY); if (node->d) cstm(J, F, node->d); /* finally */ } /* came from catch block */ if (prev == node->c) { /* ... with finally */ if (node->d) { emit(J, F, OP_ENDCATCH); emit(J, F, OP_ENDTRY); cstm(J, F, node->d); /* finally */ } else { emit(J, F, OP_ENDCATCH); } } break; } } while (node != target); }
static void ctryfinally(JF, js_Ast *trystm, js_Ast *finallystm) { int L1; L1 = emitjump(J, F, OP_TRY); { /* if we get here, we have caught an exception in the try block */ cstm(J, F, finallystm); /* inline finally block */ emit(J, F, OP_THROW); /* rethrow exception */ } label(J, F, L1); cstm(J, F, trystm); emit(J, F, OP_ENDTRY); cstm(J, F, finallystm); }
static void cstmlist(JF, js_Ast *list) { while (list) { cstm(J, F, list->a); list = list->b; } }
static void ctrycatch(JF, js_Ast *trystm, js_Ast *catchvar, js_Ast *catchstm) { int L1, L2; L1 = emitjump(J, F, OP_TRY); { /* if we get here, we have caught an exception in the try block */ emitstring(J, F, OP_CATCH, catchvar->string); cstm(J, F, catchstm); emit(J, F, OP_ENDCATCH); L2 = emitjump(J, F, OP_JUMP); /* skip past the try block */ } label(J, F, L1); cstm(J, F, trystm); emit(J, F, OP_ENDTRY); label(J, F, L2); }
static void ctrycatchfinally(JF, js_Ast *trystm, js_Ast *catchvar, js_Ast *catchstm, js_Ast *finallystm) { int L1, L2, L3; L1 = emitjump(J, F, OP_TRY); { /* if we get here, we have caught an exception in the try block */ L2 = emitjump(J, F, OP_TRY); { /* if we get here, we have caught an exception in the catch block */ cstm(J, F, finallystm); /* inline finally block */ emit(J, F, OP_THROW); /* rethrow exception */ } label(J, F, L2); emitstring(J, F, OP_CATCH, catchvar->string); cstm(J, F, catchstm); emit(J, F, OP_ENDCATCH); L3 = emitjump(J, F, OP_JUMP); /* skip past the try block to the finally block */ } label(J, F, L1); cstm(J, F, trystm); emit(J, F, OP_ENDTRY); label(J, F, L3); cstm(J, F, finallystm); }
tree collect_metadata_svmono (tree t) { int i, n=N(t); tree u, r (CONCAT); tree doc_data (APPLY, "\\doc-data"); tree abstract_data (APPLY, "\\abstract-data"); array<tree> doc_notes; array<tree> tmp= collect_metadata_latex (t); for (i=0; i<N(tmp); i++) { if (is_apply (tmp[i], "\\doc-data")) doc_data= tmp[i]; if (is_apply (tmp[i], "\\abstract-data")) abstract_data= tmp[i]; } for (i=0; i<n; i++) { u= t[i]; if (is_tuple (u, "\\subtitle", 1)) { get_springer_title_notes (u[1], doc_notes); doc_data << tree (APPLY, "\\doc-subtitle", cstm (u[1])); } } if (N(doc_notes) > 0) doc_data << doc_notes; if (N(doc_data) > 1) r << doc_data << "\n"; if (N(abstract_data) > 1) r << abstract_data << "\n"; return r; }
static void cstm(JF, js_Ast *stm) { js_Ast *target; int loop, cont, then, end; emitline(J, F, stm); switch (stm->type) { case AST_FUNDEC: break; case STM_BLOCK: cstmlist(J, F, stm->a); break; case STM_EMPTY: if (F->script) { emit(J, F, OP_POP); emit(J, F, OP_UNDEF); } break; case STM_VAR: cvarinit(J, F, stm->a); break; case STM_IF: if (stm->c) { cexp(J, F, stm->a); then = emitjump(J, F, OP_JTRUE); cstm(J, F, stm->c); end = emitjump(J, F, OP_JUMP); label(J, F, then); cstm(J, F, stm->b); label(J, F, end); } else { cexp(J, F, stm->a); end = emitjump(J, F, OP_JFALSE); cstm(J, F, stm->b); label(J, F, end); } break; case STM_DO: loop = here(J, F); cstm(J, F, stm->a); cont = here(J, F); cexp(J, F, stm->b); emitjumpto(J, F, OP_JTRUE, loop); labeljumps(J, F, stm->jumps, here(J,F), cont); break; case STM_WHILE: loop = here(J, F); cexp(J, F, stm->a); end = emitjump(J, F, OP_JFALSE); cstm(J, F, stm->b); emitjumpto(J, F, OP_JUMP, loop); label(J, F, end); labeljumps(J, F, stm->jumps, here(J,F), loop); break; case STM_FOR: case STM_FOR_VAR: if (stm->type == STM_FOR_VAR) { cvarinit(J, F, stm->a); } else { if (stm->a) { cexp(J, F, stm->a); emit(J, F, OP_POP); } } loop = here(J, F); if (stm->b) { cexp(J, F, stm->b); end = emitjump(J, F, OP_JFALSE); } else { end = 0; } cstm(J, F, stm->d); cont = here(J, F); if (stm->c) { cexp(J, F, stm->c); emit(J, F, OP_POP); } emitjumpto(J, F, OP_JUMP, loop); if (end) label(J, F, end); labeljumps(J, F, stm->jumps, here(J,F), cont); break; case STM_FOR_IN: case STM_FOR_IN_VAR: cexp(J, F, stm->b); emit(J, F, OP_ITERATOR); loop = here(J, F); { emit(J, F, OP_NEXTITER); end = emitjump(J, F, OP_JFALSE); cassignforin(J, F, stm); if (F->script) { emit(J, F, OP_ROT2); cstm(J, F, stm->c); emit(J, F, OP_ROT2); } else { cstm(J, F, stm->c); } emitjumpto(J, F, OP_JUMP, loop); } label(J, F, end); labeljumps(J, F, stm->jumps, here(J,F), loop); break; case STM_SWITCH: cswitch(J, F, stm->a, stm->b); labeljumps(J, F, stm->jumps, here(J,F), 0); break; case STM_LABEL: cstm(J, F, stm->b); /* skip consecutive labels */ while (stm->type == STM_LABEL) stm = stm->b; /* loops and switches have already been labelled */ if (!isloop(stm->type) && stm->type != STM_SWITCH) labeljumps(J, F, stm->jumps, here(J,F), 0); break; case STM_BREAK: if (stm->a) { target = breaktarget(J, F, stm, stm->a->string); if (!target) jsC_error(J, stm, "break label '%s' not found", stm->a->string); } else { target = breaktarget(J, F, stm, NULL); if (!target) jsC_error(J, stm, "unlabelled break must be inside loop or switch"); } cexit(J, F, STM_BREAK, stm, target); addjump(J, F, STM_BREAK, target, emitjump(J, F, OP_JUMP)); break; case STM_CONTINUE: if (stm->a) { target = continuetarget(J, F, stm, stm->a->string); if (!target) jsC_error(J, stm, "continue label '%s' not found", stm->a->string); } else { target = continuetarget(J, F, stm, NULL); if (!target) jsC_error(J, stm, "continue must be inside loop"); } cexit(J, F, STM_CONTINUE, stm, target); addjump(J, F, STM_CONTINUE, target, emitjump(J, F, OP_JUMP)); break; case STM_RETURN: if (stm->a) cexp(J, F, stm->a); else emit(J, F, OP_UNDEF); target = returntarget(J, F, stm); if (!target) jsC_error(J, stm, "return not in function"); cexit(J, F, STM_RETURN, stm, target); emit(J, F, OP_RETURN); break; case STM_THROW: cexp(J, F, stm->a); emit(J, F, OP_THROW); break; case STM_WITH: cexp(J, F, stm->a); emit(J, F, OP_WITH); cstm(J, F, stm->b); emit(J, F, OP_ENDWITH); break; case STM_TRY: if (stm->b && stm->c) { if (stm->d) ctrycatchfinally(J, F, stm->a, stm->b, stm->c, stm->d); else ctrycatch(J, F, stm->a, stm->b, stm->c); } else { ctryfinally(J, F, stm->a, stm->d); } break; case STM_DEBUGGER: emit(J, F, OP_DEBUGGER); break; default: if (F->script) { emit(J, F, OP_POP); cexp(J, F, stm); } else { cexp(J, F, stm); emit(J, F, OP_POP); } break; } }
tree collect_metadata_springer (tree t, bool llncs) { int i, n=N(t); tree u, r (CONCAT); tree doc_data (APPLY, "\\doc-data"); tree abstract_data (APPLY, "\\abstract-data"); array<tree> doc_notes, author_datas, author_affs; for (i=0; i<n; i++) { u= t[i]; if (is_tuple (u, "\\dedication", 1)) doc_notes << tree (APPLY, "\\doc-note", concat ("Dedication: ", u[1])); else if (is_tuple (u, "\\date", 1)) doc_data << tree (APPLY, "\\doc-date", u[1]); else if (is_tuple (u, "\\title", 1)) { get_springer_title_notes (u[1], doc_notes); doc_data << tree (APPLY, "\\doc-title", cstm (u[1])); } else if (is_tuple (u, "\\subtitle", 1)) { get_springer_title_notes (u[1], doc_notes); doc_data << tree (APPLY, "\\doc-subtitle", cstm (u[1])); } else if (is_tuple (u, "\\author", 1)) author_datas << get_springer_author_datas (u[1], "name", llncs); else if (!llncs && is_tuple (u, "\\institute", 1)) author_affs << get_springer_affiliation_datas (u[1]); else if (llncs && is_tuple (u, "\\institute", 1)) author_affs << get_llncs_affiliation_datas (u[1]); else if (is_tuple (u, "\\begin-abstract")) { tree abstract_text (CONCAT); i++; while (i<n && !is_tuple (t[i], "\\end-abstract")) { u= t[i]; if (is_tuple (u, "\\keywords", 1)) translate_springer_abstract_data (u, "keywords", abstract_data); else if (is_tuple (u, "\\tmmsc") || is_tuple (u, "\\tmarxiv") || is_tuple (u, "\\tmacm") || is_tuple (u, "\\tmpacs")) abstract_data << collect_abstract_data (u); else abstract_text << u; i++; } abstract_data << tree (APPLY, "\\abstract", abstract_text); } else if (is_tuple (u, "\\keywords", 1)) translate_springer_abstract_data (u, "keywords", abstract_data); else if (is_tuple (u, "\\subclass", 1)) translate_springer_abstract_data (u, "msc", abstract_data); else if (is_tuple (u, "\\PACS", 1)) translate_springer_abstract_data (u, "pacs", abstract_data); else if (is_tuple (u, "\\CRclass", 1)) translate_springer_abstract_data (u, "acm", abstract_data); else if (is_tuple (u, "\\tmarxiv")) abstract_data << collect_abstract_data (u); } bool spaced= false; if (llncs) { author_datas= merge_llncs_author_datas (author_datas, author_affs); } else { author_datas << author_affs; author_datas= filter_spaces (author_datas, spaced); author_datas= merge_springer_author_datas (author_datas); } for (int j=0; j<N(author_datas); j++) author_datas[j]= tree (APPLY, "\\doc-author", author_datas[j]); if (N(author_datas) > 0) doc_data << author_datas; if (N(doc_notes) > 0) doc_data << doc_notes; if (N(doc_data) > 1) r << doc_data << "\n"; if (N(abstract_data) > 1) r << abstract_data << "\n"; return r; }