📄 scan.c
字号:
dbt_read(lab_table, label_id, &label, sizeof(label_t)); count = first_data_ip + label.dp; memcpy(bc_prog.ptr+node.pos+1, &count, 2); // change LABEL-ID with DataPointer break; case kwTYPE_CALL_UDP: case kwTYPE_CALL_UDF: // update real IP memcpy(&label_id, bc_prog.ptr+node.pos+1, 2); true_ip = proc_table[label_id].ip + 5; memcpy(bc_prog.ptr+node.pos+1, &true_ip, 2); // update return-var ID true_ip = proc_table[label_id].vid; memcpy(bc_prog.ptr+node.pos+3, &true_ip, 2); break; case kwONJMP: // kwONJMP:1 trueip:2 falseip:2 command:1 count:1 label1:2 label2:2 ... count = bc_prog.ptr[node.pos+6]; // change label IDs with the real IPs for ( j = 0; j < count; j ++ ) { memcpy(&label_id, bc_prog.ptr+node.pos+(j<<1)+7, 2); dbt_read(lab_table, label_id, &label, sizeof(label_t)); w = label.ip; memcpy(bc_prog.ptr+node.pos+(j<<1)+7, &w, 2); } break; case kwGOTO: // LONG JUMPS memcpy(&label_id, bc_prog.ptr+node.pos+1, 2); dbt_read(lab_table, label_id, &label, sizeof(label_t)); w = label.ip; memcpy(bc_prog.ptr+node.pos+1, &w, 2); // change LABEL-ID with IP level = bc_prog.ptr[node.pos+3]; bc_prog.ptr[node.pos+3] = 0; // number of POPs ????????? if ( level >= label.level ) bc_prog.ptr[node.pos+3] = level - label.level; // number of POPs else bc_prog.ptr[node.pos+3] = 0; // number of POPs ????????? break; case kwFOR: a_ip = bc_search(node.pos+5, kwTO); false_ip = bc_search_stack(i+1, kwNEXT, node.level); if ( false_ip == 0xFFFF ) { sc_raise("'FOR' WITHOUT 'NEXT'"); return; } if ( a_ip > false_ip || a_ip == 0xFFFF ) { sc_raise("'FOR' WITHOUT 'TO'"); return; } memcpy(bc_prog.ptr+node.pos+3, &false_ip, 2); break; case kwWHILE: false_ip = bc_search_stack(i+1, kwWEND, node.level); if ( false_ip == 0xFFFF ) { sc_raise("'WHILE' WITHOUT 'WEND'"); return; } memcpy(bc_prog.ptr+node.pos+3, &false_ip, 2); break; case kwREPEAT: false_ip = bc_search_stack(i+1, kwUNTIL, node.level); if ( false_ip == 0xFFFF ) { sc_raise("'REPEAT' WITHOUT 'UNTIL'"); return; } memcpy(bc_prog.ptr+node.pos+3, &false_ip, 2); break; case kwIF: case kwELIF: a_ip = bc_search_stack(i+1, kwELSE, node.level); b_ip = bc_search_stack(i+1, kwENDIF, node.level); c_ip = bc_search_stack(i+1, kwELIF, node.level); false_ip = a_ip; if ( b_ip < false_ip ) false_ip = b_ip; if ( c_ip < false_ip ) false_ip = c_ip; if ( false_ip == 0xFFFF ) { sc_raise("'IF' WITHOUT 'ENDIF'"); return; } memcpy(bc_prog.ptr+node.pos+3, &false_ip, 2); break; case kwELSE: false_ip = bc_search_stack(i+1, kwENDIF, node.level); if ( false_ip == 0xFFFF ) { sc_raise("'IF' WITHOUT 'ENDIF'"); return; } memcpy(bc_prog.ptr+node.pos+3, &false_ip, 2); break;/////////////// case kwTYPE_RET: break; case kwWEND: false_ip = bc_search_stack_backward(i-1, kwWHILE, node.level); if ( false_ip == 0xFFFF ) { sc_raise("'WEND' WITHOUT 'WHILE'"); return; } memcpy(bc_prog.ptr+node.pos+3, &false_ip, 2); break; case kwUNTIL: false_ip = bc_search_stack_backward(i-1, kwREPEAT, node.level); if ( false_ip == 0xFFFF ) { sc_raise("'UNTIL' WITHOUT 'REPEAT'"); return; } memcpy(bc_prog.ptr+node.pos+3, &false_ip, 2); break; case kwNEXT: false_ip = bc_search_stack_backward(i-1, kwFOR, node.level); if ( false_ip == 0xFFFF ) { sc_raise("'NEXT' WITHOUT 'FOR'"); return; } memcpy(bc_prog.ptr+node.pos+3, &false_ip, 2); break; case kwENDIF: false_ip = bc_search_stack_backward(i-1, kwIF, node.level); if ( false_ip == 0xFFFF ) { sc_raise("'ENDIF' WITHOUT 'IF'"); return; } memcpy(bc_prog.ptr+node.pos+3, &false_ip, 2); break; }; } dev_printf("\rPASS2: Node %d/%d\n", stk_count, stk_count);}/** initialize*/void bc_init() SEC(BCSCAN);void bc_init(){ #if defined(_PalmOS) dev_cls(); #endif bc_name = tmp_alloc(TEXT_LINE_SIZE); bc_parm = tmp_alloc(TEXT_LINE_SIZE); bc_temp = tmp_alloc(TEXT_LINE_SIZE); bc_proc = tmp_alloc(TEXT_LINE_SIZE); scan_line = 0; scan_error = 0; lab_count = 0; var_count = 0; stk_count = 0; proc_count = 0; block_level = 0; block_id = 0; first_data_ip = 0xFFFF; bc_proc_level = 0; bc_proc[0] = '\0'; var_table = (var_t*) tmp_alloc(GROWSIZE * sizeof(var_t)); lab_table = dbt_create("BCS-LBL.VMT"); proc_table = (proc_t*) tmp_alloc(GROWSIZE * sizeof(proc_t)); bc_stack = dbt_create("BCS-STK.VMT"); var_size = /* lab_size = stk_size = */ proc_size = GROWSIZE; var_count = lab_count = stk_count = proc_count = 0; bc_create(&bc_prog); bc_create(&bc_data); if ( !var_table || !lab_table || !proc_table || !bc_stack ) panic("bc_init(): OUT OF MEMORY"); dev_printf("VMT Initialization...\n"); dbt_prealloc(lab_table, os_cclabs1, sizeof(label_t)); dbt_prealloc(bc_stack, os_ccpass2, sizeof(pass_node_t)); /* * create system variables */ bc_get_var_id("OSVER"); bc_get_var_id("OSNAME"); bc_get_var_id("SBVER"); bc_get_var_id("PI"); bc_get_var_id("XMAX"); bc_get_var_id("YMAX"); bc_get_var_id("BPP"); bc_get_var_id("TRUE"); bc_get_var_id("FALSE"); bc_get_var_id("LINECHART"); bc_get_var_id("BARCHART");}/** clean up*/void bc_close() SEC(BCSCAN);void bc_close(){ int i; #if defined(_PalmOS)// LocalID lid; #endif bc_destroy(&bc_prog); bc_destroy(&bc_data); for ( i = 0; i < var_count; i ++ ) tmp_free(var_table[i].name); for ( i = 0; i < proc_count; i ++ ) tmp_free(proc_table[i].name); tmp_free(var_table); dbt_close(lab_table); tmp_free(proc_table); dbt_close(bc_stack);// #if defined(_PalmOS)// if ( (lid = DmFindDatabase(0, "BCS-LBL.VMT")) != 0 ) DmDeleteDatabase(0, lid);// if ( (lid = DmFindDatabase(0, "BCS-STK.VMT")) != 0 ) DmDeleteDatabase(0, lid);// #endif var_count = lab_count = stk_count = proc_count = 0; tmp_free(bc_proc); tmp_free(bc_temp); tmp_free(bc_parm); tmp_free(bc_name);}/** returns true if the 'fileName' exists*/int basFileExist(const char *basfile){ int check = 0; char *p, *fileName; #if defined(_PalmOS) LocalID lid; #endif fileName = tmp_alloc(strlen(basfile)+1); strcpy(fileName, basfile); p = strchr(fileName, '.'); if ( !p ) strcat(fileName, ".bas"); else { if ( str_istr(fileName, ".bas") == NULL ) strcat(fileName, ".bas"); } #if defined(_PalmOS) lid = DmFindDatabase(0, fileName); check = (lid != 0); #else #if defined(_Win32) check = (access(fileName, 0) == 0); #else check = (access(fileName, R_OK) == 0); #endif #endif tmp_free(fileName); return check;}/**/void bc_load(const char *fileName) SEC(BCSCAN);void bc_load(const char *fileName){#if defined(_PalmOS) DmOpenRef fp; LocalID lid; int l, i; VoidPtr rec_p = NULL; VoidHand rec_h = NULL;#else int unxh; struct stat st;#endif strcpy(bc_fileName, fileName);#if defined(_PalmOS) lid = DmFindDatabase(0, (char *) fileName); fp = DmOpenDatabase(0, lid, dmModeReadWrite); if ( !fp ) { panic("LOAD: CAN'T OPEN FILE %s", fileName); return; } l = DmNumRecords(fp) - 1; if ( l <= 0 ) { panic("LOAD: BAD FILE STRUCTURE %s", fileName); return; } for ( i = 0; i < l; i ++ ) { rec_h = DmGetRecord(fp, i+1); if ( !rec_h ) panic("LOAD: CAN'T GET RECORD %s", fileName); rec_p = mem_lock(rec_h); if ( !rec_p ) panic("LOAD: CAN'T LOCK RECORD %s", fileName); if ( i == 0 && strlen(rec_p+6) == 0 ) bc_scan("Main", rec_p+70); // + sizeof(sec_t); else bc_scan(rec_p+6, rec_p+70); // + sizeof(sec_t); mem_unlock(rec_h); DmReleaseRecord(fp, i+1, 0); if ( bc_get_error() ) break; } DmCloseDatabase(fp);#else stat(fileName, &st); unxh = open(fileName, 0); if ( unxh == -1 ) { panic("can't open %s\n", fileName); return; } else { char *buff; /* read & compile file */ buff = (char *) tmp_alloc(st.st_size+1); read(unxh, buff, st.st_size); buff[st.st_size] = '\0'; bc_scan(NULL, buff); tmp_free(buff); close(unxh); }#endif}/*** PASS 1*/void bc_scan(const char *section, const char *text){ char *ps, *p, lc = 0; int quotes, len; char pname[33]; char *code_line; char *new_text; code_line = tmp_alloc(TEXT_LINE_SIZE); new_text = tmp_alloc((len=(strlen(text) + 4))); memset(new_text, 0, len); /* * Make it simple text * * space-chars is only the space * * CR/LF are fixed * * control chars are out */ if ( section ) strncpy(bc_sec, section, 32); else strncpy(bc_sec, "Main", 32); bc_sec[32] = '\0';// dev_printf("Preparing text...\n"); p = (char *) text; ps = new_text; quotes = 0; while ( *p ) { if ( !quotes ) { if ( *p == '\n' ) { *ps ++ = '\n'; while ( *(p+1) == ' ' || *(p+1) == '\t' ) p ++; } else if ( (*p == '\t' || *p == ' ') && lc != ' ' ) *ps ++ = ' '; else if ( (*p > ' ') || (*p & 0x80) ) *ps ++ = to_upper(*p); lc = *ps; } else *ps ++ = *p; if ( *p == '\"' ) quotes = !quotes; p ++; } *ps = '\0'; strcat(new_text, "\n"); /* */// dev_printf("Scanning for routines...\n"); p = ps = new_text; bc_proc_level = 0; *bc_proc = '\0'; while ( *p ) { if ( strncmp("#INC:", p, 5) == 0 ) { char *crp = NULL; p += 5; if ( *p == '\"' ) { p ++; crp = p; while ( *crp != '\0' && *crp != '\"' ) crp ++; if ( *crp == '\0' ) { sc_raise("#INC: MISSING \""); break; } *crp = '\0'; lc = '\"'; } else { crp = strchr(p, '\n'); *crp = '\0'; lc = '\n'; } strcpy(code_line, p); str_alltrim(code_line); if ( !basFileExist(code_line) ) sc_raise("FILE %s: FILE %s DOES NOT EXISTS", bc_fileName, code_line); else { #if defined(_PalmOS) char fileName[65]; #else char fileName[1024]; #endif char sec[33]; strcpy(sec, bc_sec); strcpy(fileName, bc_fileName); if ( strchr(code_line, '.') == NULL ) strcat(code_line, ".bas"); bc_load(code_line); strcpy(bc_fileName, fileName); strcpy(bc_sec, sec); } *crp = lc; } if ( (strncmp("SUB ", p, 4) == 0) || (strncmp("FUNC ", p, 5) == 0) ) { char *lpar = NULL; char *crp = NULL; if ( *p == 'S' ) p += 4; else p += 5; // close string lpar = strchr(p, '('); crp = strchr(p, '\n'); if ( lpar && crp ) { if ( lpar < crp ) { *lpar = '\0'; crp = NULL; } else { *crp = '\0'; lpar = NULL; } } else if ( lpar ) *lpar = '\0'; else if ( crp ) *crp = '\0'; // add declaration bc_prepname(pname, p, 32); bc_addproc(pname); if ( bc_proc_level ) { strcat(bc_proc, "/"); strcat(bc_proc, pname); } else strcpy(bc_proc, pname); bc_proc_level ++; // restore string if ( lpar ) *lpar = '('; else { if ( crp ) *crp = '\n'; } } else if ( bc_proc_level ) { if ( strncmp("END ", p, 4) == 0 || strncmp("END\n", p, 4) == 0 ) { char *dol; dol = strrchr(bc_proc, '/'); if ( dol ) *dol = '\0'; else *bc_proc = '\0'; bc_proc_level --; } } // skip text line while ( *p != '\0' && *p != '\n' ) p ++; if ( *p ) p ++; } if ( bc_proc_level ) sc_raise("FILE %s: SUB/FUNC END, MISSING", bc_fileName); bc_proc_level = 0; *bc_proc = '\0'; dev_printf("File: \033\[1m%s\033\[0m\nSection: \033\[1m%s\033\[0m\n", bc_fileName, bc_sec); /* * start */ if ( !scan_error ) { scan_line = 0; // remove this for common line nums dev_printf("PASS1: Line %d", scan_line+1); ps = p = new_text; while ( *p ) { if ( *p == '\n' ) { *p = '\0'; scan_line ++; if ( (scan_line % 32) == 0 ) dev_printf("\rPASS1: Line %d", scan_line); bc_add2i(&bc_prog, kwTYPE_LINE, scan_line); strcpy(code_line, ps); bc_scan_cmd(code_line); if ( scan_error ) break; ps = p+1; } if ( scan_error ) break; p ++; } } tmp_free(code_line); tmp_free(new_text); bc_eoc(&bc_prog); bc_resize(&bc_prog, bc_prog.count); if ( !scan_error ) { dev_printf("\rPASS1: Line %d; finished\n", scan_line+1); #if !defined(_PalmOS) dev_printf("\rMemUsed: %d\n", memmgr_getalloc()); #endif dev_printf("\n"); }}/** PASS 2*/void bc_pass2(void) SEC(BCSCAN);void bc_pass2(){ dev_printf("PASS2..."); if ( bc_proc_level ) sc_raise("MISSING SUB/FUNC-END"); else if ( block_level ) sc_raise("MISSING LOOP-END"); else { first_data_ip = bc_prog.count; bc_pass2_scan(); } if ( bc_data.count ) bc_append(&bc_prog, &bc_data);}/** create bytecode*/mem_t bc_createbin(void) SEC(BCSCAN);mem_t bc_createbin(){ word len, i; mem_t buff_h; byte *buff; label_t label; dev_printf("Creating byte-code...\n"); // total length len = 10; // num of vars + num of labels + def.data_ip + size of bytecode var len += (lab_count * 2); // size of label table len += bc_prog.count; // size of bytecode buff_h = mem_alloc(len+4); // +4 (checkop1233) buff = mem_lock(buff_h); // number of variables memcpy(buff, &var_count, 2); // number of labels memcpy(buff+2, &lab_count, 2); // label table for ( i = 0; i < lab_count; i ++ ) { dbt_read(lab_table, i, &label, sizeof(label_t)); memcpy(buff+(i<<1)+4, &label.ip, 2); } // first data ip memcpy(buff+(lab_count<<1)+4, &first_data_ip, 2); // program length memcpy(buff+(lab_count<<1)+6, &bc_prog.count, 2); // the program itself memcpy(buff+(lab_count<<1)+8, bc_prog.ptr, bc_prog.count); dev_printf("Variables %d\n", var_count); dev_printf("Labels %d\n", lab_count); dev_printf("Proc/Func %d\n", proc_count); dev_printf("Code size %d\n", bc_prog.count); dev_printf("\n"); mem_unlock(buff_h); return buff_h; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -