2525
2626#if NGC_EXPRESSIONS_ENABLE
2727
28+ #include <math.h>
29+ #include <stdio.h>
2830#include <string.h>
2931
3032#include "errors.h"
3133#include "ngc_expr.h"
3234#include "ngc_params.h"
35+ #include "stream_file.h"
36+ //#include "string_registers.h"
3337
3438#ifndef NGC_STACK_DEPTH
3539#define NGC_STACK_DEPTH 20
@@ -193,6 +197,28 @@ static status_code_t read_command (char *line, uint_fast8_t *pos, ngc_cmd_t *ope
193197 return status ;
194198}
195199
200+ static ngc_sub_t * add_sub (uint32_t o_label , vfs_file_t * file )
201+ {
202+ ngc_sub_t * sub ;
203+
204+ if ((sub = malloc (sizeof (ngc_sub_t ))) != NULL ) {
205+ sub -> o_label = o_label ;
206+ sub -> file = file ;
207+ sub -> file_pos = vfs_tell (file );
208+ sub -> next = NULL ;
209+ if (subs == NULL )
210+ subs = sub ;
211+ else {
212+ ngc_sub_t * last = subs ;
213+ while (last -> next )
214+ last = last -> next ;
215+ last -> next = sub ;
216+ }
217+ }
218+
219+ return sub ;
220+ }
221+
196222static void clear_subs (vfs_file_t * file )
197223{
198224 ngc_sub_t * current = subs , * prev = NULL , * next ;
@@ -249,7 +275,10 @@ static void stack_unwind_sub (uint32_t o_label)
249275 stack_pull ();
250276
251277 if (stack_idx >= 0 ) {
252- vfs_seek (stack [stack_idx ].file , stack [stack_idx ].file_pos );
278+ if (o_label > NGC_MAX_PARAM_ID )
279+ stream_redirect_close (stack [stack_idx ].file );
280+ else
281+ vfs_seek (stack [stack_idx ].file , stack [stack_idx ].file_pos );
253282 stack_pull ();
254283 }
255284
@@ -272,6 +301,56 @@ void ngc_flowctrl_init (void)
272301 stack_pull ();
273302}
274303
304+ /*
305+
306+ static status_code_t onError (status_code_t status)
307+ {
308+ static bool closing = false;
309+
310+ if(stack_idx >= 0) {
311+
312+ uint32_t o_label = 0;
313+ ngc_sub_t *sub;
314+
315+ if((sub = subs)) do {
316+ if(sub->o_label > NGC_MAX_PARAM_ID)
317+ o_label = sub->o_label;
318+ } while((sub = sub->next));
319+
320+ if((sub = subs)) do {
321+ if(sub->o_label == o_label)
322+ break;
323+ } while((sub = sub->next));
324+
325+ if(sub) {
326+ if(!closing) {
327+ char msg[100];
328+ closing = true;
329+ char *name = string_register_get_by_id((string_register_id_t)sub->o_label);
330+ sprintf(msg, "error %d in named sub %s.macro", (uint8_t)status, name);
331+ report_message(msg, Message_Warning);
332+ }
333+
334+ sub->o_label = 1;
335+
336+ stream_redirect_close(sub->file);
337+ status = grbl.report.status_message(status);
338+ }
339+ closing = false;
340+ ngc_flowctrl_init();
341+ }
342+
343+ return status;
344+ }
345+
346+ static status_code_t onFileEnd (vfs_file_t *file, status_code_t status)
347+ {
348+ if(stack_idx >= 0 && stack[stack_idx].file == file)
349+ ngc_flowctrl_unwind_stack(file);
350+
351+ return status;
352+ }
353+ */
275354status_code_t ngc_flowctrl (uint32_t o_label , char * line , uint_fast8_t * pos , bool * skip )
276355{
277356 float value ;
@@ -346,13 +425,11 @@ status_code_t ngc_flowctrl (uint32_t o_label, char *line, uint_fast8_t *pos, boo
346425 if (last_op == NGCFlowCtrl_Do && o_label == stack [stack_idx ].o_label )
347426 stack_pull ();
348427 } else if (!skipping && (status = ngc_eval_expression (line , pos , & value )) == Status_OK ) {
349- if (last_op == NGCFlowCtrl_Do ) {
350- if (o_label == stack [stack_idx ].o_label ) {
351- if (value != 0.0f )
352- vfs_seek (stack [stack_idx ].file , stack [stack_idx ].file_pos );
353- else
354- stack_pull ();
355- }
428+ if (last_op == NGCFlowCtrl_Do && o_label == stack [stack_idx ].o_label ) {
429+ if (value != 0.0f )
430+ vfs_seek (stack [stack_idx ].file , stack [stack_idx ].file_pos );
431+ else
432+ stack_pull ();
356433 } else if ((status = stack_push (o_label , operation )) == Status_OK ) {
357434 if (!(stack [stack_idx ].skip = value == 0.0f )) {
358435 if ((stack [stack_idx ].expr = malloc (strlen (expr ) + 1 ))) {
@@ -371,11 +448,13 @@ status_code_t ngc_flowctrl (uint32_t o_label, char *line, uint_fast8_t *pos, boo
371448 case NGCFlowCtrl_EndWhile :
372449 if (hal .stream .file ) {
373450 if (last_op == NGCFlowCtrl_While ) {
374- if (!skipping && o_label == stack [stack_idx ].o_label ) {
375- uint_fast8_t pos = 0 ;
376- if (!stack [stack_idx ].skip && (status = ngc_eval_expression (stack [stack_idx ].expr , & pos , & value )) == Status_OK ) {
377- if (!(stack [stack_idx ].skip = value == 0 ))
378- vfs_seek (stack [stack_idx ].file , stack [stack_idx ].file_pos );
451+ if (o_label == stack [stack_idx ].o_label ) {
452+ if (!skipping ) {
453+ uint_fast8_t pos = 0 ;
454+ if (!stack [stack_idx ].skip && (status = ngc_eval_expression (stack [stack_idx ].expr , & pos , & value )) == Status_OK ) {
455+ if (!(stack [stack_idx ].skip = value == 0.0f ))
456+ vfs_seek (stack [stack_idx ].file , stack [stack_idx ].file_pos );
457+ }
379458 }
380459 if (stack [stack_idx ].skip )
381460 stack_pull ();
@@ -390,7 +469,8 @@ status_code_t ngc_flowctrl (uint32_t o_label, char *line, uint_fast8_t *pos, boo
390469 if (hal .stream .file ) {
391470 if (!skipping && (status = ngc_eval_expression (line , pos , & value )) == Status_OK ) {
392471 if ((status = stack_push (o_label , operation )) == Status_OK ) {
393- if (!(stack [stack_idx ].skip = value == 0.0f )) {
472+ value = nearbyintf (value );
473+ if (!(stack [stack_idx ].skip = value <= 0.0f )) {
394474 stack [stack_idx ].file = hal .stream .file ;
395475 stack [stack_idx ].file_pos = vfs_tell (hal .stream .file );
396476 stack [stack_idx ].repeats = (uint32_t )value ;
@@ -490,20 +570,17 @@ status_code_t ngc_flowctrl (uint32_t o_label, char *line, uint_fast8_t *pos, boo
490570 case NGCFlowCtrl_Sub :
491571 if (hal .stream .file ) {
492572 ngc_sub_t * sub ;
493- if ((skip_sub = (sub = malloc (sizeof (ngc_sub_t ))) != NULL )) {
494- sub -> o_label = o_label ;
495- sub -> file = hal .stream .file ;
496- sub -> file_pos = vfs_tell (hal .stream .file );
497- sub -> next = NULL ;
498- if (subs == NULL )
499- subs = sub ;
500- else {
501- ngc_sub_t * last = subs ;
502- while (last -> next )
503- last = last -> next ;
504- last -> next = sub ;
505- }
506- } // else out of memory
573+ if (o_label > NGC_MAX_PARAM_ID ) {
574+
575+ if ((sub = subs )) do {
576+ // if(sub->o_label == o_label && sub->file == hal.stream.file)
577+ // break;
578+ } while (sub -> next && (sub = sub -> next ));
579+
580+ if (sub == NULL || sub -> o_label != o_label )
581+ status = Status_FlowControlSyntaxError ;
582+ } else if (!(skip_sub = (sub = add_sub (o_label , hal .stream .file )) != NULL ))
583+ status = Status_FlowControlOutOfMemory ;
507584 } else
508585 status = Status_FlowControlNotExecutingMacro ;
509586 break ;
@@ -524,11 +601,37 @@ status_code_t ngc_flowctrl (uint32_t o_label, char *line, uint_fast8_t *pos, boo
524601 break ;
525602
526603 case NGCFlowCtrl_Call :
527- if (hal .stream .file ) {
604+
605+ if (hal .stream .file || o_label > NGC_MAX_PARAM_ID ) {
606+
528607 if (!skipping ) {
529608
530609 ngc_sub_t * sub = subs ;
531- do {
610+
611+ if (o_label > NGC_MAX_PARAM_ID ) {
612+ #if 0
613+ char * subname ;
614+ if ((subname = string_register_get_by_id ((string_register_id_t )o_label ))) {
615+ char filename [60 ];
616+ vfs_file_t * file ;
617+
618+ strcpy (filename , "/" );
619+ strcat (filename , subname );
620+ strcat (filename , ".macro" );
621+
622+ #if LITTLEFS_ENABLE
623+ sprintf (filename , "/littlefs/P%d.macro" , macro_id );
624+
625+ if ((file = vfs_open (filename , "r" )) == NULL )
626+ #endif
627+ if ((file = stream_redirect_read (filename , onError , onFileEnd ))) {
628+ if ((sub = add_sub (o_label , file )) == NULL )
629+ status = Status_FlowControlOutOfMemory ;
630+ } else
631+ status = Status_FlowControlOutOfMemory ; // file not found...
632+ }
633+ #endif
634+ } else do {
532635 if (sub -> o_label == o_label && sub -> file == hal .stream .file )
533636 break ;
534637 } while ((sub = sub -> next ));
0 commit comments