Nife version Beta
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

1334 lines
32 KiB

  1. /* Copyright (C) 2011-2014 Patrick H. E. Foubet - S.E.R.I.A.N.E.
  2. This program is free software: you can redistribute it and/or modify
  3. it under the terms of the GNU General Public License as published by
  4. the Free Software Foundation, either version 3 of the License, or any
  5. later version.
  6. This program is distributed in the hope that it will be useful,
  7. but WITHOUT ANY WARRANTY; without even the implied warranty of
  8. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  9. GNU General Public License for more details.
  10. You should have received a copy of the GNU General Public License
  11. along with this program. If not, see <http://www.gnu.org/licenses/>
  12. *******************************************************************/
  13. /* stackF.c */
  14. #include "conf.h"
  15. #include <stdio.h>
  16. #include <stdlib.h>
  17. #include <string.h>
  18. #include <strings.h>
  19. #include "nife.h"
  20. #include "mth.h"
  21. #include "err.h"
  22. #include "lib.h"
  23. #include "stackF.h"
  24. #include "stackN.h"
  25. #include "stackC.h"
  26. #include "stackL.h"
  27. #include "stackV.h"
  28. #include "tasks.h"
  29. #define MAXCODE 2048
  30. int FctInTask=0;
  31. static void * stackF = VIDE;
  32. struct Fct {
  33. char *l; /* libelle */
  34. void *n; /* next */
  35. void *c; /* code */
  36. short typ; /* type : 0 std, 1 sys in compilation, 2 sys terminated */
  37. };
  38. void initFct(char *Lib, int typ)
  39. {
  40. void * M, *L;
  41. struct Fct * N;
  42. if ((M = malloc(sizeof(struct Fct))) == NULL) stopErr("initFct","malloc");
  43. if ((L = malloc(strlen(Lib)+1)) == NULL) stopErr("initFct","malloc");
  44. strcpy((char*)L,Lib);
  45. N = (struct Fct*)M;
  46. N->l = (char*)L;
  47. N->n = stackF;
  48. N->c = VIDE;
  49. N->typ = typ;
  50. stackF = M;
  51. }
  52. static void eraseFct(struct Fct *F)
  53. {
  54. int i,n;
  55. char *C, *E;
  56. void *A, *W;
  57. struct Fct *FD;
  58. /* printf("eraseFct(%s) at 0x%lx\n", F->l, (long)F); */
  59. free((void*)F->l);
  60. /* free associates memories */
  61. if (F->c != VIDE) {
  62. A = F->c;
  63. n = sizeof(A);
  64. i = *(int*)A;
  65. C = (char*)A+(3*sizeof(int));
  66. E = C+i;
  67. while (C < E) {
  68. switch((Code)*C) {
  69. case T_CHA :
  70. case T_CHAS :
  71. case T_NUM :
  72. case T_BKC :
  73. case T_BKC1 :
  74. bcopy((void*)(C+1),(void*)&W,n);
  75. free(W);
  76. break;
  77. case T_FCTD :
  78. case T_FCTDS :
  79. case T_FCTDW :
  80. case T_FCTDWS :
  81. bcopy((void*)(C+1),(void*)&W,n);
  82. FD = (struct Fct*)W;
  83. eraseFct(FD);
  84. break;
  85. default:
  86. break;
  87. }
  88. C+= n+1;
  89. }
  90. free(A);
  91. }
  92. free((void*)F);
  93. }
  94. void updDynFct(void *AF, int M) /* M:0=init, 1=start, 2=stop */
  95. {
  96. int i,n;
  97. char *C, *E;
  98. void *A, *W;
  99. struct Fct *F, *FD;
  100. F = (struct Fct *)AF;
  101. /* printf("updDynFct(%s) at 0x%lx\n", F->l, (long)F); */
  102. if (F->c == VIDE) return;
  103. A = F->c;
  104. n = sizeof(A);
  105. i = *(int*)A;
  106. C = (char*)A+(3*sizeof(int));
  107. E = C+i;
  108. switch(M) {
  109. case 0 : /* init */
  110. while (C < E) {
  111. switch((Code)*C) {
  112. case T_CHAS :
  113. *C=T_CHA;
  114. break;
  115. case T_VARS :
  116. *C=T_VAR;
  117. break;
  118. case T_EXEKS :
  119. *C=T_EXEK;
  120. break;
  121. case T_FCTD :
  122. case T_FCTDS :
  123. case T_FCTDW :
  124. case T_FCTDWS :
  125. *C=T_EXEK;
  126. bcopy((void*)(C+1),(void*)&W,n);
  127. FD = (struct Fct*)W;
  128. eraseFct(FD);
  129. break;
  130. default:
  131. break;
  132. }
  133. C+= n+1;
  134. }
  135. break;
  136. case 1 : /* start */
  137. while (C < E) {
  138. switch((Code)*C) {
  139. case T_FCTDS :
  140. *C=T_FCTD;
  141. break;
  142. case T_FCTDWS :
  143. *C=T_FCTDW;
  144. break;
  145. default:
  146. break;
  147. }
  148. C+= n+1;
  149. }
  150. break;
  151. case 2 : /* stop */
  152. while (C < E) {
  153. switch((Code)*C) {
  154. case T_EXEK :
  155. *C=T_EXEKS;
  156. break;
  157. case T_FCTD :
  158. *C=T_FCTDS;
  159. break;
  160. case T_FCTDW :
  161. *C=T_FCTDWS;
  162. break;
  163. default:
  164. break;
  165. }
  166. C+= n+1;
  167. }
  168. break;
  169. default:
  170. break;
  171. }
  172. }
  173. void rmLastFct(void)
  174. {
  175. struct Fct *Elt;
  176. if (stackF != VIDE) {
  177. Elt = (struct Fct *)stackF;
  178. if (Elt->typ==2) return;
  179. stackF = Elt->n;
  180. eraseFct(Elt);
  181. } else messErr(7);
  182. }
  183. static void unlinkLastFct(void)
  184. {
  185. struct Fct *Elt;
  186. if (stackF != VIDE) {
  187. Elt = (struct Fct *)stackF;
  188. stackF = Elt->n;
  189. }
  190. }
  191. struct Fct *putCodeFct(void* C)
  192. {
  193. struct Fct *Elt;
  194. if (stackF != VIDE) {
  195. Elt = (struct Fct *)stackF;
  196. if (Elt->c == VIDE) Elt->c = C;
  197. else messErr(8);
  198. }
  199. else messErr(7);
  200. return Elt;
  201. }
  202. void IF_show_stackF(void)
  203. {
  204. void * Next;
  205. struct Fct * N;
  206. char Ctyp;
  207. Next = stackF;
  208. while (Next != VIDE) {
  209. N = (struct Fct*) Next;
  210. if (N->typ) Ctyp='S'; else Ctyp=' ';
  211. printf(" %-25s%c %d octets\n",N->l,Ctyp,*((int*)N->c));
  212. Next = N->n;
  213. }
  214. printf("<end of function list>\n");
  215. }
  216. static char cod[MAXCODE];
  217. static int i_cod;
  218. /* pile pour IF ELSE THEN */
  219. static int i_adr;
  220. static void * adr[MAXCODE/4];
  221. static char tad[MAXCODE/4];
  222. /* pile pour BEGIN ... WHILE ... REPEAT / BEGIN ... AGAIN / BEGIN ... UNTIL */
  223. static int i_adB;
  224. static int adB[MAXCODE/4];
  225. static char tcB[MAXCODE/4];
  226. /* pile pour DO ... LOOP / +LOOP */
  227. static int i_adD;
  228. static int adD[MAXCODE/4];
  229. static char tcD[MAXCODE/4];
  230. /* pour l'execution */
  231. static int I_DO=-1;
  232. static char S_DO[MAXCODE/4];
  233. static long D_DO[MAXCODE/4], L_DO[MAXCODE/4];
  234. void IF_nDO (void)
  235. {
  236. putLong((long long)(I_DO+1));
  237. }
  238. static void IF_getIndDo(int v)
  239. {
  240. int i = I_DO - v;
  241. if (i<0) putLong((long long)0);
  242. else putLong((long long)D_DO[i]);
  243. }
  244. int tadExist(Code c)
  245. {
  246. int i=0;
  247. while (i<i_adr) {
  248. if (tad[i] == c) return 1;
  249. i++;
  250. }
  251. return 0;
  252. }
  253. void IF_finFct(void)
  254. {
  255. void * M;
  256. struct Fct * F;
  257. int i,l, *ea, *Ea;
  258. if ((M = malloc((3*sizeof(int))+i_cod)) == NULL)
  259. stopErr("IF_finFct","malloc");
  260. ea = (int*)M;
  261. *ea++ = i_cod;
  262. *ea=0;
  263. Ea=ea+1;
  264. *Ea=0;
  265. /* on remplace tous les MYSELF */
  266. l = sizeof(M);
  267. for (i=0; i<i_cod; i+=(l+1)) {
  268. if (cod[i]==T_MYSF) {
  269. cod[i] = T_FCT;
  270. bcopy((void*)&M,(void*)&cod[i+1],l);
  271. } else {
  272. if (cod[i]==T_ONER) {
  273. if (*ea==0) *ea = i;
  274. else {
  275. messErr(46);
  276. return;
  277. }
  278. } else {
  279. if (cod[i]==T_END) {
  280. if (*Ea==0) *Ea = i;
  281. else {
  282. messErr(47);
  283. return;
  284. }
  285. }
  286. }
  287. }
  288. }
  289. bcopy((void*)cod,(void*)((char*)M+(3*sizeof(int))),i_cod);
  290. F=putCodeFct(M);
  291. if (F->typ) {
  292. F->typ=2;
  293. addFonU(F->l,M);
  294. }
  295. /* printf("Total Fct : %d + %d !\n",i_cod,(3*sizeof(int))); */
  296. _MODIF_fctEnCours_(0);
  297. }
  298. void makeFct(Code c,void *A)
  299. {
  300. int d,i;
  301. long L, L2, LE;
  302. d = sizeof(A);
  303. /* printf("makeFct Entree : code %d + %d\n",(int)c,i_cod); */
  304. switch(c) {
  305. case T_RET :
  306. case T_NUM :
  307. case T_CHA :
  308. case T_LIB :
  309. case T_FCT :
  310. case T_MYSF :
  311. case T_DO_I :
  312. case T_DO_J :
  313. case T_DO_K :
  314. case T_VAR :
  315. case T_BKC :
  316. case T_BKC1 :
  317. case T_ONER :
  318. case T_END :
  319. case T_JEND :
  320. case T_EXEK :
  321. cod[i_cod++] = c;
  322. bcopy((void*)&A,(void*)&cod[i_cod],d);
  323. i_cod+=d;
  324. break;
  325. case T_IF :
  326. cod[i_cod++] = c;
  327. adr[i_adr]=(void*)&cod[i_cod];
  328. i_cod+=d;
  329. tad[i_adr++]=c;
  330. break;
  331. case T_ELSE :
  332. if (tad[i_adr-1] == T_IF) {
  333. cod[i_cod++] = T_JMP;
  334. adr[i_adr]=(void*)&cod[i_cod];
  335. L = (void*)&(cod[i_cod]) - adr[i_adr-1];
  336. i_cod+=d;
  337. bcopy((void*)&L,adr[i_adr-1],d);
  338. tad[i_adr++]=c;
  339. } else messErr(14);
  340. break;
  341. case T_THEN :
  342. if ((tad[i_adr-1] == T_IF) || (tad[i_adr-1] == T_ELSE)) {
  343. L = (void*)&cod[i_cod+1] - adr[i_adr-1] - (sizeof(void*)+1);/*AV5*/
  344. bcopy((void*)&L,adr[i_adr-1],d);
  345. tad[i_adr]='\0';
  346. while (tad[i_adr] != T_IF) i_adr--; /* depile adr */
  347. } else messErr(14);
  348. break;
  349. case T_BEGI :
  350. adB[i_adB]=i_cod;
  351. tcB[i_adB++]=c;
  352. break;
  353. case T_DO :
  354. cod[i_cod++] = c;
  355. i_cod+=d;
  356. adD[i_adD]=i_cod;
  357. tcD[i_adD++]=c;
  358. cod[i_cod++] = T_IFD;
  359. L = d+1;
  360. bcopy((void*)&L,(void*)&cod[i_cod],d);
  361. i_cod+=d;
  362. cod[i_cod++] = T_GOTO;
  363. L = -1;
  364. bcopy((void*)&L,(void*)&cod[i_cod],d);
  365. i_cod+=d;
  366. break;
  367. case T_PLOO :
  368. case T_LOOP :
  369. if (tcD[i_adD-1] == T_DO) {
  370. i_adD--; /* on depile */
  371. cod[i_cod++] = c;
  372. i_cod+=d;
  373. cod[i_cod++] = T_GOTO;
  374. L = adD[i_adD];
  375. bcopy((void*)&L,(void*)&cod[i_cod],d);
  376. i_cod+=d;
  377. /* maj des breaks GOTO -1 */
  378. LE = i_cod;
  379. for(i=L;i<i_cod-(d+1);i+=(d+1)) {
  380. if (cod[i] == T_GOTO) {
  381. bcopy((void*)&cod[i+1],(void*)&L2,d);
  382. if (L2==-1) bcopy((void*)&LE,(void*)&cod[i+1],d);
  383. }
  384. }
  385. } else messErr(39);
  386. break;
  387. case T_AGAI :
  388. case T_REPE :
  389. if (tcB[i_adB-1] == T_BEGI) {
  390. i_adB--; /* on depile */
  391. cod[i_cod++] = T_GOTO;
  392. L = adB[i_adB];
  393. bcopy((void*)&L,(void*)&cod[i_cod],d);
  394. i_cod+=d;
  395. /* maj des breaks GOTO -1 */
  396. LE = i_cod;
  397. for(i=L;i<i_cod-(d+1);i+=(d+1)) {
  398. if (cod[i] == T_GOTO) {
  399. bcopy((void*)&cod[i+1],(void*)&L2,d);
  400. if (L2==-1) bcopy((void*)&LE,(void*)&cod[i+1],d);
  401. }
  402. }
  403. } else messErr(22);
  404. break;
  405. case T_UNTI :
  406. case T_WHIL :
  407. if (tcB[i_adB-1] == T_BEGI) {
  408. cod[i_cod++] = T_IFN;
  409. /* if (c==T_UNTI) cod[i_cod++] = T_IFN;
  410. else cod[i_cod++] = T_IF;
  411. */
  412. L = d+1;
  413. bcopy((void*)&L,(void*)&cod[i_cod],d);
  414. i_cod+=d;
  415. cod[i_cod++] = T_GOTO;
  416. if (c==T_UNTI) L = adB[i_adB-1];
  417. else L = -1;
  418. bcopy((void*)&L,(void*)&cod[i_cod],d);
  419. i_cod+=d;
  420. if (c==T_UNTI) {
  421. i_adB--; /* depile adB */
  422. /* maj des breaks GOTO -1 */
  423. LE = i_cod;
  424. for(i=L;i<i_cod-(d+1);i+=(d+1)) {
  425. if (cod[i] == T_GOTO) {
  426. bcopy((void*)&cod[i+1],(void*)&L2,d);
  427. if (L2==-1) bcopy((void*)&LE,(void*)&cod[i+1],d);
  428. }
  429. }
  430. }
  431. } else messErr(22);
  432. break;
  433. case T_BREA :
  434. cod[i_cod++] = T_GOTO;
  435. L = -1; /* special value for BREAK */
  436. bcopy((void*)&L,(void*)&cod[i_cod],d);
  437. i_cod+=d;
  438. break;
  439. default :
  440. messErr(11);
  441. }
  442. }
  443. static void newFct2(char * S, int U)
  444. {
  445. char Lib[LDFLT+1];
  446. strncpy(Lib,S,LDFLT);
  447. Lib[LDFLT]='\0';
  448. initFct(Lib, U);
  449. _MODIF_fctEnCours_(1);
  450. dropTrSuite();
  451. i_cod = 0;
  452. i_adr = 0;
  453. i_adB = 0;
  454. i_adD = 0;
  455. }
  456. static void newFct0(char * S)
  457. {
  458. newFct2(S,0);
  459. }
  460. static void newFct1(char * S)
  461. {
  462. newFct2(S,1);
  463. }
  464. void IF_debFct(void)
  465. {
  466. putTrSuite(newFct0);
  467. }
  468. void IF_debFctS(void)
  469. {
  470. putTrSuite(newFct1);
  471. }
  472. int D_Cod=0; /* deep of execution functions */
  473. static int D_LooP=0; /* deep of execution loops */
  474. static int Do_Evts=0; /* Global events indicator for do...loop */
  475. void IF_DO_MLeave (void)
  476. {
  477. long P, i;
  478. getParLong(&P);
  479. i=I_DO+1;
  480. if (i) {
  481. if (P > i) P=i;
  482. Do_Evts=P;
  483. }
  484. }
  485. void IF_DO_Leave (void)
  486. {
  487. if (I_DO>=0) Do_Evts=1;
  488. }
  489. void IF_DO_Next (void)
  490. {
  491. if (I_DO>=0) Do_Evts=-1;
  492. }
  493. void IF_DO_Show (void)
  494. {
  495. printf("do vars : I_DO=%d Evts=%d\n",I_DO, Do_Evts);
  496. }
  497. void execCod(void *A)
  498. {
  499. int i,n, ea, Ea, *ai, InDo=0, OnErr=0, mFCTP;
  500. long L, P;
  501. char * C, *D, *F, *W, *S, *ADo_Next, *ADo_Leave;
  502. void * T, *T2;
  503. void (*f)(void);
  504. struct Fct * FR;
  505. /* printf("pid = %d ITASK=%d FctInTask=%d\n",getpid(),ITASK,FctInTask);*/
  506. if (FctInTask) {
  507. if (ITASK==0) {
  508. if (FctInTask==-1) {
  509. FctInTask=0; return;
  510. }
  511. if (MakeTask(A)) return;
  512. }
  513. if (ITASK!=FctInTask) return;
  514. }
  515. D_Cod++;
  516. ai = (int*)A;
  517. i = *ai++;
  518. ea = *ai++;
  519. Ea = *ai;
  520. if (ea) tellOnErr(A);
  521. C = (char*)A+(3*sizeof(int));
  522. D = C;
  523. F = C+i;
  524. n = sizeof(T);
  525. while (C <= F) {
  526. /* printf("execCod : %s %d - %x : %ld\n",
  527. codByAddr(A),(int)(C-D),*C,(long)*(C+1));
  528. */
  529. if (noErr() && ((C==F) || ((Code)*C != T_ONER)) ) { /* to find onerr: */
  530. if (ea && (OnErr==0)) {
  531. C = D+ea;
  532. } else {
  533. printf("Called in %s err=%d i=%d/%d cod=<%x>\n",
  534. codByAddr(A),noErr(),(int)(C-D),i,*C);
  535. break; /* end of while */
  536. }
  537. }
  538. if (C==F) break; /* end of code */
  539. switch((Code)*C) {
  540. case T_ONER :
  541. if (noErr()==0) { /* jmp end: */
  542. if (Ea) C = D+Ea;
  543. else C = F; /* to break */
  544. } else {
  545. if (OnErr==0) {
  546. OnErr=1;
  547. majLastErr(A);
  548. razErr();
  549. } else C = F;
  550. }
  551. break;
  552. case T_RET :
  553. C = F; /* to break */
  554. break;
  555. case T_END :
  556. break; /* nothing */
  557. case T_JEND :
  558. if (Ea) C = D+Ea;
  559. else C = F; /* to break */
  560. break;
  561. case T_NUM :
  562. bcopy((void*)(C+1),(void*)&T,n);
  563. insertVal(T);
  564. break;
  565. case T_CHA :
  566. bcopy((void*)(C+1),(void*)&W,n);
  567. putString(W);
  568. break;
  569. case T_LIB :
  570. if (InstallOn) {
  571. if (InstallOn < 3) {
  572. bcopy((void*)(C+1),(void*)&T,n);
  573. _MODIF_FCT_INST_(T);
  574. _MODIF_FCT_TYP_(1);
  575. } else {
  576. _MODIF_FCT_INST_(VIDE);
  577. _MODIF_FCT_TYP_(0);
  578. }
  579. InstallOn=0;
  580. } else {
  581. bcopy((void*)(C+1),(void*)&f,n);
  582. f();
  583. /* free context loops */
  584. if (Do_Evts) { /* quit or cut */
  585. /*printf("execCod T_LIB : Evts %d\n",Do_Evts);*/
  586. if (InDo) {
  587. if (Do_Evts>0) {
  588. C=ADo_Leave;
  589. I_DO--;
  590. InDo = 0;
  591. Do_Evts--;
  592. } else {
  593. C=ADo_Next;
  594. Do_Evts=0;
  595. }
  596. } else { /* quit */
  597. C = F;
  598. }
  599. }
  600. }
  601. break;
  602. case T_FCT :
  603. if (InstallOn) {
  604. if (InstallOn < 3) {
  605. bcopy((void*)(C+1),(void*)&T,n);
  606. T2=fctByCode(T);
  607. _MODIF_FCT_INST_(T2);
  608. _MODIF_FCT_TYP_(2);
  609. } else {
  610. _MODIF_FCT_INST_(VIDE);
  611. _MODIF_FCT_TYP_(0);
  612. }
  613. InstallOn=0;
  614. } else {
  615. bcopy((void*)(C+1),(void*)&T,n);
  616. execCod(T);
  617. /* free context loops */
  618. if (Do_Evts) { /* quit or cut */
  619. /*printf("execCod T_FCT : Evts %d\n",Do_Evts);*/
  620. if (InDo) {
  621. if (Do_Evts>0) {
  622. C=ADo_Leave;
  623. I_DO--;
  624. InDo = 0;
  625. Do_Evts--;
  626. } else {
  627. C=ADo_Next;
  628. Do_Evts=0;
  629. }
  630. } else { /* quit */
  631. C = F;
  632. }
  633. }
  634. }
  635. break;
  636. case T_FCTDS :
  637. case T_EXEKS :
  638. if ((S = getString()) != NULL)
  639. free((void*)S); /* remove the string */
  640. break;
  641. case T_FCTD :
  642. if ((S = getString()) != NULL)
  643. free((void*)S); /* remove the string */
  644. if (noErr()) break;
  645. case T_FCTDW :
  646. case T_FCTP :
  647. bcopy((void*)(C+1),(void*)&T,n);
  648. FR = (struct Fct *)T;
  649. execCod(FR->c);
  650. /* free context loops */
  651. if (Do_Evts) { /* quit or cut */
  652. /*printf("execCod T_FCTD : Evts %d\n",Do_Evts);*/
  653. if (InDo) {
  654. if (Do_Evts>0) {
  655. C=ADo_Leave;
  656. I_DO--;
  657. InDo = 0;
  658. Do_Evts--;
  659. } else {
  660. C=ADo_Next;
  661. Do_Evts=0;
  662. }
  663. } else { /* quit */
  664. C = F;
  665. }
  666. }
  667. if (*C == T_FCTP) {
  668. if (mFCTP) *C = T_FCTDW;
  669. else *C = T_FCTD;
  670. }
  671. break;
  672. case T_EXEK :
  673. if ((S = getString()) != NULL) {
  674. if (strlen(S)>0) { /* to do with T_FCTD */
  675. mFCTP=0;
  676. T = makeFunction(S);
  677. if (T != VIDE) {
  678. bcopy((void*)&T, (void*)(C+1),n);
  679. *C = T_FCTP;
  680. C -= (n+1);
  681. unlinkLastFct();
  682. /* upgrading precedent code ? not always ! */
  683. if (C >= D) {
  684. if (*C == T_CHA) { /* case of a string */
  685. *C = T_CHAS;
  686. mFCTP=1;
  687. }
  688. if (*C == T_VAR) { /* case of a variable string */
  689. bcopy((void*)(C+1),(void*)&W,n);
  690. if (isVarChar(W)) {
  691. *C = T_VARS;
  692. mFCTP=1;
  693. }
  694. }
  695. }
  696. } else /* error in compilation */
  697. *C = T_EXEKS;
  698. }
  699. free((void*)S);
  700. }
  701. break;
  702. case T_IF :
  703. if (!getBool()) {
  704. bcopy((void*)(C+1),(void*)&L,n);
  705. C += L;
  706. }
  707. break;
  708. case T_IFN :
  709. if (getBool()) {
  710. bcopy((void*)(C+1),(void*)&L,n);
  711. C += L;
  712. }
  713. break;
  714. case T_DO :
  715. I_DO++;
  716. InDo=1;
  717. /* maj do_adresses */
  718. W = C + (2*(n+1));
  719. bcopy((void*)(W+1),(void*)&L,n);
  720. ADo_Leave=D+L-n-1;
  721. ADo_Next=ADo_Leave-(2*(n+1));
  722. /* printf("execCod T_DO : AL= %d AN=%d\n",
  723. (int)(ADo_Leave-D), (int)(ADo_Next-D));*/
  724. getParLong(&P);
  725. D_DO[I_DO] = P;
  726. getParLong(&P);
  727. L_DO[I_DO] = P;
  728. if (P > D_DO[I_DO]) S_DO[I_DO]=0;
  729. else S_DO[I_DO]=1;
  730. break;
  731. case T_DO_I :
  732. IF_getIndDo(0);
  733. break;
  734. case T_DO_J :
  735. IF_getIndDo(1);
  736. break;
  737. case T_DO_K :
  738. IF_getIndDo(2);
  739. break;
  740. case T_IFD :
  741. if (S_DO[I_DO]) {
  742. if (D_DO[I_DO] > L_DO[I_DO]) {
  743. bcopy((void*)(C+1),(void*)&L,n);
  744. C += L;
  745. } else {
  746. I_DO--;
  747. InDo=0;
  748. }
  749. } else {
  750. if (D_DO[I_DO] < L_DO[I_DO]) {
  751. bcopy((void*)(C+1),(void*)&L,n);
  752. C += L;
  753. } else {
  754. I_DO--;
  755. InDo=0;
  756. }
  757. }
  758. break;
  759. case T_LOOP :
  760. if (S_DO[I_DO]) D_DO[I_DO]--;
  761. else D_DO[I_DO]++;
  762. break;
  763. case T_PLOO :
  764. getParLong(&P);
  765. D_DO[I_DO]+=P;
  766. break;
  767. case T_JMP :
  768. bcopy((void*)(C+1),(void*)&L,n);
  769. C += L;
  770. break;
  771. case T_GOTO :
  772. bcopy((void*)(C+1),(void*)&L,n);
  773. C = D + L - n-1;
  774. break;
  775. case T_VAR :
  776. if (InstallOn) {
  777. if (InstallOn == 3) {
  778. bcopy((void*)(C+1),(void*)&T,n);
  779. _MODIF_FCT_INST_(T);
  780. _MODIF_FCT_TYP_(3);
  781. } else {
  782. _MODIF_FCT_INST_(VIDE);
  783. _MODIF_FCT_TYP_(0);
  784. }
  785. InstallOn=0;
  786. } else {
  787. bcopy((void*)(C+1),(void*)&W,n);
  788. executeVar(W);
  789. /* free context loops */
  790. if (Do_Evts) { /* quit or cut */
  791. /*printf("execCod T_VAR : Evts %d\n",Do_Evts);*/
  792. if (InDo) {
  793. if (Do_Evts>0) {
  794. C=ADo_Leave;
  795. I_DO--;
  796. InDo = 0;
  797. Do_Evts--;
  798. } else {
  799. C=ADo_Next;
  800. Do_Evts=0;
  801. }
  802. } else { /* quit */
  803. C = F;
  804. }
  805. }
  806. }
  807. break;
  808. case T_BKC :
  809. bcopy((void*)(C+1),(void*)&W,n);
  810. execLib(W);
  811. break;
  812. case T_BKC1 : /* like makeFct */
  813. bcopy((void*)(C+1),(void*)&W,n);
  814. /* try to modify the code */
  815. if (VARS==2) { /* VARS UP */
  816. if ((T = varByName(W)) != VIDE) {
  817. *C = T_VAR;
  818. } else {
  819. if ((T = fctByName(W)) != VIDE) {
  820. *C = T_FCT;
  821. FR = (struct Fct *)T;
  822. T = FR->c;
  823. }
  824. }
  825. } else {
  826. if ((T = fctByName(W)) != VIDE) {
  827. *C = T_FCT;
  828. FR = (struct Fct *)T;
  829. T = FR->c;
  830. } else {
  831. if ((VARS==1) && ((T = varByName(W)) != VIDE)) {
  832. *C = T_VAR;
  833. }
  834. }
  835. }
  836. if ((Code)*C != T_BKC1) { /* code is updated */
  837. bcopy((void*)&T, (void*)(C+1),n);
  838. C-=(n+1); /* it must be executed */
  839. }
  840. break;
  841. case T_NOP :
  842. case T_CHAS :
  843. case T_VARS :
  844. case T_FCTDWS :
  845. break;
  846. default :
  847. messErr(11);
  848. }
  849. C+= n+1;
  850. }
  851. D_Cod--;
  852. if (ea) tellOnErr(VIDE);
  853. }
  854. void execFctV(void * A)
  855. {
  856. struct Fct * N;
  857. N = (struct Fct*) A;
  858. execCod(N->c);
  859. }
  860. int IF_execFct(char * L)
  861. {
  862. void * Next;
  863. struct Fct * N;
  864. Next = stackF;
  865. while (Next != VIDE) {
  866. N = (struct Fct*) Next;
  867. if (strcmp(N->l,L)==0) {
  868. if (fctEnCours) makeFct(T_FCT,N->c);
  869. else execCod(N->c);
  870. return 1;
  871. }
  872. Next = N->n;
  873. }
  874. return 0;
  875. }
  876. void * fctByName(char * L)
  877. {
  878. void * Next;
  879. struct Fct * N;
  880. Next = stackF;
  881. while (Next != VIDE) {
  882. N = (struct Fct*) Next;
  883. if (strcmp(N->l,L)==0) return Next;
  884. Next = N->n;
  885. }
  886. return VIDE;
  887. }
  888. void * fctByCode(void * C)
  889. {
  890. void * Next;
  891. struct Fct * N;
  892. Next = stackF;
  893. while (Next != VIDE) {
  894. N = (struct Fct*) Next;
  895. if (N->c==C) return Next;
  896. Next = N->n;
  897. }
  898. return VIDE;
  899. }
  900. static void rmFct(char * L)
  901. {
  902. void ** PNext;
  903. struct Fct * N;
  904. dropTrSuite();
  905. PNext = &stackF;
  906. while (*PNext != VIDE) {
  907. N = (struct Fct*) *PNext;
  908. if (N->typ==0)
  909. if (strcmp(N->l,L)==0) {
  910. *PNext = N->n;
  911. eraseFct(N);
  912. return;
  913. }
  914. PNext = &N->n;
  915. }
  916. messErr(21);
  917. }
  918. static void rmAFct(char * L)
  919. {
  920. void ** PNext;
  921. struct Fct * N;
  922. dropTrSuite();
  923. PNext = &stackF;
  924. while (*PNext != VIDE) {
  925. N = (struct Fct*) *PNext;
  926. if ((N->typ==0) && (strncmp(N->l,L,strlen(L))==0)) {
  927. *PNext = N->n;
  928. eraseFct(N);
  929. }
  930. else PNext = &N->n;
  931. }
  932. }
  933. static void rmOFct(char * L)
  934. {
  935. void ** PNext, ** FP;
  936. struct Fct * N, * F;
  937. dropTrSuite();
  938. F = VIDE;
  939. PNext = &stackF;
  940. while (*PNext != VIDE) {
  941. N = (struct Fct*) *PNext;
  942. if (N->typ==0)
  943. if (strcmp(N->l,L)==0) {
  944. FP = PNext;
  945. F = N;
  946. }
  947. PNext = &N->n;
  948. }
  949. if (F != VIDE) {
  950. *FP = F->n;
  951. eraseFct(F);
  952. }
  953. else messErr(21);
  954. }
  955. char * fctByAddr(void * A)
  956. {
  957. void * Next;
  958. struct Fct * N;
  959. Next = stackF;
  960. while (Next != VIDE) {
  961. N = (struct Fct*) Next;
  962. if (Next==A) return N->l;
  963. Next = N->n;
  964. }
  965. return NULL;
  966. }
  967. char * codByAddr(void * A)
  968. {
  969. void * Next;
  970. struct Fct * N;
  971. Next = stackF;
  972. while (Next != VIDE) {
  973. N = (struct Fct*) Next;
  974. if (N->c==A) return N->l;
  975. Next = N->n;
  976. }
  977. return NULL;
  978. }
  979. void prMarge(int n)
  980. {
  981. int N, i;
  982. N = n*3;
  983. for(i=0;i<N;i++) printf(" ");
  984. }
  985. static void scanFoncI(void * AdF, int marge)
  986. {
  987. void *A, *W;
  988. struct Fct * N;
  989. int i,n, ea, Ea, *ai;
  990. long L;
  991. char * C, *F, *D, lm[6];
  992. N = (struct Fct *)AdF;
  993. *lm = '\0';
  994. A = N->c;
  995. ai = (int*)A;
  996. i = *ai++;
  997. ea = *ai++;
  998. Ea = *ai;
  999. C = (char*)A+(3*sizeof(int));
  1000. D = C;
  1001. F = C+i;
  1002. n = sizeof(A);
  1003. if (marge) prMarge(marge);
  1004. if (N->typ) printf ("System ");
  1005. printf("Fonction : %s (%d) : 0x%lx\n", N->l, i, (unsigned long)A );
  1006. if (ea+Ea) {
  1007. if (ea) printf("Catching error at %d",ea);
  1008. if (Ea) {
  1009. if (ea) printf(" - ");
  1010. printf("End label at %d",Ea);
  1011. }
  1012. printf("\n");
  1013. }
  1014. while (C < F) {
  1015. if (marge) prMarge(marge);
  1016. printf(" %.4d : ",(int)(C-D));
  1017. switch((Code)*C) {
  1018. case T_NOP :
  1019. case T_CHAS :
  1020. case T_VARS :
  1021. case T_FCTDWS :
  1022. printf("NOP\n");
  1023. break;
  1024. case T_FCTDS :
  1025. case T_EXEKS :
  1026. printf("\"drop\n");
  1027. break;
  1028. case T_RET :
  1029. printf("RETURN\n");
  1030. break;
  1031. case T_ONER :
  1032. printf("onerr: label\n");
  1033. break;
  1034. case T_END :
  1035. printf("end: label\n");
  1036. break;
  1037. case T_JEND :
  1038. printf("goto end:\n");
  1039. break;
  1040. case T_NUM :
  1041. bcopy((void*)(C+1),(void*)&W,n);
  1042. printf("Number value : ");
  1043. printNumber(W);
  1044. printf("\n");
  1045. break;
  1046. case T_CHA :
  1047. bcopy((void*)(C+1),(void*)&W,n);
  1048. printf("Character String \"%s\"\n",(char*)W);
  1049. break;
  1050. case T_LIB :
  1051. bcopy((void*)(C+1),(void*)&W,n);
  1052. printf("Call to library : %s\n", libByAddr(W));
  1053. break;
  1054. case T_FCT :
  1055. bcopy((void*)(C+1),(void*)&W,n);
  1056. printf("Function : %s\n", codByAddr(W));
  1057. break;
  1058. case T_FCTD :
  1059. printf("\"drop + ");
  1060. case T_FCTDW :
  1061. bcopy((void*)(C+1),(void*)&W,n);
  1062. N = (struct Fct *)W;
  1063. printf("Dynamic Function at 0x%lx\n", (long)W);
  1064. scanFoncI(W,marge+1);
  1065. break;
  1066. case T_IF :
  1067. bcopy((void*)(C+1),(void*)&L,n);
  1068. printf("IF false goto %ld\n",(C-D)+L+n+1);
  1069. break;
  1070. case T_DO :
  1071. printf("DO [ LIMIT I -- ]\n");
  1072. break;
  1073. case T_DO_I :
  1074. printf("GET I [ -- I ]\n");
  1075. break;
  1076. case T_DO_J :
  1077. printf("GET J [ -- J ]\n");
  1078. break;
  1079. case T_DO_K :
  1080. printf("GET K [ -- K ]\n");
  1081. break;
  1082. case T_LOOP :
  1083. printf("I=+/-1\n");
  1084. break;
  1085. case T_PLOO :
  1086. printf("I += V [ V -- ]\n");
  1087. break;
  1088. case T_IFN :
  1089. bcopy((void*)(C+1),(void*)&L,n);
  1090. printf("IF true goto %ld\n",(C-D)+L+n+1);
  1091. break;
  1092. case T_IFD :
  1093. bcopy((void*)(C+1),(void*)&L,n);
  1094. printf("IF (LIMIT NOT REACHED) goto %ld\n",(C-D)+L+n+1);
  1095. break;
  1096. case T_JMP :
  1097. bcopy((void*)(C+1),(void*)&L,n);
  1098. printf("JMP $+%ld\n",L);
  1099. break;
  1100. case T_GOTO :
  1101. bcopy((void*)(C+1),(void*)&L,n);
  1102. printf("GOTO %ld\n",L);
  1103. break;
  1104. case T_EXEK :
  1105. printf("Dynamic Compile (\"execk) !\n");
  1106. break;
  1107. case T_VAR :
  1108. bcopy((void*)(C+1),(void*)&W,n);
  1109. printf("Call variable : %s\n", varByAddr(W));
  1110. break;
  1111. case T_BKC1 :
  1112. strcpy(lm,"1st ");
  1113. case T_BKC :
  1114. bcopy((void*)(C+1),(void*)&W,n);
  1115. printf("Back Compile %s: \"%s\"\n",lm, (char*)W);
  1116. break;
  1117. default :
  1118. printf("0x%x : code inconnu !!\n",(int)*C);
  1119. }
  1120. C+= n+1;
  1121. }
  1122. }
  1123. static void scanFonc(char * Lib)
  1124. {
  1125. void ** PNext;
  1126. struct Fct * N;
  1127. dropTrSuite();
  1128. PNext = &stackF;
  1129. while (*PNext != VIDE) {
  1130. N = (struct Fct*) *PNext;
  1131. if (strcmp(N->l,Lib)==0) break;
  1132. PNext = &N->n;
  1133. }
  1134. if (strcmp(N->l,Lib)!=0) {
  1135. messErr(21);
  1136. return;
  1137. }
  1138. scanFoncI((void*)N ,0);
  1139. }
  1140. void IF_execCS(void)
  1141. {
  1142. char * f;
  1143. f = getString();
  1144. if (f != NULL) {
  1145. if (!IF_execFct(f)) {
  1146. printf("%s - ",f); messErr(21);
  1147. }
  1148. free((void*)f);
  1149. }
  1150. }
  1151. void IF_execCSl(void)
  1152. {
  1153. char * f;
  1154. f = getString();
  1155. if (f != NULL) {
  1156. if (IF_execFct(f)) putBool(TRUE);
  1157. else putBool(FALSE);
  1158. free((void*)f);
  1159. }
  1160. else putBool(FALSE);
  1161. }
  1162. void IF_execCSv(void)
  1163. {
  1164. char * f;
  1165. f = getString();
  1166. if (f != NULL) {
  1167. if (!IF_execVar(f)) {
  1168. printf("%s - ",f); messErr(24);
  1169. }
  1170. free((void*)f);
  1171. }
  1172. }
  1173. void IF_execCSvl(void)
  1174. {
  1175. char * f;
  1176. f = getString();
  1177. if (f != NULL) {
  1178. if (IF_execVar(f)) putBool(TRUE);
  1179. else putBool(FALSE);
  1180. free((void*)f);
  1181. }
  1182. else putBool(FALSE);
  1183. }
  1184. void IF_delFct(void)
  1185. {
  1186. putTrSuite(rmFct);
  1187. }
  1188. void IF_delAFct(void)
  1189. {
  1190. putTrSuite(rmAFct);
  1191. }
  1192. void IF_delOFct(void)
  1193. {
  1194. putTrSuite(rmOFct);
  1195. }
  1196. void IF_scanFct(void)
  1197. {
  1198. putTrSuite(scanFonc);
  1199. }
  1200. static void IF_instruct(Code C)
  1201. {
  1202. if (fctEnCours) makeFct(C,NULL);
  1203. else messErr(13);
  1204. }
  1205. void IF_RET(void) { IF_instruct(T_RET); }
  1206. void IF_IF(void) { IF_instruct(T_IF); }
  1207. void IF_THEN(void) { IF_instruct(T_THEN); }
  1208. void IF_ELSE(void) { IF_instruct(T_ELSE); }
  1209. void IF_BEGIN(void) { IF_instruct(T_BEGI); }
  1210. void IF_AGAIN(void) { IF_instruct(T_AGAI); }
  1211. void IF_UNTIL(void) { IF_instruct(T_UNTI); }
  1212. void IF_WHILE(void) { IF_instruct(T_WHIL); }
  1213. void IF_REPEAT(void) { IF_instruct(T_REPE); }
  1214. void IF_BREAK(void) { IF_instruct(T_BREA); }
  1215. void IF_MYSELF(void) { IF_instruct(T_MYSF); }
  1216. void IF_DO(void) { IF_instruct(T_DO); }
  1217. void IF_LOOP(void) { IF_instruct(T_LOOP); }
  1218. void IF_PLOOP(void) { IF_instruct(T_PLOO); }
  1219. void IF_I_DO(void) { IF_instruct(T_DO_I); }
  1220. void IF_J_DO(void) { IF_instruct(T_DO_J); }
  1221. void IF_K_DO(void) { IF_instruct(T_DO_K); }
  1222. void IF_ONERR(void) { IF_instruct(T_ONER); }
  1223. void IF_END(void) { IF_instruct(T_END); }
  1224. void IF_JEND(void) { IF_instruct(T_JEND); }
  1225. void IF_EXEK(void) { IF_instruct(T_EXEK); }
  1226. /* code for back compilation of calling functions and variables */
  1227. void suiteBackC(char *S)
  1228. {
  1229. void * M;
  1230. dropTrSuite();
  1231. if (strlen(S) > LDFLT) {
  1232. messErr(9);
  1233. return;
  1234. }
  1235. if (S[strlen(S)-1] != '\'') {
  1236. messErr(44);
  1237. return;
  1238. }
  1239. S[strlen(S)-1] = '\0';
  1240. if ((M = malloc(strlen(S)+1)) == NULL) stopErr("suiteBackC","malloc");
  1241. #ifdef DEBUG_M
  1242. printf("New String address : %lu \n",(unsigned long)M);
  1243. #endif
  1244. strcpy((char*)M,S);
  1245. if (fctEnCours) makeFct(T_BKC,M);
  1246. else messErr(13);
  1247. }
  1248. void IF_debBackC(void)
  1249. {
  1250. putTrSuite(suiteBackC);
  1251. }
  1252. void suiteBackC1(char *S)
  1253. {
  1254. void * M;
  1255. dropTrSuite();
  1256. if (strlen(S) > LDFLT) {
  1257. messErr(9);
  1258. return;
  1259. }
  1260. if (S[strlen(S)-1] != '`') {
  1261. messErr(44);
  1262. return;
  1263. }
  1264. S[strlen(S)-1] = '\0';
  1265. if ((M = malloc(strlen(S)+1)) == NULL) stopErr("suiteBackC1","malloc");
  1266. #ifdef DEBUG_M
  1267. printf("New String address : %lu \n",(unsigned long)M);
  1268. #endif
  1269. strcpy((char*)M,S);
  1270. if (fctEnCours) makeFct(T_BKC1,M);
  1271. else messErr(13);
  1272. }
  1273. void IF_debBackC1(void)
  1274. {
  1275. putTrSuite(suiteBackC1);
  1276. }