OPC.c 47 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016
  1. /* voc 2.1.0 [2019/11/01]. Bootstrapping compiler for address size 8, alignment 8. xrtspaSF */
  2. #define SHORTINT INT8
  3. #define INTEGER INT16
  4. #define LONGINT INT32
  5. #define SET UINT32
  6. #include "SYSTEM.h"
  7. #include "Configuration.h"
  8. #include "OPM.h"
  9. #include "OPT.h"
  10. static INT16 OPC_indentLevel;
  11. static INT8 OPC_hashtab[105];
  12. static CHAR OPC_keytab[50][9];
  13. static BOOLEAN OPC_GlbPtrs;
  14. static CHAR OPC_BodyNameExt[13];
  15. export void OPC_Andent (OPT_Struct typ);
  16. static void OPC_AnsiParamList (OPT_Object obj, BOOLEAN showParamNames);
  17. export OPT_Object OPC_BaseTProc (OPT_Object obj);
  18. export void OPC_BegBlk (void);
  19. export void OPC_BegStat (void);
  20. static void OPC_CProcDefs (OPT_Object obj, INT16 vis);
  21. export void OPC_Case (INT64 caseVal, INT16 form);
  22. static void OPC_CharacterLiteral (INT64 c);
  23. export void OPC_Cmp (INT16 rel);
  24. export void OPC_CompleteIdent (OPT_Object obj);
  25. export void OPC_Constant (OPT_Const con, INT16 form);
  26. static void OPC_DeclareBase (OPT_Object dcl);
  27. static void OPC_DeclareObj (OPT_Object dcl, BOOLEAN scopeDef);
  28. static void OPC_DeclareParams (OPT_Object par, BOOLEAN macro);
  29. static void OPC_DeclareTProcs (OPT_Object obj, BOOLEAN *empty);
  30. static void OPC_DefAnonRecs (OPT_Node n);
  31. export void OPC_DefineInter (OPT_Object proc);
  32. static void OPC_DefineTProcMacros (OPT_Object obj, BOOLEAN *empty);
  33. static void OPC_DefineTProcTypes (OPT_Object obj);
  34. static void OPC_DefineType (OPT_Struct str);
  35. export void OPC_EndBlk (void);
  36. export void OPC_EndBlk0 (void);
  37. export void OPC_EndStat (void);
  38. export void OPC_EnterBody (void);
  39. export void OPC_EnterProc (OPT_Object proc);
  40. export void OPC_ExitBody (void);
  41. export void OPC_ExitProc (OPT_Object proc, BOOLEAN eoBlock, BOOLEAN implicitRet);
  42. static void OPC_FieldList (OPT_Struct typ, BOOLEAN last, INT32 *off, INT32 *n, INT32 *curAlign);
  43. static void OPC_FillGap (INT32 gap, INT32 off, INT32 align, INT32 *n, INT32 *curAlign);
  44. export void OPC_GenBdy (OPT_Node n);
  45. static void OPC_GenDynTypes (OPT_Node n, INT16 vis);
  46. export void OPC_GenEnumPtrs (OPT_Object var);
  47. export void OPC_GenHdr (OPT_Node n);
  48. export void OPC_GenHdrIncludes (void);
  49. static void OPC_GenHeaderMsg (void);
  50. export void OPC_Halt (INT32 n);
  51. export void OPC_Ident (OPT_Object obj);
  52. static void OPC_IdentList (OPT_Object obj, INT16 vis);
  53. static void OPC_Include (CHAR *name, ADDRESS name__len);
  54. static void OPC_IncludeImports (OPT_Object obj, INT16 vis);
  55. export void OPC_Increment (BOOLEAN decrement);
  56. export void OPC_Indent (INT16 count);
  57. export void OPC_Init (void);
  58. static void OPC_InitImports (OPT_Object obj);
  59. static void OPC_InitKeywords (void);
  60. export void OPC_InitTDesc (OPT_Struct typ);
  61. static void OPC_InitTProcs (OPT_Object typ, OPT_Object obj);
  62. export void OPC_IntLiteral (INT64 n, INT32 size);
  63. export void OPC_Len (OPT_Object obj, OPT_Struct array, INT64 dim);
  64. static void OPC_LenList (OPT_Object par, BOOLEAN ansiDefine, BOOLEAN showParamName);
  65. static INT16 OPC_Length (CHAR *s, ADDRESS s__len);
  66. export BOOLEAN OPC_NeedsRetval (OPT_Object proc);
  67. export INT32 OPC_NofPtrs (OPT_Struct typ);
  68. static INT16 OPC_PerfectHash (CHAR *s, ADDRESS s__len);
  69. static BOOLEAN OPC_Prefixed (OPT_ConstExt x, CHAR *y, ADDRESS y__len);
  70. static void OPC_ProcHeader (OPT_Object proc, BOOLEAN define);
  71. static void OPC_ProcPredefs (OPT_Object obj, INT8 vis);
  72. static void OPC_PutBase (OPT_Struct typ);
  73. static void OPC_PutPtrOffsets (OPT_Struct typ, INT32 adr, INT32 *cnt);
  74. static void OPC_RegCmds (OPT_Object obj);
  75. export void OPC_SetInclude (BOOLEAN exclude);
  76. static void OPC_Stars (OPT_Struct typ, BOOLEAN *openClause);
  77. static void OPC_Str1 (CHAR *s, ADDRESS s__len, INT32 x);
  78. static void OPC_StringLiteral (CHAR *s, ADDRESS s__len, INT32 l);
  79. export void OPC_TDescDecl (OPT_Struct typ);
  80. export void OPC_TypeDefs (OPT_Object obj, INT16 vis);
  81. export void OPC_TypeOf (OPT_Object ap);
  82. static BOOLEAN OPC_Undefined (OPT_Object obj);
  83. void OPC_Init (void)
  84. {
  85. OPC_indentLevel = 0;
  86. __MOVE("__init(void)", OPC_BodyNameExt, 13);
  87. }
  88. void OPC_Indent (INT16 count)
  89. {
  90. OPC_indentLevel += count;
  91. }
  92. void OPC_BegStat (void)
  93. {
  94. INT16 i;
  95. i = OPC_indentLevel;
  96. while (i > 0) {
  97. OPM_Write(0x09);
  98. i -= 1;
  99. }
  100. }
  101. void OPC_EndStat (void)
  102. {
  103. OPM_Write(';');
  104. OPM_WriteLn();
  105. }
  106. void OPC_BegBlk (void)
  107. {
  108. OPM_Write('{');
  109. OPM_WriteLn();
  110. OPC_indentLevel += 1;
  111. }
  112. void OPC_EndBlk (void)
  113. {
  114. OPC_indentLevel -= 1;
  115. OPC_BegStat();
  116. OPM_Write('}');
  117. OPM_WriteLn();
  118. }
  119. void OPC_EndBlk0 (void)
  120. {
  121. OPC_indentLevel -= 1;
  122. OPC_BegStat();
  123. OPM_Write('}');
  124. }
  125. static void OPC_Str1 (CHAR *s, ADDRESS s__len, INT32 x)
  126. {
  127. CHAR ch;
  128. INT16 i;
  129. __DUP(s, s__len, CHAR);
  130. ch = s[0];
  131. i = 0;
  132. while (ch != 0x00) {
  133. if (ch == '#') {
  134. OPM_WriteInt(x);
  135. } else {
  136. OPM_Write(ch);
  137. }
  138. i += 1;
  139. ch = s[__X(i, s__len)];
  140. }
  141. __DEL(s);
  142. }
  143. static INT16 OPC_Length (CHAR *s, ADDRESS s__len)
  144. {
  145. INT16 i;
  146. i = 0;
  147. while (s[__X(i, s__len)] != 0x00) {
  148. i += 1;
  149. }
  150. return i;
  151. }
  152. static INT16 OPC_PerfectHash (CHAR *s, ADDRESS s__len)
  153. {
  154. INT16 i, h;
  155. i = 0;
  156. h = 0;
  157. while ((s[__X(i, s__len)] != 0x00 && i < 5)) {
  158. h = 3 * h + (INT16)s[__X(i, s__len)];
  159. i += 1;
  160. }
  161. return (int)__MOD(h, 105);
  162. }
  163. void OPC_Ident (OPT_Object obj)
  164. {
  165. INT16 mode, level, h;
  166. mode = obj->mode;
  167. level = obj->mnolev;
  168. if ((__IN(mode, 0x62, 32) && level > 0) || __IN(mode, 0x14, 32)) {
  169. OPM_WriteStringVar((void*)obj->name, 256);
  170. h = OPC_PerfectHash((void*)obj->name, 256);
  171. if (OPC_hashtab[__X(h, 105)] >= 0) {
  172. if (__STRCMP(OPC_keytab[__X(OPC_hashtab[__X(h, 105)], 50)], obj->name) == 0) {
  173. OPM_Write('_');
  174. }
  175. }
  176. } else if ((mode == 5 && __IN(obj->typ->form, 0x90, 32))) {
  177. if (obj->typ == OPT_adrtyp) {
  178. OPM_WriteString((CHAR*)"ADDRESS", 8);
  179. } else {
  180. if (obj->typ->form == 4) {
  181. OPM_WriteString((CHAR*)"INT", 4);
  182. } else {
  183. OPM_WriteString((CHAR*)"UINT", 5);
  184. }
  185. OPM_WriteInt(__ASHL(obj->typ->size, 3));
  186. }
  187. } else {
  188. if (mode != 5 || obj->linkadr != 2) {
  189. if (mode == 13) {
  190. OPC_Ident(obj->link->typ->strobj);
  191. } else if (level < 0) {
  192. OPM_WriteStringVar((void*)OPT_GlbMod[__X(-level, 64)]->name, 256);
  193. if (OPM_currFile == 0) {
  194. OPT_GlbMod[__X(-level, 64)]->vis = 1;
  195. }
  196. } else {
  197. OPM_WriteStringVar((void*)OPM_modName, 32);
  198. }
  199. OPM_Write('_');
  200. } else if (obj == OPT_sysptrtyp->strobj || obj == OPT_bytetyp->strobj) {
  201. OPM_WriteString((CHAR*)"SYSTEM_", 8);
  202. }
  203. OPM_WriteStringVar((void*)obj->name, 256);
  204. }
  205. }
  206. static void OPC_Stars (OPT_Struct typ, BOOLEAN *openClause)
  207. {
  208. INT16 pointers;
  209. *openClause = 0;
  210. if (((typ->strobj == NIL || typ->strobj->name[0] == 0x00) && typ->comp != 4)) {
  211. if (__IN(typ->comp, 0x0c, 32)) {
  212. OPC_Stars(typ->BaseTyp, &*openClause);
  213. *openClause = typ->comp == 2;
  214. } else if (typ->form == 12) {
  215. OPM_Write('(');
  216. OPM_Write('*');
  217. } else {
  218. pointers = 0;
  219. while (((typ->strobj == NIL || typ->strobj->name[0] == 0x00) && typ->form == 11)) {
  220. pointers += 1;
  221. typ = typ->BaseTyp;
  222. }
  223. if (pointers > 0) {
  224. if (typ->comp != 3) {
  225. OPC_Stars(typ, &*openClause);
  226. }
  227. if (*openClause) {
  228. OPM_Write('(');
  229. *openClause = 0;
  230. }
  231. while (pointers > 0) {
  232. OPM_Write('*');
  233. pointers -= 1;
  234. }
  235. }
  236. }
  237. }
  238. }
  239. static void OPC_DeclareObj (OPT_Object dcl, BOOLEAN scopeDef)
  240. {
  241. OPT_Struct typ = NIL;
  242. BOOLEAN varPar, openClause;
  243. INT16 form, comp;
  244. typ = dcl->typ;
  245. varPar = ((dcl->mode == 2 && typ->comp != 2) || typ->comp == 3) || scopeDef;
  246. OPC_Stars(typ, &openClause);
  247. if (varPar) {
  248. if (openClause) {
  249. OPM_Write('(');
  250. }
  251. OPM_Write('*');
  252. }
  253. if (dcl->name[0] != 0x00) {
  254. OPC_Ident(dcl);
  255. }
  256. if ((varPar && openClause)) {
  257. OPM_Write(')');
  258. }
  259. openClause = 0;
  260. for (;;) {
  261. form = typ->form;
  262. comp = typ->comp;
  263. if (((typ->strobj != NIL && typ->strobj->name[0] != 0x00) || form == 10) || comp == 4) {
  264. break;
  265. } else if ((form == 11 && typ->BaseTyp->comp != 3)) {
  266. openClause = 1;
  267. } else if (form == 12 || __IN(comp, 0x0c, 32)) {
  268. if (openClause) {
  269. OPM_Write(')');
  270. openClause = 0;
  271. }
  272. if (form == 12) {
  273. OPM_Write(')');
  274. OPC_AnsiParamList(typ->link, 0);
  275. break;
  276. } else if (comp == 2) {
  277. OPM_Write('[');
  278. OPM_WriteInt(typ->n);
  279. OPM_Write(']');
  280. }
  281. } else {
  282. break;
  283. }
  284. typ = typ->BaseTyp;
  285. }
  286. }
  287. void OPC_Andent (OPT_Struct typ)
  288. {
  289. if (typ->strobj == NIL || typ->align >= 65536) {
  290. OPM_WriteStringVar((void*)OPM_modName, 32);
  291. OPC_Str1((CHAR*)"__#", 4, __ASHR(typ->align, 16));
  292. } else {
  293. OPC_Ident(typ->strobj);
  294. }
  295. }
  296. static BOOLEAN OPC_Undefined (OPT_Object obj)
  297. {
  298. return obj->name[0] == 0x00 || (((obj->mnolev >= 0 && obj->linkadr != (3 + OPM_currFile))) && obj->linkadr != 2);
  299. }
  300. static void OPC_DeclareBase (OPT_Object dcl)
  301. {
  302. OPT_Struct typ = NIL, prev = NIL;
  303. OPT_Object obj = NIL;
  304. INT16 nofdims;
  305. INT32 off, n, dummy;
  306. typ = dcl->typ;
  307. prev = typ;
  308. while ((((((((typ->strobj == NIL || typ->comp == 3) || OPC_Undefined(typ->strobj)) && typ->comp != 4)) && typ->form != 10)) && !((typ->form == 11 && typ->BaseTyp->comp == 3)))) {
  309. prev = typ;
  310. typ = typ->BaseTyp;
  311. }
  312. obj = typ->strobj;
  313. if (typ->form == 10) {
  314. OPM_WriteString((CHAR*)"void", 5);
  315. } else if ((obj != NIL && !OPC_Undefined(obj))) {
  316. OPC_Ident(obj);
  317. } else if (typ->comp == 4) {
  318. OPM_WriteString((CHAR*)"struct ", 8);
  319. OPC_Andent(typ);
  320. if ((prev->form != 11 && (obj != NIL || dcl->name[0] == 0x00))) {
  321. if ((typ->BaseTyp != NIL && typ->BaseTyp->strobj->vis != 0)) {
  322. OPM_WriteString((CHAR*)" { /* ", 7);
  323. OPC_Ident(typ->BaseTyp->strobj);
  324. OPM_WriteString((CHAR*)" */", 4);
  325. OPM_WriteLn();
  326. OPC_Indent(1);
  327. } else {
  328. OPM_Write(' ');
  329. OPC_BegBlk();
  330. }
  331. OPC_FieldList(typ, 1, &off, &n, &dummy);
  332. OPC_EndBlk0();
  333. }
  334. } else if ((typ->form == 11 && typ->BaseTyp->comp == 3)) {
  335. typ = typ->BaseTyp->BaseTyp;
  336. nofdims = 1;
  337. while (typ->comp == 3) {
  338. nofdims += 1;
  339. typ = typ->BaseTyp;
  340. }
  341. OPM_WriteString((CHAR*)"struct ", 8);
  342. OPC_BegBlk();
  343. OPC_BegStat();
  344. OPC_Str1((CHAR*)"ADDRESS len[#]", 15, nofdims);
  345. OPC_EndStat();
  346. OPC_BegStat();
  347. __NEW(obj, OPT_ObjDesc);
  348. __NEW(obj->typ, OPT_StrDesc);
  349. obj->typ->form = 13;
  350. obj->typ->comp = 2;
  351. obj->typ->n = 1;
  352. obj->typ->BaseTyp = typ;
  353. obj->mode = 4;
  354. __MOVE("data", obj->name, 5);
  355. obj->linkadr = 0;
  356. OPC_DeclareBase(obj);
  357. OPM_Write(' ');
  358. OPC_DeclareObj(obj, 0);
  359. OPC_EndStat();
  360. OPC_EndBlk0();
  361. }
  362. }
  363. INT32 OPC_NofPtrs (OPT_Struct typ)
  364. {
  365. OPT_Object fld = NIL;
  366. OPT_Struct btyp = NIL;
  367. INT32 n;
  368. if ((typ->form == 11 && typ->sysflag == 0)) {
  369. return 1;
  370. } else if ((typ->comp == 4 && __MASK(typ->sysflag, -256) == 0)) {
  371. btyp = typ->BaseTyp;
  372. if (btyp != NIL) {
  373. n = OPC_NofPtrs(btyp);
  374. } else {
  375. n = 0;
  376. }
  377. fld = typ->link;
  378. while ((fld != NIL && fld->mode == 4)) {
  379. if (__STRCMP(fld->name, "@ptr") != 0) {
  380. n = n + OPC_NofPtrs(fld->typ);
  381. } else {
  382. n += 1;
  383. }
  384. fld = fld->link;
  385. }
  386. return n;
  387. } else if (typ->comp == 2) {
  388. btyp = typ->BaseTyp;
  389. n = typ->n;
  390. while (btyp->comp == 2) {
  391. n = btyp->n * n;
  392. btyp = btyp->BaseTyp;
  393. }
  394. return OPC_NofPtrs(btyp) * n;
  395. } else {
  396. return 0;
  397. }
  398. __RETCHK;
  399. }
  400. static void OPC_PutPtrOffsets (OPT_Struct typ, INT32 adr, INT32 *cnt)
  401. {
  402. OPT_Object fld = NIL;
  403. OPT_Struct btyp = NIL;
  404. INT32 n, i;
  405. if ((typ->form == 11 && typ->sysflag == 0)) {
  406. OPM_WriteInt(adr);
  407. OPM_WriteString((CHAR*)", ", 3);
  408. *cnt += 1;
  409. if (__MASK(*cnt, -16) == 0) {
  410. OPM_WriteLn();
  411. OPM_Write(0x09);
  412. }
  413. } else if ((typ->comp == 4 && __MASK(typ->sysflag, -256) == 0)) {
  414. btyp = typ->BaseTyp;
  415. if (btyp != NIL) {
  416. OPC_PutPtrOffsets(btyp, adr, &*cnt);
  417. }
  418. fld = typ->link;
  419. while ((fld != NIL && fld->mode == 4)) {
  420. if (__STRCMP(fld->name, "@ptr") != 0) {
  421. OPC_PutPtrOffsets(fld->typ, adr + fld->adr, &*cnt);
  422. } else {
  423. OPM_WriteInt(adr + fld->adr);
  424. OPM_WriteString((CHAR*)", ", 3);
  425. *cnt += 1;
  426. if (__MASK(*cnt, -16) == 0) {
  427. OPM_WriteLn();
  428. OPM_Write(0x09);
  429. }
  430. }
  431. fld = fld->link;
  432. }
  433. } else if (typ->comp == 2) {
  434. btyp = typ->BaseTyp;
  435. n = typ->n;
  436. while (btyp->comp == 2) {
  437. n = btyp->n * n;
  438. btyp = btyp->BaseTyp;
  439. }
  440. if (OPC_NofPtrs(btyp) > 0) {
  441. i = 0;
  442. while (i < n) {
  443. OPC_PutPtrOffsets(btyp, adr + i * btyp->size, &*cnt);
  444. i += 1;
  445. }
  446. }
  447. }
  448. }
  449. static void OPC_InitTProcs (OPT_Object typ, OPT_Object obj)
  450. {
  451. if (obj != NIL) {
  452. OPC_InitTProcs(typ, obj->left);
  453. if (obj->mode == 13) {
  454. OPC_BegStat();
  455. OPM_WriteString((CHAR*)"__INITBP(", 10);
  456. OPC_Ident(typ);
  457. OPM_WriteString((CHAR*)", ", 3);
  458. OPC_Ident(obj);
  459. OPC_Str1((CHAR*)", #)", 5, __ASHR(obj->adr, 16));
  460. OPC_EndStat();
  461. }
  462. OPC_InitTProcs(typ, obj->right);
  463. }
  464. }
  465. static void OPC_PutBase (OPT_Struct typ)
  466. {
  467. if (typ != NIL) {
  468. OPC_PutBase(typ->BaseTyp);
  469. OPC_Ident(typ->strobj);
  470. OPM_WriteString((CHAR*)"__typ", 6);
  471. OPM_WriteString((CHAR*)", ", 3);
  472. }
  473. }
  474. static void OPC_LenList (OPT_Object par, BOOLEAN ansiDefine, BOOLEAN showParamName)
  475. {
  476. OPT_Struct typ = NIL;
  477. INT16 dim;
  478. if (showParamName) {
  479. OPC_Ident(par);
  480. OPM_WriteString((CHAR*)"__len", 6);
  481. }
  482. dim = 1;
  483. typ = par->typ->BaseTyp;
  484. while (typ->comp == 3) {
  485. if (ansiDefine) {
  486. OPM_WriteString((CHAR*)", ADDRESS ", 11);
  487. } else {
  488. OPM_WriteString((CHAR*)", ", 3);
  489. }
  490. if (showParamName) {
  491. OPC_Ident(par);
  492. OPM_WriteString((CHAR*)"__len", 6);
  493. OPM_WriteInt(dim);
  494. }
  495. typ = typ->BaseTyp;
  496. dim += 1;
  497. }
  498. }
  499. static void OPC_DeclareParams (OPT_Object par, BOOLEAN macro)
  500. {
  501. OPM_Write('(');
  502. while (par != NIL) {
  503. if (macro) {
  504. OPM_WriteStringVar((void*)par->name, 256);
  505. } else {
  506. if ((par->mode == 1 && par->typ->form == 5)) {
  507. OPM_Write('_');
  508. }
  509. OPC_Ident(par);
  510. }
  511. if (par->typ->comp == 3) {
  512. OPM_WriteString((CHAR*)", ", 3);
  513. OPC_LenList(par, 0, 1);
  514. } else if ((par->mode == 2 && par->typ->comp == 4)) {
  515. OPM_WriteString((CHAR*)", ", 3);
  516. OPM_WriteStringVar((void*)par->name, 256);
  517. OPM_WriteString((CHAR*)"__typ", 6);
  518. }
  519. par = par->link;
  520. if (par != NIL) {
  521. OPM_WriteString((CHAR*)", ", 3);
  522. }
  523. }
  524. OPM_Write(')');
  525. }
  526. static void OPC_DefineTProcTypes (OPT_Object obj)
  527. {
  528. OPT_Object par = NIL;
  529. if (obj->typ != OPT_notyp) {
  530. OPC_DefineType(obj->typ);
  531. }
  532. par = obj->link;
  533. while (par != NIL) {
  534. OPC_DefineType(par->typ);
  535. par = par->link;
  536. }
  537. }
  538. static void OPC_DeclareTProcs (OPT_Object obj, BOOLEAN *empty)
  539. {
  540. if (obj != NIL) {
  541. OPC_DeclareTProcs(obj->left, &*empty);
  542. if (obj->mode == 13) {
  543. if (obj->typ != OPT_notyp) {
  544. OPC_DefineType(obj->typ);
  545. }
  546. if (OPM_currFile == 0) {
  547. if (obj->vis == 1) {
  548. OPC_DefineTProcTypes(obj);
  549. OPM_WriteString((CHAR*)"import ", 8);
  550. *empty = 0;
  551. OPC_ProcHeader(obj, 0);
  552. }
  553. } else {
  554. *empty = 0;
  555. OPC_DefineTProcTypes(obj);
  556. if (obj->vis == 0) {
  557. OPM_WriteString((CHAR*)"static ", 8);
  558. } else {
  559. OPM_WriteString((CHAR*)"export ", 8);
  560. }
  561. OPC_ProcHeader(obj, 0);
  562. }
  563. }
  564. OPC_DeclareTProcs(obj->right, &*empty);
  565. }
  566. }
  567. OPT_Object OPC_BaseTProc (OPT_Object obj)
  568. {
  569. OPT_Struct typ = NIL, base = NIL;
  570. INT32 mno;
  571. typ = obj->link->typ;
  572. if (typ->form == 11) {
  573. typ = typ->BaseTyp;
  574. }
  575. base = typ->BaseTyp;
  576. mno = __ASHR(obj->adr, 16);
  577. while ((base != NIL && mno < base->n)) {
  578. typ = base;
  579. base = typ->BaseTyp;
  580. }
  581. OPT_FindField(obj->name, typ, &obj);
  582. return obj;
  583. }
  584. static void OPC_DefineTProcMacros (OPT_Object obj, BOOLEAN *empty)
  585. {
  586. if (obj != NIL) {
  587. OPC_DefineTProcMacros(obj->left, &*empty);
  588. if ((((obj->mode == 13 && obj == OPC_BaseTProc(obj))) && (OPM_currFile != 0 || obj->vis == 1))) {
  589. OPM_WriteString((CHAR*)"#define __", 11);
  590. OPC_Ident(obj);
  591. OPC_DeclareParams(obj->link, 1);
  592. OPM_WriteString((CHAR*)" __SEND(", 9);
  593. if (obj->link->typ->form == 11) {
  594. OPM_WriteString((CHAR*)"__TYPEOF(", 10);
  595. OPC_Ident(obj->link);
  596. OPM_Write(')');
  597. } else {
  598. OPC_Ident(obj->link);
  599. OPM_WriteString((CHAR*)"__typ", 6);
  600. }
  601. OPC_Str1((CHAR*)", #, ", 6, __ASHR(obj->adr, 16));
  602. if (obj->typ == OPT_notyp) {
  603. OPM_WriteString((CHAR*)"void", 5);
  604. } else {
  605. OPC_Ident(obj->typ->strobj);
  606. }
  607. OPM_WriteString((CHAR*)"(*)", 4);
  608. OPC_AnsiParamList(obj->link, 0);
  609. OPM_WriteString((CHAR*)", ", 3);
  610. OPC_DeclareParams(obj->link, 1);
  611. OPM_Write(')');
  612. OPM_WriteLn();
  613. }
  614. OPC_DefineTProcMacros(obj->right, &*empty);
  615. }
  616. }
  617. static void OPC_DefineType (OPT_Struct str)
  618. {
  619. OPT_Object obj = NIL, field = NIL, par = NIL;
  620. BOOLEAN empty;
  621. if (OPM_currFile == 1 || str->ref < 255) {
  622. obj = str->strobj;
  623. if (obj == NIL || OPC_Undefined(obj)) {
  624. if (obj != NIL) {
  625. if (obj->linkadr == 1) {
  626. if (str->form != 11) {
  627. OPM_Mark(244, str->txtpos);
  628. obj->linkadr = 2;
  629. }
  630. } else {
  631. obj->linkadr = 1;
  632. }
  633. }
  634. if (str->comp == 4) {
  635. if (str->BaseTyp != NIL) {
  636. OPC_DefineType(str->BaseTyp);
  637. }
  638. field = str->link;
  639. while ((field != NIL && field->mode == 4)) {
  640. if (field->vis != 0 || OPM_currFile == 1) {
  641. OPC_DefineType(field->typ);
  642. }
  643. field = field->link;
  644. }
  645. } else if (str->form == 11) {
  646. if (str->BaseTyp->comp != 4) {
  647. OPC_DefineType(str->BaseTyp);
  648. }
  649. } else if (__IN(str->comp, 0x0c, 32)) {
  650. if ((str->BaseTyp->strobj != NIL && str->BaseTyp->strobj->linkadr == 1)) {
  651. OPM_Mark(244, str->txtpos);
  652. str->BaseTyp->strobj->linkadr = 2;
  653. }
  654. OPC_DefineType(str->BaseTyp);
  655. } else if (str->form == 12) {
  656. if (str->BaseTyp != OPT_notyp) {
  657. OPC_DefineType(str->BaseTyp);
  658. }
  659. field = str->link;
  660. while (field != NIL) {
  661. OPC_DefineType(field->typ);
  662. field = field->link;
  663. }
  664. }
  665. }
  666. if ((obj != NIL && OPC_Undefined(obj))) {
  667. OPM_WriteString((CHAR*)"typedef", 8);
  668. OPM_WriteLn();
  669. OPM_Write(0x09);
  670. OPC_Indent(1);
  671. obj->linkadr = 1;
  672. OPC_DeclareBase(obj);
  673. OPM_Write(' ');
  674. obj->typ->strobj = NIL;
  675. OPC_DeclareObj(obj, 0);
  676. obj->typ->strobj = obj;
  677. obj->linkadr = 3 + OPM_currFile;
  678. OPC_EndStat();
  679. OPC_Indent(-1);
  680. OPM_WriteLn();
  681. if (obj->typ->comp == 4) {
  682. empty = 1;
  683. OPC_DeclareTProcs(str->link, &empty);
  684. OPC_DefineTProcMacros(str->link, &empty);
  685. if (!empty) {
  686. OPM_WriteLn();
  687. }
  688. }
  689. }
  690. }
  691. }
  692. static BOOLEAN OPC_Prefixed (OPT_ConstExt x, CHAR *y, ADDRESS y__len)
  693. {
  694. INT16 i;
  695. __DUP(y, y__len, CHAR);
  696. i = 0;
  697. while ((*x)[__X(i + 1, 256)] == y[__X(i, y__len)]) {
  698. i += 1;
  699. }
  700. __DEL(y);
  701. return y[__X(i, y__len)] == 0x00;
  702. }
  703. static void OPC_CProcDefs (OPT_Object obj, INT16 vis)
  704. {
  705. INT16 i;
  706. OPT_ConstExt ext = NIL;
  707. INT16 _for__7;
  708. if (obj != NIL) {
  709. OPC_CProcDefs(obj->left, vis);
  710. if ((((obj->mode == 9 && (INT16)obj->vis >= vis)) && obj->adr == 1)) {
  711. ext = obj->conval->ext;
  712. i = 1;
  713. if (((*ext)[1] != '#' && !(OPC_Prefixed(ext, (CHAR*)"extern ", 8) || OPC_Prefixed(ext, (CHAR*)"import ", 8)))) {
  714. OPM_WriteString((CHAR*)"#define ", 9);
  715. OPC_Ident(obj);
  716. OPC_DeclareParams(obj->link, 1);
  717. OPM_Write(0x09);
  718. }
  719. _for__7 = (INT16)(*obj->conval->ext)[0];
  720. i = i;
  721. while (i <= _for__7) {
  722. OPM_Write((*obj->conval->ext)[__X(i, 256)]);
  723. i += 1;
  724. }
  725. OPM_WriteLn();
  726. }
  727. OPC_CProcDefs(obj->right, vis);
  728. }
  729. }
  730. void OPC_TypeDefs (OPT_Object obj, INT16 vis)
  731. {
  732. if (obj != NIL) {
  733. OPC_TypeDefs(obj->left, vis);
  734. if ((obj->mode == 5 && obj->typ->txtpos > 0)) {
  735. OPC_DefineType(obj->typ);
  736. }
  737. OPC_TypeDefs(obj->right, vis);
  738. }
  739. }
  740. static void OPC_DefAnonRecs (OPT_Node n)
  741. {
  742. OPT_Object o = NIL;
  743. OPT_Struct typ = NIL;
  744. while ((n != NIL && n->class == 14)) {
  745. typ = n->typ;
  746. if ((typ->strobj == NIL && (OPM_currFile == 1 || typ->ref < 255))) {
  747. OPC_DefineType(typ);
  748. __NEW(o, OPT_ObjDesc);
  749. o->typ = typ;
  750. o->name[0] = 0x00;
  751. OPC_DeclareBase(o);
  752. OPC_EndStat();
  753. OPM_WriteLn();
  754. }
  755. n = n->link;
  756. }
  757. }
  758. void OPC_TDescDecl (OPT_Struct typ)
  759. {
  760. INT32 nofptrs;
  761. OPT_Object o = NIL;
  762. OPC_BegStat();
  763. OPM_WriteString((CHAR*)"__TDESC(", 9);
  764. OPC_Andent(typ);
  765. OPC_Str1((CHAR*)", #", 4, typ->n + 1);
  766. OPC_Str1((CHAR*)", #) = {__TDFLDS(", 18, OPC_NofPtrs(typ));
  767. OPM_Write('"');
  768. if (typ->strobj != NIL) {
  769. OPM_WriteStringVar((void*)typ->strobj->name, 256);
  770. }
  771. OPM_Write('"');
  772. OPC_Str1((CHAR*)", #), {", 8, typ->size);
  773. nofptrs = 0;
  774. OPC_PutPtrOffsets(typ, 0, &nofptrs);
  775. OPC_Str1((CHAR*)"#}}", 4, -((nofptrs + 1) * OPM_AddressSize));
  776. OPC_EndStat();
  777. }
  778. void OPC_InitTDesc (OPT_Struct typ)
  779. {
  780. OPC_BegStat();
  781. OPM_WriteString((CHAR*)"__INITYP(", 10);
  782. OPC_Andent(typ);
  783. OPM_WriteString((CHAR*)", ", 3);
  784. if (typ->BaseTyp != NIL) {
  785. OPC_Andent(typ->BaseTyp);
  786. } else {
  787. OPC_Andent(typ);
  788. }
  789. OPC_Str1((CHAR*)", #)", 5, typ->extlev);
  790. OPC_EndStat();
  791. if (typ->strobj != NIL) {
  792. OPC_InitTProcs(typ->strobj, typ->link);
  793. }
  794. }
  795. static void OPC_FillGap (INT32 gap, INT32 off, INT32 align, INT32 *n, INT32 *curAlign)
  796. {
  797. INT32 adr;
  798. adr = off;
  799. OPT_Align(&adr, align);
  800. if ((*curAlign < align && gap - (adr - off) >= align)) {
  801. gap -= (adr - off) + align;
  802. OPC_BegStat();
  803. switch (align) {
  804. case 2:
  805. OPM_WriteString((CHAR*)"INT16", 6);
  806. break;
  807. case 4:
  808. OPM_WriteString((CHAR*)"INT32", 6);
  809. break;
  810. case 8:
  811. OPM_WriteString((CHAR*)"INT64", 6);
  812. break;
  813. default:
  814. OPM_LogWLn();
  815. OPM_LogWStr((CHAR*)"Unexpected enclosing alignment in FillGap.", 43);
  816. break;
  817. }
  818. OPC_Str1((CHAR*)" _prvt#", 8, *n);
  819. *n += 1;
  820. OPC_EndStat();
  821. *curAlign = align;
  822. }
  823. if (gap > 0) {
  824. OPC_BegStat();
  825. OPC_Str1((CHAR*)"char _prvt#", 12, *n);
  826. *n += 1;
  827. OPC_Str1((CHAR*)"[#]", 4, gap);
  828. OPC_EndStat();
  829. }
  830. }
  831. static void OPC_FieldList (OPT_Struct typ, BOOLEAN last, INT32 *off, INT32 *n, INT32 *curAlign)
  832. {
  833. OPT_Object fld = NIL;
  834. OPT_Struct base = NIL;
  835. INT32 gap, adr, align, fldAlign;
  836. fld = typ->link;
  837. align = __MASK(typ->align, -65536);
  838. if (typ->BaseTyp != NIL) {
  839. OPC_FieldList(typ->BaseTyp, 0, &*off, &*n, &*curAlign);
  840. } else {
  841. *off = 0;
  842. *n = 0;
  843. *curAlign = 1;
  844. }
  845. while ((fld != NIL && fld->mode == 4)) {
  846. if ((OPM_currFile == 0 && fld->vis == 0) || (((OPM_currFile == 1 && fld->vis == 0)) && typ->mno != 0)) {
  847. fld = fld->link;
  848. while ((((fld != NIL && fld->mode == 4)) && fld->vis == 0)) {
  849. fld = fld->link;
  850. }
  851. } else {
  852. adr = *off;
  853. fldAlign = OPT_BaseAlignment(fld->typ);
  854. OPT_Align(&adr, fldAlign);
  855. gap = fld->adr - adr;
  856. if (fldAlign > *curAlign) {
  857. *curAlign = fldAlign;
  858. }
  859. if (gap > 0) {
  860. OPC_FillGap(gap, *off, align, &*n, &*curAlign);
  861. }
  862. OPC_BegStat();
  863. OPC_DeclareBase(fld);
  864. OPM_Write(' ');
  865. OPC_DeclareObj(fld, 0);
  866. *off = fld->adr + fld->typ->size;
  867. base = fld->typ;
  868. fld = fld->link;
  869. while ((((((((fld != NIL && fld->mode == 4)) && fld->typ == base)) && fld->adr == *off)) && ((OPM_currFile == 1 || fld->vis != 0) || fld->typ->strobj == NIL))) {
  870. OPM_WriteString((CHAR*)", ", 3);
  871. OPC_DeclareObj(fld, 0);
  872. *off = fld->adr + fld->typ->size;
  873. fld = fld->link;
  874. }
  875. OPC_EndStat();
  876. }
  877. }
  878. if (last) {
  879. adr = typ->size - __ASHR(typ->sysflag, 8);
  880. if (adr == 0) {
  881. gap = 1;
  882. } else {
  883. gap = adr - *off;
  884. }
  885. if (gap > 0) {
  886. OPC_FillGap(gap, *off, align, &*n, &*curAlign);
  887. }
  888. }
  889. }
  890. static void OPC_IdentList (OPT_Object obj, INT16 vis)
  891. {
  892. OPT_Struct base = NIL;
  893. BOOLEAN first;
  894. INT16 lastvis;
  895. base = NIL;
  896. first = 1;
  897. while ((obj != NIL && obj->mode != 13)) {
  898. if ((__IN(vis, 0x05, 32) || (vis == 1 && obj->vis != 0)) || (vis == 3 && !obj->leaf)) {
  899. if (obj->typ != base || (INT16)obj->vis != lastvis) {
  900. if (!first) {
  901. OPC_EndStat();
  902. }
  903. first = 0;
  904. base = obj->typ;
  905. lastvis = obj->vis;
  906. OPC_BegStat();
  907. if ((vis == 1 && obj->vis != 0)) {
  908. OPM_WriteString((CHAR*)"import ", 8);
  909. } else if ((obj->mnolev == 0 && vis == 0)) {
  910. if (obj->vis == 0) {
  911. OPM_WriteString((CHAR*)"static ", 8);
  912. } else {
  913. OPM_WriteString((CHAR*)"export ", 8);
  914. }
  915. }
  916. if ((((vis == 2 && obj->mode == 1)) && base->form == 5)) {
  917. OPM_WriteString((CHAR*)"double", 7);
  918. } else {
  919. OPC_DeclareBase(obj);
  920. }
  921. } else {
  922. OPM_Write(',');
  923. }
  924. OPM_Write(' ');
  925. if ((((vis == 2 && obj->mode == 1)) && base->form == 5)) {
  926. OPM_Write('_');
  927. }
  928. OPC_DeclareObj(obj, vis == 3);
  929. if (obj->typ->comp == 3) {
  930. OPC_EndStat();
  931. OPC_BegStat();
  932. base = OPT_adrtyp;
  933. OPM_WriteString((CHAR*)"ADDRESS ", 9);
  934. OPC_LenList(obj, 0, 1);
  935. } else if ((obj->mode == 2 && obj->typ->comp == 4)) {
  936. OPC_EndStat();
  937. OPC_BegStat();
  938. OPM_WriteString((CHAR*)"ADDRESS *", 10);
  939. OPC_Ident(obj);
  940. OPM_WriteString((CHAR*)"__typ", 6);
  941. base = NIL;
  942. } else if ((((((__IN(5, OPM_Options, 32) && vis == 0)) && obj->mnolev > 0)) && obj->typ->form == 11)) {
  943. OPM_WriteString((CHAR*)" = NIL", 7);
  944. }
  945. }
  946. obj = obj->link;
  947. }
  948. if (!first) {
  949. OPC_EndStat();
  950. }
  951. }
  952. static void OPC_AnsiParamList (OPT_Object obj, BOOLEAN showParamNames)
  953. {
  954. CHAR name[32];
  955. OPM_Write('(');
  956. if (obj == NIL || obj->mode == 13) {
  957. OPM_WriteString((CHAR*)"void", 5);
  958. } else {
  959. for (;;) {
  960. OPC_DeclareBase(obj);
  961. if (showParamNames) {
  962. OPM_Write(' ');
  963. OPC_DeclareObj(obj, 0);
  964. } else {
  965. __COPY(obj->name, name, 32);
  966. obj->name[0] = 0x00;
  967. OPC_DeclareObj(obj, 0);
  968. __COPY(name, obj->name, 256);
  969. }
  970. if (obj->typ->comp == 3) {
  971. OPM_WriteString((CHAR*)", ADDRESS ", 11);
  972. OPC_LenList(obj, 1, showParamNames);
  973. } else if ((obj->mode == 2 && obj->typ->comp == 4)) {
  974. OPM_WriteString((CHAR*)", ADDRESS *", 12);
  975. if (showParamNames) {
  976. OPC_Ident(obj);
  977. OPM_WriteString((CHAR*)"__typ", 6);
  978. }
  979. }
  980. if (obj->link == NIL || obj->link->mode == 13) {
  981. break;
  982. }
  983. OPM_WriteString((CHAR*)", ", 3);
  984. obj = obj->link;
  985. }
  986. }
  987. OPM_Write(')');
  988. }
  989. static void OPC_ProcHeader (OPT_Object proc, BOOLEAN define)
  990. {
  991. if (proc->typ == OPT_notyp) {
  992. OPM_WriteString((CHAR*)"void", 5);
  993. } else {
  994. OPC_Ident(proc->typ->strobj);
  995. }
  996. OPM_Write(' ');
  997. OPC_Ident(proc);
  998. OPM_Write(' ');
  999. OPC_AnsiParamList(proc->link, 1);
  1000. if (!define) {
  1001. OPM_Write(';');
  1002. }
  1003. OPM_WriteLn();
  1004. }
  1005. static void OPC_ProcPredefs (OPT_Object obj, INT8 vis)
  1006. {
  1007. if (obj != NIL) {
  1008. OPC_ProcPredefs(obj->left, vis);
  1009. if ((((__IN(obj->mode, 0xc0, 32) && obj->vis >= vis)) && (obj->history != 4 || obj->mode == 6))) {
  1010. if (vis == 1) {
  1011. OPM_WriteString((CHAR*)"import ", 8);
  1012. } else if (obj->vis == 0) {
  1013. OPM_WriteString((CHAR*)"static ", 8);
  1014. } else {
  1015. OPM_WriteString((CHAR*)"export ", 8);
  1016. }
  1017. OPC_ProcHeader(obj, 0);
  1018. }
  1019. OPC_ProcPredefs(obj->right, vis);
  1020. }
  1021. }
  1022. static void OPC_Include (CHAR *name, ADDRESS name__len)
  1023. {
  1024. __DUP(name, name__len, CHAR);
  1025. OPM_WriteString((CHAR*)"#include ", 10);
  1026. OPM_Write('"');
  1027. OPM_WriteStringVar((void*)name, name__len);
  1028. OPM_WriteString((CHAR*)".h", 3);
  1029. OPM_Write('"');
  1030. OPM_WriteLn();
  1031. __DEL(name);
  1032. }
  1033. static void OPC_IncludeImports (OPT_Object obj, INT16 vis)
  1034. {
  1035. if (obj != NIL) {
  1036. OPC_IncludeImports(obj->left, vis);
  1037. if ((((obj->mode == 11 && obj->mnolev != 0)) && (INT16)OPT_GlbMod[__X(-obj->mnolev, 64)]->vis >= vis)) {
  1038. OPC_Include(OPT_GlbMod[__X(-obj->mnolev, 64)]->name, 256);
  1039. }
  1040. OPC_IncludeImports(obj->right, vis);
  1041. }
  1042. }
  1043. static void OPC_GenDynTypes (OPT_Node n, INT16 vis)
  1044. {
  1045. OPT_Struct typ = NIL;
  1046. while ((n != NIL && n->class == 14)) {
  1047. typ = n->typ;
  1048. if (vis == 0 || typ->ref < 255) {
  1049. OPC_BegStat();
  1050. if (vis == 1) {
  1051. OPM_WriteString((CHAR*)"import ", 8);
  1052. } else if ((typ->strobj != NIL && typ->strobj->mnolev > 0)) {
  1053. OPM_WriteString((CHAR*)"static ", 8);
  1054. } else {
  1055. OPM_WriteString((CHAR*)"export ", 8);
  1056. }
  1057. OPM_WriteString((CHAR*)"ADDRESS *", 10);
  1058. OPC_Andent(typ);
  1059. OPM_WriteString((CHAR*)"__typ", 6);
  1060. OPC_EndStat();
  1061. }
  1062. n = n->link;
  1063. }
  1064. }
  1065. void OPC_GenHdr (OPT_Node n)
  1066. {
  1067. OPM_currFile = 0;
  1068. OPC_DefAnonRecs(n);
  1069. OPC_TypeDefs(OPT_topScope->right, 1);
  1070. OPM_WriteLn();
  1071. OPC_IdentList(OPT_topScope->scope, 1);
  1072. OPM_WriteLn();
  1073. OPC_GenDynTypes(n, 1);
  1074. OPM_WriteLn();
  1075. OPC_ProcPredefs(OPT_topScope->right, 1);
  1076. OPM_WriteString((CHAR*)"import ", 8);
  1077. OPM_WriteString((CHAR*)"void *", 7);
  1078. OPM_WriteStringVar((void*)OPM_modName, 32);
  1079. OPM_WriteString(OPC_BodyNameExt, 13);
  1080. OPC_EndStat();
  1081. OPM_WriteLn();
  1082. OPC_CProcDefs(OPT_topScope->right, 1);
  1083. OPM_WriteLn();
  1084. OPM_WriteString((CHAR*)"#endif // ", 11);
  1085. OPM_WriteStringVar((void*)OPM_modName, 32);
  1086. OPM_WriteLn();
  1087. }
  1088. static void OPC_GenHeaderMsg (void)
  1089. {
  1090. INT16 i;
  1091. OPM_WriteString((CHAR*)"/* ", 4);
  1092. OPM_WriteString((CHAR*)"voc", 4);
  1093. OPM_Write(' ');
  1094. OPM_WriteString(Configuration_versionLong, 76);
  1095. OPM_Write(' ');
  1096. i = 0;
  1097. while (i <= 31) {
  1098. if (__IN(i, OPM_Options, 32)) {
  1099. switch (i) {
  1100. case 0:
  1101. OPM_Write('x');
  1102. break;
  1103. case 2:
  1104. OPM_Write('r');
  1105. break;
  1106. case 3:
  1107. OPM_Write('t');
  1108. break;
  1109. case 4:
  1110. OPM_Write('s');
  1111. break;
  1112. case 5:
  1113. OPM_Write('p');
  1114. break;
  1115. case 7:
  1116. OPM_Write('a');
  1117. break;
  1118. case 9:
  1119. OPM_Write('e');
  1120. break;
  1121. case 10:
  1122. OPM_Write('m');
  1123. break;
  1124. case 13:
  1125. OPM_Write('S');
  1126. break;
  1127. case 14:
  1128. OPM_Write('c');
  1129. break;
  1130. case 15:
  1131. OPM_Write('M');
  1132. break;
  1133. case 16:
  1134. OPM_Write('f');
  1135. break;
  1136. case 17:
  1137. OPM_Write('F');
  1138. break;
  1139. case 18:
  1140. OPM_Write('v');
  1141. break;
  1142. default:
  1143. OPM_LogWStr((CHAR*)"( more options defined in OPM than checked in OPC.GenHeaderMsg, if you are a compiler developer, add them to OPC.GenHeaderMsg", 126);
  1144. OPM_LogWLn();
  1145. break;
  1146. }
  1147. }
  1148. i += 1;
  1149. }
  1150. OPM_WriteString((CHAR*)" */", 4);
  1151. OPM_WriteLn();
  1152. }
  1153. void OPC_GenHdrIncludes (void)
  1154. {
  1155. OPM_currFile = 2;
  1156. OPC_GenHeaderMsg();
  1157. OPM_WriteLn();
  1158. OPM_WriteString((CHAR*)"#ifndef ", 9);
  1159. OPM_WriteStringVar((void*)OPM_modName, 32);
  1160. OPM_WriteString((CHAR*)"__h", 4);
  1161. OPM_WriteLn();
  1162. OPM_WriteString((CHAR*)"#define ", 9);
  1163. OPM_WriteStringVar((void*)OPM_modName, 32);
  1164. OPM_WriteString((CHAR*)"__h", 4);
  1165. OPM_WriteLn();
  1166. OPM_WriteLn();
  1167. OPC_Include((CHAR*)"SYSTEM", 7);
  1168. OPC_IncludeImports(OPT_topScope->right, 1);
  1169. OPM_WriteLn();
  1170. }
  1171. void OPC_GenBdy (OPT_Node n)
  1172. {
  1173. OPM_currFile = 1;
  1174. OPC_GenHeaderMsg();
  1175. OPM_WriteLn();
  1176. OPM_WriteString((CHAR*)"#define SHORTINT INT", 21);
  1177. OPM_WriteInt(__ASHL(OPT_sinttyp->size, 3));
  1178. OPM_WriteLn();
  1179. OPM_WriteString((CHAR*)"#define INTEGER INT", 21);
  1180. OPM_WriteInt(__ASHL(OPT_inttyp->size, 3));
  1181. OPM_WriteLn();
  1182. OPM_WriteString((CHAR*)"#define LONGINT INT", 21);
  1183. OPM_WriteInt(__ASHL(OPT_linttyp->size, 3));
  1184. OPM_WriteLn();
  1185. OPM_WriteString((CHAR*)"#define SET UINT", 22);
  1186. OPM_WriteInt(__ASHL(OPT_settyp->size, 3));
  1187. OPM_WriteLn();
  1188. OPM_WriteLn();
  1189. OPC_Include((CHAR*)"SYSTEM", 7);
  1190. OPC_IncludeImports(OPT_topScope->right, 0);
  1191. OPM_WriteLn();
  1192. OPC_DefAnonRecs(n);
  1193. OPC_TypeDefs(OPT_topScope->right, 0);
  1194. OPM_WriteLn();
  1195. OPC_IdentList(OPT_topScope->scope, 0);
  1196. OPM_WriteLn();
  1197. OPC_GenDynTypes(n, 0);
  1198. OPM_WriteLn();
  1199. OPC_ProcPredefs(OPT_topScope->right, 0);
  1200. OPM_WriteLn();
  1201. OPC_CProcDefs(OPT_topScope->right, 0);
  1202. OPM_WriteLn();
  1203. }
  1204. static void OPC_RegCmds (OPT_Object obj)
  1205. {
  1206. if (obj != NIL) {
  1207. OPC_RegCmds(obj->left);
  1208. if ((obj->mode == 7 && obj->history != 4)) {
  1209. if ((((obj->vis != 0 && obj->link == NIL)) && obj->typ == OPT_notyp)) {
  1210. OPC_BegStat();
  1211. OPM_WriteString((CHAR*)"__REGCMD(\"", 11);
  1212. OPM_WriteStringVar((void*)obj->name, 256);
  1213. OPM_WriteString((CHAR*)"\", ", 4);
  1214. OPC_Ident(obj);
  1215. OPM_Write(')');
  1216. OPC_EndStat();
  1217. }
  1218. }
  1219. OPC_RegCmds(obj->right);
  1220. }
  1221. }
  1222. static void OPC_InitImports (OPT_Object obj)
  1223. {
  1224. if (obj != NIL) {
  1225. OPC_InitImports(obj->left);
  1226. if ((obj->mode == 11 && obj->mnolev != 0)) {
  1227. OPC_BegStat();
  1228. OPM_WriteString((CHAR*)"__MODULE_IMPORT(", 17);
  1229. OPM_WriteStringVar((void*)OPT_GlbMod[__X(-obj->mnolev, 64)]->name, 256);
  1230. OPM_Write(')');
  1231. OPC_EndStat();
  1232. }
  1233. OPC_InitImports(obj->right);
  1234. }
  1235. }
  1236. void OPC_GenEnumPtrs (OPT_Object var)
  1237. {
  1238. OPT_Struct typ = NIL;
  1239. INT32 n;
  1240. OPC_GlbPtrs = 0;
  1241. while (var != NIL) {
  1242. typ = var->typ;
  1243. if (OPC_NofPtrs(typ) > 0) {
  1244. if (!OPC_GlbPtrs) {
  1245. OPC_GlbPtrs = 1;
  1246. OPM_WriteString((CHAR*)"static void EnumPtrs(void (*P)(void*))", 39);
  1247. OPM_WriteLn();
  1248. OPC_BegBlk();
  1249. }
  1250. OPC_BegStat();
  1251. if (typ->form == 11) {
  1252. OPM_WriteString((CHAR*)"P(", 3);
  1253. OPC_Ident(var);
  1254. OPM_Write(')');
  1255. } else if (typ->comp == 4) {
  1256. OPM_WriteString((CHAR*)"__ENUMR(&", 10);
  1257. OPC_Ident(var);
  1258. OPM_WriteString((CHAR*)", ", 3);
  1259. OPC_Andent(typ);
  1260. OPM_WriteString((CHAR*)"__typ", 6);
  1261. OPC_Str1((CHAR*)", #", 4, typ->size);
  1262. OPM_WriteString((CHAR*)", 1, P)", 8);
  1263. } else if (typ->comp == 2) {
  1264. n = typ->n;
  1265. typ = typ->BaseTyp;
  1266. while (typ->comp == 2) {
  1267. n = n * typ->n;
  1268. typ = typ->BaseTyp;
  1269. }
  1270. if (typ->form == 11) {
  1271. OPM_WriteString((CHAR*)"__ENUMP(", 9);
  1272. OPC_Ident(var);
  1273. OPC_Str1((CHAR*)", #, P)", 8, n);
  1274. } else if (typ->comp == 4) {
  1275. OPM_WriteString((CHAR*)"__ENUMR(", 9);
  1276. OPC_Ident(var);
  1277. OPM_WriteString((CHAR*)", ", 3);
  1278. OPC_Andent(typ);
  1279. OPM_WriteString((CHAR*)"__typ", 6);
  1280. OPC_Str1((CHAR*)", #", 4, typ->size);
  1281. OPC_Str1((CHAR*)", #, P)", 8, n);
  1282. }
  1283. }
  1284. OPC_EndStat();
  1285. }
  1286. var = var->link;
  1287. }
  1288. if (OPC_GlbPtrs) {
  1289. OPC_EndBlk();
  1290. OPM_WriteLn();
  1291. }
  1292. }
  1293. void OPC_EnterBody (void)
  1294. {
  1295. OPM_WriteLn();
  1296. OPM_WriteString((CHAR*)"export ", 8);
  1297. if (__IN(10, OPM_Options, 32)) {
  1298. OPM_WriteString((CHAR*)"int main(int argc, char **argv)", 32);
  1299. OPM_WriteLn();
  1300. } else {
  1301. OPM_WriteString((CHAR*)"void *", 7);
  1302. OPM_WriteString(OPM_modName, 32);
  1303. OPM_WriteString(OPC_BodyNameExt, 13);
  1304. OPM_WriteLn();
  1305. }
  1306. OPC_BegBlk();
  1307. OPC_BegStat();
  1308. if (__IN(10, OPM_Options, 32)) {
  1309. OPM_WriteString((CHAR*)"__INIT(argc, argv)", 19);
  1310. } else {
  1311. OPM_WriteString((CHAR*)"__DEFMOD", 9);
  1312. }
  1313. OPC_EndStat();
  1314. if ((__IN(10, OPM_Options, 32) && 0)) {
  1315. OPC_BegStat();
  1316. OPM_WriteString((CHAR*)"/*don`t do it!*/ printf(\"DEMO VERSION: DO NOT USE THIS PROGRAM FOR ANY COMMERCIAL PURPOSE\\n\")", 94);
  1317. OPC_EndStat();
  1318. }
  1319. OPC_InitImports(OPT_topScope->right);
  1320. OPC_BegStat();
  1321. if (__IN(10, OPM_Options, 32)) {
  1322. OPM_WriteString((CHAR*)"__REGMAIN(\"", 12);
  1323. } else {
  1324. OPM_WriteString((CHAR*)"__REGMOD(\"", 11);
  1325. }
  1326. OPM_WriteString(OPM_modName, 32);
  1327. if (OPC_GlbPtrs) {
  1328. OPM_WriteString((CHAR*)"\", EnumPtrs)", 13);
  1329. } else {
  1330. OPM_WriteString((CHAR*)"\", 0)", 6);
  1331. }
  1332. OPC_EndStat();
  1333. if (__STRCMP(OPM_modName, "SYSTEM") != 0) {
  1334. OPC_RegCmds(OPT_topScope);
  1335. }
  1336. }
  1337. void OPC_ExitBody (void)
  1338. {
  1339. OPC_BegStat();
  1340. if (__IN(10, OPM_Options, 32)) {
  1341. OPM_WriteString((CHAR*)"__FINI;", 8);
  1342. } else {
  1343. OPM_WriteString((CHAR*)"__ENDMOD;", 10);
  1344. }
  1345. OPM_WriteLn();
  1346. OPC_EndBlk();
  1347. }
  1348. void OPC_DefineInter (OPT_Object proc)
  1349. {
  1350. OPT_Object scope = NIL;
  1351. scope = proc->scope;
  1352. OPM_WriteString((CHAR*)"static ", 8);
  1353. OPM_WriteString((CHAR*)"struct ", 8);
  1354. OPM_WriteStringVar((void*)scope->name, 256);
  1355. OPM_Write(' ');
  1356. OPC_BegBlk();
  1357. OPC_IdentList(proc->link, 3);
  1358. OPC_IdentList(scope->scope, 3);
  1359. OPC_BegStat();
  1360. OPM_WriteString((CHAR*)"struct ", 8);
  1361. OPM_WriteStringVar((void*)scope->name, 256);
  1362. OPM_Write(' ');
  1363. OPM_Write('*');
  1364. OPM_WriteString((CHAR*)"lnk", 4);
  1365. OPC_EndStat();
  1366. OPC_EndBlk0();
  1367. OPM_Write(' ');
  1368. OPM_Write('*');
  1369. OPM_WriteStringVar((void*)scope->name, 256);
  1370. OPM_WriteString((CHAR*)"_s", 3);
  1371. OPC_EndStat();
  1372. OPM_WriteLn();
  1373. OPC_ProcPredefs(scope->right, 0);
  1374. OPM_WriteLn();
  1375. }
  1376. BOOLEAN OPC_NeedsRetval (OPT_Object proc)
  1377. {
  1378. return (proc->typ != OPT_notyp && !proc->scope->leaf);
  1379. }
  1380. void OPC_EnterProc (OPT_Object proc)
  1381. {
  1382. OPT_Object var = NIL, scope = NIL;
  1383. OPT_Struct typ = NIL;
  1384. INT16 dim;
  1385. if (proc->vis != 1) {
  1386. OPM_WriteString((CHAR*)"static ", 8);
  1387. }
  1388. OPC_ProcHeader(proc, 1);
  1389. OPC_BegBlk();
  1390. scope = proc->scope;
  1391. OPC_IdentList(scope->scope, 0);
  1392. if (!scope->leaf) {
  1393. OPC_BegStat();
  1394. OPM_WriteString((CHAR*)"struct ", 8);
  1395. OPM_WriteStringVar((void*)scope->name, 256);
  1396. OPM_Write(' ');
  1397. OPM_WriteString((CHAR*)"_s", 3);
  1398. OPC_EndStat();
  1399. }
  1400. if (OPC_NeedsRetval(proc)) {
  1401. OPC_BegStat();
  1402. OPC_Ident(proc->typ->strobj);
  1403. OPM_WriteString((CHAR*)" __retval", 10);
  1404. OPC_EndStat();
  1405. }
  1406. var = proc->link;
  1407. while (var != NIL) {
  1408. if ((var->typ->comp == 2 && var->mode == 1)) {
  1409. OPC_BegStat();
  1410. if (var->typ->strobj == NIL) {
  1411. OPM_Mark(200, var->typ->txtpos);
  1412. } else {
  1413. OPC_Ident(var->typ->strobj);
  1414. }
  1415. OPM_Write(' ');
  1416. OPC_Ident(var);
  1417. OPM_WriteString((CHAR*)"__copy", 7);
  1418. OPC_EndStat();
  1419. }
  1420. var = var->link;
  1421. }
  1422. var = proc->link;
  1423. while (var != NIL) {
  1424. if ((((__IN(var->typ->comp, 0x0c, 32) && var->mode == 1)) && var->typ->sysflag == 0)) {
  1425. OPC_BegStat();
  1426. if (var->typ->comp == 2) {
  1427. OPM_WriteString((CHAR*)"__DUPARR(", 10);
  1428. OPC_Ident(var);
  1429. OPM_WriteString((CHAR*)", ", 3);
  1430. if (var->typ->strobj == NIL) {
  1431. OPM_Mark(200, var->typ->txtpos);
  1432. } else {
  1433. OPC_Ident(var->typ->strobj);
  1434. }
  1435. } else {
  1436. OPM_WriteString((CHAR*)"__DUP(", 7);
  1437. OPC_Ident(var);
  1438. OPM_WriteString((CHAR*)", ", 3);
  1439. OPC_Ident(var);
  1440. OPM_WriteString((CHAR*)"__len", 6);
  1441. typ = var->typ->BaseTyp;
  1442. dim = 1;
  1443. while (typ->comp == 3) {
  1444. OPM_WriteString((CHAR*)" * ", 4);
  1445. OPC_Ident(var);
  1446. OPM_WriteString((CHAR*)"__len", 6);
  1447. OPM_WriteInt(dim);
  1448. typ = typ->BaseTyp;
  1449. dim += 1;
  1450. }
  1451. OPM_WriteString((CHAR*)", ", 3);
  1452. if (typ->strobj == NIL) {
  1453. OPM_Mark(200, typ->txtpos);
  1454. } else {
  1455. OPC_Ident(typ->strobj);
  1456. }
  1457. }
  1458. OPM_Write(')');
  1459. OPC_EndStat();
  1460. }
  1461. var = var->link;
  1462. }
  1463. if (!scope->leaf) {
  1464. var = proc->link;
  1465. while (var != NIL) {
  1466. if (!var->leaf) {
  1467. OPC_BegStat();
  1468. OPM_WriteString((CHAR*)"_s", 3);
  1469. OPM_Write('.');
  1470. OPC_Ident(var);
  1471. OPM_WriteString((CHAR*)" = ", 4);
  1472. if (__IN(var->typ->comp, 0x0c, 32)) {
  1473. OPM_WriteString((CHAR*)"(void*)", 8);
  1474. } else if (var->mode != 2) {
  1475. OPM_Write('&');
  1476. }
  1477. OPC_Ident(var);
  1478. if (var->typ->comp == 3) {
  1479. typ = var->typ;
  1480. dim = 0;
  1481. do {
  1482. OPM_WriteString((CHAR*)"; ", 3);
  1483. OPM_WriteString((CHAR*)"_s", 3);
  1484. OPM_Write('.');
  1485. OPC_Ident(var);
  1486. OPM_WriteString((CHAR*)"__len", 6);
  1487. if (dim != 0) {
  1488. OPM_WriteInt(dim);
  1489. }
  1490. OPM_WriteString((CHAR*)" = ", 4);
  1491. OPC_Ident(var);
  1492. OPM_WriteString((CHAR*)"__len", 6);
  1493. if (dim != 0) {
  1494. OPM_WriteInt(dim);
  1495. }
  1496. typ = typ->BaseTyp;
  1497. } while (!(typ->comp != 3));
  1498. } else if ((var->mode == 2 && var->typ->comp == 4)) {
  1499. OPM_WriteString((CHAR*)"; ", 3);
  1500. OPM_WriteString((CHAR*)"_s", 3);
  1501. OPM_Write('.');
  1502. OPC_Ident(var);
  1503. OPM_WriteString((CHAR*)"__typ", 6);
  1504. OPM_WriteString((CHAR*)" = ", 4);
  1505. OPC_Ident(var);
  1506. OPM_WriteString((CHAR*)"__typ", 6);
  1507. }
  1508. OPC_EndStat();
  1509. }
  1510. var = var->link;
  1511. }
  1512. var = scope->scope;
  1513. while (var != NIL) {
  1514. if (!var->leaf) {
  1515. OPC_BegStat();
  1516. OPM_WriteString((CHAR*)"_s", 3);
  1517. OPM_Write('.');
  1518. OPC_Ident(var);
  1519. OPM_WriteString((CHAR*)" = ", 4);
  1520. if (var->typ->comp != 2) {
  1521. OPM_Write('&');
  1522. } else {
  1523. OPM_WriteString((CHAR*)"(void*)", 8);
  1524. }
  1525. OPC_Ident(var);
  1526. OPC_EndStat();
  1527. }
  1528. var = var->link;
  1529. }
  1530. OPC_BegStat();
  1531. OPM_WriteString((CHAR*)"_s", 3);
  1532. OPM_Write('.');
  1533. OPM_WriteString((CHAR*)"lnk", 4);
  1534. OPM_WriteString((CHAR*)" = ", 4);
  1535. OPM_WriteStringVar((void*)scope->name, 256);
  1536. OPM_WriteString((CHAR*)"_s", 3);
  1537. OPC_EndStat();
  1538. OPC_BegStat();
  1539. OPM_WriteStringVar((void*)scope->name, 256);
  1540. OPM_WriteString((CHAR*)"_s", 3);
  1541. OPM_WriteString((CHAR*)" = ", 4);
  1542. OPM_Write('&');
  1543. OPM_WriteString((CHAR*)"_s", 3);
  1544. OPC_EndStat();
  1545. }
  1546. }
  1547. void OPC_ExitProc (OPT_Object proc, BOOLEAN eoBlock, BOOLEAN implicitRet)
  1548. {
  1549. OPT_Object var = NIL;
  1550. BOOLEAN indent;
  1551. indent = eoBlock;
  1552. if ((implicitRet && proc->typ != OPT_notyp)) {
  1553. OPM_Write(0x09);
  1554. OPM_WriteString((CHAR*)"__RETCHK;", 10);
  1555. OPM_WriteLn();
  1556. } else if (!eoBlock || implicitRet) {
  1557. if (!proc->scope->leaf) {
  1558. if (indent) {
  1559. OPC_BegStat();
  1560. } else {
  1561. indent = 1;
  1562. }
  1563. OPM_WriteStringVar((void*)proc->scope->name, 256);
  1564. OPM_WriteString((CHAR*)"_s", 3);
  1565. OPM_WriteString((CHAR*)" = ", 4);
  1566. OPM_WriteString((CHAR*)"_s", 3);
  1567. OPM_Write('.');
  1568. OPM_WriteString((CHAR*)"lnk", 4);
  1569. OPC_EndStat();
  1570. }
  1571. var = proc->link;
  1572. while (var != NIL) {
  1573. if ((((var->typ->comp == 3 && var->mode == 1)) && var->typ->sysflag == 0)) {
  1574. if (indent) {
  1575. OPC_BegStat();
  1576. } else {
  1577. indent = 1;
  1578. }
  1579. OPM_WriteString((CHAR*)"__DEL(", 7);
  1580. OPC_Ident(var);
  1581. OPM_Write(')');
  1582. OPC_EndStat();
  1583. }
  1584. var = var->link;
  1585. }
  1586. }
  1587. if (eoBlock) {
  1588. OPC_EndBlk();
  1589. OPM_WriteLn();
  1590. } else if (indent) {
  1591. OPC_BegStat();
  1592. }
  1593. }
  1594. void OPC_CompleteIdent (OPT_Object obj)
  1595. {
  1596. INT16 comp, level;
  1597. level = obj->mnolev;
  1598. if (obj->adr == 1) {
  1599. if (obj->typ->comp == 4) {
  1600. OPC_Ident(obj);
  1601. OPM_WriteString((CHAR*)"__", 3);
  1602. } else {
  1603. OPM_WriteString((CHAR*)"(*(", 4);
  1604. OPC_Ident(obj->typ->strobj);
  1605. OPM_WriteString((CHAR*)"*)&", 4);
  1606. OPC_Ident(obj);
  1607. OPM_Write(')');
  1608. }
  1609. } else if ((level != OPM_level && level > 0)) {
  1610. comp = obj->typ->comp;
  1611. if ((obj->mode != 2 && comp != 3)) {
  1612. OPM_Write('*');
  1613. }
  1614. OPM_WriteStringVar((void*)obj->scope->name, 256);
  1615. OPM_WriteString((CHAR*)"_s", 3);
  1616. OPM_WriteString((CHAR*)"->", 3);
  1617. OPC_Ident(obj);
  1618. } else {
  1619. OPC_Ident(obj);
  1620. }
  1621. }
  1622. void OPC_TypeOf (OPT_Object ap)
  1623. {
  1624. INT16 i;
  1625. __ASSERT(ap->typ->comp == 4, 0);
  1626. if (ap->mode == 2) {
  1627. if ((INT16)ap->mnolev != OPM_level) {
  1628. OPM_WriteStringVar((void*)ap->scope->name, 256);
  1629. OPM_WriteString((CHAR*)"_s->", 5);
  1630. OPC_Ident(ap);
  1631. } else {
  1632. OPC_Ident(ap);
  1633. }
  1634. OPM_WriteString((CHAR*)"__typ", 6);
  1635. } else if (ap->typ->strobj != NIL) {
  1636. OPC_Ident(ap->typ->strobj);
  1637. OPM_WriteString((CHAR*)"__typ", 6);
  1638. } else {
  1639. OPC_Andent(ap->typ);
  1640. }
  1641. }
  1642. void OPC_Cmp (INT16 rel)
  1643. {
  1644. switch (rel) {
  1645. case 9:
  1646. OPM_WriteString((CHAR*)" == ", 5);
  1647. break;
  1648. case 10:
  1649. OPM_WriteString((CHAR*)" != ", 5);
  1650. break;
  1651. case 11:
  1652. OPM_WriteString((CHAR*)" < ", 4);
  1653. break;
  1654. case 12:
  1655. OPM_WriteString((CHAR*)" <= ", 5);
  1656. break;
  1657. case 13:
  1658. OPM_WriteString((CHAR*)" > ", 4);
  1659. break;
  1660. case 14:
  1661. OPM_WriteString((CHAR*)" >= ", 5);
  1662. break;
  1663. default:
  1664. OPM_LogWStr((CHAR*)"unhandled case in OPC.Cmp, rel = ", 34);
  1665. OPM_LogWNum(rel, 0);
  1666. OPM_LogWLn();
  1667. break;
  1668. }
  1669. }
  1670. static void OPC_CharacterLiteral (INT64 c)
  1671. {
  1672. if (c < 32 || c > 126) {
  1673. OPM_WriteString((CHAR*)"0x", 3);
  1674. OPM_WriteHex(c);
  1675. } else {
  1676. OPM_Write('\'');
  1677. if ((c == 92 || c == 39) || c == 63) {
  1678. OPM_Write('\\');
  1679. }
  1680. OPM_Write(__CHR(c));
  1681. OPM_Write('\'');
  1682. }
  1683. }
  1684. static void OPC_StringLiteral (CHAR *s, ADDRESS s__len, INT32 l)
  1685. {
  1686. INT32 i;
  1687. INT16 c;
  1688. __DUP(s, s__len, CHAR);
  1689. OPM_Write('"');
  1690. i = 0;
  1691. while (i < l) {
  1692. c = (INT16)s[__X(i, s__len)];
  1693. if (c < 32 || c > 126) {
  1694. OPM_Write('\\');
  1695. OPM_Write(__CHR(48 + __ASHR(c, 6)));
  1696. c = __MASK(c, -64);
  1697. OPM_Write(__CHR(48 + __ASHR(c, 3)));
  1698. c = __MASK(c, -8);
  1699. OPM_Write(__CHR(48 + c));
  1700. } else {
  1701. if ((c == 92 || c == 34) || c == 63) {
  1702. OPM_Write('\\');
  1703. }
  1704. OPM_Write(__CHR(c));
  1705. }
  1706. i += 1;
  1707. }
  1708. OPM_Write('"');
  1709. __DEL(s);
  1710. }
  1711. void OPC_Case (INT64 caseVal, INT16 form)
  1712. {
  1713. CHAR ch;
  1714. OPM_WriteString((CHAR*)"case ", 6);
  1715. switch (form) {
  1716. case 3:
  1717. OPC_CharacterLiteral(caseVal);
  1718. break;
  1719. case 4:
  1720. OPM_WriteInt(caseVal);
  1721. break;
  1722. default:
  1723. OPM_LogWStr((CHAR*)"unhandled case in OPC.Case, form = ", 36);
  1724. OPM_LogWNum(form, 0);
  1725. OPM_LogWLn();
  1726. break;
  1727. }
  1728. OPM_WriteString((CHAR*)": ", 3);
  1729. }
  1730. void OPC_SetInclude (BOOLEAN exclude)
  1731. {
  1732. if (exclude) {
  1733. OPM_WriteString((CHAR*)" &= ~", 6);
  1734. } else {
  1735. OPM_WriteString((CHAR*)" |= ", 5);
  1736. }
  1737. }
  1738. void OPC_Increment (BOOLEAN decrement)
  1739. {
  1740. if (decrement) {
  1741. OPM_WriteString((CHAR*)" -= ", 5);
  1742. } else {
  1743. OPM_WriteString((CHAR*)" += ", 5);
  1744. }
  1745. }
  1746. void OPC_Halt (INT32 n)
  1747. {
  1748. OPC_Str1((CHAR*)"__HALT(#)", 10, n);
  1749. }
  1750. void OPC_IntLiteral (INT64 n, INT32 size)
  1751. {
  1752. if ((((size > 4 && n <= 2147483647)) && n > (-2147483647-1))) {
  1753. OPM_WriteString((CHAR*)"((INT", 6);
  1754. OPM_WriteInt(__ASHL(size, 3));
  1755. OPM_WriteString((CHAR*)")(", 3);
  1756. OPM_WriteInt(n);
  1757. OPM_WriteString((CHAR*)"))", 3);
  1758. } else {
  1759. OPM_WriteInt(n);
  1760. }
  1761. }
  1762. void OPC_Len (OPT_Object obj, OPT_Struct array, INT64 dim)
  1763. {
  1764. INT64 d;
  1765. d = dim;
  1766. while (d > 0) {
  1767. array = array->BaseTyp;
  1768. d -= 1;
  1769. }
  1770. if (array->comp == 3) {
  1771. OPC_CompleteIdent(obj);
  1772. OPM_WriteString((CHAR*)"__len", 6);
  1773. if (dim != 0) {
  1774. OPM_WriteInt(dim);
  1775. }
  1776. } else {
  1777. OPM_WriteInt(array->n);
  1778. }
  1779. }
  1780. void OPC_Constant (OPT_Const con, INT16 form)
  1781. {
  1782. INT16 i;
  1783. UINT64 s;
  1784. INT64 hex;
  1785. BOOLEAN skipLeading;
  1786. switch (form) {
  1787. case 1:
  1788. OPM_WriteInt(con->intval);
  1789. break;
  1790. case 2:
  1791. OPM_WriteInt(con->intval);
  1792. break;
  1793. case 3:
  1794. OPC_CharacterLiteral(con->intval);
  1795. break;
  1796. case 4:
  1797. OPM_WriteInt(con->intval);
  1798. break;
  1799. case 5:
  1800. OPM_WriteReal(con->realval, 'f');
  1801. break;
  1802. case 6:
  1803. OPM_WriteReal(con->realval, 0x00);
  1804. break;
  1805. case 7:
  1806. OPM_WriteString((CHAR*)"0x", 3);
  1807. skipLeading = 1;
  1808. s = con->setval;
  1809. i = 64;
  1810. do {
  1811. hex = 0;
  1812. do {
  1813. i -= 1;
  1814. hex = __ASHL(hex, 1);
  1815. if (__IN(i, s, 64)) {
  1816. hex += 1;
  1817. }
  1818. } while (!(__MASK(i, -8) == 0));
  1819. if (hex != 0 || !skipLeading) {
  1820. OPM_WriteHex(hex);
  1821. skipLeading = 0;
  1822. }
  1823. } while (!(i == 0));
  1824. if (skipLeading) {
  1825. OPM_Write('0');
  1826. }
  1827. break;
  1828. case 8:
  1829. OPC_StringLiteral(*con->ext, 256, con->intval2 - 1);
  1830. break;
  1831. case 9:
  1832. OPM_WriteString((CHAR*)"NIL", 4);
  1833. break;
  1834. default:
  1835. OPM_LogWStr((CHAR*)"unhandled case in OPC.Constant, form = ", 40);
  1836. OPM_LogWNum(form, 0);
  1837. OPM_LogWLn();
  1838. break;
  1839. }
  1840. }
  1841. static struct InitKeywords__46 {
  1842. INT8 *n;
  1843. struct InitKeywords__46 *lnk;
  1844. } *InitKeywords__46_s;
  1845. static void Enter__47 (CHAR *s, ADDRESS s__len);
  1846. static void Enter__47 (CHAR *s, ADDRESS s__len)
  1847. {
  1848. INT16 h;
  1849. __DUP(s, s__len, CHAR);
  1850. h = OPC_PerfectHash((void*)s, s__len);
  1851. OPC_hashtab[__X(h, 105)] = *InitKeywords__46_s->n;
  1852. __COPY(s, OPC_keytab[__X(*InitKeywords__46_s->n, 50)], 9);
  1853. *InitKeywords__46_s->n += 1;
  1854. __DEL(s);
  1855. }
  1856. static void OPC_InitKeywords (void)
  1857. {
  1858. INT8 n, i;
  1859. struct InitKeywords__46 _s;
  1860. _s.n = &n;
  1861. _s.lnk = InitKeywords__46_s;
  1862. InitKeywords__46_s = &_s;
  1863. n = 0;
  1864. i = 0;
  1865. while (i <= 104) {
  1866. OPC_hashtab[__X(i, 105)] = -1;
  1867. i += 1;
  1868. }
  1869. Enter__47((CHAR*)"ADDRESS", 8);
  1870. Enter__47((CHAR*)"INT16", 6);
  1871. Enter__47((CHAR*)"INT32", 6);
  1872. Enter__47((CHAR*)"INT64", 6);
  1873. Enter__47((CHAR*)"INT8", 5);
  1874. Enter__47((CHAR*)"UINT16", 7);
  1875. Enter__47((CHAR*)"UINT32", 7);
  1876. Enter__47((CHAR*)"UINT64", 7);
  1877. Enter__47((CHAR*)"UINT8", 6);
  1878. Enter__47((CHAR*)"asm", 4);
  1879. Enter__47((CHAR*)"auto", 5);
  1880. Enter__47((CHAR*)"break", 6);
  1881. Enter__47((CHAR*)"case", 5);
  1882. Enter__47((CHAR*)"char", 5);
  1883. Enter__47((CHAR*)"const", 6);
  1884. Enter__47((CHAR*)"continue", 9);
  1885. Enter__47((CHAR*)"default", 8);
  1886. Enter__47((CHAR*)"do", 3);
  1887. Enter__47((CHAR*)"double", 7);
  1888. Enter__47((CHAR*)"else", 5);
  1889. Enter__47((CHAR*)"enum", 5);
  1890. Enter__47((CHAR*)"extern", 7);
  1891. Enter__47((CHAR*)"export", 7);
  1892. Enter__47((CHAR*)"float", 6);
  1893. Enter__47((CHAR*)"for", 4);
  1894. Enter__47((CHAR*)"fortran", 8);
  1895. Enter__47((CHAR*)"goto", 5);
  1896. Enter__47((CHAR*)"if", 3);
  1897. Enter__47((CHAR*)"import", 7);
  1898. Enter__47((CHAR*)"int", 4);
  1899. Enter__47((CHAR*)"long", 5);
  1900. Enter__47((CHAR*)"register", 9);
  1901. Enter__47((CHAR*)"return", 7);
  1902. Enter__47((CHAR*)"short", 6);
  1903. Enter__47((CHAR*)"signed", 7);
  1904. Enter__47((CHAR*)"sizeof", 7);
  1905. Enter__47((CHAR*)"size_t", 7);
  1906. Enter__47((CHAR*)"static", 7);
  1907. Enter__47((CHAR*)"struct", 7);
  1908. Enter__47((CHAR*)"switch", 7);
  1909. Enter__47((CHAR*)"typedef", 8);
  1910. Enter__47((CHAR*)"union", 6);
  1911. Enter__47((CHAR*)"unsigned", 9);
  1912. Enter__47((CHAR*)"void", 5);
  1913. Enter__47((CHAR*)"volatile", 9);
  1914. Enter__47((CHAR*)"while", 6);
  1915. InitKeywords__46_s = _s.lnk;
  1916. }
  1917. export void *OPC__init(void)
  1918. {
  1919. __DEFMOD;
  1920. __MODULE_IMPORT(Configuration);
  1921. __MODULE_IMPORT(OPM);
  1922. __MODULE_IMPORT(OPT);
  1923. __REGMOD("OPC", 0);
  1924. __REGCMD("BegBlk", OPC_BegBlk);
  1925. __REGCMD("BegStat", OPC_BegStat);
  1926. __REGCMD("EndBlk", OPC_EndBlk);
  1927. __REGCMD("EndBlk0", OPC_EndBlk0);
  1928. __REGCMD("EndStat", OPC_EndStat);
  1929. __REGCMD("EnterBody", OPC_EnterBody);
  1930. __REGCMD("ExitBody", OPC_ExitBody);
  1931. __REGCMD("GenHdrIncludes", OPC_GenHdrIncludes);
  1932. __REGCMD("Init", OPC_Init);
  1933. /* BEGIN */
  1934. OPC_InitKeywords();
  1935. __ENDMOD;
  1936. }