📄 gbc_trans_ctrl.c
字号:
boolean is_until; if (type == RS_LOOP) control_check(RS_DO, "LOOP without DO", "Unexpected LOOP"); else if (type == RS_UNTIL) control_check(RS_REPEAT, "UNTIL without REPEAT", "Unexpected UNTIL"); else if (type == RS_WEND) control_check(RS_WHILE, "WEND without WHILE", "Unexpected WEND"); control_jump_each_pos_with(current_ctrl->pos_continue); is_until = PATTERN_is(*JOB->current, RS_UNTIL); if ((type != RS_WEND) && (PATTERN_is(*JOB->current, RS_WHILE) || is_until)) { JOB->current++; TRANS_expression(FALSE); pos = CODE_get_current_pos(); if (is_until) CODE_jump_if_false(); else CODE_jump_if_true(); CODE_jump_length(pos, control_get_value()); } else { pos = CODE_get_current_pos(); CODE_jump(); CODE_jump_length(pos, control_get_value()); } control_jump_each_pos(); control_leave();}PRIVATE void trans_select_break(boolean do_not_add_pos){ if (current_ctrl->value) { if (!do_not_add_pos) { control_add_current_pos(); CODE_jump(); } CODE_jump_length(current_ctrl->value, CODE_get_current_pos()); }}PUBLIC void TRANS_select(void){ control_enter(RS_SELECT); if (PATTERN_is(*JOB->current, RS_CASE)) JOB->current++; TRANS_expression(FALSE); CODE_pop_ctrl(current_ctrl->local);}PUBLIC void TRANS_case(void){ int i; short pos; short local; control_check(RS_SELECT, "CASE without SELECT", "Unexpected CASE"); trans_select_break(FALSE); local = current_ctrl->local; control_enter(RS_CASE); for(i = 0; ; i++) { if (i > MAX_CASE_EXPR) THROW("Too many expressions in CASE"); /*CODE_dup(); TRANS_expression(FALSE); CODE_op(C_EQ, 2);*/ TRANS_expression(FALSE); CODE_push_local(local); CODE_op(C_EQ, 2, TRUE); if (!PATTERN_is(*JOB->current, RS_COMMA)) { pos = CODE_get_current_pos(); CODE_jump_if_false(); break; } control_add_current_pos(); CODE_jump_if_true(); JOB->current++; } control_jump_each_pos(); control_leave(); current_ctrl->value = pos;}PUBLIC void TRANS_default(void){ control_check(RS_SELECT, "DEFAULT without SELECT", "Unexpected DEFAULT"); trans_select_break(FALSE); current_ctrl->value = 0; /*CODE_get_current_pos();*/}PUBLIC void TRANS_end_select(void){ control_check(RS_SELECT, "END SELECT without SELECT", "Unexpected END SELECT"); /* if (current_ctrl->value) CODE_jump_length(current_ctrl->value, CODE_get_current_pos()); */ trans_select_break(TRUE); control_jump_each_pos(); control_leave();}PUBLIC void TRANS_break(void){ TRANS_CTRL *ctrl_inner = control_get_inner(); if (!ctrl_inner) THROW("Unexpected BREAK"); control_add_pos(&ctrl_inner->pos_break, CODE_get_current_pos()); CODE_jump();}PUBLIC void TRANS_continue(void){ TRANS_CTRL *ctrl_inner = control_get_inner(); if (!ctrl_inner) THROW("Unexpected CONTINUE"); control_add_pos(&ctrl_inner->pos_continue, CODE_get_current_pos()); CODE_jump();}PUBLIC void TRANS_return(void){ if (FUNCTION_is_procedure(JOB->func)) { if (!(PATTERN_is_newline(*JOB->current) || PATTERN_is_end(*JOB->current))) THROW("Cannot return a value in a procedure"); } if (PATTERN_is_newline(*JOB->current) || PATTERN_is_end(*JOB->current)) CODE_return(0); else { TRANS_expression(FALSE); CODE_return(1); }}PUBLIC void TRANS_for(void){ PATTERN *loop_var; short local; control_enter(RS_FOR); loop_var = JOB->current; TRANS_affectation(); if (!CODE_check_pop_local_last(&local)) THROW("`FOR' variable must be local"); control_check_loop_var(local); TRANS_want(RS_TO, "TO"); TRANS_expression(FALSE); if (PATTERN_is(*JOB->current, RS_STEP)) { JOB->current++; TRANS_expression(FALSE); } else { CODE_push_number(1); } /*CODE_pop_ctrl(current_ctrl->local + 1); CODE_pop_ctrl(current_ctrl->local);*/ if (!PATTERN_is_newline(*JOB->current)) THROW("Syntax error. End of line expected"); CODE_jump_first(current_ctrl->local); control_set_value(CODE_get_current_pos()); /* current = JOB->current; JOB->current = loop_var; TRANS_expression(FALSE); JOB->current = current; */ control_add_current_pos(); CODE_jump_next(); CODE_pop_local(local); /* current = JOB->current; JOB->current = loop_var; TRANS_expression(FALSE); if (!CODE_popify_last()) ERROR_panic("Cannot popify FOR expression ??"); JOB->current = current; */}PUBLIC void TRANS_for_each(void){ PATTERN *iterator = JOB->current; PATTERN *save; bool var = TRUE; while (!PATTERN_is(*JOB->current, RS_IN)) { if (PATTERN_is_newline_end(*JOB->current)) { JOB->current = iterator; var = FALSE; break; } JOB->current++; } control_enter(RS_EACH); if (var) JOB->current++; TRANS_expression(FALSE); /*CODE_pop_ctrl(current_ctrl->local);*/ CODE_first(current_ctrl->local); control_set_value(CODE_get_current_pos()); control_add_current_pos(); if (var) { CODE_next(FALSE); save = JOB->current; JOB->current = iterator; TRANS_expression(FALSE); if (!CODE_popify_last()) THROW("Invalid assignment"); JOB->current = save; } else CODE_next(TRUE); return;}PUBLIC void TRANS_next(void){ ushort pos; control_check_two(RS_FOR, RS_EACH, "`Next' without `For'", "Unexpected `Next'"); /* if (current_ctrl->type == RS_FOR) { control_jump_each_pos_with(current_ctrl->pos_continue); pos = CODE_get_current_pos(); CODE_jump(); CODE_jump_length(pos, control_get_value()); control_jump_each_pos(); control_leave(); } else { */ control_jump_each_pos_with(current_ctrl->pos_continue); pos = CODE_get_current_pos(); CODE_jump(); CODE_jump_length(pos, control_get_value()); control_jump_each_pos(); control_leave();}PUBLIC void TRANS_try(void){ ushort pos; pos = CODE_get_current_pos(); CODE_try(); TRANS_statement(); CODE_jump_length(pos, CODE_get_current_pos()); CODE_end_try();}PUBLIC void TRANS_finally(void){ ushort pos = CODE_get_current_pos(); if ((JOB->func->finally != 0) || (JOB->func->catch != 0) || (pos == 0)) THROW("Unexpected `Finally'"); JOB->func->finally = pos;}PUBLIC void TRANS_catch(void){ ushort pos = CODE_get_current_pos(); if ((JOB->func->catch != 0) || (pos == 0)) THROW("Unexpected `Catch'"); CODE_catch(); JOB->func->catch = CODE_get_current_pos();}PUBLIC void TRANS_label(void){ CLASS_SYMBOL *sym; long sym_index; TRANS_LABEL *label; sym_index = PATTERN_index(*JOB->current); JOB->current++; sym = CLASS_declare(JOB->class, sym_index, FALSE); if (label_info == NULL) ARRAY_create(&label_info); sym->local.type = TYPE_make(T_NULL, 0L, TK_LABEL); sym->local.value = ARRAY_count(label_info); label = ARRAY_add(&label_info); label->index = sym_index; label->ctrl_id = (ctrl_level == 0) ? 0 : current_ctrl->id; label->pos = CODE_get_current_pos(); #ifdef DEBUG_GOTO printf("TRANS_label: %.*s ctrl_id = %d\n", sym->symbol.len, sym->symbol.name, label->ctrl_id); #endif /* on saute le ':' */ JOB->current++;}PUBLIC void TRANS_with(void){ control_enter(RS_WITH); TRANS_expression(FALSE); CODE_pop_ctrl(current_ctrl->local);}PUBLIC void TRANS_use_with(void){ TRANS_CTRL *ctrl_inner = control_get_inner_with(); if (ctrl_inner == NULL) THROW("Syntax Error. Point syntax used outside of WITH / END WITH"); CODE_push_local(ctrl_inner->local);}PUBLIC void TRANS_end_with(void){ control_check(RS_WITH, "END WITH without WITH", "Unexpected END WITH"); control_leave();}PUBLIC void TRANS_raise(void){ CLASS_SYMBOL *sym; int np; if (!PATTERN_is_identifier(*JOB->current)) THROW("Syntax error in event name"); sym = CLASS_get_symbol(JOB->class, PATTERN_index(*JOB->current)); JOB->current++; if (TYPE_get_kind(sym->global.type) != TK_EVENT) THROW("Syntax error in event name"); if (TYPE_is_static(JOB->func->type)) THROW("Cannot raise events in static function"); CODE_push_event(sym->global.value); np = 0; if (TRANS_is(RS_LBRA)) { for (;;) { if (TRANS_is(RS_RBRA)) break; if (np > 0) TRANS_want(RS_COMMA, "comma"); if (np >= MAX_PARAM_FUNC) THROW("Too many arguments"); TRANS_expression(FALSE); np++; } } CODE_call(np, FALSE); if (TRANS_is(RS_AS)) TRANS_reference(); else CODE_drop();}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -