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

Revision 1042, 69.2 KB checked in by reyalP, 2 years ago (diff)

fix ubasic click, press and release, broken in r1036

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