うおーるぼっと版 豊四季タイニーBASIC
Dependencies: BufferSerial Servo TB6612FNG2 mbed
ttbasic.cpp
00001 /* 00002 TOYOSHIKI TinyBASIC V1.0 00003 Reference source 00004 (C)2012 Tetsuya Suzuki, All rights reserved. 00005 */ 00006 00007 // Compiler requires description 00008 //#include <stdlib.h> 00009 //#include "sci.h" 00010 #include "mbed.h" 00011 #include "BufferSerial.h" 00012 #include "Servo.h" 00013 #include "TB6612.h" 00014 00015 LocalFileSystem local("local"); // Create the local filesystem under the name "local" 00016 BufferSerial pc(USBTX, USBRX, 2000); 00017 //BufferSerial pc(p9, p10, 2000); 00018 Servo servo0(p25); 00019 Servo servo1(p26); 00020 TB6612 left(p21,p12,p11); 00021 TB6612 right(p22,p14,p13); 00022 DigitalOut out0(LED1); 00023 DigitalOut out1(LED2); 00024 DigitalOut out2(LED3); 00025 DigitalOut out3(LED4); 00026 DigitalIn in0(p29); //SW2 00027 DigitalIn in1(p30); //SW3 00028 AnalogIn ain0(p15); //Photo0 00029 AnalogIn ain1(p16); //Photo1 00030 AnalogIn ain2(p17); //Photo2 00031 AnalogIn ain3(p18); //Photo3 00032 00033 void io_init() 00034 { 00035 pc.baud(115200); 00036 in0.mode(PullUp); 00037 in1.mode(PullUp); 00038 out0 = 0; out1 = 0; out2 = 0; out3 = 0; 00039 servo0.calibrate(0.0009,180.0); 00040 servo1.calibrate(0.0009,180.0); 00041 // servo0.calibrate(0.0006,180.0); //RS306MD 00042 // servo1.calibrate(0.0006,180.0); //RS306MD 00043 servo0 = 0.5; servo1 = 0.5; 00044 left = 0; 00045 right = 0; 00046 00047 } 00048 00049 // Depending on device functions 00050 // TO-DO Rewrite these functions to fit your machine 00051 // And see 'getrnd()' 00052 //void c_putch(char c){putch2(c);} 00053 //char c_getch(){return getch2();} 00054 //char c_kbhit(){return(kbhit2());} 00055 void c_putch(char c){pc.putc(c);} 00056 char c_getch(){return pc.getc();} 00057 char c_kbhit(){return(pc.readable());} 00058 void newline(void){ 00059 c_putch(13); //CR 00060 c_putch(10); //LF 00061 } 00062 00063 // TOYOSHIKI TinyBASIC symbols 00064 // TO-DO Rewrite defined values to fit your machine as needed 00065 #define SIZE_LINE 64 //Command line buffer length + NULL 00066 #define SIZE_IBUF 64 //i-code conversion buffer size 00067 #define SIZE_LIST 1024 //List buffer size 00068 #define SIZE_ARRY 32 //Array area size 00069 #define SIZE_GSTK 6 //GOSUB stack size(2/nest) 00070 #define SIZE_LSTK 15 //FOR stack size(5/nest) 00071 00072 // RAM mapping 00073 char lbuf[SIZE_LINE]; //Command line buffer 00074 unsigned char ibuf[SIZE_IBUF]; //i-code conversion buffer 00075 short var[26]; //Variable area 00076 short arr[SIZE_ARRY]; //Array area 00077 unsigned char listbuf[SIZE_LIST]; //List area 00078 unsigned char* clp; //Pointer current line 00079 unsigned char* cip; //Pointer current Intermediate code 00080 unsigned char* gstk[SIZE_GSTK]; //GOSUB stack 00081 unsigned char gstki; //GOSUB stack index 00082 unsigned char* lstk[SIZE_LSTK]; //FOR stack 00083 unsigned char lstki; //FOR stack index 00084 00085 // Prototypes (necessity minimum) 00086 short iexp(void); 00087 00088 // Keyword table 00089 const char* kwtbl[] = { 00090 "GOTO", "GOSUB", "RETURN", 00091 "FOR", "TO", "STEP", "NEXT", 00092 "IF", "REM", "STOP", 00093 // "INPUT", "PRINT", "LET", 00094 "INPUT", "PRINT", "OUT", "SERVO", "WAIT", "MOVE", "LET", 00095 ",", ";", 00096 "-", "+", "*", "/", "(", ")", 00097 ">=", "#", ">", "=", "<=", "<", 00098 // "@", "RND", "ABS", "SIZE", 00099 "@", "RND", "ABS", "INP", "AIN", "SIZE", 00100 // "LIST", "RUN", "NEW" 00101 "LIST", "RUN", "LOAD", "NEW" 00102 }; 00103 00104 // Keyword count 00105 #define SIZE_KWTBL (sizeof(kwtbl) / sizeof(const char*)) 00106 00107 // i-code(Intermediate code) assignment 00108 enum{ 00109 I_GOTO, I_GOSUB, I_RETURN, 00110 I_FOR, I_TO, I_STEP, I_NEXT, 00111 I_IF, I_REM, I_STOP, 00112 // I_INPUT, I_PRINT, I_LET, 00113 I_INPUT, I_PRINT, I_OUT, I_SERVO, I_WAIT, I_MOVE, I_LET, 00114 I_COMMA, I_SEMI, 00115 I_MINUS, I_PLUS, I_MUL, I_DIV, I_OPEN, I_CLOSE, 00116 I_GTE, I_SHARP, I_GT, I_EQ, I_LTE, I_LT, 00117 // I_ARRAY, I_RND, I_ABS, I_SIZE, 00118 I_ARRAY, I_RND, I_ABS, I_INP, I_AIN, I_SIZE, 00119 // I_LIST, I_RUN, I_NEW, 00120 I_LIST, I_RUN, I_LOAD, I_NEW, 00121 I_NUM, I_VAR, I_STR, 00122 I_EOL 00123 }; 00124 00125 // List formatting condition 00126 #define IS_OP(p) (p >= I_MINUS && p <= I_LT) // Operator style 00127 #define IS_SEP(p) (p == I_COMMA || p == I_SEMI) // Separator style 00128 #define IS_TOKSP(p) (/*p >= I_GOTO && */p <= I_LET && p != I_RETURN) // Token style 00129 00130 // Error messages 00131 unsigned char err;// Error message index 00132 const char* errmsg[] ={ 00133 "OK", 00134 "Devision by zero", 00135 "Overflow", 00136 "Subscript out of range", 00137 "Icode buffer full", 00138 "List full", 00139 "GOSUB too many nested", 00140 "RETURN stack underflow", 00141 "FOR too many nested", 00142 "NEXT without FOR", 00143 "NEXT without counter", 00144 "NEXT mismatch FOR", 00145 "FOR without variable", 00146 "FOR without TO", 00147 "LET without variable", 00148 "IF without condition", 00149 "Undefined line number", 00150 "\'(\' or \')\' expected", 00151 "\'=\' expected", 00152 "Illegal command", 00153 "Syntax error", 00154 "Internal error", 00155 "Abort by [ESC]" 00156 }; 00157 00158 // Error code assignment 00159 enum{ 00160 ERR_OK, 00161 ERR_DIVBY0, 00162 ERR_VOF, 00163 ERR_SOL, 00164 ERR_IBUFOF, 00165 ERR_LBUFOF, 00166 ERR_GSTKOF, 00167 ERR_GSTKUF, 00168 ERR_LSTKOF, 00169 ERR_LSTKUF, 00170 ERR_NEXTWOV, 00171 ERR_NEXTUM, 00172 ERR_FORWOV, 00173 ERR_FORWOTO, 00174 ERR_LETWOV, 00175 ERR_IFWOC, 00176 ERR_ULN, 00177 ERR_PAREN, 00178 ERR_VWOEQ, 00179 ERR_COM, 00180 ERR_SYNTAX, 00181 ERR_SYS, 00182 ERR_ESC 00183 }; 00184 00185 // Standard C libraly (about same) functions 00186 char c_toupper(char c) {return(c <= 'z' && c >= 'a' ? c - 32 : c);} 00187 char c_isprint(char c) {return(c >= 32 && c <= 126);} 00188 char c_isspace(char c) {return(c <= ' ' &&(c == ' ' || (c <= 13 && c >= 9)));} 00189 char c_isdigit(char c) {return(c <= '9' && c >= '0');} 00190 char c_isalpha(char c) {return ((c <= 'z' && c >= 'a') || (c <= 'Z' && c >= 'A'));} 00191 char* c_strchr(char *s, char c){ 00192 while(*s) { 00193 if(*s == c) return (s); 00194 ++s; 00195 } 00196 return NULL; 00197 } 00198 void c_puts(const char *s) {while(*s) c_putch(*s++);} 00199 void c_gets(){ 00200 char c; 00201 unsigned char len; 00202 00203 len = 0; 00204 while((c = c_getch()) != 13){ 00205 if( c == 9) c = ' '; // TAB exchange Space 00206 if((c == 8) && (len > 0)){ // Backspace manipulation 00207 len--; 00208 c_putch(8); c_putch(' '); c_putch(8); 00209 } else 00210 if(c_isprint(c) && (len < (SIZE_LINE - 1))){ 00211 lbuf[len++] = c; 00212 c_putch(c); 00213 } 00214 } 00215 newline(); 00216 lbuf[len] = 0; // Put NULL 00217 00218 if(len > 0){ 00219 while(c_isspace(lbuf[--len])); // Skip space 00220 lbuf[++len] = 0; // Put NULL 00221 } 00222 } 00223 00224 // GOSUB-RETURN stack 00225 void gpush(unsigned char* pd){ 00226 if(gstki < SIZE_GSTK){ 00227 gstk[gstki++] = pd; 00228 return; 00229 } 00230 err = ERR_GSTKOF; 00231 } 00232 00233 unsigned char* gpop(){ 00234 if(gstki > 0){ 00235 return gstk[--gstki]; 00236 } 00237 err = ERR_GSTKUF; 00238 return NULL; 00239 } 00240 00241 // FOR-NEXT stack 00242 void lpush(unsigned char* pd){ 00243 if(lstki < SIZE_LSTK){ 00244 lstk[lstki++] = pd; 00245 return; 00246 } 00247 err = ERR_LSTKOF; 00248 } 00249 00250 unsigned char* lpop(){ 00251 if(lstki > 0){ 00252 return lstk[--lstki]; 00253 } 00254 err = ERR_LSTKUF; 00255 return NULL; 00256 } 00257 00258 // Print OK or error message 00259 void error() 00260 { 00261 newline(); 00262 c_puts(errmsg[err]); 00263 newline(); 00264 err = 0; 00265 } 00266 00267 // Print numeric specified columns 00268 void putnum(short value, short d){ 00269 unsigned char i; 00270 unsigned char sign; 00271 00272 if(value < 0){ 00273 sign = 1; 00274 value = -value; 00275 } else { 00276 sign = 0; 00277 } 00278 00279 lbuf[6] = 0; 00280 i = 6; 00281 do { 00282 lbuf[--i] = (value % 10) + '0'; 00283 value /= 10; 00284 } while(value > 0); 00285 00286 if(sign) 00287 lbuf[--i] = '-'; 00288 00289 //String length = 6 - i 00290 while(6 - i < d){ // If short 00291 c_putch(' '); // Fill space 00292 d--; 00293 } 00294 c_puts(&lbuf[i]); 00295 } 00296 00297 // Input numeric and return value 00298 // Called by only INPUT statement 00299 short getnum(){ 00300 short value, tmp; 00301 char c; 00302 unsigned char len; 00303 unsigned char sign; 00304 00305 len = 0; 00306 while((c = c_getch()) != 13){ 00307 if((c == 8) && (len > 0)){ // Backspace manipulation 00308 len--; 00309 c_putch(8); c_putch(' '); c_putch(8); 00310 } else 00311 if( (len == 0 && (c == '+' || c == '-')) || 00312 (len < 6 && c_isdigit(c))){ // Numeric or sign only 00313 lbuf[len++] = c; 00314 c_putch(c); 00315 } 00316 } 00317 newline(); 00318 lbuf[len] = 0; 00319 00320 switch(lbuf[0]){ 00321 case '-': 00322 sign = 1; 00323 len = 1; 00324 break; 00325 case '+': 00326 sign = 0; 00327 len = 1; 00328 break; 00329 default: 00330 sign = 0; 00331 len = 0; 00332 break; 00333 } 00334 00335 value = 0; // Initialize value 00336 tmp = 0; // Temp value 00337 while(lbuf[len]){ 00338 tmp = 10 * value + lbuf[len++] - '0'; 00339 if(value > tmp){ // It means overflow 00340 err = ERR_VOF; 00341 } 00342 value = tmp; 00343 } 00344 if(sign) 00345 return -value; 00346 return value; 00347 } 00348 00349 // Byte X,L,H -> Short HL 00350 // Used to get line number or I_NUM value 00351 short getvalue(unsigned char* ip){ 00352 if(*ip == 0) 00353 return 32767; // Case X = 0 00354 return((short)*(ip + 1) + ((short)*(ip + 2) << 8)); 00355 } 00356 00357 // Get argument in parenthesis 00358 short getparam(){ 00359 short value; 00360 00361 if(*cip != I_OPEN){ 00362 err = ERR_PAREN; 00363 return 0; 00364 } 00365 cip++; 00366 value = iexp(); 00367 if(err) return 0; 00368 00369 if(*cip != I_CLOSE){ 00370 err = ERR_PAREN; 00371 return 0; 00372 } 00373 cip++; 00374 00375 return value; 00376 } 00377 00378 // Search line by line number 00379 unsigned char* getlp(short lineno){ 00380 unsigned char *lp; 00381 00382 lp = listbuf; 00383 while(*lp){ 00384 if(getvalue(lp) >= lineno) 00385 break; 00386 lp += *lp; 00387 } 00388 return lp; 00389 } 00390 00391 // Convert token to i-code 00392 // Return byte length or 0 00393 unsigned char toktoi(){ 00394 unsigned char i; // Loop counter(i-code sometime) 00395 unsigned char len; //byte counter 00396 short value; 00397 short tmp; 00398 char* pkw; // Temporary keyword pointer 00399 char* ptok; // Temporary token pointer 00400 char c; // Surround the string character, " or ' 00401 char* s; // Pointer to charactor at line buffer 00402 00403 s = lbuf; 00404 len = 0; // Clear byte length 00405 while(*s){ 00406 while(c_isspace(*s)) s++; // Skip space 00407 00408 //Try keyword conversion 00409 for(i = 0; i < SIZE_KWTBL; i++){ 00410 pkw = (char *)kwtbl[i]; // Point keyword 00411 ptok = s; // Point top of command line 00412 // Compare 00413 while((*pkw != 0) && (*pkw == c_toupper(*ptok))){ 00414 pkw++; 00415 ptok++; 00416 } 00417 if(*pkw == 0){// Case success 00418 // i have i-code 00419 if(len >= SIZE_IBUF - 1){// List area full 00420 err = ERR_IBUFOF; 00421 return 0; 00422 } 00423 ibuf[len++] = i; 00424 s = ptok; 00425 break; 00426 } 00427 } 00428 00429 // Case statement needs an argument except numeric, valiable, or strings 00430 switch(i){ 00431 case I_REM: 00432 while(c_isspace(*s)) s++; // Skip space 00433 ptok = s; 00434 for(i = 0; *ptok++; i++); // Get length 00435 if(len >= SIZE_IBUF - 2 - i){ 00436 err = ERR_IBUFOF; 00437 return 0; 00438 } 00439 ibuf[len++] = i; // Put length 00440 while(i--){ // Copy strings 00441 ibuf[len++] = *s++; 00442 } 00443 return len; 00444 default: 00445 break; 00446 } 00447 00448 if(*pkw != 0){ // Case not keyword 00449 ptok = s; // Point top of command line 00450 00451 // Try numeric conversion 00452 if(c_isdigit(*ptok)){ 00453 value = 0; 00454 tmp = 0; 00455 do{ 00456 tmp = 10 * value + *ptok++ - '0'; 00457 if(value > tmp){ 00458 err = ERR_VOF; 00459 return 0; 00460 } 00461 value = tmp; 00462 } while(c_isdigit(*ptok)); 00463 00464 if(len >= SIZE_IBUF - 3){ 00465 err = ERR_IBUFOF; 00466 return 0; 00467 } 00468 s = ptok; 00469 ibuf[len++] = I_NUM; 00470 ibuf[len++] = value & 255; 00471 ibuf[len++] = value >> 8; 00472 } else 00473 00474 // Try valiable conversion 00475 if(c_isalpha(*ptok)){ 00476 if(len >= SIZE_IBUF - 2){ 00477 err = ERR_IBUFOF; 00478 return 0; 00479 } 00480 if(len >= 2 && ibuf[len -2] == I_VAR){ // Case series of variables 00481 err = ERR_SYNTAX; // Syntax error 00482 return 0; 00483 } 00484 ibuf[len++] = I_VAR; // Put i-code 00485 ibuf[len++] = c_toupper(*ptok) - 'A'; // Put index of valiable area 00486 s++; 00487 } else 00488 00489 // Try string conversion 00490 if(*s == '\"' || *s == '\''){// If start of string 00491 c = *s; 00492 s++; // Skip " or ' 00493 ptok = s; 00494 for(i = 0; (*ptok != c) && c_isprint(*ptok); i++) // Get length 00495 ptok++; 00496 if(len >= SIZE_IBUF - 1 - i){ // List area full 00497 err = ERR_IBUFOF; 00498 return 0; 00499 } 00500 ibuf[len++] = I_STR; // Put i-code 00501 ibuf[len++] = i; // Put length 00502 while(i--){ // Put string 00503 ibuf[len++] = *s++; 00504 } 00505 if(*s == c) s++; // Skip " or ' 00506 00507 // Nothing mutch 00508 } else { 00509 err = ERR_SYNTAX; 00510 return 0; 00511 } 00512 } 00513 } 00514 ibuf[len++] = I_EOL; // Put end of line 00515 return len; // Return byte length 00516 } 00517 00518 //Listing 1 line of i-code 00519 void putlist(unsigned char* ip){ 00520 unsigned char i; 00521 short value; 00522 00523 while(*ip != I_EOL){ 00524 // Case keyword 00525 if(*ip < SIZE_KWTBL){ 00526 c_puts(kwtbl[*ip]); 00527 if(IS_TOKSP(*ip) || *ip == I_SEMI)c_putch(' '); 00528 if(*ip == I_REM){ 00529 ip++; 00530 i = *ip++; 00531 while(i--){ 00532 c_putch(*ip++); 00533 } 00534 return; 00535 } 00536 ip++; 00537 } else 00538 00539 // Case numeric 00540 if(*ip == I_NUM){ 00541 putnum(getvalue(ip), 0); 00542 ip += 3; 00543 if(!IS_OP(*ip) && !IS_SEP(*ip)) c_putch(' '); 00544 } else 00545 00546 // Case valiable 00547 if(*ip == I_VAR){ 00548 ip++; 00549 c_putch(*ip++ + 'A'); 00550 if(!IS_OP(*ip) && !IS_SEP(*ip)) c_putch(' '); 00551 } else 00552 00553 // Case string 00554 if(*ip == I_STR){ 00555 ip++; 00556 value = 0; 00557 i = *ip; 00558 while(i--){ 00559 if(*(ip + i + 1) == '\"') 00560 value = 1; 00561 } 00562 if(value) c_putch('\''); else c_putch('\"'); 00563 i = *ip++; 00564 while(i--){ 00565 c_putch(*ip++); 00566 } 00567 if(value) c_putch('\''); else c_putch('\"'); 00568 00569 // Nothing match, I think, such case is impossible 00570 } else { 00571 err = ERR_SYS; 00572 return; 00573 } 00574 } 00575 } 00576 00577 // Insert i-code to the list 00578 void inslist(){ 00579 unsigned char len; 00580 unsigned char *lp1, *lp2; 00581 00582 cip = ibuf; 00583 clp = getlp(getvalue(cip)); 00584 00585 lp1 = clp; 00586 if(getvalue(lp1) == getvalue(cip)){ 00587 // Temporary measures of the case that 00588 // same line numbere exists and list area full, 00589 // existing line is deleted and new line is not inserted in. 00590 00591 // if((getsize() - *lp1) < *cip){ 00592 // err = ERR_LBUFOF; 00593 // return; 00594 // } 00595 00596 lp2 = lp1 + *lp1; 00597 while((len = *lp2) != 0){ 00598 while(len--){ 00599 *lp1++ = *lp2++; 00600 } 00601 } 00602 *lp1 = 0; 00603 } 00604 00605 // Case line number only 00606 if(*cip == 4) 00607 return; 00608 00609 // Check insertable 00610 while(*lp1){ 00611 lp1 += *lp1; 00612 } 00613 if(*cip > (listbuf + SIZE_LIST - lp1 - 1)){ 00614 err = ERR_LBUFOF; 00615 return; 00616 } 00617 00618 // Make space 00619 len = lp1 - clp + 1; 00620 lp2 = lp1 + *cip; 00621 while(len--){ 00622 *lp2-- = *lp1--; 00623 } 00624 00625 // Insert 00626 len = *cip; 00627 while(len--){ 00628 *clp++ = *cip++; 00629 } 00630 } 00631 //------------------------------------------------------------- 00632 short getinp(){ 00633 short value1; 00634 short value2; 00635 00636 value1 = getparam(); 00637 if(err) return 0; 00638 00639 if(value1 < 0) { 00640 err = ERR_SYNTAX; 00641 return 0; 00642 } 00643 00644 switch(value1){ 00645 case 0: 00646 value2 = in0; 00647 break; 00648 case 1: 00649 value2 = in1; 00650 break; 00651 default: 00652 err = ERR_SYNTAX; 00653 return 0; 00654 } 00655 return value2; 00656 } 00657 00658 short getain(){ 00659 short value1; 00660 short value2; 00661 00662 value1 = getparam(); 00663 if(err) return 0; 00664 00665 if(value1 < 0) { 00666 err = ERR_SYNTAX; 00667 return 0; 00668 } 00669 00670 switch(value1){ 00671 case 0: 00672 value2 = ain0.read_u16(); 00673 break; 00674 case 1: 00675 value2 = ain1.read_u16(); 00676 break; 00677 case 2: 00678 value2 = ain2.read_u16(); 00679 break; 00680 case 3: 00681 value2 = ain3.read_u16(); 00682 break; 00683 default: 00684 err = ERR_SYNTAX; 00685 return 0; 00686 } 00687 return value2; 00688 } 00689 00690 void iout(){ 00691 short value1, value2; 00692 00693 value1 = iexp(); 00694 if(err) return ; 00695 00696 if(*cip != I_COMMA){ 00697 err = ERR_SYNTAX; 00698 return; 00699 } 00700 00701 cip++; 00702 value2 = iexp(); 00703 if(err) return ; 00704 00705 if(value1 < 0) { 00706 err = ERR_SYNTAX; 00707 return; 00708 } 00709 00710 switch(value1){ 00711 case 0: 00712 out0 = value2 & 0x01; 00713 break; 00714 case 1: 00715 out1 = value2 & 0x01; 00716 break; 00717 case 2: 00718 out2 = value2 & 0x01; 00719 break; 00720 case 3: 00721 out3 = value2 & 0x01; 00722 break; 00723 default: 00724 err = ERR_SYNTAX; 00725 return ; 00726 } 00727 } 00728 00729 void iservo(){ 00730 short value1, value2; 00731 00732 value1 = iexp(); 00733 if(err) return ; 00734 00735 if(*cip != I_COMMA){ 00736 err = ERR_SYNTAX; 00737 return; 00738 } 00739 00740 cip++; 00741 value2 = iexp(); 00742 if(err) return ; 00743 00744 if(value1 < 0) { 00745 err = ERR_SYNTAX; 00746 return; 00747 } 00748 if(value2 < 0) value2 = 0; 00749 if(value2 > 180) value2 = 180; 00750 00751 switch(value1){ 00752 case 0: 00753 servo0 = value2 / 180; 00754 break; 00755 case 1: 00756 servo1 = value2 / 180; 00757 break; 00758 default: 00759 err = ERR_SYNTAX; 00760 return ; 00761 } 00762 } 00763 00764 void imove(){ 00765 short value1, value2, value3; 00766 00767 value1 = iexp(); 00768 if(err) return ; 00769 00770 if(*cip != I_COMMA){ 00771 err = ERR_SYNTAX; 00772 return; 00773 } 00774 00775 cip++; 00776 value2 = iexp(); 00777 if(err) return ; 00778 00779 if(*cip != I_COMMA){ 00780 err = ERR_SYNTAX; 00781 return; 00782 } 00783 00784 cip++; 00785 value3 = iexp(); 00786 if(err) return ; 00787 00788 if(value1 < -100) value1 = -100; 00789 if(value1 > 100) value1 = 100; 00790 if(value2 < -100) value2 = -100; 00791 if(value2 > 100) value2 = 100; 00792 00793 if(value3 < 0) value3 = 0; 00794 00795 left = value1; 00796 right = value2; 00797 if(value3 > 0) wait_ms(value3); 00798 00799 } 00800 00801 int iload(char *filename) { 00802 FILE * fp; 00803 unsigned char len; 00804 00805 fp = fopen( filename , "r" ); 00806 if( fp == NULL ) { 00807 err = ERR_SYS; 00808 error(); 00809 return -1; 00810 } 00811 00812 while( fgets( lbuf , sizeof( lbuf ) , fp ) != NULL ) { 00813 // puts(lbuf); 00814 int i = 0; 00815 while(*(lbuf + i)!=0x00) //remove CR LF 00816 { 00817 if((*(lbuf + i) == 0x0a) || (*(lbuf + i) == 0x0d)) 00818 { 00819 *(lbuf + i) = 0x00; 00820 } 00821 i++; 00822 } 00823 len = toktoi(); // Convert token to i-code 00824 if(err){ // Error 00825 newline(); 00826 c_puts("YOU TYPE:"); 00827 c_puts(lbuf); 00828 error(); 00829 fclose( fp ); 00830 return -1; 00831 } 00832 00833 if(*ibuf == I_NUM){ // Case the top includes line number 00834 *ibuf = len; // Change I_NUM to byte length 00835 inslist(); // Insert list 00836 if(err){ 00837 fclose( fp ); 00838 error(); // List buffer overflow 00839 return -1; 00840 } 00841 } 00842 else { 00843 fclose( fp ); 00844 err = ERR_SYS; 00845 error(); // Print OK, and Clear error flag 00846 return -1; 00847 } 00848 } 00849 fclose( fp ); 00850 return 0; 00851 } 00852 //------------------------------------------------------------- 00853 00854 // Return free memory 00855 short getsize(){ 00856 short value; 00857 unsigned char* lp; 00858 00859 lp = listbuf; 00860 while(*lp){ 00861 lp += *lp; 00862 } 00863 00864 value = listbuf + SIZE_LIST - lp - 1; 00865 return value; 00866 } 00867 00868 // Return Absolute value 00869 short getabs(){ 00870 short value; 00871 00872 value = getparam(); 00873 if(err) return 0; 00874 00875 if(value < 0) value *= -1; 00876 return value; 00877 } 00878 00879 // Return random number 00880 // TO-DO Rewrite this function to fit your machine 00881 short getrnd(void){ 00882 short value; 00883 00884 value = getparam(); 00885 if(err) return 0; 00886 00887 return(rand() % value); 00888 } 00889 00890 short getarray() 00891 { 00892 short index; 00893 00894 index = getparam(); 00895 if(err) return 0; 00896 00897 if(index < SIZE_ARRY){ 00898 return arr[index]; 00899 } else { 00900 err = ERR_SOL; 00901 return 0; 00902 } 00903 } 00904 00905 short ivalue(){ 00906 short value; 00907 00908 switch(*cip){ 00909 case I_PLUS: 00910 cip++; 00911 value = ivalue(); 00912 break; 00913 case I_MINUS: 00914 cip++; 00915 value = 0 - ivalue(); 00916 break; 00917 case I_VAR: 00918 cip++; 00919 value = var[*cip++]; 00920 break; 00921 case I_NUM: 00922 value = getvalue(cip); 00923 cip += 3; 00924 break; 00925 case I_ARRAY: 00926 cip++; 00927 value = getarray(); 00928 break; 00929 case I_OPEN: 00930 value = getparam(); 00931 break; 00932 case I_RND: 00933 cip++; 00934 value = getrnd(); 00935 break; 00936 case I_ABS: 00937 cip++; 00938 value = getabs(); 00939 break; 00940 case I_INP: 00941 cip++; 00942 value = getinp(); 00943 break; 00944 case I_AIN: 00945 cip++; 00946 value = getain(); 00947 break; 00948 case I_SIZE: 00949 cip++; 00950 if(*cip == I_OPEN){ 00951 cip++; 00952 if(*cip == I_CLOSE) 00953 cip++; 00954 else{ 00955 err = ERR_PAREN; 00956 } 00957 } 00958 value = getsize(); 00959 break; 00960 00961 default: 00962 value = 0; 00963 err = ERR_SYNTAX; 00964 break; 00965 } 00966 return value; 00967 } 00968 00969 short icalc() 00970 { 00971 short value1, value2; 00972 00973 value1 = ivalue(); 00974 00975 while(1){ 00976 if(*cip == I_DIV){ 00977 cip++; 00978 value2 = ivalue(); 00979 if(value2 == 0){ 00980 err = ERR_DIVBY0; 00981 break; 00982 } 00983 value1 /= value2; 00984 } else 00985 if(*cip == I_MUL){ 00986 cip++; 00987 value2 = ivalue(); 00988 value1 *= value2; 00989 } else { 00990 break; 00991 } 00992 } 00993 return value1; 00994 } 00995 00996 short iexp() 00997 { 00998 short value1, value2; 00999 01000 value1 = icalc(); 01001 01002 while(*cip == I_PLUS || *cip == I_MINUS){ 01003 value2 = icalc(); 01004 value1 += value2; 01005 } 01006 return value1; 01007 } 01008 01009 void iprint(){ 01010 short value; 01011 short len; 01012 unsigned char i; 01013 01014 len = 0; 01015 while(1){ 01016 switch(*cip){ 01017 case I_SEMI: 01018 case I_EOL: 01019 break; 01020 case I_STR: 01021 cip++; 01022 i = *cip++; 01023 while(i--){ 01024 c_putch(*cip++); 01025 } 01026 break; 01027 case I_SHARP: 01028 cip++; 01029 len = iexp(); 01030 if(err) return; 01031 break; 01032 default: 01033 value = iexp(); 01034 if(err) return; 01035 putnum(value, len); 01036 break; 01037 } 01038 01039 if(*cip == I_COMMA){ 01040 cip++; 01041 }else{ 01042 break; 01043 } 01044 }; 01045 newline(); 01046 } 01047 01048 void iinput(){ 01049 unsigned char i; 01050 short value; 01051 short index; 01052 01053 while(1){ 01054 switch(*cip){ 01055 case I_STR: 01056 cip++; 01057 i = *cip++; 01058 while(i--){ 01059 c_putch(*cip++); 01060 } 01061 if(*cip == I_VAR){ 01062 cip++; 01063 value = getnum(); 01064 var[*cip++] = value; 01065 } else 01066 if(*cip == I_ARRAY){ 01067 cip++; 01068 index = getparam(); 01069 if(err) return; 01070 if(index >= SIZE_ARRY){ 01071 err = ERR_SOL; 01072 return; 01073 } 01074 value = getnum(); 01075 arr[index] = value; 01076 } 01077 break; 01078 case I_VAR: 01079 cip++; 01080 c_putch(*cip + 'A'); 01081 c_putch(':'); 01082 value = getnum(); 01083 var[*cip++] = value; 01084 break; 01085 case I_ARRAY: 01086 cip++; 01087 index = getparam(); 01088 if(err) 01089 return; 01090 if(index >= SIZE_ARRY){ 01091 err = ERR_SOL; 01092 return; 01093 } 01094 c_putch('@');c_putch('('); 01095 putnum(index,0); 01096 c_putch(')');c_putch(':'); 01097 value = getnum(); 01098 arr[index] = value; 01099 break; 01100 } 01101 01102 switch(*cip){ 01103 case I_COMMA: 01104 cip++; 01105 break; 01106 case I_SEMI: 01107 case I_EOL: 01108 return; 01109 default: 01110 err = ERR_SYNTAX; 01111 return; 01112 } 01113 } 01114 } 01115 01116 //char iif(){ 01117 signed char iif(){ 01118 short value1, value2; 01119 unsigned char i; 01120 01121 value1 = iexp(); 01122 if(err) return -1; 01123 01124 i = *cip++; 01125 01126 value2 = iexp(); 01127 if(err) return -1; 01128 01129 switch(i){ 01130 case I_EQ: 01131 return value1 == value2; 01132 case I_SHARP: 01133 return value1 != value2; 01134 case I_LT: 01135 return value1 < value2; 01136 case I_LTE: 01137 return value1 <= value2; 01138 case I_GT: 01139 return value1 > value2; 01140 case I_GTE: 01141 return value1 >= value2; 01142 default: 01143 err = ERR_IFWOC; 01144 return -1; 01145 } 01146 } 01147 01148 void ivar(){ 01149 short value; 01150 short index; 01151 01152 index = *cip++; 01153 if(*cip == I_EQ){ 01154 cip++; 01155 value = iexp(); 01156 if(err) return; 01157 } else { 01158 err = ERR_VWOEQ; 01159 return; 01160 } 01161 01162 if(index < 26){ 01163 var[index] = value; 01164 } else { 01165 err = ERR_SOL; 01166 } 01167 } 01168 01169 void iarray(){ 01170 short value; 01171 short index; 01172 01173 index = getparam(); 01174 if(err) return; 01175 if(*cip == I_EQ){ 01176 cip++; 01177 value = iexp(); 01178 if(err) return; 01179 } else { 01180 err = ERR_VWOEQ; 01181 return; 01182 } 01183 01184 if(index < SIZE_ARRY){ 01185 arr[index] = value; 01186 } else { 01187 err = ERR_SOL; 01188 } 01189 } 01190 01191 void ilet(){ 01192 switch(*cip){ 01193 case I_VAR: 01194 cip++; 01195 ivar(); 01196 break; 01197 case I_ARRAY: 01198 cip++; 01199 iarray(); 01200 break; 01201 default: 01202 err = ERR_LETWOV; 01203 break; 01204 } 01205 } 01206 01207 void ilist(){ 01208 short lineno; 01209 01210 if(*cip == I_NUM){ 01211 lineno = getvalue(cip); 01212 cip += 3; 01213 } else { 01214 lineno = 0; 01215 } 01216 01217 for( clp = listbuf; 01218 *clp && (getvalue(clp) < lineno); 01219 clp += *clp); 01220 01221 while(*clp){ 01222 putnum(getvalue(clp), 0); 01223 c_putch(' '); 01224 putlist(clp + 3); 01225 if(err){ 01226 break; 01227 } 01228 newline(); 01229 clp += *clp; 01230 } 01231 } 01232 01233 void inew(void){ 01234 unsigned char i; 01235 01236 for(i = 0; i < 26; i++) 01237 var[i] = 0; 01238 gstki = 0; 01239 lstki = 0; 01240 *listbuf = 0; 01241 clp = listbuf; 01242 } 01243 01244 unsigned char* iexe(){ 01245 short lineno; 01246 unsigned char cd; 01247 unsigned char* lp; 01248 short vto, vstep; 01249 short index; 01250 01251 while(1){ 01252 if(c_kbhit()){ 01253 if(c_getch() == 27){ 01254 while(*clp){ 01255 clp += *clp; 01256 } 01257 err = ERR_ESC; 01258 return clp; 01259 } 01260 } 01261 01262 switch(*cip){ 01263 case I_GOTO: 01264 cip++; 01265 lineno = iexp(); 01266 clp = getlp(lineno); 01267 if(lineno != getvalue(clp)){ 01268 err = ERR_ULN; 01269 return NULL; 01270 } 01271 cip = clp + 3; 01272 continue; 01273 case I_GOSUB: 01274 cip++; 01275 lineno = iexp(); 01276 if(err) return NULL; 01277 lp = getlp(lineno); 01278 if(lineno != getvalue(lp)){ 01279 err = ERR_ULN; 01280 return NULL; 01281 } 01282 gpush(clp); 01283 gpush(cip); 01284 if(err) return NULL; 01285 clp = lp; 01286 cip = clp + 3; 01287 continue; 01288 case I_RETURN: 01289 cip = gpop(); 01290 lp = gpop(); 01291 if(err) return NULL; 01292 clp = lp; 01293 break; 01294 case I_FOR: 01295 cip++; 01296 if(*cip++ != I_VAR){ 01297 err = ERR_FORWOV; 01298 return NULL; 01299 } 01300 index = *cip; 01301 ivar(); 01302 if(err) return NULL; 01303 01304 if(*cip == I_TO){ 01305 cip++; 01306 vto = iexp(); 01307 } else { 01308 err = ERR_FORWOTO; 01309 return NULL; 01310 } 01311 if(*cip == I_STEP){ 01312 cip++; 01313 vstep = iexp(); 01314 } else { 01315 vstep = 1; 01316 } 01317 01318 lpush(clp); 01319 lpush(cip); 01320 lpush((unsigned char*)vto); 01321 lpush((unsigned char*)vstep); 01322 lpush((unsigned char*)index); 01323 if(err) return NULL; 01324 break; 01325 case I_NEXT: 01326 cip++; 01327 if(*cip++ !=I_VAR){ 01328 err = ERR_NEXTWOV; 01329 return NULL; 01330 } 01331 01332 if(lstki < 5){ 01333 err = ERR_LSTKUF; 01334 return NULL; 01335 } 01336 index = (short)lstk[lstki - 1]; 01337 if(index != *cip){ 01338 err = ERR_NEXTUM; 01339 return NULL; 01340 } 01341 cip++; 01342 vstep = (short)lstk[lstki - 2]; 01343 var[index] += vstep; 01344 01345 vto = (short)lstk[lstki - 3]; 01346 if( ((vstep < 0) && (var[index] < vto)) || 01347 ((vstep > 0) && (var[index] > vto))){ 01348 lstki -= 5; 01349 break; 01350 } 01351 cip = lstk[lstki - 4]; 01352 clp = lstk[lstki - 5]; 01353 continue; 01354 01355 case I_IF: 01356 cip++; 01357 cd = iif(); 01358 if(err){ 01359 err = ERR_IFWOC; 01360 return NULL; 01361 } 01362 if(cd) 01363 continue; 01364 // If false, same as REM 01365 case I_REM: 01366 // Seek pointer to I_EOL 01367 // No problem even if it points not realy end of line 01368 while(*cip != I_EOL) cip++; 01369 break; 01370 case I_STOP: 01371 while(*clp){ 01372 clp += *clp; 01373 } 01374 return clp; 01375 case I_INPUT: 01376 cip++; 01377 iinput(); 01378 break; 01379 case I_PRINT: 01380 cip++; 01381 iprint(); 01382 break; 01383 case I_LET: 01384 cip++; 01385 ilet(); 01386 break; 01387 case I_OUT: 01388 cip++; 01389 iout(); 01390 break; 01391 case I_SERVO: 01392 cip++; 01393 iservo(); 01394 break; 01395 case I_MOVE: 01396 cip++; 01397 imove(); 01398 break; 01399 case I_WAIT: 01400 cip++; 01401 int t = iexp(); 01402 if(err) return NULL; 01403 if(t < 0) t = 0; 01404 wait_ms(t); 01405 break; 01406 case I_VAR: 01407 cip++; 01408 ivar(); 01409 break; 01410 case I_ARRAY: 01411 cip++; 01412 iarray(); 01413 break; 01414 case I_LIST: 01415 case I_NEW: 01416 case I_RUN: 01417 err = ERR_COM; 01418 return NULL; 01419 } 01420 01421 switch(*cip){ 01422 case I_SEMI: 01423 cip++; 01424 break; 01425 case I_EOL: 01426 return clp + *clp; 01427 default: 01428 err = ERR_SYNTAX; 01429 return NULL; 01430 } 01431 } 01432 } 01433 01434 void irun(){ 01435 unsigned char* lp; 01436 01437 gstki = 0; 01438 lstki = 0; 01439 clp = listbuf; 01440 01441 while(*clp){ 01442 cip = clp + 3; 01443 lp = iexe(); 01444 if(err) 01445 return; 01446 clp = lp; 01447 } 01448 } 01449 01450 void icom(){ 01451 cip = ibuf; 01452 switch(*cip){ 01453 case I_LIST: 01454 cip++; 01455 if(*cip == I_EOL || *(cip + 3) == I_EOL) 01456 ilist(); 01457 else 01458 err = ERR_SYNTAX; 01459 break; 01460 case I_NEW: 01461 cip++; 01462 if(*cip == I_EOL) 01463 inew(); 01464 else 01465 err = ERR_SYNTAX; 01466 break; 01467 case I_LOAD: 01468 cip++; 01469 iload("/local/AUTO.BAS"); 01470 break; 01471 case I_RUN: 01472 cip++; 01473 irun(); 01474 break; 01475 default: 01476 iexe(); 01477 break; 01478 } 01479 01480 if(err && err != ERR_ESC){ 01481 if(cip >= listbuf && cip < listbuf + SIZE_LIST && *clp) 01482 { 01483 newline(); c_puts("ERR LINE:"); 01484 putnum(getvalue(clp), 0); 01485 c_putch(' '); 01486 putlist(clp + 3); 01487 } 01488 else 01489 { 01490 newline(); c_puts("YOU TYPE: "); 01491 putlist(ibuf); 01492 } 01493 } 01494 01495 } 01496 01497 void basic(){ 01498 unsigned char len; 01499 01500 // sci2_init(); 01501 io_init(); 01502 inew(); 01503 c_puts("TOYOSHIKI TINY BASIC"); newline(); 01504 // c_puts("PIC24F EDITION"); newline(); 01505 c_puts("Wallbot EDITION"); newline(); 01506 error(); // Print OK, and Clear error flag 01507 01508 if(in0 == 0) //Auto Load & Run 01509 { 01510 c_puts("Auto Load & Run"); 01511 newline(); 01512 if(iload("/local/AUTO.BAS") == 0) 01513 { 01514 error(); // Print OK, and Clear error flag 01515 irun(); 01516 } 01517 error(); // Print OK, and Clear error flag 01518 } 01519 01520 // Input 1 line and execute 01521 while(1){ 01522 c_putch('>');// Prompt 01523 c_gets(); // Input 1 line 01524 len = toktoi(); // Convert token to i-code 01525 if(err){ // Error 01526 newline(); c_puts("YOU TYPE:"); 01527 c_puts(lbuf); 01528 error(); 01529 continue; // Do nothing 01530 } 01531 01532 if(*ibuf == I_NUM){ // Case the top includes line number 01533 *ibuf = len; // Change I_NUM to byte length 01534 inslist(); // Insert list 01535 if(err){ 01536 error(); // List buffer overflow 01537 } 01538 } else { 01539 icom(); // Execute direct 01540 error(); // Print OK, and Clear error flag 01541 } 01542 } 01543 } 01544 01545
Generated on Mon Jul 18 2022 02:18:30 by 1.7.2