source: trunk/lib/ubasic/ubasic.c @ 854

Revision 854, 67.7 KB checked in by reyalp, 3 years ago (diff)

WARNING this may break some existing scripts, see http://chdk.setepontos.com/index.php/topic,4408.0.html and http://chdk.setepontos.com/index.php/topic,4276.0.html

  • add UBASIC_DEBUG option to build the verbose debug version of ubasic_test, fix warning in tokenizer.c test version
  • Property svn:eol-style set to native
Line 
1/*
2 * Copyright (c) 2006, Adam Dunkels
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 *    notice, this list of conditions and the following disclaimer in the
12 *    documentation and/or other materials provided with the distribution.
13 * 3. Neither the name of the author nor the names of its contributors
14 *    may be used to endorse or promote products derived from this software
15 *    without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 *
29 */
30
31#if DEBUG
32#define DEBUG_PRINTF(...)  printf(__VA_ARGS__)
33#else
34#define DEBUG_PRINTF(...)
35#endif
36
37#ifdef UBASIC_TEST
38#include "../../include/ubasic.h"
39#include "../../include/platform.h"
40#include "../../include/script.h"
41#include "../../include/shot_histogram.h"
42#include "../../include/levent.h"
43#include <string.h>
44#include <time.h>
45#include <fcntl.h>
46#include <io.h>
47#include <stdlib.h> /* rand,srand */
48#else
49#include "ubasic.h"
50#include "platform.h"
51#include "script.h"
52#include "camera.h"
53#include "shot_histogram.h"
54#include "stdlib.h"
55#include "levent.h"
56#endif
57#include "tokenizer.h"
58
59
60#include "../../include/conf.h"
61
62#include "camera_functions.h"
63
64
65#define INCLUDE_OLD_GET__SYNTAX
66
67#ifdef DEBUG
68#include <stdio.h>
69#endif
70
71static char const *program_ptr;
72#define MAX_STRINGLEN 40
73static char string[MAX_STRINGLEN];
74
75#define MAX_GOSUB_STACK_DEPTH 10
76static short gosub_stack[MAX_GOSUB_STACK_DEPTH];
77static int gosub_stack_ptr;
78
79#define MAX_IF_STACK_DEPTH 4
80static short if_stack[MAX_IF_STACK_DEPTH];
81static int if_stack_ptr;
82
83struct select_state {
84  int select_value;
85  short case_run;
86};
87#define MAX_SELECT_STACK_DEPTH 4
88static struct select_state select_stack[MAX_SELECT_STACK_DEPTH];
89static int select_stack_ptr;
90
91#define MAX_WHILE_STACK_DEPTH 4
92static short while_stack[MAX_WHILE_STACK_DEPTH];
93static int while_stack_ptr;
94
95#define MAX_DO_STACK_DEPTH 4
96static short do_stack[MAX_DO_STACK_DEPTH];
97static int do_stack_ptr;
98
99struct for_state {
100  short line_after_for;
101  short for_variable;
102  int to;
103  int step;
104};
105#define MAX_FOR_STACK_DEPTH 4
106static struct for_state for_stack[MAX_FOR_STACK_DEPTH];
107static int for_stack_ptr;
108
109#define MAX_VARNUM 52
110static int variables[MAX_VARNUM];
111
112static int ended;
113
114static int expr(void);
115static void line_statement(void);
116static void statement(void);
117static int relation(void);
118
119int ubasic_error;
120const char *ubasic_errstrings[UBASIC_E_ENDMARK] =
121{
122    "No err",
123    "Parse err",
124    "Unk stmt",
125    "Unk key",
126    "Unk label",
127    "gosub: Stack ful",
128    "bad return",
129    "if: Stack ful",
130    "bad endif",
131    "select: Stack ful",
132    "bad end_select",
133    "for: Stack ful",
134    "bad next",
135    "do: Stack ful",
136    "bad until",
137    "while: Stack ful",
138    "bad wend",
139    "Unk err"
140};
141
142/*---------------------------------------------------------------------------*/
143int
144ubasic_linenumber()
145{
146  return tokenizer_line_number();
147}
148
149/*---------------------------------------------------------------------------*/
150void
151ubasic_init(const char *program)
152{
153  program_ptr = program;
154  for_stack_ptr = gosub_stack_ptr = while_stack_ptr = do_stack_ptr = if_stack_ptr = select_stack_ptr = 0;
155  tokenizer_init(program);
156  ended = 0;
157  ubasic_error = UBASIC_E_NONE;
158}
159/*---------------------------------------------------------------------------*/
160static void
161accept(int token)
162{
163  if(token != tokenizer_token()) {
164    DEBUG_PRINTF("Token not what was expected (expected %d, got %d)\n",
165                 token, tokenizer_token());
166    tokenizer_error_print();
167     tokenizer_next();
168     ended = 1;
169     ubasic_error = UBASIC_E_PARSE;
170     return;
171  }
172  DEBUG_PRINTF("Expected %d, got it\n", token);
173  tokenizer_next();
174}
175/*---------------------------------------------------------------------------*/
176static void
177accept_cr()
178{
179    while(tokenizer_token() != TOKENIZER_CR &&
180            tokenizer_token() != TOKENIZER_ENDOFINPUT)
181      tokenizer_next();
182    accept(TOKENIZER_CR);
183}
184/*---------------------------------------------------------------------------*/
185static int
186varfactor(void)
187{
188  int r;
189  DEBUG_PRINTF("varfactor: obtaining %d from variable %d\n", variables[tokenizer_variable_num()], tokenizer_variable_num());
190  r = ubasic_get_variable(tokenizer_variable_num());
191  accept(TOKENIZER_VARIABLE);
192  return r;
193}
194/*---------------------------------------------------------------------------*/
195static int
196factor(void)
197{
198  int r = 0;
199
200  DEBUG_PRINTF("factor: token %d\n", tokenizer_token());
201  switch(tokenizer_token()) {
202  case TOKENIZER_NUMBER:
203    r = tokenizer_num();
204    DEBUG_PRINTF("factor: number %d\n", r);
205    accept(TOKENIZER_NUMBER);
206    break;
207  case TOKENIZER_LEFTPAREN:
208    accept(TOKENIZER_LEFTPAREN);
209    r = relation();
210    accept(TOKENIZER_RIGHTPAREN);
211    break;
212  case TOKENIZER_PLUS:
213    accept(TOKENIZER_PLUS);
214    r = factor();
215    break;
216  case TOKENIZER_MINUS:
217    accept(TOKENIZER_MINUS);
218    r = - factor();
219    break;
220  case TOKENIZER_LNOT:
221    accept(TOKENIZER_LNOT);
222    r = ! relation();
223    break;
224case TOKENIZER_GET_VBATT:
225    accept(TOKENIZER_GET_VBATT);
226    r = (unsigned short) stat_get_vbatt();
227    break;
228 case TOKENIZER_GET_DAY_SECONDS:
229    accept(TOKENIZER_GET_DAY_SECONDS);
230    r = shooting_get_day_seconds();
231    break;
232 case TOKENIZER_GET_TICK_COUNT:
233    accept(TOKENIZER_GET_TICK_COUNT);
234    r = shooting_get_tick_count();     
235   break;
236 case TOKENIZER_GET_MODE:
237    accept(TOKENIZER_GET_MODE);
238    int m=mode_get()&MODE_SHOOTING_MASK;
239    int mode_video=MODE_IS_VIDEO(m);
240    if ((mode_get()&MODE_MASK) != MODE_PLAY) r = 0;
241    if ((mode_get()&MODE_MASK) == MODE_PLAY) r = 1;
242    if (((mode_get()&MODE_MASK) != MODE_PLAY) && mode_video) r = 2;
243   break;
244 case TOKENIZER_GET_RAW_NR:
245    accept(TOKENIZER_GET_RAW_NR);
246    r = ubasic_camera_get_nr();     
247    break;
248 case TOKENIZER_IS_KEY:
249    accept(TOKENIZER_IS_KEY);
250    tokenizer_string(string, sizeof(string));
251    tokenizer_next();
252    r = ubasic_camera_is_clicked(string);
253    break;
254case TOKENIZER_SCRIPT_AUTOSTARTED:
255    accept(TOKENIZER_SCRIPT_AUTOSTARTED);
256    r = ubasic_camera_script_autostart();
257    break;
258case TOKENIZER_GET_SCRIPT_AUTOSTART:
259    accept(TOKENIZER_GET_SCRIPT_AUTOSTART);
260#ifdef UBASIC_TEST
261        r = 0;
262#else   
263    r = conf.script_startup;
264#endif
265    break;
266case TOKENIZER_GET_USB_POWER:
267    accept(TOKENIZER_GET_USB_POWER);
268    r = get_usb_power(0);     
269    break;
270case TOKENIZER_GET_EXP_COUNT:
271    accept(TOKENIZER_GET_EXP_COUNT);
272    r = get_exposure_counter();
273    break;
274case TOKENIZER_IS_PRESSED:
275    accept(TOKENIZER_IS_PRESSED);
276    tokenizer_string(string, sizeof(string));
277    tokenizer_next();
278    r = ubasic_camera_is_pressed(string);
279    break;
280  case TOKENIZER_RANDOM:
281    accept(TOKENIZER_RANDOM);
282    int min = expr();
283    int max = expr();
284    srand((int)shooting_get_bv96()+(unsigned short)stat_get_vbatt()+get_tick_count());
285    ubasic_camera_sleep(rand()%10);
286    r = min + rand()%(max-min+1);
287  break;
288  case TOKENIZER_GET_MOVIE_STATUS:
289    accept(TOKENIZER_GET_MOVIE_STATUS);
290    r = movie_status;
291   break;
292  case TOKENIZER_GET_PLATFORM_ID:
293    accept(TOKENIZER_GET_PLATFORM_ID);
294    r = PLATFORMID;
295   break;
296  case TOKENIZER_GET_DRIVE_MODE:
297    accept(TOKENIZER_GET_DRIVE_MODE);
298    r = shooting_get_drive_mode();
299   break;
300  case TOKENIZER_GET_FOCUS_MODE:
301    accept(TOKENIZER_GET_FOCUS_MODE);
302    r = shooting_get_prop(PROPCASE_FOCUS_MODE);
303   break;
304        case TOKENIZER_GET_DISPLAY_MODE:
305    accept(TOKENIZER_GET_DISPLAY_MODE);
306    r = shooting_get_prop(PROPCASE_DISPLAY_MODE);
307   break;
308  case TOKENIZER_GET_FLASH_MODE:
309    accept(TOKENIZER_GET_FLASH_MODE);
310    r = shooting_get_prop(PROPCASE_FLASH_MODE);
311   break;
312  case TOKENIZER_GET_SHOOTING:
313    accept(TOKENIZER_GET_SHOOTING);
314    r = shooting_get_prop(PROPCASE_SHOOTING);
315   break;
316  case TOKENIZER_GET_FLASH_READY:
317    accept(TOKENIZER_GET_FLASH_READY);
318    r = shooting_get_prop(PROPCASE_IS_FLASH_READY);
319   break;
320  case TOKENIZER_GET_IS_MODE:
321    accept(TOKENIZER_GET_IS_MODE);
322    r = shooting_get_prop(PROPCASE_IS_MODE);
323   break;
324  case TOKENIZER_GET_EV:
325    accept(TOKENIZER_GET_EV);
326    r = shooting_get_prop(PROPCASE_EV_CORRECTION_1);
327   break;
328  case TOKENIZER_GET_RESOLUTION:
329    accept(TOKENIZER_GET_RESOLUTION);
330    r = shooting_get_prop(PROPCASE_RESOLUTION);
331   break;
332  case TOKENIZER_GET_QUALITY:
333    accept(TOKENIZER_GET_QUALITY);
334    r = shooting_get_prop(PROPCASE_QUALITY);
335   break;
336  case TOKENIZER_GET_ORIENTATION_SENSOR:
337    accept(TOKENIZER_GET_ORIENTATION_SENSOR);
338    r = shooting_get_prop(PROPCASE_ORIENTATION_SENSOR);
339   break;
340  case TOKENIZER_GET_ZOOM_STEPS:
341    accept(TOKENIZER_GET_ZOOM_STEPS);
342    r = zoom_points;
343   break;
344  case TOKENIZER_GET_ND_PRESENT:
345    accept(TOKENIZER_GET_ND_PRESENT);
346    #if !CAM_HAS_ND_FILTER
347    r = 0;
348    #endif
349    #if CAM_HAS_ND_FILTER && !CAM_HAS_IRIS_DIAPHRAGM
350    r = 1;
351    #endif
352    #if CAM_HAS_ND_FILTER && CAM_HAS_IRIS_DIAPHRAGM
353    r = 2;
354    #endif
355   break;
356  case TOKENIZER_GET_PROPSET:
357    accept(TOKENIZER_GET_PROPSET);
358    #if CAM_PROPSET == 1
359    r = 1;
360    #elif CAM_PROPSET == 2
361    r = 2;
362    #endif
363   break;
364  case TOKENIZER_GET_TV96:
365    accept(TOKENIZER_GET_TV96);
366    r = shooting_get_tv96();
367    break;
368  case TOKENIZER_GET_USER_TV96:
369    accept(TOKENIZER_GET_USER_TV96);
370    r = shooting_get_user_tv96();
371    break;   
372  case TOKENIZER_GET_USER_TV_ID:
373    accept(TOKENIZER_GET_USER_TV_ID);
374    r = shooting_get_user_tv_id();
375    break;
376  case TOKENIZER_GET_AV96:
377    accept(TOKENIZER_GET_AV96);
378    r = shooting_get_av96();
379    break; 
380  case TOKENIZER_GET_USER_AV96:
381    accept(TOKENIZER_GET_USER_AV96);
382    r = shooting_get_user_av96();
383    break;   
384  case TOKENIZER_GET_USER_AV_ID:
385    accept(TOKENIZER_GET_USER_AV_ID);
386    r = shooting_get_user_av_id();
387    break;
388  case TOKENIZER_GET_ZOOM:
389    accept(TOKENIZER_GET_ZOOM);
390    r = shooting_get_zoom();
391    break;
392  case TOKENIZER_GET_FOCUS:
393    accept(TOKENIZER_GET_FOCUS);
394    r = shooting_get_subject_distance();
395    break;
396  case TOKENIZER_GET_NEAR_LIMIT:
397    accept(TOKENIZER_GET_NEAR_LIMIT);
398    r = shooting_get_near_limit_of_acceptable_sharpness();
399    break;
400  case TOKENIZER_GET_FAR_LIMIT:
401    accept(TOKENIZER_GET_FAR_LIMIT);
402    r = shooting_get_far_limit_of_acceptable_sharpness();
403    break; 
404   case TOKENIZER_GET_DOF:
405    accept(TOKENIZER_GET_DOF);
406    r = shooting_get_depth_of_field();
407    break;
408  case TOKENIZER_GET_HYPERFOCAL_DIST:
409    accept(TOKENIZER_GET_HYPERFOCAL_DIST);
410    r = shooting_get_hyperfocal_distance();
411    break; 
412  case TOKENIZER_GET_ISO_MARKET:
413    accept(TOKENIZER_GET_ISO_MARKET);
414    r = (int)shooting_get_iso_market();
415    break;
416  case TOKENIZER_GET_ISO_REAL:
417    accept(TOKENIZER_GET_ISO_REAL);
418    r = (int)shooting_get_iso_real();
419    break;
420  case TOKENIZER_GET_BV96:
421    accept(TOKENIZER_GET_BV96);
422    r = (int)shooting_get_bv96();
423    break; 
424  case TOKENIZER_GET_SV96:
425    accept(TOKENIZER_GET_SV96);
426    r = (int)shooting_get_sv96();
427    break;   
428  case TOKENIZER_GET_ISO_MODE:
429    accept(TOKENIZER_GET_ISO_MODE);
430    r = shooting_get_iso_mode();
431    break;
432  case TOKENIZER_GET_DISK_SIZE:
433    accept(TOKENIZER_GET_DISK_SIZE);
434    r = GetTotalCardSpaceKb();
435    break;
436  case TOKENIZER_GET_FREE_DISK_SPACE:
437    accept(TOKENIZER_GET_FREE_DISK_SPACE);
438    r = GetFreeCardSpaceKb();
439    break;
440
441  case TOKENIZER_GET_JPG_COUNT:
442    accept(TOKENIZER_GET_JPG_COUNT);
443    r = GetJpgCount();
444    break;
445  case TOKENIZER_GET_VIDEO_BUTTON:
446    accept(TOKENIZER_GET_VIDEO_BUTTON);
447    #if CAM_HAS_VIDEO_BUTTON
448    r = 1;
449    #else
450    r = 0;
451    #endif
452    break;
453  case TOKENIZER_GET_RAW_COUNT:
454    accept(TOKENIZER_GET_RAW_COUNT);
455    r = GetRawCount();
456    break;
457  case TOKENIZER_GET_PROP:
458    accept(TOKENIZER_GET_PROP);
459    int var = expr();
460    r = shooting_get_prop(var);
461    break;
462  case TOKENIZER_GET_HISTO_RANGE:
463    accept(TOKENIZER_GET_HISTO_RANGE);
464    int from = expr();
465    int to = expr();
466    if (shot_histogram_isenabled()) r = (unsigned short)shot_histogram_get_range(from, to);
467    else r = -1;
468    break;
469  case TOKENIZER_GET_TEMPERATURE:
470    accept(TOKENIZER_GET_TEMPERATURE);
471    int temp = expr();
472    switch (temp)
473    {
474        case 0:
475                r = get_optical_temp();
476                break;
477        case 1:
478                r = get_ccd_temp();
479                break;
480        case 2:
481                r = get_battery_temp();
482                break;
483                default: // do something sane if given a bad index
484                        r = 0;
485  }
486    break;
487  case TOKENIZER_GET_TIME: {
488    accept(TOKENIZER_GET_TIME);
489         unsigned long t2 = time(NULL);
490    int tmode = expr();
491     static struct tm *ttm;
492     ttm = localtime(&t2);
493    if (tmode==0) r = ttm->tm_sec;
494    else if (tmode==1) r = ttm->tm_min;
495    else if (tmode==2) r = ttm->tm_hour;
496    else if (tmode==3) r = ttm->tm_mday;
497    else if (tmode==4) r = ttm->tm_mon+1;
498    else if (tmode==5) r = 1900+ttm->tm_year;
499 break;
500 }
501 case TOKENIZER_GET_RAW:
502    accept(TOKENIZER_GET_RAW);
503#ifdef UBASIC_TEST
504        r = 1;
505#else   
506    r = conf.save_raw;
507#endif   
508    break;
509 // get CHDK capture mode value, or 0 if in playback or unknown (broken modemap)
510 // NOTE: different from get_mode, since this returns the actual value
511 case TOKENIZER_GET_CAPTURE_MODE:
512    accept(TOKENIZER_GET_CAPTURE_MODE);
513    r = mode_get();
514    if ( (r&MODE_MASK) == MODE_REC)
515        r &= MODE_SHOOTING_MASK;
516    else
517        r = 0;
518    break;
519 // check if CHDK capture mode exists in modemap of this camera
520 case TOKENIZER_IS_CAPTURE_MODE_VALID: {
521    accept(TOKENIZER_IS_CAPTURE_MODE_VALID);
522    int modenum = expr();
523    if (shooting_mode_chdk2canon(modenum) == -1)
524        r = 0;
525    else
526        r = 1;
527    break;
528  }
529  default:
530    r = varfactor();
531    break;
532  }
533  return r;
534}
535/*---------------------------------------------------------------------------*/
536static int
537term(void)
538{
539  int f1, f2;
540  int op;
541
542  f1 = factor();
543  op = tokenizer_token();
544  DEBUG_PRINTF("term: token %d\n", op);
545  while(op == TOKENIZER_ASTR ||
546        op == TOKENIZER_SLASH ||
547        op == TOKENIZER_LT ||
548        op == TOKENIZER_GT ||
549        op == TOKENIZER_GE ||
550        op == TOKENIZER_LE ||
551        op == TOKENIZER_NE ||
552        op == TOKENIZER_EQ ||
553        op == TOKENIZER_XOR ||
554        op == TOKENIZER_OR ||
555        op == TOKENIZER_MOD) {
556    tokenizer_next();
557    f2 = factor();
558    DEBUG_PRINTF("term: %d %d %d\n", f1, op, f2);
559    switch(op) {
560    case TOKENIZER_ASTR:
561      f1 = f1 * f2;
562      break;
563    case TOKENIZER_SLASH:
564      f1 = f1 / f2;
565      break;
566    case TOKENIZER_MOD:
567      f1 = f1 % f2;
568      break;
569    case TOKENIZER_LT:
570      f1 = f1 < f2;
571      break;
572    case TOKENIZER_GT:
573      f1 = f1 > f2;
574      break;
575    case TOKENIZER_EQ:
576      f1 = f1 == f2;
577      break;
578    case TOKENIZER_NE:
579      f1 = f1 != f2;
580      break;
581    case TOKENIZER_LE:
582      f1 = f1 <= f2;
583      break;
584    case TOKENIZER_GE:
585      f1 = f1 >= f2;
586      break;
587    case TOKENIZER_OR:
588      f1 = f1 | f2;
589      break;
590    case TOKENIZER_XOR:
591      f1 = f1 ^ f2;
592      break;
593    }
594    op = tokenizer_token();
595  }
596  DEBUG_PRINTF("term: %d\n", f1);
597  return f1;
598}
599/*---------------------------------------------------------------------------*/
600static int
601expr(void)
602{
603  int t1, t2;
604  int op;
605 
606  t1 = term();
607  op = tokenizer_token();
608  DEBUG_PRINTF("expr: token %d\n", op);
609  while(op == TOKENIZER_PLUS ||
610        op == TOKENIZER_MINUS ||
611        op == TOKENIZER_AND ||
612        op == TOKENIZER_LOR ||
613        op == TOKENIZER_XOR) {
614    tokenizer_next();
615    t2 = term();
616    DEBUG_PRINTF("expr: %d %d %d\n", t1, op, t2);
617    switch(op) {
618    case TOKENIZER_PLUS:
619      t1 = t1 + t2;
620      break;
621    case TOKENIZER_MINUS:
622      t1 = t1 - t2;
623      break;
624    case TOKENIZER_AND:
625      t1 = t1 & t2;
626      break;
627    case TOKENIZER_LOR:
628      t1 = t1 || t2;
629      break;
630    }
631    op = tokenizer_token();
632  }
633  DEBUG_PRINTF("expr: %d\n", t1);
634  return t1;
635}
636/*---------------------------------------------------------------------------*/
637static int
638relation(void)
639{
640  int r1, r2;
641  int op;
642 
643  r1 = expr();
644  op = tokenizer_token();
645  DEBUG_PRINTF("relation: token %d\n", op);
646  while(op == TOKENIZER_LAND) {
647    tokenizer_next();
648    r2 = expr();
649    DEBUG_PRINTF("relation: %d %d %d\n", r1, op, r2);
650    switch(op) {
651    case TOKENIZER_LAND:
652      r1 = r1 && r2;
653      break;
654    }
655    op = tokenizer_token();
656  }
657  return r1;
658}
659
660#if 0
661/*---------------------------------------------------------------------------*/
662static void
663jump_linenum(int linenum)
664{
665  tokenizer_init(program_ptr);
666  while(tokenizer_num() != linenum) {
667    do {
668      do {
669        tokenizer_next();
670      } while(tokenizer_token() != TOKENIZER_CR &&
671              tokenizer_token() != TOKENIZER_ENDOFINPUT);
672      if(tokenizer_token() == TOKENIZER_CR) {
673        tokenizer_next();
674      }
675    } while(tokenizer_token() != TOKENIZER_NUMBER);
676    DEBUG_PRINTF("jump_linenum: Found line %d\n", tokenizer_num());
677  }
678}
679#endif
680
681/*---------------------------------------------------------------------------*/
682static void
683jump_line(int linenum)
684{
685  tokenizer_init(program_ptr);
686  while(tokenizer_line_number() != linenum) {
687    tokenizer_next();
688  }
689  /* swallow the CR that would be read next */
690  accept(TOKENIZER_CR);
691
692}
693/*---------------------------------------------------------------------------*/
694// TODO: error handling?
695int
696jump_label(char * label)
697{
698  char currLabel[MAX_STRINGLEN];
699  tokenizer_init(program_ptr);
700  currLabel[0] = 0;
701  while(tokenizer_token() != TOKENIZER_ENDOFINPUT) {
702    tokenizer_next();
703    if (tokenizer_token() == TOKENIZER_LABEL) {
704      tokenizer_label(currLabel, sizeof(currLabel));
705      tokenizer_next();
706      if(strcmp(label, currLabel) == 0) {
707        accept(TOKENIZER_CR);
708        DEBUG_PRINTF("jump_linenum: Found line %d\n", tokenizer_line_number());
709        break;
710      }
711    }
712  }
713  if (tokenizer_token() == TOKENIZER_ENDOFINPUT) {
714    if (state_kbd_script_run == 1) { 
715      DEBUG_PRINTF("Label %s not found", label);
716      ubasic_error = UBASIC_E_UNK_LABEL;
717    }
718      return 0;
719  } else {
720      return 1;
721  }
722}
723/*---------------------------------------------------------------------------*/
724static void
725goto_statement(void)
726{
727  accept(TOKENIZER_GOTO);
728  if(tokenizer_token() == TOKENIZER_STRING) {
729    tokenizer_string(string, sizeof(string));
730    tokenizer_next();
731    jump_label(string);
732  } else {
733    DEBUG_PRINTF("ubasic.c: goto_statement(): no label specified\n");
734    ended = 1;
735    ubasic_error = UBASIC_E_UNK_LABEL;
736  }
737}
738/*---------------------------------------------------------------------------*/
739static void
740print_screen_statement(void)
741{
742  int val;
743  accept(TOKENIZER_PRINT_SCREEN);
744  val = expr();
745  accept(TOKENIZER_CR);
746  script_print_screen_statement(val);
747}
748/*---------------------------------------------------------------------------*/
749static void
750print_statement(void)
751{
752  static char buf[128];
753
754  buf[0]=0;
755  accept(TOKENIZER_PRINT);
756  do {
757    DEBUG_PRINTF("Print loop\n");
758    if(tokenizer_token() == TOKENIZER_STRING) {
759      tokenizer_string(string, sizeof(string));
760      sprintf(buf+strlen(buf), "%s", string);
761      tokenizer_next();
762    } else if(tokenizer_token() == TOKENIZER_COMMA) {
763      strcat(buf, " ");
764      tokenizer_next();
765    } else if(tokenizer_token() == TOKENIZER_SEMICOLON) {
766      tokenizer_next();
767    } else {
768      sprintf(buf+strlen(buf), "%d", expr());
769    }
770  } while(tokenizer_token() != TOKENIZER_CR && tokenizer_token() != TOKENIZER_ENDOFINPUT && tokenizer_token() != TOKENIZER_ELSE);
771  script_console_add_line(buf);
772  DEBUG_PRINTF("End of print\n");
773  accept_cr();
774}
775/*---------------------------------------------------------------------------*/
776/* IF-STATEMENT                                                              */
777
778static void
779endif_statement(void)
780{
781  if(if_stack_ptr > 0) {
782    accept(TOKENIZER_ENDIF);
783    accept(TOKENIZER_CR);
784    if_stack_ptr--;
785  } else {
786    DEBUG_PRINTF("ubasic.c: endif_statement(): endif without if-statement\n");
787    ended = 1;
788    ubasic_error = UBASIC_E_UNMATCHED_IF;
789  }
790}
791/*---------------------------------------------------------------------------*/
792static void
793if_statement(void)
794{
795  int r, else_cntr,endif_cntr,f_nt,f_sl;
796 
797  accept(TOKENIZER_IF);
798  DEBUG_PRINTF("if_statement: get_relation\n");
799  r = relation();
800  DEBUG_PRINTF("if_statement: relation %d\n", r);
801  accept(TOKENIZER_THEN);
802  if (ended) {
803    return;
804  }
805
806  if (tokenizer_token() == TOKENIZER_CR) {
807    // CR after then -> multiline IF-Statement
808    if(if_stack_ptr < MAX_IF_STACK_DEPTH) {
809      if_stack[if_stack_ptr] = r;
810      if_stack_ptr++;
811    } else {
812      DEBUG_PRINTF("if_statement: IF-stack depth exceeded\n");
813      ended = 1;
814      ubasic_error = UBASIC_E_IF_STACK_EXHAUSTED;
815      return;
816    }
817    DEBUG_PRINTF("if_statement: stack_ptr %d\n", if_stack_ptr);
818    accept(TOKENIZER_CR);
819    if(r) {
820      DEBUG_PRINTF("if_statement: result true\n");
821      return;
822    }else {
823      DEBUG_PRINTF("if_statement: result false\n");
824     
825      else_cntr=endif_cntr=0; // number of else/endif possible in current nesting
826      f_nt=f_sl=0; // f_nt nested then ?, f_fs flag single line
827
828      while(((tokenizer_token() != TOKENIZER_ELSE &&  tokenizer_token() != TOKENIZER_ENDIF)
829           || else_cntr || endif_cntr) && tokenizer_token() != TOKENIZER_ENDOFINPUT){
830        f_nt=0;
831        // nested if
832        if( tokenizer_token() == TOKENIZER_IF) {
833          else_cntr+=1;
834          endif_cntr+=1;
835          f_sl=0;
836          DEBUG_PRINTF("IF: line %d, token %d, else %d, end %d\n", tokenizer_line_number(),tokenizer_token(),else_cntr,endif_cntr);
837        }
838        if( tokenizer_token() == TOKENIZER_THEN) {
839          f_nt=1;
840          tokenizer_next();
841          DEBUG_PRINTF("THEN: line %d, token %d, else %d, end %d\n", tokenizer_line_number(),tokenizer_token(),else_cntr,endif_cntr);
842          if (tokenizer_token() != TOKENIZER_CR) {
843            f_sl=1;
844          }
845          DEBUG_PRINTF("THEN_SL: line %d, token %d, else %d, end %d\n", tokenizer_line_number(),tokenizer_token(),else_cntr,endif_cntr);
846        }
847        if(tokenizer_token() == TOKENIZER_ELSE) {
848          else_cntr--;
849          DEBUG_PRINTF("ELSE: line %d, token %d, else %d, end %d\n", tokenizer_line_number(),tokenizer_token(),else_cntr,endif_cntr);
850          if (else_cntr<0) {
851            DEBUG_PRINTF("ubasic.c: if_statement(): else without if-statement\n");
852            ended = 1;
853            ubasic_error = UBASIC_E_UNMATCHED_IF;
854            return;
855          }
856        }
857        if(!f_sl && (tokenizer_token() == TOKENIZER_ENDIF)) {
858          endif_cntr--;
859          if (endif_cntr != else_cntr)
860            else_cntr--;
861          DEBUG_PRINTF("ENDIF: line %d, token %d, else %d, end %d\n", tokenizer_line_number(),tokenizer_token(),else_cntr,endif_cntr);
862        } else {
863          if (f_sl && (tokenizer_token() == TOKENIZER_CR))  {
864            f_sl=0;
865            endif_cntr--;
866            if (endif_cntr != else_cntr)
867              else_cntr--;
868            DEBUG_PRINTF("ENDIF_SL: line %d, token %d, else %d, end %d\n", tokenizer_line_number(),tokenizer_token(),else_cntr,endif_cntr);
869          } else {
870            if (tokenizer_token()==TOKENIZER_ENDIF){
871              DEBUG_PRINTF("ubasic.c: if_statement(): endif in singleline if-statement\n");
872              ended = 1;
873              ubasic_error = UBASIC_E_PARSE;
874              return;
875            }
876          }
877        }
878        if (!f_nt) {
879          tokenizer_next();
880        }
881      }
882      if(tokenizer_token() == TOKENIZER_ELSE) {
883        return;
884      }
885    }     
886    endif_statement();
887  }else {
888  // Singleline IF-Statement
889    if(r) {
890      statement();
891    } else {
892      do {
893        tokenizer_next();
894      } while(tokenizer_token() != TOKENIZER_ELSE &&
895        tokenizer_token() != TOKENIZER_CR &&
896        tokenizer_token() != TOKENIZER_ENDOFINPUT);
897      if(tokenizer_token() == TOKENIZER_ELSE) {
898        accept(TOKENIZER_ELSE);
899        statement();
900      } else {
901        accept(TOKENIZER_CR);
902      }
903    }
904  }
905}
906/*---------------------------------------------------------------------------*/
907static void
908else_statement(void)
909{
910  int r=0, endif_cntr, f_nt;
911 
912  accept(TOKENIZER_ELSE);
913  if(if_stack_ptr > 0) {
914    r = if_stack[if_stack_ptr-1];
915  }
916  else{
917    DEBUG_PRINTF("ubasic.c: else_statement(): else without if-statement\n");
918    ended = 1;
919    ubasic_error = UBASIC_E_PARSE;
920    return;
921  }
922  DEBUG_PRINTF("else_statement: relation %d\n", r);
923 
924  if (tokenizer_token() == TOKENIZER_CR) {
925    accept(TOKENIZER_CR);
926    if(!r) {
927      DEBUG_PRINTF("else_statement: result true\n");
928      return;
929    } else {
930      DEBUG_PRINTF("else_statement: result false\n");
931      endif_cntr=0;
932      while(((tokenizer_token() != TOKENIZER_ENDIF )
933           || endif_cntr) && tokenizer_token() != TOKENIZER_ENDOFINPUT){
934        f_nt=0;
935        if( tokenizer_token() == TOKENIZER_IF) {
936          endif_cntr+=1;
937        }
938        if( tokenizer_token() == TOKENIZER_THEN) {
939          tokenizer_next();
940          // then followed by CR -> multi line
941          if (tokenizer_token() == TOKENIZER_CR) {
942            f_nt=1;
943          } else { // single line
944            endif_cntr--;
945            while(tokenizer_token() != TOKENIZER_ENDIF && tokenizer_token() != TOKENIZER_CR
946                 && tokenizer_token() != TOKENIZER_ENDOFINPUT){
947              tokenizer_next();
948            }
949            if (tokenizer_token()==TOKENIZER_ENDIF){
950              DEBUG_PRINTF("ubasic.c: else_statement(): endif in singleline if-statement\n");
951              ended = 1;
952              ubasic_error = UBASIC_E_PARSE;
953              return;
954            }
955          }
956        }
957        if( tokenizer_token() == TOKENIZER_ENDIF)  {
958          endif_cntr--;
959        }
960        if (!f_nt) {
961          tokenizer_next();
962        }
963      }
964    }
965    endif_statement();
966  }else{
967    DEBUG_PRINTF("ubasic.c: else_statement(): CR after ELSE expected\n");
968    ended = 1;
969    ubasic_error = UBASIC_E_PARSE;
970  }
971}
972/*---------------------------------------------------------------------------*/
973
974/*---------------------------------------------------------------------------*/
975/* SELECT-STATEMENT                                                          */
976
977static void
978dec_select_stack(void)
979{
980  if(select_stack_ptr > 0) {
981      select_stack_ptr--;
982  } else {
983    DEBUG_PRINTF("select_statement: SELECT-Stack fail\n");
984    ended = 1;
985    ubasic_error = UBASIC_E_UNMATCHED_END_SELECT;
986  }
987}
988/*---------------------------------------------------------------------------*/
989static void
990end_select_statement(void)
991{
992  if(select_stack_ptr > 0) {
993    accept(TOKENIZER_END_SELECT);
994    accept(TOKENIZER_CR);
995    dec_select_stack();
996  } else {
997    DEBUG_PRINTF("ubasic.c: end_select_statement(): end_select without select-statement\n");
998    ended = 1;
999    ubasic_error = UBASIC_E_UNMATCHED_END_SELECT;
1000  }
1001}
1002/*---------------------------------------------------------------------------*/
1003static void
1004case_statement(void)
1005{
1006  int select_value, case_value_1, case_value_2, case_value_eq;
1007  short case_run, case_goto = 0, case_gosub = 0;
1008  int cur_ln, gosub_ln = 0;
1009 
1010  accept(TOKENIZER_CASE);
1011  if(select_stack_ptr > 0) {
1012    select_value = select_stack[select_stack_ptr - 1].select_value;
1013    case_run = select_stack[select_stack_ptr - 1].case_run;
1014 
1015    if (!case_run) {
1016      case_value_1 = expr();
1017      case_value_eq = (select_value == case_value_1);
1018      if (case_value_eq) { DEBUG_PRINTF("case_statement: case_value_eq %d, case_value %d\n", case_value_eq, case_value_1); } 
1019
1020      if(tokenizer_token() == TOKENIZER_TO) {
1021        accept(TOKENIZER_TO);
1022        case_value_2 = expr();
1023        if (case_value_1 < case_value_2) {
1024          case_value_eq = ((select_value >= case_value_1) && (select_value <= case_value_2));
1025          DEBUG_PRINTF("case_statement: case_value %d to %d\n", case_value_1, case_value_2);
1026        } else {
1027          case_value_eq = ((select_value >= case_value_2) && (select_value <= case_value_1));
1028          DEBUG_PRINTF("case_statement: case_value %d to %d\n", case_value_2, case_value_1);
1029        }
1030      } else if (tokenizer_token() == TOKENIZER_COMMA) {
1031        do {
1032          accept(TOKENIZER_COMMA);
1033          if (case_value_eq) {
1034            case_value_2 = expr();
1035          } else {
1036            case_value_1 = expr();
1037            case_value_eq = (select_value == case_value_1);
1038          }
1039        } while (tokenizer_token() == TOKENIZER_COMMA);
1040        DEBUG_PRINTF("case_statement: case_value_eq %d, case_value_comma %d\n", case_value_eq, case_value_1);
1041      }
1042     
1043      accept(TOKENIZER_SEMICOLON);
1044      if (case_value_eq) {
1045        case_goto = (tokenizer_token() == TOKENIZER_GOTO);
1046        case_gosub = (tokenizer_token() == TOKENIZER_GOSUB);
1047//GOSUB - save curr linenumber
1048        cur_ln = tokenizer_line_number();
1049//GOSUB
1050        statement();
1051//GOSUB  - save new linenumber, reset to curr linenumber
1052      if (case_gosub) {
1053        gosub_ln = tokenizer_line_number();
1054        jump_line(cur_ln+1);
1055        DEBUG_PRINTF("case_statement: GOSUB: toLN=%d, nextLN=%d\n", gosub_ln, cur_ln+1);
1056      }
1057//GOSUB
1058        DEBUG_PRINTF("case_statement: case execute\n");
1059        case_run = 1;
1060        select_stack[select_stack_ptr - 1].case_run = case_run;
1061      } else {
1062        DEBUG_PRINTF("case_statement: case jump; case_run: %d\n", case_run);
1063        accept_cr();
1064      }
1065    } else {accept_cr();}
1066//REM
1067    while ((tokenizer_token() == TOKENIZER_REM) && (!case_goto)) {statement();}
1068//REM
1069    if (case_goto) { dec_select_stack(); } else {
1070      if ((tokenizer_token() != TOKENIZER_CASE) && (tokenizer_token() != TOKENIZER_CASE_ELSE) &&
1071         (tokenizer_token() != TOKENIZER_END_SELECT)) {
1072         DEBUG_PRINTF("ubasic.c: select_statement(): don't found case, case_else or end_select\n");
1073         ended = 1;
1074         ubasic_error = UBASIC_E_PARSE;
1075      } else {
1076//GOSUB test for end_select and set to gosub-linenumber
1077        if (tokenizer_token() == TOKENIZER_END_SELECT) { end_select_statement(); }
1078        if (case_gosub) {
1079          gosub_stack[gosub_stack_ptr-1] = tokenizer_line_number();
1080          jump_line(gosub_ln);
1081          DEBUG_PRINTF("end_select_statement: GOSUB: returnLN=%d\n", gosub_stack[gosub_stack_ptr-1]);
1082        }
1083      } 
1084//GOSUB       
1085    }
1086  } else {
1087    DEBUG_PRINTF("case_statement: SELECT-Stack fail\n");
1088    ended = 1;
1089    ubasic_error = UBASIC_E_UNMATCHED_END_SELECT;
1090  }
1091}
1092/*---------------------------------------------------------------------------*/
1093static void
1094case_else_statement(void)
1095{
1096  short case_goto = 0, case_gosub = 0;
1097  int cur_ln, gosub_ln = 0;
1098 
1099  accept(TOKENIZER_CASE_ELSE);
1100  if(select_stack_ptr > 0) {
1101    if (!select_stack[select_stack_ptr - 1].case_run) {
1102      case_goto = (tokenizer_token() == TOKENIZER_GOTO);
1103      case_gosub = (tokenizer_token() == TOKENIZER_GOSUB);
1104//GOSUB - save curr linenumber
1105      cur_ln = tokenizer_line_number();
1106//GOSUB
1107      statement();
1108//GOSUB  - save new linenumber, reset to curr linenumber
1109      if (case_gosub) {
1110        gosub_ln = tokenizer_line_number();
1111        jump_line(cur_ln+1);
1112        DEBUG_PRINTF("case_else_statement: GOSUB: toLN=%d, nextLN=%d\n", gosub_ln, cur_ln+1);
1113      }
1114//GOSUB
1115      DEBUG_PRINTF("case_else_statement: case_else execute\n");
1116    } else {
1117      DEBUG_PRINTF("case_else_statement: case_else jump; case_run: %d\n", select_stack[select_stack_ptr - 1].case_run);
1118      accept_cr();
1119    }
1120//REM
1121    while ((tokenizer_token() == TOKENIZER_REM) && (!case_goto)) {statement();}
1122//REM
1123    if (case_goto) { dec_select_stack(); } else {
1124//GOSUB test for end_select and set to gosub-linenumber
1125      if (tokenizer_token() != TOKENIZER_END_SELECT) {
1126        DEBUG_PRINTF("ubasic.c: select_statement(): don't found end_select\n");
1127        ended = 1;
1128        ubasic_error = UBASIC_E_PARSE;
1129      } else {
1130          end_select_statement();
1131        if (case_gosub) {
1132          gosub_stack[gosub_stack_ptr-1] = tokenizer_line_number();
1133          jump_line(gosub_ln);
1134          DEBUG_PRINTF("end_select_statement: GOSUB: returnLN=%d\n", gosub_stack[gosub_stack_ptr-1]);
1135        }
1136      } 
1137//GOSUB     
1138    }
1139  } else {
1140    DEBUG_PRINTF("case_else_statement: SELECT-Stack fault\n");
1141    ended = 1;
1142    ubasic_error = UBASIC_E_UNMATCHED_END_SELECT;
1143  }
1144}
1145/*---------------------------------------------------------------------------*/
1146static void
1147select_statement(void)
1148{
1149 
1150  int select_value;
1151 
1152  accept(TOKENIZER_SELECT);
1153  select_value = expr(); 
1154  accept(TOKENIZER_CR);
1155//REM
1156    while (tokenizer_token() == TOKENIZER_REM) {statement();}
1157//REM
1158 
1159  if(select_stack_ptr < MAX_SELECT_STACK_DEPTH) {
1160    select_stack[select_stack_ptr].select_value = select_value;
1161    select_stack[select_stack_ptr].case_run = 0;
1162    DEBUG_PRINTF("select_statement: new select, value %d\n",select_stack[select_stack_ptr].select_value);
1163    select_stack_ptr++;
1164    if (tokenizer_token() != TOKENIZER_CASE) {
1165      DEBUG_PRINTF("ubasic.c: select_statement(): don't found case-statement\n");
1166      ended = 1;
1167      ubasic_error = UBASIC_E_PARSE;
1168    }
1169    else { case_statement(); }
1170  } else {
1171    DEBUG_PRINTF("select_statement: SELECT-stack depth exceeded\n");
1172    ended = 1;
1173    ubasic_error = UBASIC_E_SELECT_STACK_EXHAUSTED;
1174  }
1175}
1176/* SELECT-STATEMENT END                                                      */
1177/*---------------------------------------------------------------------------*/
1178static void
1179let_statement(void)
1180{
1181 
1182  int var;
1183
1184  var = tokenizer_variable_num();
1185
1186  accept(TOKENIZER_VARIABLE);
1187  accept(TOKENIZER_EQ);
1188  ubasic_set_variable(var, expr());
1189  DEBUG_PRINTF("let_statement: assign %d to %d\n", variables[var], var);
1190  accept_cr();
1191}
1192/*---------------------------------------------------------------------------*/
1193static void
1194rem_statement(void)
1195{
1196  accept(TOKENIZER_REM);
1197  DEBUG_PRINTF("rem_statement\n");
1198  accept(TOKENIZER_CR);
1199}
1200/*---------------------------------------------------------------------------*/
1201static void
1202cls_statement(void)
1203{
1204  accept(TOKENIZER_CLS);
1205  script_console_clear();
1206  DEBUG_PRINTF("cls_statement\n");
1207  accept(TOKENIZER_CR);
1208}
1209/*---------------------------------------------------------------------------*/
1210static void
1211gosub_statement(void)
1212{
1213  accept(TOKENIZER_GOSUB);
1214  if(tokenizer_token() == TOKENIZER_STRING) {
1215    tokenizer_string(string, sizeof(string));
1216    do {
1217    tokenizer_next();
1218    } while(tokenizer_token() != TOKENIZER_CR);
1219    accept(TOKENIZER_CR);
1220    if(gosub_stack_ptr < MAX_GOSUB_STACK_DEPTH) {
1221/*    tokenizer_line_number_inc();*/
1222      gosub_stack[gosub_stack_ptr] = tokenizer_line_number();
1223      gosub_stack_ptr++;
1224      jump_label(string);
1225    } else {
1226      DEBUG_PRINTF("gosub_statement: gosub stack exhausted\n");
1227      ended = 1;
1228      ubasic_error = UBASIC_E_GOSUB_STACK_EXHAUSTED;
1229    }
1230  } else {
1231    DEBUG_PRINTF("ubasic.c: goto_statement(): no label specified\n");
1232    ended = 1;
1233    ubasic_error = UBASIC_E_UNK_LABEL;
1234  }
1235}
1236/*---------------------------------------------------------------------------*/
1237static void
1238return_statement(void)
1239{
1240  accept(TOKENIZER_RETURN);
1241  if(gosub_stack_ptr > 0) {
1242    gosub_stack_ptr--;
1243    jump_line(gosub_stack[gosub_stack_ptr]);
1244  } else {
1245    DEBUG_PRINTF("return_statement: non-matching return\n");
1246    ended = 1;
1247    ubasic_error = UBASIC_E_UNMATCHED_RETURN;
1248  }
1249}
1250/*---------------------------------------------------------------------------*/
1251static void
1252next_statement(void)
1253{
1254  int var, value;
1255 
1256  accept(TOKENIZER_NEXT);
1257  var = tokenizer_variable_num();
1258  accept(TOKENIZER_VARIABLE);
1259  if(for_stack_ptr > 0 &&
1260     var == for_stack[for_stack_ptr - 1].for_variable) {
1261    value = ubasic_get_variable(var) + for_stack[for_stack_ptr - 1].step;
1262    ubasic_set_variable(var, value);
1263   
1264    if(((for_stack[for_stack_ptr - 1].step > 0) && (value <= for_stack[for_stack_ptr - 1].to)) ||
1265       ((for_stack[for_stack_ptr - 1].step < 0) && (value >= for_stack[for_stack_ptr - 1].to)))
1266        jump_line(for_stack[for_stack_ptr - 1].line_after_for);
1267    else {
1268      for_stack_ptr--;
1269      accept(TOKENIZER_CR);
1270    }
1271  } else {
1272    DEBUG_PRINTF("next_statement: non-matching next (expected %d, found %d)\n", for_stack[for_stack_ptr - 1].for_variable, var);
1273    ended = 1;
1274    ubasic_error = UBASIC_E_UNMATCHED_NEXT;
1275  }
1276
1277}
1278/*---------------------------------------------------------------------------*/
1279static void
1280for_statement(void)
1281{
1282  int for_variable, to, step;
1283 
1284  accept(TOKENIZER_FOR);
1285  for_variable = tokenizer_variable_num();
1286  accept(TOKENIZER_VARIABLE);
1287  accept(TOKENIZER_EQ);
1288  ubasic_set_variable(for_variable, expr());
1289  accept(TOKENIZER_TO);
1290  to = expr();                     
1291  step = 1;
1292  if (tokenizer_token() != TOKENIZER_CR) {
1293          accept(TOKENIZER_STEP);
1294          step = expr();         
1295  }
1296  accept(TOKENIZER_CR);
1297
1298  if(for_stack_ptr < MAX_FOR_STACK_DEPTH) {
1299    for_stack[for_stack_ptr].line_after_for = tokenizer_line_number();
1300    for_stack[for_stack_ptr].for_variable = for_variable;
1301    for_stack[for_stack_ptr].to = to;
1302    for_stack[for_stack_ptr].step = step;
1303    DEBUG_PRINTF("for_statement: new for, var %d to %d\n",
1304                 for_stack[for_stack_ptr].for_variable,
1305                 for_stack[for_stack_ptr].to);
1306                 
1307    for_stack_ptr++;
1308  } else {
1309    DEBUG_PRINTF("for_statement: for stack depth exceeded\n");
1310    ended = 1;
1311    ubasic_error = UBASIC_E_FOR_STACK_EXHAUSTED;
1312  }
1313}
1314/*---------------------------------------------------------------------------*/
1315static void
1316do_statement(void)
1317{
1318  accept(TOKENIZER_DO);
1319  accept(TOKENIZER_CR);
1320  if(do_stack_ptr < MAX_DO_STACK_DEPTH) {
1321     do_stack[do_stack_ptr] = tokenizer_line_number();
1322     do_stack_ptr++;
1323  } else {
1324    DEBUG_PRINTF("do_statement: do stack depth exceeded\n");
1325    ended = 1;
1326    ubasic_error = UBASIC_E_DO_STACK_EXHAUSTED;
1327  }
1328}
1329/*---------------------------------------------------------------------------*/
1330static void
1331until_statement(void)
1332{
1333  int r;
1334 
1335  accept(TOKENIZER_UNTIL);
1336  r = relation();
1337  if(do_stack_ptr > 0) {
1338    if(!r) {
1339      jump_line(do_stack[do_stack_ptr-1]);
1340    } else {
1341      do_stack_ptr--;
1342          accept_cr();
1343    }
1344  } else {
1345    DEBUG_PRINTF("until_statement: unmatched until\n");
1346    ended = 1;
1347    ubasic_error = UBASIC_E_UNMATCHED_UNTIL;
1348  }
1349}
1350/*---------------------------------------------------------------------------*/
1351static void
1352while_statement(void)
1353{
1354  int r, while_cntr;
1355 
1356  accept(TOKENIZER_WHILE);
1357  if(while_stack_ptr < MAX_WHILE_STACK_DEPTH) {
1358    if ((while_stack_ptr == 0)||((while_stack_ptr > 0) && (while_stack[while_stack_ptr-1] != tokenizer_line_number()))){
1359      while_stack[while_stack_ptr] = tokenizer_line_number();
1360      while_stack_ptr++;
1361    }
1362  } else {
1363    DEBUG_PRINTF("while_statement: while stack depth exceeded\n");
1364    ended = 1;
1365    ubasic_error = UBASIC_E_WHILE_STACK_EXHAUSTED;
1366    return;
1367  }
1368
1369  r = relation();
1370  if(while_stack_ptr > 0) {
1371    if(!r) {
1372        while_cntr=0;
1373      while((tokenizer_token() != TOKENIZER_WEND  || while_cntr ) &&
1374              tokenizer_token() != TOKENIZER_ENDOFINPUT){   
1375              if (tokenizer_token() == TOKENIZER_WHILE) while_cntr+=1;
1376              if (tokenizer_token() == TOKENIZER_WEND) while_cntr-=1;           
1377              tokenizer_next();
1378            } 
1379      while_stack_ptr--;
1380   
1381      accept(TOKENIZER_WEND);
1382      accept(TOKENIZER_CR);     
1383    } else {
1384          accept_cr();       
1385    }
1386  } else {
1387    DEBUG_PRINTF("while_statement: unmatched wend\n");
1388    ended = 1;
1389    ubasic_error = UBASIC_E_UNMATCHED_WEND;
1390  }
1391}
1392/*---------------------------------------------------------------------------*/
1393static void
1394wend_statement(void)
1395{
1396  accept(TOKENIZER_WEND);
1397  if(while_stack_ptr > 0) {
1398    jump_line(while_stack[while_stack_ptr-1]);
1399  } else {
1400    DEBUG_PRINTF("wend_statement: unmatched wend\n");
1401    ended = 1;
1402    ubasic_error = UBASIC_E_UNMATCHED_WEND;
1403  }
1404}
1405/*---------------------------------------------------------------------------*/
1406static void
1407end_statement(void)
1408{
1409  accept(TOKENIZER_END);
1410  ended = 1;
1411}
1412/*---------------------------------------------------------------------------*/
1413static void
1414click_statement(void)
1415{
1416  accept(TOKENIZER_CLICK);
1417  tokenizer_string(string, sizeof(string));
1418  ubasic_camera_click(string);
1419  tokenizer_next();
1420  DEBUG_PRINTF("End of click\n");
1421  accept_cr();
1422}
1423/*---------------------------------------------------------------------------*/
1424static void
1425press_statement(void)
1426{
1427  accept(TOKENIZER_PRESS);
1428  tokenizer_string(string, sizeof(string));
1429  ubasic_camera_press(string);
1430  tokenizer_next();
1431  DEBUG_PRINTF("End of press\n");
1432  accept_cr();
1433}
1434/*---------------------------------------------------------------------------*/
1435static void
1436release_statement(void)
1437{
1438  accept(TOKENIZER_RELEASE);
1439  tokenizer_string(string, sizeof(string));
1440  ubasic_camera_release(string);
1441  tokenizer_next();
1442  DEBUG_PRINTF("End of release\n");
1443  accept_cr();
1444}
1445/*---------------------------------------------------------------------------*/
1446static void
1447sleep_statement(void)
1448{
1449  int val;
1450  accept(TOKENIZER_SLEEP);
1451  val = expr();
1452  ubasic_camera_sleep(val);
1453  DEBUG_PRINTF("End of sleep\n");
1454  accept_cr();
1455}
1456/*---------------------------------------------------------------------------*/
1457static void
1458shoot_statement(void)
1459{
1460  accept(TOKENIZER_SHOOT);
1461  ubasic_camera_shoot();
1462  DEBUG_PRINTF("End of shoot\n");
1463  accept_cr();
1464}
1465
1466/*---------------------------------------------------------------------------*/
1467
1468#ifdef INCLUDE_OLD_GET__SYNTAX
1469
1470static void get_tv96_statement()
1471{
1472    int var;
1473    accept(TOKENIZER_GET_TV96);
1474    var = tokenizer_variable_num();
1475    accept(TOKENIZER_VARIABLE);
1476    ubasic_set_variable(var, shooting_get_tv96());
1477    accept_cr();
1478}
1479
1480static void get_user_tv96_statement()
1481{
1482    int var;
1483    accept(TOKENIZER_GET_USER_TV96);
1484    var = tokenizer_variable_num();
1485    accept(TOKENIZER_VARIABLE);
1486    ubasic_set_variable(var, shooting_get_user_tv96());
1487    accept_cr();
1488}
1489
1490
1491static void get_user_tv_id_statement()
1492{
1493    int var;
1494    accept(TOKENIZER_GET_USER_TV_ID);
1495    var = tokenizer_variable_num();
1496    accept(TOKENIZER_VARIABLE);
1497    ubasic_set_variable(var, shooting_get_user_tv_id());
1498    accept_cr();
1499}
1500
1501static void get_av96_statement()
1502{
1503    int var;
1504    accept(TOKENIZER_GET_AV96);
1505    var = tokenizer_variable_num();
1506    accept(TOKENIZER_VARIABLE);
1507    ubasic_set_variable(var, shooting_get_av96());
1508    accept_cr();
1509}
1510
1511static void get_user_av96_statement()
1512{
1513    int var;
1514    accept(TOKENIZER_GET_USER_AV96);
1515    var = tokenizer_variable_num();
1516    accept(TOKENIZER_VARIABLE);
1517    ubasic_set_variable(var, shooting_get_user_av96());
1518    accept_cr();
1519}
1520
1521static void get_user_av_id_statement()
1522{
1523    int var;
1524    accept(TOKENIZER_GET_USER_AV_ID);
1525    var = tokenizer_variable_num();
1526    accept(TOKENIZER_VARIABLE);
1527    ubasic_set_variable(var, shooting_get_user_av_id());
1528    accept_cr();
1529}
1530
1531static void get_zoom_statement()
1532{
1533    int var;
1534    accept(TOKENIZER_GET_ZOOM);
1535    var = tokenizer_variable_num();
1536    accept(TOKENIZER_VARIABLE);
1537    ubasic_set_variable(var, shooting_get_zoom());
1538    accept_cr();
1539}
1540
1541static void get_focus_statement()
1542{
1543    int var;
1544    accept(TOKENIZER_GET_FOCUS);
1545    var = tokenizer_variable_num();
1546    accept(TOKENIZER_VARIABLE);
1547    ubasic_set_variable(var, shooting_get_subject_distance());
1548    accept_cr();
1549}
1550
1551static void get_near_limit_statement()
1552{
1553    int var;
1554    accept(TOKENIZER_GET_NEAR_LIMIT);
1555    var = tokenizer_variable_num();
1556    accept(TOKENIZER_VARIABLE);
1557    ubasic_set_variable(var, shooting_get_near_limit_of_acceptable_sharpness());
1558    accept_cr();
1559}
1560
1561static void get_far_limit_statement()
1562{
1563    int var;
1564    accept(TOKENIZER_GET_FAR_LIMIT);
1565    var = tokenizer_variable_num();
1566    accept(TOKENIZER_VARIABLE);
1567    ubasic_set_variable(var, shooting_get_far_limit_of_acceptable_sharpness());
1568    accept_cr();
1569}
1570
1571static void get_dof_statement()
1572{
1573    int var;
1574    accept(TOKENIZER_GET_DOF);
1575    var = tokenizer_variable_num();
1576    accept(TOKENIZER_VARIABLE);
1577    ubasic_set_variable(var, shooting_get_depth_of_field());
1578    accept_cr();
1579}
1580
1581static void get_hyperfocal_distance_statement()
1582{
1583    int var;
1584    accept(TOKENIZER_GET_HYPERFOCAL_DIST);
1585    var = tokenizer_variable_num();
1586    accept(TOKENIZER_VARIABLE);
1587    ubasic_set_variable(var, shooting_get_hyperfocal_distance());
1588    accept_cr();
1589}
1590
1591static void get_disk_size_statement()
1592{
1593    int var;
1594    accept(TOKENIZER_GET_DISK_SIZE);
1595    var = tokenizer_variable_num();
1596    accept(TOKENIZER_VARIABLE);
1597    ubasic_set_variable(var, GetTotalCardSpaceKb());
1598    accept_cr();
1599}
1600
1601static void get_free_disk_space_statement()
1602{
1603    int var;
1604    accept(TOKENIZER_GET_FREE_DISK_SPACE);
1605    var = tokenizer_variable_num();
1606    accept(TOKENIZER_VARIABLE);
1607    ubasic_set_variable(var, GetFreeCardSpaceKb());
1608    accept_cr();
1609}
1610
1611static void get_jpg_count_statement()
1612{
1613    int var;
1614    accept(TOKENIZER_GET_JPG_COUNT);
1615    var = tokenizer_variable_num();
1616    accept(TOKENIZER_VARIABLE);
1617    ubasic_set_variable(var, GetJpgCount());
1618    accept_cr();
1619}
1620
1621static void get_raw_count_statement()
1622{
1623    int var;
1624    accept(TOKENIZER_GET_RAW_COUNT);
1625    var = tokenizer_variable_num();
1626    accept(TOKENIZER_VARIABLE);
1627    ubasic_set_variable(var, GetRawCount());
1628    accept_cr();
1629}
1630
1631static void get_vbatt_statement()
1632{
1633    int var;
1634    accept(TOKENIZER_GET_VBATT);
1635    var = tokenizer_variable_num();
1636    accept(TOKENIZER_VARIABLE);
1637    ubasic_set_variable(var, (unsigned short)stat_get_vbatt());
1638       
1639    accept_cr();
1640}
1641
1642static void get_prop_statement()
1643{
1644    int var, var1;
1645    accept(TOKENIZER_GET_PROP);
1646    var = expr();
1647    var1 = tokenizer_variable_num();
1648    accept(TOKENIZER_VARIABLE);
1649    ubasic_set_variable(var1, shooting_get_prop(var));
1650       
1651    accept_cr();
1652}
1653
1654static void get_iso_market_statement()
1655{
1656    int var;
1657    accept(TOKENIZER_GET_ISO_MARKET);
1658    var = tokenizer_variable_num();
1659    accept(TOKENIZER_VARIABLE);
1660    ubasic_set_variable(var, (int)shooting_get_iso_market());
1661    accept_cr();
1662}
1663
1664static void get_iso_real_statement()
1665{
1666    int var;
1667    accept(TOKENIZER_GET_ISO_REAL);
1668    var = tokenizer_variable_num();
1669    accept(TOKENIZER_VARIABLE);
1670    ubasic_set_variable(var, (int)shooting_get_iso_real());
1671    accept_cr();
1672}
1673
1674static void get_bv96_statement()
1675{
1676    int var;
1677    accept(TOKENIZER_GET_BV96);
1678    var = tokenizer_variable_num();
1679    accept(TOKENIZER_VARIABLE);
1680    ubasic_set_variable(var, (int)shooting_get_bv96());
1681    accept_cr();
1682}
1683
1684static void get_sv96_statement()
1685{
1686    int var;
1687    accept(TOKENIZER_GET_SV96);
1688    var = tokenizer_variable_num();
1689    accept(TOKENIZER_VARIABLE);
1690    ubasic_set_variable(var, (int)shooting_get_sv96());
1691    accept_cr();
1692}
1693
1694static void get_iso_mode_statement()
1695{
1696    int var;
1697    accept(TOKENIZER_GET_ISO_MODE);
1698    var = tokenizer_variable_num();
1699    accept(TOKENIZER_VARIABLE);
1700    ubasic_set_variable(var, shooting_get_iso_mode());
1701    accept_cr();
1702}
1703
1704#endif
1705
1706
1707static void set_tv96_statement()
1708{
1709    int to;
1710    accept(TOKENIZER_SET_TV96);
1711    to = expr();
1712    shooting_set_tv96((short int)to, SET_LATER);
1713    accept_cr();
1714}
1715
1716static void play_sound_statement()
1717{
1718    int to;
1719    accept(TOKENIZER_PLAY_SOUND);
1720    to = expr();
1721    play_sound(to);
1722    accept_cr();
1723}
1724static void set_shutter_speed_statement()
1725{
1726    int to;
1727    accept(TOKENIZER_SET_SHUTTER_SPEED);
1728    to = expr();
1729    shooting_set_shutter_speed_ubasic(to, SET_LATER);
1730    accept_cr();
1731}
1732
1733static void set_tv96_direct_statement()
1734{
1735    int to;
1736    accept(TOKENIZER_SET_TV96_DIRECT);
1737    to = expr();
1738    shooting_set_tv96_direct((short int)to, SET_LATER);
1739    accept_cr();
1740}
1741
1742static void set_user_tv96_statement()
1743{
1744    int to;
1745    accept(TOKENIZER_SET_USER_TV96);
1746    to = expr();
1747    shooting_set_user_tv96((short int)to);
1748    accept_cr();
1749}
1750
1751static void set_user_tv_by_id_statement()
1752{
1753    int to;
1754    accept(TOKENIZER_SET_USER_TV_BY_ID);
1755    to = expr();
1756    shooting_set_user_tv_by_id(to);
1757    accept_cr();
1758}
1759
1760static void set_user_tv_by_id_rel_statement()
1761{
1762    int to;
1763    accept(TOKENIZER_SET_USER_TV_BY_ID_REL);
1764    to = expr();
1765    shooting_set_user_tv_by_id_rel(to);
1766    accept_cr();
1767}
1768
1769static void set_sv96_statement()
1770{
1771    int to;
1772    accept(TOKENIZER_SET_SV96);
1773    to = expr();
1774    shooting_set_sv96((short int)to, SET_LATER);
1775    accept_cr();
1776}
1777
1778
1779/*---------------------------------------------------------------------------*/
1780
1781
1782static void set_av96_statement()
1783{
1784    int to;
1785    accept(TOKENIZER_SET_AV96);
1786    to = expr();
1787    shooting_set_av96((short int)to, SET_LATER);
1788    accept_cr();
1789}
1790
1791static void set_av96_direct_statement()
1792{
1793    int to;
1794    accept(TOKENIZER_SET_AV96_DIRECT);
1795    to = expr();
1796    shooting_set_av96_direct((short int)to, SET_LATER);
1797    accept_cr();
1798}
1799
1800static void set_user_av96_statement()
1801{
1802    int to;
1803    accept(TOKENIZER_SET_USER_AV96);
1804    to = expr();
1805    shooting_set_user_av96((short int)to);
1806    accept_cr();
1807}
1808
1809static void set_user_av_by_id_statement()
1810{
1811    int to;
1812    accept(TOKENIZER_SET_USER_AV_BY_ID);
1813    to = expr();
1814    shooting_set_user_av_by_id(to);
1815    accept_cr();
1816}
1817
1818static void set_user_av_by_id_rel_statement()
1819{
1820    int to;
1821    accept(TOKENIZER_SET_USER_AV_BY_ID_REL);
1822    to = expr();
1823    shooting_set_user_av_by_id_rel(to);
1824    accept_cr();
1825}
1826
1827/*---------------------------------------------------------------------------*/
1828
1829static void set_zoom_statement()
1830{
1831    int to;
1832    accept(TOKENIZER_SET_ZOOM);
1833    to = expr();
1834    shooting_set_zoom(to);
1835    accept_cr();
1836}
1837
1838static void set_zoom_rel_statement()
1839{
1840    int to;
1841    accept(TOKENIZER_SET_ZOOM_REL);
1842    to = expr();
1843    shooting_set_zoom_rel(to);
1844    accept_cr();
1845}
1846
1847static void set_zoom_speed_statement()
1848{
1849    int to;
1850    accept(TOKENIZER_SET_ZOOM_SPEED);
1851    to = expr();
1852    shooting_set_zoom_speed(to);
1853    accept_cr();
1854}
1855
1856/*---------------------------------------------------------------------------*/
1857
1858
1859static void set_ev_statement()
1860        {
1861            int to;
1862            accept(TOKENIZER_SET_EV);
1863            to = expr();
1864                shooting_set_prop(PROPCASE_EV_CORRECTION_1, to);
1865                shooting_set_prop(PROPCASE_EV_CORRECTION_2, to);
1866            accept_cr();
1867        }
1868
1869static void set_movie_status_statement()
1870{
1871    int to;
1872    accept(TOKENIZER_SET_MOVIE_STATUS);
1873    to = expr();
1874if (to==1) {
1875        if (movie_status == 4) {
1876        movie_status = 1;
1877}}
1878if (to==2) {
1879        if (movie_status == 1) {
1880        movie_status = 4;
1881}
1882}
1883if (to==3) {
1884        if (movie_status == 1 || 4) {
1885        movie_status = 5;
1886}}
1887
1888
1889    accept_cr();
1890}
1891
1892static void set_resolution_statement()
1893{
1894    int to;
1895    accept(TOKENIZER_SET_RESOLUTION);
1896    to = expr();
1897                shooting_set_prop(PROPCASE_RESOLUTION, to);
1898    accept_cr();
1899}
1900
1901static void set_quality_statement()
1902{
1903    int to;
1904    accept(TOKENIZER_SET_QUALITY);
1905    to = expr();
1906                shooting_set_prop(PROPCASE_QUALITY, to);
1907    accept_cr();
1908}
1909
1910
1911static void set_focus_statement()
1912{
1913    int to;
1914    accept(TOKENIZER_SET_FOCUS);
1915    to = expr();
1916    int m=mode_get()&MODE_SHOOTING_MASK;
1917        int mode_video=MODE_IS_VIDEO(m);
1918#if CAM_HAS_MANUAL_FOCUS
1919    if (shooting_get_focus_mode() || (mode_video)) shooting_set_focus(to, SET_NOW);
1920    else shooting_set_focus(to, SET_LATER);
1921#else
1922    if (mode_video) shooting_set_focus(to, SET_NOW);
1923    else shooting_set_focus(to, SET_LATER);   
1924#endif   
1925    accept_cr();
1926}
1927
1928static void set_led_statement()
1929{
1930    int to, to1, to2;
1931    accept(TOKENIZER_SET_LED);
1932    to = expr();
1933    to1 = expr();
1934        to2 = 200;
1935        if (tokenizer_token() != TOKENIZER_CR && tokenizer_token() != TOKENIZER_ELSE ) {
1936                to2 = expr();
1937    }
1938        ubasic_set_led(to, to1, to2);
1939    accept_cr();
1940}
1941static void set_prop_statement()
1942{
1943    int to, to1;
1944    accept(TOKENIZER_SET_PROP);
1945    to = expr();
1946    to1 = expr();
1947        shooting_set_prop(to, to1);
1948    accept_cr();
1949}
1950
1951
1952
1953/*---------------------------------------------------------------------------*/
1954//ARM Begin
1955
1956
1957/*static void set_iso_market_statement()
1958{
1959    int to;
1960    accept(TOKENIZER_SET_ISO_MARKET);
1961    to = expr();
1962    shooting_set_iso_market(to);
1963    accept_cr();
1964}
1965
1966static void set_iso_real_delta_from_base_statement()
1967{
1968    int to;
1969    accept(TOKENIZER_SET_ISO_DL_F_B);
1970    to = expr();
1971    shooting_set_iso_real_delta_from_base(to);
1972    accept_cr();
1973}*/
1974
1975static void set_iso_real_statement()
1976{
1977    short int to;
1978    accept(TOKENIZER_SET_ISO_REAL);
1979    to = expr();
1980    shooting_set_iso_real(to, SET_LATER);
1981    accept_cr();
1982}
1983
1984//ARM End
1985
1986
1987static void set_iso_mode_statement()
1988{
1989    int to;
1990    accept(TOKENIZER_SET_ISO_MODE);
1991    to = expr();
1992    shooting_set_iso_mode(to);
1993    accept_cr();
1994}
1995static void set_raw_statement()
1996{
1997    int to;
1998    accept(TOKENIZER_SET_RAW);
1999    to = expr();
2000    ubasic_camera_set_raw(to);
2001    accept_cr();
2002}
2003static void set_raw_nr_statement()
2004{
2005    int to;
2006    accept(TOKENIZER_SET_RAW_NR);
2007    to = expr();
2008    ubasic_camera_set_nr(to);
2009    accept_cr();
2010}
2011
2012static void set_nd_filter_statement()
2013{
2014    int to;
2015    accept(TOKENIZER_SET_ND_FILTER);
2016    to = expr();
2017    shooting_set_nd_filter_state(to, SET_LATER);
2018    accept_cr();
2019}
2020
2021
2022static void set_autostart_statement()
2023{
2024    int to;
2025    accept(TOKENIZER_SET_SCRIPT_AUTOSTART);
2026    to = expr();
2027#ifndef UBASIC_TEST
2028        if (to >= 0 && to <= 2) conf.script_startup=to;
2029        conf_save();
2030#endif
2031    accept_cr();
2032}
2033static void exit_alt_statement()
2034{
2035    int to;
2036    accept(TOKENIZER_EXIT_ALT);
2037    to = expr();
2038    exit_alt(to);
2039    accept_cr();
2040}
2041
2042static void set_capture_mode_canon_statement()
2043{
2044    int to;
2045    accept(TOKENIZER_SET_CAPTURE_MODE_CANON);
2046    to = expr();
2047    // if the value as negative, assume it is a mistakenly sign extended PROPCASE_SHOOTING_MODE value
2048    if( to < 0)
2049        to &= 0xFFFF;
2050    shooting_set_mode_canon(to);
2051    accept_cr();
2052}
2053
2054static void set_capture_mode_statement()
2055{
2056    int to;
2057    accept(TOKENIZER_SET_CAPTURE_MODE);
2058    to = expr();
2059    shooting_set_mode_chdk(to);
2060    accept_cr();
2061}
2062
2063/*---------------------------------------------------------------------------*/
2064
2065static void wait_click_statement()
2066{
2067    int timeout=0;
2068    accept(TOKENIZER_WAIT_CLICK);
2069    if (tokenizer_token() != TOKENIZER_CR &&
2070        tokenizer_token() != TOKENIZER_ELSE ) {
2071        timeout = expr();
2072    }
2073    ubasic_camera_wait_click(timeout);
2074    accept_cr();
2075}
2076
2077static void is_key_statement(void)
2078{
2079    int var;
2080    accept(TOKENIZER_IS_KEY);
2081    var = tokenizer_variable_num();
2082    accept(TOKENIZER_VARIABLE);
2083    tokenizer_string(string, sizeof(string));
2084    tokenizer_next();
2085    ubasic_set_variable(var, ubasic_camera_is_clicked(string));
2086    DEBUG_PRINTF("End of is_key\n");
2087    accept_cr();
2088}
2089
2090static void wheel_left_statement(void){
2091  accept(TOKENIZER_WHEEL_LEFT);
2092#ifdef CAM_HAS_JOGDIAL
2093  JogDial_CCW();
2094#endif
2095  accept_cr();
2096}
2097
2098
2099static void wheel_right_statement(void){
2100  accept(TOKENIZER_WHEEL_RIGHT);
2101#ifdef CAM_HAS_JOGDIAL
2102  JogDial_CW();
2103#endif
2104  accept_cr();
2105}
2106
2107static void set_backlight_statement(void)
2108{
2109  int val;
2110  accept(TOKENIZER_SET_BACKLIGHT);
2111  val = expr();
2112  if (val > 0) TurnOnBackLight();
2113  else TurnOffBackLight();
2114  accept_cr();
2115}
2116
2117static void
2118set_aflock_statement(void)
2119{
2120  int val;
2121  accept(TOKENIZER_SET_AFLOCK);
2122  val = expr();
2123  if (val>0) DoAFLock();  // 1: enable AFLock
2124  else UnlockAF();       // 0: disable unlock AF
2125  accept_cr();
2126}
2127
2128
2129static void shutdown_statement(void){
2130  accept(TOKENIZER_SHUT_DOWN);
2131  camera_shutdown_in_a_second();
2132  accept_cr();
2133}
2134
2135/*---------------------------------------------------------------------------*/
2136
2137static void md_get_cell_diff_statement()
2138{
2139    int var, col, row;
2140    accept(TOKENIZER_MD_GET_CELL_DIFF);
2141
2142                col=expr();tokenizer_next();
2143
2144                row=expr();tokenizer_next();
2145
2146    var = tokenizer_variable_num();
2147    accept(TOKENIZER_VARIABLE);
2148       
2149    ubasic_set_variable(var, md_get_cell_diff(col,row));
2150    accept_cr();
2151}
2152
2153static void md_detect_motion_statement()
2154{
2155
2156 int columns;
2157 int rows;
2158 int pixel_measure_mode;
2159 int detection_timeout;
2160 int measure_interval;
2161 int threshold;
2162 int draw_grid=0;
2163 int clipping_region_mode=0;
2164 int clipping_region_row1=0;
2165 int clipping_region_column1=0;
2166 int clipping_region_row2=0;
2167 int clipping_region_column2=0;
2168 int ret_var_num;
2169 int parameters=0;
2170 int pixels_step=1;
2171 int msecs_before_trigger=0;
2172
2173 //static char buf[128];
2174
2175    accept(TOKENIZER_MD_DETECT_MOTION);
2176
2177//              sprintf(buf,"token: %d",tokenizer_token()); script_console_add_line(buf);
2178                columns=expr();tokenizer_next();
2179
2180//              sprintf(buf,"tk: %d",tokenizer_token()); script_console_add_line(buf);
2181                rows=expr();tokenizer_next();
2182
2183//              sprintf(buf,"tk %d",tokenizer_token()); script_console_add_line(buf);
2184                pixel_measure_mode=expr();tokenizer_next();
2185
2186                detection_timeout=expr();tokenizer_next();
2187
2188//              printf("token: %d",tokenizer_token());
2189                measure_interval=expr();tokenizer_next();
2190
2191//              printf("token: %d",tokenizer_token());
2192                threshold=expr();tokenizer_next();
2193
2194//              printf("token: %d",tokenizer_token());
2195                draw_grid=expr();tokenizer_next();
2196
2197//              printf("token: %d",tokenizer_token());
2198    ret_var_num = tokenizer_variable_num();
2199
2200//              printf("%d,%d,%d,%d",columns,rows,pixel_measure_mode, detection_timeout);
2201
2202    accept(TOKENIZER_VARIABLE);
2203
2204
2205    if (tokenizer_token() != TOKENIZER_CR && tokenizer_token() != TOKENIZER_ELSE) {
2206                        // eat COMA     
2207//                      tokenizer_next();
2208                }
2209
2210
2211               
2212    if (tokenizer_token() != TOKENIZER_CR && tokenizer_token() != TOKENIZER_ELSE) {
2213                                tokenizer_next();
2214        clipping_region_mode = expr();
2215    }
2216    if (tokenizer_token() != TOKENIZER_CR && tokenizer_token() != TOKENIZER_ELSE ) {
2217                                tokenizer_next();
2218        clipping_region_column1 = expr();
2219    }
2220    if (tokenizer_token() != TOKENIZER_CR && tokenizer_token() != TOKENIZER_ELSE ) {
2221                                tokenizer_next();
2222        clipping_region_row1 = expr();
2223    }
2224    if (tokenizer_token() != TOKENIZER_CR && tokenizer_token() != TOKENIZER_ELSE ) {
2225                                tokenizer_next();
2226        clipping_region_column2 = expr();
2227    }
2228    if (tokenizer_token() != TOKENIZER_CR && tokenizer_token() != TOKENIZER_ELSE ) {
2229                                tokenizer_next();
2230        clipping_region_row2 = expr();
2231    }
2232    if (tokenizer_token() != TOKENIZER_CR && tokenizer_token() != TOKENIZER_ELSE ) {
2233                                tokenizer_next();
2234        parameters = expr();
2235    }
2236    if (tokenizer_token() != TOKENIZER_CR && tokenizer_token() != TOKENIZER_ELSE ) {
2237                                tokenizer_next();
2238        pixels_step = expr();
2239    }
2240
2241    if (tokenizer_token() != TOKENIZER_CR && tokenizer_token() != TOKENIZER_ELSE ) {
2242                                tokenizer_next();
2243        msecs_before_trigger = expr();
2244    }
2245                       
2246
2247    accept_cr();
2248
2249//              sprintf(buf,"[%dx%d] md:%d tmout:%d", columns, rows, pixel_measure_mode, detection_timeout);
2250//              script_console_add_line(buf);
2251
2252//              sprintf(buf,"int:%d trsh:%d g:%d vr:%d", measure_interval, threshold, draw_grid, ret_var_num);
2253//              script_console_add_line(buf);
2254
2255//              sprintf(buf,"clip %d [%d,%d][%d,%d]", clipping_region_mode, clipping_region_column1, clipping_region_row1, clipping_region_column2,clipping_region_row2);
2256//              script_console_add_line(buf);
2257
2258        md_init_motion_detector(
2259                        columns, rows, pixel_measure_mode, detection_timeout,
2260                        measure_interval, threshold, draw_grid, ret_var_num,
2261                        clipping_region_mode,
2262                        clipping_region_column1, clipping_region_row1,
2263                        clipping_region_column2, clipping_region_row2,
2264                        parameters, pixels_step, msecs_before_trigger
2265        );
2266}
2267
2268/*---------------------------------------------------------------------------*/
2269
2270static void shot_histo_enable_statement()
2271{
2272    int to;
2273    accept(TOKENIZER_SHOT_HISTO_ENABLE);
2274    to = expr();
2275    shot_histogram_set(to);
2276    accept_cr();
2277}
2278
2279static void set_record_statement()
2280{
2281    int to;
2282    accept(TOKENIZER_SET_RECORD);
2283    to = expr();
2284    if(to) {
2285        levent_set_record();
2286    }
2287    else {
2288        levent_set_play();
2289    }
2290    accept_cr();
2291}
2292
2293
2294static void
2295statement(void)
2296{
2297  ubasic_token token;
2298
2299  token = tokenizer_token();
2300
2301  switch(token) {
2302// aflock
2303  case TOKENIZER_SET_AFLOCK:
2304    set_aflock_statement();
2305    break;
2306
2307  case TOKENIZER_PRINT_SCREEN:
2308    print_screen_statement();
2309    break;
2310  case TOKENIZER_PRINT:
2311    print_statement();
2312    break;
2313
2314  case TOKENIZER_SLEEP:
2315    sleep_statement();
2316    break;
2317  case TOKENIZER_CLICK:
2318    click_statement();
2319    break;
2320  case TOKENIZER_PRESS:
2321    press_statement();
2322    break;
2323  case TOKENIZER_RELEASE:
2324    release_statement();
2325    break;
2326  case TOKENIZER_SHOOT:
2327    shoot_statement();
2328    break;
2329#ifdef INCLUDE_OLD_GET__SYNTAX
2330  case TOKENIZER_GET_TV96:
2331    get_tv96_statement();
2332    break;
2333  case TOKENIZER_GET_USER_TV96:
2334    get_user_tv96_statement();
2335    break;   
2336  case TOKENIZER_GET_USER_TV_ID:
2337    get_user_tv_id_statement();
2338    break;
2339  case TOKENIZER_GET_AV96:
2340    get_av96_statement();
2341    break; 
2342  case TOKENIZER_GET_USER_AV96:
2343    get_user_av96_statement();
2344    break;   
2345  case TOKENIZER_GET_USER_AV_ID:
2346    get_user_av_id_statement();
2347    break;
2348  case TOKENIZER_GET_ZOOM:
2349    get_zoom_statement();
2350    break;
2351  case TOKENIZER_GET_FOCUS:
2352    get_focus_statement();
2353    break;
2354  case TOKENIZER_GET_NEAR_LIMIT:
2355    get_near_limit_statement();
2356    break;
2357  case TOKENIZER_GET_FAR_LIMIT:
2358    get_far_limit_statement();
2359    break; 
2360  case TOKENIZER_GET_DOF:
2361    get_dof_statement();
2362    break;
2363  case TOKENIZER_GET_HYPERFOCAL_DIST:
2364    get_hyperfocal_distance_statement();
2365    break; 
2366  case TOKENIZER_GET_ISO_MARKET:
2367    get_iso_market_statement();
2368    break;
2369  case TOKENIZER_GET_ISO_REAL:
2370    get_iso_real_statement();
2371    break;
2372  case TOKENIZER_GET_BV96:
2373    get_bv96_statement();
2374    break; 
2375  case TOKENIZER_GET_SV96:
2376    get_sv96_statement();
2377    break;   
2378  case TOKENIZER_GET_ISO_MODE:
2379    get_iso_mode_statement();
2380    break;
2381  case TOKENIZER_GET_VBATT:
2382    get_vbatt_statement();
2383    break;
2384  case TOKENIZER_GET_DISK_SIZE:
2385    get_disk_size_statement();
2386    break;
2387  case TOKENIZER_GET_FREE_DISK_SPACE:
2388    get_free_disk_space_statement();
2389    break;
2390  case TOKENIZER_GET_JPG_COUNT:
2391    get_jpg_count_statement();
2392    break;
2393  case TOKENIZER_GET_RAW_COUNT:
2394    get_raw_count_statement();
2395    break;
2396  case TOKENIZER_GET_PROP:
2397    get_prop_statement();
2398    break;
2399#endif
2400  case TOKENIZER_SET_TV96_DIRECT:
2401    set_tv96_direct_statement();
2402    break;   
2403  case TOKENIZER_SET_TV96:
2404    set_tv96_statement();
2405    break; 
2406  case TOKENIZER_PLAY_SOUND:
2407    play_sound_statement();
2408    break; 
2409  case TOKENIZER_SET_SHUTTER_SPEED:
2410    set_shutter_speed_statement();
2411    break;   
2412  case TOKENIZER_SET_USER_TV96:
2413    set_user_tv96_statement();
2414    break;   
2415  case TOKENIZER_SET_USER_TV_BY_ID:
2416    set_user_tv_by_id_statement();
2417    break;
2418  case TOKENIZER_SET_USER_TV_BY_ID_REL:
2419    set_user_tv_by_id_rel_statement();
2420    break;
2421  case TOKENIZER_SET_AV96_DIRECT:
2422    set_av96_direct_statement();
2423    break;   
2424  case TOKENIZER_SET_AV96:
2425    set_av96_statement();
2426    break; 
2427   
2428  case TOKENIZER_SET_USER_AV96:
2429    set_user_av96_statement();
2430    break;   
2431  case TOKENIZER_SET_USER_AV_BY_ID:
2432    set_user_av_by_id_statement();
2433    break;
2434  case TOKENIZER_SET_USER_AV_BY_ID_REL:
2435    set_user_av_by_id_rel_statement();
2436    break;
2437   
2438  case TOKENIZER_SET_ND_FILTER:
2439    set_nd_filter_statement();
2440    break; 
2441 
2442  case TOKENIZER_SET_ZOOM:
2443    set_zoom_statement();
2444    break;
2445  case TOKENIZER_SET_ZOOM_REL:
2446    set_zoom_rel_statement();
2447    break;
2448  case TOKENIZER_SET_ZOOM_SPEED:
2449    set_zoom_speed_statement();
2450    break;
2451
2452  case TOKENIZER_SET_FOCUS:
2453    set_focus_statement();
2454    break;
2455  //ARM Begin
2456  /*case TOKENIZER_SET_ISO_MARKET:
2457    set_iso_market_statement();
2458    break;
2459  case TOKENIZER_SET_ISO_DL_F_B:
2460    set_iso_real_delta_from_base_statement();
2461    break;*/ 
2462  case TOKENIZER_SET_ISO_REAL:
2463    set_iso_real_statement();
2464    break;
2465  case TOKENIZER_SET_SV96:
2466    set_sv96_statement();
2467    break; 
2468 
2469  //ARM End
2470 
2471   
2472
2473  case TOKENIZER_SET_ISO_MODE:
2474    set_iso_mode_statement();
2475    break;
2476
2477  case TOKENIZER_SET_PROP:
2478    set_prop_statement();
2479    break;
2480  case TOKENIZER_SET_LED:
2481    set_led_statement();
2482    break;
2483
2484  case TOKENIZER_SET_EV:
2485        set_ev_statement();
2486   break;
2487   
2488    case TOKENIZER_SET_MOVIE_STATUS:
2489        set_movie_status_statement();
2490   break;
2491   case TOKENIZER_SET_RESOLUTION:
2492        set_resolution_statement();
2493   break;
2494   case TOKENIZER_SET_QUALITY:
2495        set_quality_statement();
2496   break;
2497
2498  case TOKENIZER_WAIT_CLICK:
2499    wait_click_statement();
2500    break;
2501  case TOKENIZER_IS_KEY:
2502    is_key_statement();
2503    break;
2504
2505  case TOKENIZER_WHEEL_LEFT:
2506    wheel_left_statement();
2507    break;
2508  case TOKENIZER_WHEEL_RIGHT:
2509    wheel_right_statement();
2510    break;
2511
2512  case TOKENIZER_IF:
2513    if_statement();
2514    break;
2515  case TOKENIZER_ELSE:
2516    else_statement();
2517    break;
2518  case TOKENIZER_ENDIF:
2519    endif_statement();
2520    break;
2521  case TOKENIZER_SELECT:
2522    select_statement();
2523    break;
2524  case TOKENIZER_CASE:
2525    case_statement();
2526    break;
2527  case TOKENIZER_CASE_ELSE:
2528    case_else_statement();
2529    break;
2530  case TOKENIZER_GOTO:
2531    goto_statement();
2532    break;
2533  case TOKENIZER_GOSUB:
2534    gosub_statement();
2535    break;
2536  case TOKENIZER_RETURN:
2537    return_statement();
2538    break;
2539  case TOKENIZER_FOR:
2540    for_statement();
2541    break;
2542  case TOKENIZER_NEXT:
2543    next_statement();
2544    break;
2545  case TOKENIZER_DO:
2546    do_statement();
2547    break;
2548  case TOKENIZER_UNTIL:
2549    until_statement();
2550    break;
2551  case TOKENIZER_WHILE:
2552    while_statement();
2553    break;
2554  case TOKENIZER_WEND:
2555    wend_statement();
2556    break;
2557  case TOKENIZER_END:
2558    end_statement();
2559    break;
2560  case TOKENIZER_LET:
2561    accept(TOKENIZER_LET);
2562    /* Fall through. */
2563  case TOKENIZER_VARIABLE:
2564    let_statement();
2565    break;
2566  case TOKENIZER_REM:
2567    rem_statement();
2568    break;
2569  case TOKENIZER_CLS:
2570    cls_statement();
2571    break;
2572  case TOKENIZER_SET_RAW:
2573    set_raw_statement();
2574    break;
2575  case TOKENIZER_SET_RAW_NR:
2576    set_raw_nr_statement();
2577    break;
2578  case TOKENIZER_SET_SCRIPT_AUTOSTART:
2579    set_autostart_statement();
2580    break;
2581  case TOKENIZER_EXIT_ALT:
2582    exit_alt_statement();
2583    break;
2584  case TOKENIZER_SHUT_DOWN:
2585    shutdown_statement();
2586    break;
2587  case TOKENIZER_SET_BACKLIGHT:
2588    set_backlight_statement();
2589    break;
2590
2591// >> mx3 . motion detector
2592        case   TOKENIZER_MD_DETECT_MOTION:
2593                md_detect_motion_statement();
2594                break;
2595        case  TOKENIZER_MD_GET_CELL_DIFF:
2596                md_get_cell_diff_statement();
2597                break;
2598// << mx3 . motion_detector
2599
2600  case TOKENIZER_SHOT_HISTO_ENABLE:
2601    shot_histo_enable_statement();
2602    break;
2603
2604  case TOKENIZER_SET_RECORD:
2605    set_record_statement();
2606    break;
2607
2608  case TOKENIZER_SET_CAPTURE_MODE:
2609    set_capture_mode_statement();
2610    break;
2611
2612  case TOKENIZER_SET_CAPTURE_MODE_CANON:
2613    set_capture_mode_canon_statement();
2614    break;
2615
2616
2617  default:
2618    DEBUG_PRINTF("ubasic.c: statement(): not implemented %d\n", token);
2619    ended = 1;
2620    ubasic_error = UBASIC_E_UNK_STATEMENT;
2621  }
2622}
2623/*---------------------------------------------------------------------------*/
2624static void
2625line_statement(void)
2626{
2627  /* line numbers have been removed */
2628  DEBUG_PRINTF("----------- Line number %d ---------\n", tokenizer_line_number());
2629  /*    current_linenum = tokenizer_num();*/
2630#if 0
2631  if (tokenizer_token() == TOKENIZER_LABEL) {
2632#ifdef DEBUG
2633      tokenizer_label(string, sizeof(string));
2634      DEBUG_PRINTF("line_statement: label: %s\n", string );
2635#endif
2636      accept(TOKENIZER_LABEL);
2637      accept(TOKENIZER_CR);
2638      return;
2639  }
2640#endif
2641  /* reyalp - eat up to 100 labels or rems at a time so they don't cost 10ms each */
2642  int count = 100;
2643  do {
2644    int r=tokenizer_token();
2645    if ( r == TOKENIZER_LABEL ) {
2646      /* hit limit and we are on a label, return */
2647      if( count == 1 )
2648        return;
2649#ifdef DEBUG
2650      tokenizer_label(string, sizeof(string));
2651      DEBUG_PRINTF("line_statement: label: %s\n", string );
2652#endif
2653      accept(TOKENIZER_LABEL);
2654      accept(TOKENIZER_CR);
2655    }
2656    else if ( r == TOKENIZER_REM ) {
2657      rem_statement();
2658    }
2659  } while(--count);
2660  statement();
2661  return;
2662}
2663/*---------------------------------------------------------------------------*/
2664void
2665ubasic_run(void)
2666{
2667  if(tokenizer_finished()) {
2668    DEBUG_PRINTF("uBASIC program finished\n");
2669    return;
2670  }
2671
2672  line_statement();
2673}
2674/*---------------------------------------------------------------------------*/
2675int
2676ubasic_finished(void)
2677{
2678  return ended || tokenizer_finished();
2679}
2680/*---------------------------------------------------------------------------*/
2681void
2682ubasic_set_variable(int varnum, int value)
2683{
2684  if(varnum >= 0 && varnum < MAX_VARNUM) {
2685    variables[varnum] = value;
2686  }
2687}
2688/*---------------------------------------------------------------------------*/
2689int
2690ubasic_get_variable(int varnum)
2691{
2692  if(varnum >= 0 && varnum < MAX_VARNUM) {
2693    return variables[varnum];
2694  }
2695  return 0;
2696}
2697/*---------------------------------------------------------------------------*/
2698void
2699ubasic_end() {
2700}
2701/*---------------------------------------------------------------------------*/
Note: See TracBrowser for help on using the repository browser.