spaghett.txt 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520
  1. Spaghetti programming language
  2. by Jeffry Johnston <spaghetti@kidsquid.com>
  3. Sept 14, 2001
  4. Introduction
  5. ------------
  6. This is an experiment in making a shorthand-type programming language. If
  7. you don't like GOTO you won't like this language. However, if you do like
  8. GOTO you still might not like this language :) Designed to produce
  9. "spaghetti" code, to the point where every program line can be arranged
  10. pretty much randomly and the program should still function properly.
  11. Memory
  12. ------
  13. There is one large block of 8-bit memory. On program load the first 256
  14. bytes of memory will contain the values 0-255, location 256 will equal 26 and
  15. location 257 will equal 1. The rest of the memory will be zeroed. Any byte
  16. of memory can be changed.
  17. Variables
  18. ---------
  19. The variables "a" through "z" are used together as a combined pointer, and
  20. are located from memory locations 256 to 281. Pointers "a" and "b" together
  21. ("b" automatically being the high byte) allows for 65536 bytes of memory to
  22. be accessed. Operations on "a" through "z" will modify only the byte
  23. involved. For example, assume that "a" is 255 and "b" is 7. If 2 is added
  24. to "a", then "a" will equal 1 and "b" will still equal 7. If addressing up
  25. to "z" is used, you'd need at least 4.11*10^62 bytes of memory ;). I imagine
  26. that most programs will only need "a" and "b".
  27. The variable "*" is similar to the C dereference, useful for modifying or
  28. grabbing the byte of memory at the combined pointer. This will initially
  29. point to location 282 because of locations 256 and 257.
  30. To reference a specific byte of memory, use a decimal number to represent the
  31. array element. For an immediate value, use numbers less than 256.
  32. Examples:
  33. Spaghetti Basic
  34. 1776 m(1776)
  35. 65 m(65) or 65, unless m(65) was modified
  36. 256 m(256) or m(a)
  37. b m(257) or m(b)
  38. * m(...+256*b+a)
  39. Commands
  40. --------
  41. Spaghetti Basic C
  42. line[ line line:;
  43. x=y x=y x=y;
  44. x+y x=x+y x+=y;
  45. x-y x=x-y x-=y;
  46. x&y x=x AND y x&=y;
  47. x? x=ASC(INPUT$(1)) x=(char)getchar();
  48. ?x PRINT CHR$(x); putchar(x);
  49. x<y:line IF x<y THEN GOTO line ELSE if (x<y) goto line; else
  50. x~y:line IF x=y THEN GOTO line ELSE if (x==y) goto line; else
  51. ]line :GOTO line goto line;
  52. ' ' /* */
  53. Line Numbers and Jumps
  54. ----------------------
  55. The "[" command sets the line number for the current line. Every non-blank
  56. line must have a leading line number. Program execution will start at line
  57. number 1.
  58. The "]" command specifies the line that will be jumped to. Jumping to the
  59. next physical line is not allowed. Jumping to line 0 exits the program.
  60. Every line must have a trailing jump instruction.
  61. Spaghetti Examples
  62. ------------------
  63. 2[*~13:0]3 'Echo
  64. 1[*?]2
  65. 3[?*]1
  66. 10[?100]11 'Hello World
  67. 9[?108]10
  68. 13[?101]2
  69. 12[?10]0
  70. 4[?111]5
  71. 8[?114]9
  72. 2[?108]3
  73. 11[?33]12
  74. 6[?87]7
  75. 3[?108]4
  76. 1[?48]13
  77. 5[?32]6
  78. 7[?111]8
  79. 1[*=99]800 '99 Bottles of beer N=99
  80. 809[283~9:400]810 'xx Bottle(s) of beer on the wall
  81. 813[283~13:814]815 'xx Bottle(s) of beer
  82. 805[283~5:600]806 'Take one down and pass it around
  83. 812[283~12:600]813 'xx Bottle(s) of beer on the wall
  84. 821[283=0]822 '100 200 300 400 500 600
  85. 804[283~4:500]805 '100 200 300 400 600
  86. 806[283~6:100]807 '700 600
  87. 818[283~17:500]819 '100 200 300 400 500 600 600
  88. 800[283~0:100]801
  89. 814[*-1]100 'N=N-1
  90. 808[283~8:300]809
  91. 810[283~10:600]811
  92. 817[283~16:400]818
  93. 803[283~3:400]804
  94. 820[283~19:600]821
  95. 822[*~0:0]800 'IF N=0 THEN END
  96. 807[283~7:200]808
  97. 819[283~18:600]820
  98. 802[283~2:300]803
  99. 816[283~15:300]817
  100. 811[283~11:700]812
  101. 801[283~1:200]802
  102. 815[283~14:200]816
  103. 103[284-10]104
  104. 101[285=0]102 'B=0
  105. 104[285+1]102
  106. 105[284+48]106
  107. 109[?284]110 'PRINT CHR$(B);
  108. 102[284<10:105]103 'A=A MOD B:B=A\10
  109. 106[285+48]107
  110. 108[?285]109
  111. 107[285~48:109]108 'IF A<>48 PRINT CHR$(A);
  112. 100[284=*]101 'A=N
  113. 110[283+1]800
  114. 207[283+1]800
  115. 206[?101]207
  116. 205[?108]206
  117. 204[?116]205
  118. 203[?116]204
  119. 202[?111]203
  120. 201[?98]202
  121. 200[?32]201 '200 PRINT " bottle";
  122. 302[283+1]800
  123. 301[?115]302
  124. 300[*~1:302]301 '300 IF N<>1 THEN PRINT "s";
  125. 400[?32]401 '400 PRINT " of beer";
  126. 402[?102]403
  127. 401[?111]402
  128. 404[?98]405
  129. 403[?32]404
  130. 406[?101]407
  131. 405[?101]406
  132. 408[283+1]800
  133. 407[?114]408
  134. 500[?32]501 '500 PRINT " on the wall";
  135. 503[?32]504
  136. 502[?110]503
  137. 505[?104]506
  138. 504[?116]505
  139. 506[?101]507
  140. 508[?119]509
  141. 511[?108]512
  142. 507[?32]508
  143. 509[?97]510
  144. 512[283+1]800
  145. 510[?108]511
  146. 501[?111]502
  147. 601[?10]602
  148. 600[?13]601 '600 PRINT
  149. 602[283+1]800
  150. 700[?84]701 '700 PRINT "Take one down, pass it around";
  151. 703[?101]704
  152. 706[?110]707
  153. 709[?100]710
  154. 712[?110]713
  155. 715[?112]716
  156. 718[?115]719
  157. 721[?116]722
  158. 724[?114]725
  159. 727[?110]728
  160. 701[?97]702
  161. 704[?32]705
  162. 707[?101]708
  163. 710[?111]711
  164. 713[?44]714
  165. 716[?97]717
  166. 719[?32]720
  167. 722[?32]723
  168. 725[?111]726
  169. 728[?100]729
  170. 702[?107]703
  171. 705[?111]706
  172. 708[?32]709
  173. 711[?119]712
  174. 714[?32]715
  175. 717[?115]718
  176. 720[?105]721
  177. 723[?97]724
  178. 726[?117]727
  179. 729[283+1]800
  180. Spaghetti Compiler
  181. ------------------
  182. 'SPAGHETT.BAS -- Spaghetti program compiler for Microsoft QuickBasic
  183. 'Programmed by Jeffry Johnston, September 16, 2001
  184. 'Can output Basic, C, or ASM code.
  185. DEFINT A-Z
  186. PRINT "Spaghetti compiler, Programmed by Jeffry Johnston": PRINT
  187. INPUT "Enter filename of Spaghetti source [.SPG]: ", F$
  188. F = INSTR(F$, ".")
  189. IF F = 0 THEN E$ = ".SPG" ELSE E$ = MID$(F$, F): F$ = MID$(F$, 1, F - 1)
  190. PRINT "1) QuickBasic"
  191. PRINT "2) GW-BASIC / BasicA"
  192. PRINT "3) C"
  193. PRINT "4) A86 (MS-DOS)"
  194. PRINT "5) MASM (MS-DOS)"
  195. DO:
  196. INPUT "Choose output format: ", O:
  197. LOOP WHILE O < 1 OR O > 5
  198. SELECT CASE O
  199. CASE 1, 2
  200. O$ = ".BAS"
  201. CASE 3
  202. O$ = ".C"
  203. CASE 4, 5
  204. O$ = ".ASM"
  205. END SELECT
  206. OPEN F$ + E$ FOR INPUT AS #1
  207. OPEN F$ + O$ FOR OUTPUT AS #2
  208. PRINT "Writing "; F$; O$; "..."
  209. SELECT CASE O
  210. CASE 1
  211. PRINT #2, "DEFINT A-Z"
  212. PRINT #2, "DIM M(30000)"
  213. PRINT #2, "FOR P = 0 TO 255: M(P) = P: NEXT P"
  214. PRINT #2, "OPEN " + CHR$(34) + "CONS:" + CHR$(34) + " FOR OUTPUT AS #1"
  215. PRINT #2, "M(256) = 26: M(257) = 1"
  216. PRINT #2, "GOTO 1"
  217. CASE 2
  218. PRINT #2, "0 DEFINT A-Z: DIM M(20000): FOR P = 0 TO 255: M(P) = P: NEXT P: OPEN " + CHR$(34) + "CONS:" + CHR$(34) + " FOR OUTPUT AS #1: M(256) = 26: M(257) = 1: GOTO 1"
  219. CASE 3
  220. PRINT #2, "#include <stdio.h>"
  221. PRINT #2, "#include <string.h>"
  222. PRINT #2, "int main(void) {"
  223. PRINT #2, " char m[32767],*p=m,*x,*y;"
  224. PRINT #2, " int i;"
  225. PRINT #2, " memset(m,0,32768);"
  226. PRINT #2, " for(i=0;i<256;i++,p++) *p=i;"
  227. PRINT #2, " m[256]=26; m[257]=1;"
  228. PRINT #2, " goto l1;"
  229. CASE 4
  230. PRINT #2, "PROGRAM PROC NEAR"
  231. PRINT #2, " MOV DI,OFFSET M"
  232. PRINT #2, " XOR AX,AX"
  233. PRINT #2, "ASCII: STOSB"
  234. PRINT #2, " INC AL"
  235. PRINT #2, " JNZ ASCII"
  236. PRINT #2, " MOV CX,16256"
  237. PRINT #2, " REP STOSW"
  238. PRINT #2, " MOV BYTE PTR M[256],26"
  239. PRINT #2, " MOV BYTE PTR M[257],1"
  240. PRINT #2, " JMP L1"
  241. CASE 5
  242. PRINT #2, "DOSSEG"
  243. PRINT #2, ".MODEL SMALL"
  244. PRINT #2, ".STACK 100h"
  245. PRINT #2, ".DATA"
  246. PRINT #2, " M DB 32768 DUP (?)"
  247. PRINT #2, ".CODE"
  248. PRINT #2, "PROGRAM PROC NEAR"
  249. PRINT #2, " MOV AX,DGROUP"
  250. PRINT #2, " MOV DS,AX"
  251. PRINT #2, " MOV ES,AX"
  252. PRINT #2, " MOV DI,OFFSET M"
  253. PRINT #2, " XOR AX,AX"
  254. PRINT #2, "ASCII: STOSB"
  255. PRINT #2, " INC AL"
  256. PRINT #2, " JNZ ASCII"
  257. PRINT #2, " MOV CX,16256"
  258. PRINT #2, " REP STOSW"
  259. PRINT #2, " MOV BYTE PTR M[256],26"
  260. PRINT #2, " MOV BYTE PTR M[257],1"
  261. PRINT #2, " JMP L1"
  262. END SELECT
  263. L1 = -1: L2 = -1
  264. DO WHILE NOT EOF(1)
  265. LINE INPUT #1, A$: A$ = LTRIM$(RTRIM$(A$))
  266. IF A$ = "" THEN GOTO L00P
  267. A$ = A$ + "@": L = L + 1
  268. S = 1: GOSUB GETNUM
  269. IF L1 = N OR L2 = N THEN E$ = "Invalid line order": GOTO EROR ELSE L2 = -1
  270. SELECT CASE O
  271. CASE 1, 2
  272. PRINT #2, N$ + " ";
  273. CASE 3
  274. PRINT #2, "l" + N$ + ":;"
  275. CASE 4, 5
  276. PRINT #2, "L" + N$ + ":"
  277. END SELECT
  278. IF MID$(A$, S + 1, 1) <> "[" THEN E$ = "Missing line number": GOTO EROR
  279. S = S + 2
  280. C$ = "": IF MID$(A$, S, 1) = "?" THEN S = S + 1: C$ = "#"
  281. V$ = "X": GOSUB PARSE
  282. IF C$ = "" THEN C$ = MID$(A$, S, 1): S = S + 1
  283. IF C$ <> "#" AND C$ <> "?" THEN V$ = "Y": GOSUB PARSE
  284. SELECT CASE C$
  285. CASE "="
  286. SELECT CASE O
  287. CASE 1, 2
  288. PRINT #2, "M(X) = M(Y): ";
  289. CASE 3
  290. PRINT #2, " *x=*y;";
  291. CASE 4, 5
  292. PRINT #2, " MOV AL,[SI]"
  293. PRINT #2, " MOV [DI],AL"
  294. END SELECT
  295. CASE "+"
  296. SELECT CASE O
  297. CASE 1, 2
  298. PRINT #2, "M(X) = (M(X) + M(Y)) MOD 256: ";
  299. CASE 3
  300. PRINT #2, " *x=(*x+*y)%256;";
  301. CASE 4, 5
  302. PRINT #2, " MOV AL,[SI]"
  303. PRINT #2, " ADD [DI],AL"
  304. END SELECT
  305. CASE "-"
  306. SELECT CASE O
  307. CASE 1, 2
  308. PRINT #2, "M(X) = (256 + M(X) - M(Y)) MOD 256: ";
  309. CASE 3
  310. PRINT #2, " *x=(256+*x-*y)%256;";
  311. CASE 4, 5
  312. PRINT #2, " MOV AL,[SI]"
  313. PRINT #2, " SUB [DI],AL"
  314. END SELECT
  315. CASE "&"
  316. SELECT CASE O
  317. CASE 1, 2
  318. PRINT #2, "M(X) = M(X) AND M(Y): ";
  319. CASE 3
  320. PRINT #2, " *x&=*y;";
  321. CASE 4, 5
  322. PRINT #2, " MOV AL,[SI]"
  323. PRINT #2, " AND [DI],AL"
  324. END SELECT
  325. CASE "?"
  326. SELECT CASE O
  327. CASE 1, 2
  328. PRINT #2, "M(X) = ASC(INPUT$(1)): ";
  329. CASE 3
  330. PRINT #2, " *x=(char)getchar();";
  331. CASE 4, 5
  332. PRINT #2, " MOV AH,08h"
  333. PRINT #2, " INT 21h"
  334. PRINT #2, " MOV [DI],AL"
  335. END SELECT
  336. CASE "#"
  337. SELECT CASE O
  338. CASE 1
  339. PRINT #2, "PRINT #1, CHR$(M(X)); : ";
  340. CASE 2
  341. PRINT #2, "IF M(X) <> 10 THEN PRINT #1, CHR$(M(X)); : ";
  342. CASE 3
  343. PRINT #2, " putchar(*x);";
  344. CASE 4, 5
  345. PRINT #2, " MOV AH,02h"
  346. PRINT #2, " MOV DL,[DI]"
  347. PRINT #2, " INT 21h"
  348. END SELECT
  349. CASE "<"
  350. S = S + 1: GOSUB GETNUM: S = S + 1: L2 = N
  351. SELECT CASE O
  352. CASE 1, 2
  353. PRINT #2, "IF M(X) < M(Y) THEN ";
  354. GOSUB GTO
  355. PRINT #2, " ELSE ";
  356. CASE 3
  357. PRINT #2, " if (*x<*y) ";
  358. GOSUB GTO
  359. PRINT #2, " else";
  360. CASE 4, 5
  361. PRINT #2, " MOV AL,[SI]"
  362. PRINT #2, " CMP [DI],AL"
  363. T = T + 1
  364. PRINT #2, " JAE T" + LTRIM$(STR$(T))
  365. GOSUB GTO
  366. PRINT #2, "T" + LTRIM$(STR$(T)) + ":"
  367. END SELECT
  368. CASE "~"
  369. S = S + 1: GOSUB GETNUM: S = S + 1: L2 = N
  370. SELECT CASE O
  371. CASE 1, 2
  372. PRINT #2, "IF M(X) = M(Y) THEN ";
  373. GOSUB GTO
  374. PRINT #2, " ELSE ";
  375. CASE 3
  376. PRINT #2, " if (*x==*y)";
  377. GOSUB GTO
  378. PRINT #2, " else";
  379. CASE 4, 5
  380. PRINT #2, " MOV AL,[SI]"
  381. PRINT #2, " CMP [DI],AL"
  382. T = T + 1
  383. PRINT #2, " JNZ T" + LTRIM$(STR$(T))
  384. GOSUB GTO
  385. PRINT #2, "T" + LTRIM$(STR$(T)) + ":"
  386. END SELECT
  387. END SELECT
  388. IF MID$(A$, S, 1) <> "]" THEN E$ = "Missing jump": GOTO EROR
  389. S = S + 1: GOSUB GETNUM: L1 = N
  390. GOSUB GTO
  391. A$ = MID$(A$, 1, LEN(A$) - 1)
  392. V = INSTR(MID$(A$, S), "'")
  393. SELECT CASE O
  394. CASE 1, 2
  395. IF V = 0 THEN PRINT #2, "" ELSE PRINT #2, " " + MID$(A$, S + V - 1)
  396. CASE 3
  397. IF V = 0 THEN PRINT #2, "" ELSE PRINT #2, " /* " + MID$(A$, S + V) + " */"
  398. CASE 4, 5
  399. IF V > 0 THEN PRINT #2, "; " + MID$(A$, S + V)
  400. END SELECT
  401. L00P:
  402. LOOP
  403. SELECT CASE O
  404. CASE 1, 2
  405. PRINT #2, ""
  406. CASE 3
  407. PRINT #2, "end:;"
  408. PRINT #2, " return 0;"
  409. PRINT #2, "}"
  410. CASE 4
  411. PRINT #2, "PROGRAM ENDP"
  412. PRINT #2, "M:"
  413. CASE 5
  414. PRINT #2, "PROGRAM ENDP"
  415. PRINT #2, "END PROGRAM"
  416. END SELECT
  417. PRINT "Done."
  418. CLOSE #1, #2
  419. END
  420. EROR:
  421. PRINT LTRIM$(STR$(L)); ": "; E$
  422. END
  423. GETNUM:
  424. N = 0
  425. DO
  426. V = ASC(MID$(A$, S, 1)) - 48
  427. IF V < 0 OR V > 9 THEN S = S - 1: EXIT DO
  428. N = N * 10 + V: S = S + 1
  429. LOOP
  430. N$ = LTRIM$(STR$(N))
  431. RETURN
  432. PARSE:
  433. SELECT CASE MID$(A$, S, 1)
  434. CASE "a" TO "z"
  435. X$ = LTRIM$(STR$(ASC(MID$(A$, S, 1)) + 159))
  436. SELECT CASE O
  437. CASE 1, 2
  438. PRINT #2, V$ + " = " + X$ + ": ";
  439. CASE 3
  440. PRINT #2, " " + LCASE$(V$) + "=m+" + X$ + ";"
  441. CASE 4, 5
  442. PRINT #2, " MOV ";
  443. PRINT #2, MID$("DS", ASC(V$) - 87, 1) + "I,OFFSET M+" + X$
  444. END SELECT
  445. CASE "*"
  446. SELECT CASE O
  447. CASE 1, 2
  448. PRINT #2, V$ + " = 256 * M(257) + M(256): ";
  449. CASE 3
  450. PRINT #2, " " + LCASE$(V$) + "=m+256*m[257]+m[256];"
  451. CASE 4, 5
  452. PRINT #2, " MOV ";
  453. PRINT #2, MID$("DS", ASC(V$) - 87, 1) + "I,WORD PTR M[256]"
  454. END SELECT
  455. CASE ELSE
  456. GOSUB GETNUM
  457. SELECT CASE O
  458. CASE 1, 2
  459. PRINT #2, V$ + " = " + N$ + ": ";
  460. CASE 3
  461. PRINT #2, " " + LCASE$(V$) + "=m+" + N$ + ";"
  462. CASE 4, 5
  463. PRINT #2, " MOV ";
  464. PRINT #2, MID$("DS", ASC(V$) - 87, 1) + "I,OFFSET M+" + N$
  465. END SELECT
  466. END SELECT
  467. S = S + 1
  468. RETURN
  469. GTO:
  470. IF VAL(N$) = 0 THEN
  471. SELECT CASE O
  472. CASE 1
  473. PRINT #2, "END";
  474. CASE 2
  475. PRINT #2, "SYSTEM";
  476. CASE 3
  477. PRINT #2, " goto end;";
  478. CASE 4
  479. PRINT #2, " RET"
  480. CASE 5
  481. PRINT #2, " MOV AX,4C00h"
  482. PRINT #2, " INT 21h"
  483. END SELECT
  484. ELSE
  485. SELECT CASE O
  486. CASE 1, 2
  487. PRINT #2, "GOTO " + N$;
  488. CASE 3
  489. PRINT #2, " goto l" + N$ + ";";
  490. CASE 4, 5
  491. PRINT #2, " JMP L" + N$
  492. END SELECT
  493. END IF
  494. RETURN