import ARYITER_TAG.patch from refcount branch
[nedit-bw.git] / switch-statement.patch
blob1cd648edeca3fd44e641370f2d974992ab6d1921
1 ---
3 source/highlightData.c | 2
4 source/parse.y | 169 ++++++++++++++++++++++++++++++++++++++++++++++++-
5 2 files changed, 169 insertions(+), 2 deletions(-)
7 diff --quilt old/source/highlightData.c new/source/highlightData.c
8 --- old/source/highlightData.c
9 +++ new/source/highlightData.c
10 @@ -558,7 +558,7 @@ static char *DefaultPatternSets[] = {
11 Menu Actions:\"<(?:new(?:_tab|_opposite)?|open|open-dialog|open_dialog|open-selected|open_selected|close|save|save-as|save_as|save-as-dialog|save_as_dialog|revert-to-saved|revert_to_saved|revert_to_saved_dialog|include-file|include_file|include-file-dialog|include_file_dialog|load-macro-file|load_macro_file|load-macro-file-dialog|load_macro_file_dialog|load-tags-file|load_tags_file|load-tags-file-dialog|load_tags_file_dialog|unload_tags_file|load_tips_file|load_tips_file_dialog|unload_tips_file|print|print-selection|print_selection|exit|undo|redo|delete|select-all|select_all|shift-left|shift_left|shift-left-by-tab|shift_left_by_tab|shift-right|shift_right|shift-right-by-tab|shift_right_by_tab|find|find-dialog|find_dialog|find-again|find_again|find-selection|find_selection|find_incremental|start_incremental_find|replace|replace-dialog|replace_dialog|replace-all|replace_all|replace-in-selection|replace_in_selection|replace-again|replace_again|replace_find|replace_find_same|replace_find_again|goto-line-number|goto_line_number|goto-line-number-dialog|goto_line_number_dialog|goto-selected|goto_selected|mark|mark-dialog|mark_dialog|goto-mark|goto_mark|goto-mark-dialog|goto_mark_dialog|match|select_to_matching|goto_matching|find-definition|find_definition|show_tip|split-pane|split_pane|close-pane|close_pane|detach_document(?:_dialog)?|move_document_dialog|(?:next|previous|last)_document|uppercase|lowercase|fill-paragraph|fill_paragraph|control-code-dialog|control_code_dialog|filter-selection-dialog|filter_selection_dialog|filter-selection|filter_selection|execute-command|execute_command|execute-command-dialog|execute_command_dialog|execute-command-line|execute_command_line|shell-menu-command|shell_menu_command|macro-menu-command|macro_menu_command|bg_menu_command|post_window_bg_menu|post_tab_context_menu|beginning-of-selection|beginning_of_selection|end-of-selection|end_of_selection|repeat_macro|repeat_dialog|raise_window|focus_pane|set_statistics_line|set_incremental_search_line|set_show_line_numbers|set_auto_indent|set_wrap_text|set_wrap_margin|set_highlight_syntax|set_make_backup_copy|set_incremental_backup|set_show_matching|set_match_syntax_based|set_overtype_mode|set_locked|set_tab_dist|set_em_tab_dist|set_use_tabs|set_fonts|set_language_mode)(?=\\s*\\()\":::Subroutine::\n\
12 Text Actions:\"<(?:self-insert|self_insert|grab-focus|grab_focus|extend-adjust|extend_adjust|extend-start|extend_start|extend-end|extend_end|secondary-adjust|secondary_adjust|secondary-or-drag-adjust|secondary_or_drag_adjust|secondary-start|secondary_start|secondary-or-drag-start|secondary_or_drag_start|process-bdrag|process_bdrag|move-destination|move_destination|move-to|move_to|move-to-or-end-drag|move_to_or_end_drag|end_drag|copy-to|copy_to|copy-to-or-end-drag|copy_to_or_end_drag|exchange|process-cancel|process_cancel|paste-clipboard|paste_clipboard|copy-clipboard|copy_clipboard|cut-clipboard|cut_clipboard|copy-primary|copy_primary|cut-primary|cut_primary|newline|newline-and-indent|newline_and_indent|newline-no-indent|newline_no_indent|delete-selection|delete_selection|delete-previous-character|delete_previous_character|delete-next-character|delete_next_character|delete-previous-word|delete_previous_word|delete-next-word|delete_next_word|delete-to-start-of-line|delete_to_start_of_line|delete-to-end-of-line|delete_to_end_of_line|forward-character|forward_character|backward-character|backward_character|key-select|key_select|process-up|process_up|process-down|process_down|process-shift-up|process_shift_up|process-shift-down|process_shift_down|process-home|process_home|forward-word|forward_word|backward-word|backward_word|forward-paragraph|forward_paragraph|backward-paragraph|backward_paragraph|beginning-of-line|beginning_of_line|end-of-line|end_of_line|beginning-of-file|beginning_of_file|end-of-file|end_of_file|next-page|next_page|previous-page|previous_page|page-left|page_left|page-right|page_right|toggle-overstrike|toggle_overstrike|scroll-up|scroll_up|scroll-down|scroll_down|scroll_left|scroll_right|scroll-to-line|scroll_to_line|select-all|select_all|select_word|deselect-all|deselect_all|focusIn|focusOut|process-return|process_return|process-tab|process_tab|insert-string|insert_string|mouse_pan)(?=\\s*\\()\":::Subroutine::\n\
13 Macro Hooks:\"<(?:(?:pre|post)_(?:open|save)|cursor_moved|modified|(?:losing_)?focus)_hook(?=\\s*\\()\":::Subroutine1::\n\
14 - Keyword:\"<(?:break|continue|define|delete|do|else|finally|for|if|in|readonly|return|typeof|while)>\":::Keyword::\n\
15 + Keyword:\"<(?:break|case|continue|default|define|delete|do|else|finally|for|if|in|readonly|return|switch|typeof|while)>\":::Keyword::\n\
16 Braces:\"[{}\\[\\]]\":::Keyword::\n\
17 Global Variable:\"\\$[A-Za-z0-9_]+\":::Identifier1::\n\
18 String sq:\"'\":\"'\"::String::\n\
19 diff --quilt old/source/parse.y new/source/parse.y
20 --- old/source/parse.y
21 +++ new/source/parse.y
22 @@ -109,6 +109,61 @@ static int nextSymIsField = 0;
23 /* set to 1 when we don't want a full symbol, just a name (string) for a
24 field name following a '.' */
26 +#define PTRBLK_SIZE ((64 - sizeof(void *)) / sizeof(void *))
27 +typedef struct PtrBlkTag {
28 + void *ptrs[PTRBLK_SIZE];
29 + struct PtrBlkTag *next;
30 +} PtrBlk;
31 +typedef struct PtrListTag {
32 + PtrBlk *head, *tail;
33 + int nPtrs;
34 +} PtrList;
36 +#define PTRBLK_START(tgt) \
37 + do { \
38 + (tgt).head = (tgt).tail = NULL; \
39 + (tgt).nPtrs = 0; \
40 + } while (0)
42 +#define PTRBLK_CPY(tgt, src) \
43 + do { \
44 + (tgt).head = (src).head; \
45 + (tgt).tail = (src).tail; \
46 + (tgt).nPtrs = (src).nPtrs; \
47 + } while (0)
49 +#define PTRBLK_ADD(tgt, ptr) \
50 + do { \
51 + if ((tgt).nPtrs % PTRBLK_SIZE == 0) { \
52 + PtrBlk *ptrblk = malloc(sizeof(*ptrblk)); \
53 + ptrblk->next = NULL; \
54 + if ((tgt).head == NULL) { \
55 + (tgt).head = (tgt).tail = ptrblk; \
56 + } \
57 + else {\
58 + (tgt).tail->next = ptrblk; \
59 + (tgt).tail = ptrblk; \
60 + } \
61 + } \
62 + (tgt).tail->ptrs[(tgt).nPtrs % PTRBLK_SIZE] = (ptr); \
63 + (tgt).nPtrs++; \
64 + } while (0)
66 +#define PTRBLK_FORALL(src, ...) \
67 + do { \
68 + int i = 0; \
69 + while (i < (src).nPtrs) { \
70 + void *ptr = (src).head->ptrs[i % PTRBLK_SIZE]; \
71 + (__VA_ARGS__); \
72 + i++; \
73 + if (i % PTRBLK_SIZE == 0 || i == (src).nPtrs) { \
74 + PtrBlk *next = (src).head->next; \
75 + free((src).head); \
76 + (src).head = next; \
77 + } \
78 + } \
79 + } while (0)
83 %union {
84 @@ -117,12 +172,16 @@ static int nextSymIsField = 0;
85 const char *str;
86 enum operations oper;
87 AccumulatorData *acc;
88 + struct {
89 + PtrList plist;
90 + Inst *start;
91 + } cstmts;
93 %token <str> SYMBOL STRING FIELD
94 %token <num> NUMBER
95 %token DELETE ARG_LOOKUP
96 %token IF WHILE DO ELSE FOR BREAK CONTINUE RETURN DEFINE TYPEOF KEYVAL READONLY
97 -%token FINALLY
98 +%token FINALLY SWITCH CASE DEFAULT
99 %type <num> keyargs key keyopt catlist fnarglsopt fnarglist fnarg
100 %type <inst> cond branch for while do else and or mark
101 %type <str> evalsym
102 @@ -134,6 +193,8 @@ static int nextSymIsField = 0;
103 %type <inst> lventry
104 %token ARGSEP
105 %type <inst> thenx elsex thenelsex
106 +%type <inst> switch case switchcont
107 +%type <cstmts> casestmts
109 %nonassoc IF_NO_ELSE
110 %nonassoc ELSE
111 @@ -266,6 +327,32 @@ stmt: ';' blank
112 ADD_OP(OP_FINALIZE_LOOP);
115 + | switch '(' switchcont numexpr ')' '{' blank casestmts '}'
116 + blank {
117 + int i = 0;
118 + /* simulated break statement */
119 + ADD_OP(OP_PUSH_IMMED); ADD_IMMED(0);
120 + /* fill startLoop with endLoop addr */
121 + SET_BR_OFF($1, GetPC());
122 + /* continue is pop before numexpr */
123 + ADD_OP(OP_END_LOOP); ADD_BR_OFF($3);
124 + /* empty finally block */
125 + ADD_OP(OP_PEEK_POP); ADD_IMMED(2);
126 + ADD_OP(OP_FINALIZE_LOOP);
128 + /* clear casestmts plist */
129 + while (i < $8.plist.nPtrs) {
130 + void *ptr = $8.plist.head->ptrs[i % PTRBLK_SIZE];
131 + i++;
132 + if (i % PTRBLK_SIZE == 0 || i == $8.plist.nPtrs) {
133 + PtrBlk *next = $8.plist.head->next;
134 + free($8.plist.head);
135 + $8.plist.head = next;
141 | BREAK numexpropt stmtend blank {
142 ADD_OP(OP_BREAK_LOOP);
144 @@ -744,6 +831,8 @@ do: DO blank { START_LOOP($$); }
146 for: FOR blank { START_LOOP($$); }
148 +switch: SWITCH blank { START_LOOP($$); }
150 else: ELSE blank {
151 ADD_OP(OP_BRANCH); $$ = GetPC(); ADD_BR_OFF(0);
153 @@ -788,6 +877,69 @@ thenelsex: TE {
157 +dup: /* empty */ {
158 + ADD_OP(OP_DUP);
162 +case: CASE dup numexpr ':' blank {
163 + ADD_OP(OP_EQ);
164 + ADD_OP(OP_BRANCH_TRUE);
165 + $$ = GetPC(); ADD_BR_OFF(0);
167 + | DEFAULT ':' blank {
168 + ADD_OP(OP_BRANCH);
169 + $$ = GetPC(); ADD_BR_OFF(0);
173 +casestmts: case {
174 + $$.start = GetPC();
175 + PTRBLK_START($$.plist);
176 + PTRBLK_ADD($$.plist, $1);
177 + SET_BR_OFF($1, GetPC());
179 + | stmt {
180 + yyerror("statements before any case"); YYERROR;
182 + | casestmts mark case {
183 + int i;
184 + /* we move the cases by this number back */
185 + ptrdiff_t stmtsLen = $2 - $1.start;
186 + /* we move the previously stmts by this number forth */
187 + ptrdiff_t caseLen = GetPC() - $2;
188 + PtrBlk *curr;
189 + $$.plist = $1.plist;
191 + /* setup case */
192 + SET_BR_OFF($3, GetPC() + stmtsLen - caseLen);
193 + PTRBLK_ADD($$.plist, $3 - stmtsLen);
195 + /* move new case infront of all previously statements */
196 + $$.start = SwapCode($1.start, $2, GetPC());
198 + /* add the offset to all previously branch offsets */
199 + i = 0;
200 + curr = $$.plist.head;
201 + while (i < $$.plist.nPtrs) {
202 + Inst *br = $$.plist.head->ptrs[i % PTRBLK_SIZE];
203 + br->val.branch += caseLen;
204 + i++;
205 + if (i % PTRBLK_SIZE == 0 || i == $$.plist.nPtrs) {
206 + curr = curr->next;
210 + | casestmts stmt {
211 + $$.plist = $1.plist;
212 + $$.start = $1.start;
214 + | casestmts blockwb {
215 + $$.plist = $1.plist;
216 + $$.start = $1.start;
220 dot: '.' %prec '.' {
221 nextSymIsField = 1;
223 @@ -799,6 +951,18 @@ branch: /* nothing */ {
224 ADD_BR_OFF(0);
228 +** for continuing a switch, we need to pop the first expression from the stack,
229 +** but not for the first one, value is the continue address
231 +switchcont: /* nothing */ {
232 + ADD_OP(OP_BRANCH);
233 + ADD_BR_OFF(0);
234 + $$ = GetPC();
235 + ADD_OP(OP_POP);
236 + SET_BR_OFF($$ - 1, GetPC());
239 blank: /* nothing */
240 | blank '\n'
242 @@ -941,6 +1105,9 @@ static int yylex(void)
243 if (!strcmp(symName, "typeof")) return TYPEOF;
244 if (!strcmp(symName, "readonly")) return READONLY;
245 if (!strcmp(symName, "finally")) return FINALLY;
246 + if (!strcmp(symName, "switch")) return SWITCH;
247 + if (!strcmp(symName, "case")) return CASE;
248 + if (!strcmp(symName, "default")) return DEFAULT;
250 yylval.str = LookupString(symName, True);
251 if (nextSymIsField) {