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

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