BASIC compiler/interpreter for PIC32MX/MZ-80K
Revisão | e62bfb9afe5abbf484a001aff3884f25d648c448 (tree) |
---|---|
Hora | 2019-04-14 09:21:02 |
Autor | Katsumi <kmorimatsu@sour...> |
Commiter | Katsumi |
Accept "_" for label/varnames. Correct protozoa button direction.
@@ -519,5 +519,9 @@ extern int g_int_vector[]; | ||
519 | 519 | #define div36_32(x) div32(x,0xe38e38e4,37) |
520 | 520 | #define rem36_32(x) (x-36*div36_32(x)) |
521 | 521 | |
522 | +// Divide by 37 (valid for 31 bits) | |
523 | +#define div37_31(x) div32(x,0xdd67c8a7,37) | |
524 | +#define rem37_31(x) (x-37*div37_31(x)) | |
525 | + | |
522 | 526 | // Check if within RAM |
523 | 527 | #define withinRAM(x) ((&RAM[0])<=((char*)(x)) && ((char*)(x))<(&RAM[RAMSIZE])) |
@@ -228,14 +228,11 @@ static const char initext[]= | ||
228 | 228 | "#PRINT\n"; |
229 | 229 | |
230 | 230 | static const char bastext[]= |
231 | -"I=1:WHILE I<=10\n" | |
232 | -"I=I+1:WEND\n" | |
231 | +"CLS\n" | |
232 | +"LABEL TEST_:i=0/0\n" | |
233 | +"\n" | |
233 | 234 | "\n" |
234 | -"I=1:DO\n" | |
235 | -"I=I+1:LOOP UNTIL I=11\n" | |
236 | 235 | "\n" |
237 | -"FOR I=1 TO 10\n" | |
238 | -"NEXT\n" | |
239 | 236 | "\n" |
240 | 237 | "\n" |
241 | 238 | "\n"; |
@@ -63,20 +63,19 @@ void err_peri_not_init(void); | ||
63 | 63 | |
64 | 64 | #define ADDITIONAL_STR_FUNCTIONS |
65 | 65 | #define ADDITIONAL_RESERVED_VAR_NAMES \ |
66 | - 0x00015045, /*OUT*/ \ | |
67 | - 0x01975e81, /*OUT8H*/ \ | |
68 | - 0x01975e85, /*OUT8L*/ \ | |
69 | - 0x01975d7a, /*OUT16*/ \ | |
70 | - 0x0001015b, /*IN*/ \ | |
71 | - 0x0007dde1, /*IN8H*/ \ | |
72 | - 0x0007dde5, /*IN8L*/ \ | |
73 | - 0x0007dcda, /*IN16*/ \ | |
74 | - 0x05f0a740, /*ANALOG*/ \ | |
75 | - 0x00015596, /*PWM*/ \ | |
76 | - 0x45f58f5d, /*SERIAL*/ \ | |
77 | - 0x000163c6, /*SPI*/ \ | |
78 | - 0x00012de4, /*I2C*/ | |
79 | - | |
66 | + 0x000154aa, /*OUT*/ \ | |
67 | + 0x01c5c253, /*OUT8H*/ \ | |
68 | + 0x01c5c257, /*OUT8L*/ \ | |
69 | + 0x01c5c145, /*OUT16*/ \ | |
70 | + 0x00010164, /*IN*/ \ | |
71 | + 0x000870fd, /*IN8H*/ \ | |
72 | + 0x00087101, /*IN8L*/ \ | |
73 | + 0x00086fef, /*IN16*/ \ | |
74 | + 0x06bd06f3, /*ANALOG*/ \ | |
75 | + 0x00015a46, /*PWM*/ \ | |
76 | + 0x502e9b15, /*SERIAL*/ \ | |
77 | + 0x0001694a, /*SPI*/ \ | |
78 | + 0x00013077, /*I2C*/ \ | |
80 | 79 | |
81 | 80 | #define EXTRA_MASK 0x003F |
82 | 81 | #define EXTRA_STEP 0x0001 |
@@ -62,15 +62,16 @@ char* resolve_label(int s6){ | ||
62 | 62 | s6-=65536; |
63 | 63 | str[6]=0x00; |
64 | 64 | for(i=5;0<=i;i--){ |
65 | - if (s6<36) { | |
66 | - // First character must be A-Z, corresponding to 1-26 but not 10-35. | |
65 | + if (s6<37) { | |
66 | + // First character must be A-Z or _, corresponding to 1-27 but not 10-36. | |
67 | 67 | // See get_label() for the detail. |
68 | - str[i]=s6-1+'A'; | |
68 | + if (s6==27) str[i]='_'; | |
69 | + else str[i]=s6-1+'A'; | |
69 | 70 | break; |
70 | 71 | } else { |
71 | - // From second, 0-9 corresponds to 0-9 and A-Z corresponds to 10-35. | |
72 | - str[i]="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"[rem36_32(s6)]; | |
73 | - s6=div36_32(s6); | |
72 | + // From second, 0-9 corresponds to 0-9 and A-Z corresponds to 10-36. | |
73 | + str[i]="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_"[rem37_31(s6)]; | |
74 | + s6=div37_31(s6); | |
74 | 75 | } |
75 | 76 | } |
76 | 77 | return (char*)(str+i); |
@@ -44,17 +44,19 @@ char* get_label(void){ | ||
44 | 44 | g_label=0; |
45 | 45 | return 0; |
46 | 46 | } |
47 | - } else if ('A'<=b1 && b1<='Z') { | |
47 | + } else if ('A'<=b1 && b1<='Z' || b1=='_') { | |
48 | 48 | // May be label |
49 | + // When changing here, see also chech_var_name() | |
49 | 50 | do { |
50 | - // First character must be A-Z | |
51 | - // From second, A-Z and 0-9 can be used. | |
52 | - i*=36; | |
51 | + // First character must be A-Z or _ | |
52 | + // From second, A-Z, _, and 0-9 can be used. | |
53 | + i*=37; | |
54 | + if (b1=='_') b1='Z'+1; | |
53 | 55 | if ('0'<=b1 && b1<='9') { |
54 | 56 | i+=b1-'0'; |
55 | 57 | } else if (g_srcpos==prevpos) { |
56 | - // First character must be A-Z. | |
57 | - // Subtract 9, resulting 1-26 but not 10-35. | |
58 | + // First character must be A-Z or _. | |
59 | + // Subtract 9, resulting in 1-27 but not 10-36. | |
58 | 60 | // This subtraction is required to maintain |
59 | 61 | // final number being <0x80000000. |
60 | 62 | i+=b1-'A'+1; |
@@ -63,7 +65,7 @@ char* get_label(void){ | ||
63 | 65 | } |
64 | 66 | g_srcpos++; |
65 | 67 | b1=g_source[g_srcpos]; |
66 | - } while ('0'<= b1 && b1<='9' || 'A'<=b1 && b1<='Z'); | |
68 | + } while ('0'<= b1 && b1<='9' || 'A'<=b1 && b1<='Z' || b1=='_'); | |
67 | 69 | // Length of the label must be between 2 and 6. |
68 | 70 | if (g_srcpos-prevpos<2 || 6<g_srcpos-prevpos) { |
69 | 71 | g_srcpos=prevpos; |
@@ -16,14 +16,15 @@ function name2int(name){ | ||
16 | 16 | var i=0; |
17 | 17 | var b1=g_source.charCodeAt(0); |
18 | 18 | do { |
19 | - // First character must be A-Z | |
20 | - // From second, A-Z and 0-9 can be used. | |
21 | - i*=36; | |
19 | + // First character must be A-Z or _ | |
20 | + // From second, A-Z, _, and 0-9 can be used. | |
21 | + i*=37; | |
22 | + if (b1=='_'.charCodeAt(0)) b1='Z'.charCodeAt(0)+1; | |
22 | 23 | if ('0'.charCodeAt(0)<=b1 && b1<='9'.charCodeAt(0)) { |
23 | 24 | i+=b1-'0'.charCodeAt(0); |
24 | 25 | } else if (g_srcpos==prevpos) { |
25 | - // First character must be A-Z. | |
26 | - // Subtract 9, resulting 1-26 but not 10-35. | |
26 | + // First character must be A-Z or _. | |
27 | + // Subtract 9, resulting in 1-27 but not 10-36. | |
27 | 28 | // This subtraction is required to maintain |
28 | 29 | // final number being <0x80000000. |
29 | 30 | i+=b1-'A'.charCodeAt(0)+1; |
@@ -32,10 +33,58 @@ function name2int(name){ | ||
32 | 33 | } |
33 | 34 | g_srcpos++; |
34 | 35 | b1=g_source.charCodeAt(g_srcpos); |
35 | - } while ('0'.charCodeAt(0)<= b1 && b1<='9'.charCodeAt(0) || 'A'.charCodeAt(0)<=b1 && b1<='Z'.charCodeAt(0)); | |
36 | + } while ('0'.charCodeAt(0)<= b1 && b1<='9'.charCodeAt(0) || b1=='_'.charCodeAt(0) || | |
37 | + 'A'.charCodeAt(0)<=b1 && b1<='Z'.charCodeAt(0)); | |
36 | 38 | return i+65536; |
37 | 39 | } |
38 | 40 | |
41 | +function int2name(s6){ | |
42 | + var rem37_31=function(s6){ | |
43 | + return s6 % 37; | |
44 | + }; | |
45 | + var div37_31=function(s6){ | |
46 | + return (s6-(s6 % 37))/37; | |
47 | + }; | |
48 | + var str=new Array(); | |
49 | + var i,res; | |
50 | + s6-=65536; | |
51 | + str[6]=0; | |
52 | + for(i=5;0<=i;i--){ | |
53 | + if (s6<37) { | |
54 | + // First character must be A-Z or _, corresponding to 1-27 but not 10-36. | |
55 | + // See get_label() for the detail. | |
56 | + if (s6==27) str[i]='_'.charCodeAt(0); | |
57 | + else str[i]=s6-1+'A'.charCodeAt(0); | |
58 | + break; | |
59 | + } else { | |
60 | + // From second, 0-9 corresponds to 0-9 and A-Z corresponds to 10-36. | |
61 | + str[i]="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_".charCodeAt(rem37_31(s6)); | |
62 | + s6=div37_31(s6); | |
63 | + } | |
64 | + } | |
65 | + //return (char*)(str+i); | |
66 | + for(res='';str[i];i++) { | |
67 | + res+=String.fromCharCode(str[i]); | |
68 | + } | |
69 | + return res; | |
70 | +} | |
71 | + | |
72 | +// Show max number by this system. | |
73 | +//WScript.Echo(name2int('______').toString(16)); | |
74 | + | |
75 | +// Test functions for 10000 times with randomized var names | |
76 | +for(i=0;i<10000;i++){ | |
77 | + t="ABCDEFGHIJKLMNOPQRSTUVWXYZ_".charAt(Math.random()*27); | |
78 | + for(j=0;j<1+Math.random()*4;j++){ | |
79 | + t+="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_".charAt(Math.random()*37); | |
80 | + } | |
81 | + j=name2int(t); | |
82 | + if (int2name(j)!=t || j<0 || 0x7fffffff<j) { | |
83 | + WScript.Echo('ERROR: '+t+' ('+j+'; 0x'+j.toString(16)+') '+i); | |
84 | + WScript.Quit(); | |
85 | + } | |
86 | +} | |
87 | + | |
39 | 88 | var namearray=[ |
40 | 89 | 'ABS', |
41 | 90 | 'ACOS', |
@@ -168,14 +217,16 @@ var namearray=[ | ||
168 | 217 | 'I2C', |
169 | 218 | ]; |
170 | 219 | var result=''; |
220 | +var commented=0; | |
171 | 221 | for(key in namearray){ |
172 | 222 | var nameint='0000'+name2int(namearray[key]).toString(16); |
173 | 223 | nameint=nameint.substr(nameint.length-8); |
174 | 224 | if (namearray[key].substr(0,2)=='//') { |
175 | 225 | // This is a comment |
176 | 226 | result+=namearray[key]+"\r\n"; |
227 | + commented=1; | |
177 | 228 | } else { |
178 | - result+="\t0x"+nameint+", /*"+namearray[key]+"*/\r\n"; | |
229 | + result+="\t0x"+nameint+", /*"+namearray[key]+"*/"+(commented ? " \\\r\n" : "\r\n"); | |
179 | 230 | } |
180 | 231 | } |
181 | 232 |
@@ -313,7 +313,7 @@ char* label_statement(){ | ||
313 | 313 | char* err; |
314 | 314 | char b1; |
315 | 315 | b1=g_source[g_srcpos]; |
316 | - if (b1<'A' || 'Z'<b1) return ERR_SYNTAX; // Number is not allowed here. | |
316 | + if ('0'<=b1 && b1<='9') return ERR_SYNTAX; // Number is not allowed here. | |
317 | 317 | err=get_label(); |
318 | 318 | if (err) return err; |
319 | 319 | // Check existing label with the same name here. |
@@ -18,120 +18,120 @@ | ||
18 | 18 | */ |
19 | 19 | |
20 | 20 | static const int reserved_var_names[]={ |
21 | - 0x000106b8, /*ABS*/ | |
22 | - 0x0001f67c, /*ACOS*/ | |
23 | - 0x0002414c, /*ARGS*/ | |
24 | - 0x0001090c, /*ASC*/ | |
25 | - 0x0002469f, /*ASIN*/ | |
26 | - 0x00024a8f, /*ATAN*/ | |
27 | - 0x002f7c1e, /*ATAN2*/ | |
28 | - 0x0047c31c, /*BREAK*/ | |
29 | - 0x00035869, /*CALL*/ | |
30 | - 0x00575afe, /*CDATA*/ | |
31 | - 0x00036c3d, /*CEIL*/ | |
32 | - 0x000111af, /*CHR*/ | |
33 | - 0x0cb1b682, /*CIRCLE*/ | |
34 | - 0x005d1ea3, /*CLEAR*/ | |
35 | - 0x00011240, /*CLS*/ | |
36 | - 0x005f66cb, /*COLOR*/ | |
37 | - 0x000112ac, /*COS*/ | |
38 | - 0x0003a041, /*COSH*/ | |
39 | - 0x00616415, /*CREAD*/ | |
40 | - 0x0de593fb, /*CURSOR*/ | |
41 | - 0x00040fbe, /*DATA*/ | |
42 | - 0x00011644, /*DEC*/ | |
43 | - 0x0fe19c42, /*DELETE*/ | |
44 | - 0x000116de, /*DIM*/ | |
45 | - 0x000100a8, /*DO*/ | |
46 | - 0x0004fd8e, /*ELSE*/ | |
47 | - 0x1434a177, /*ELSEIF*/ | |
48 | - 0x00011c99, /*END*/ | |
49 | - 0x0091c927, /*ENDIF*/ | |
50 | - 0x00053854, /*EXEC*/ | |
51 | - 0x00011e0d, /*EXP*/ | |
52 | - 0x000579c8, /*FABS*/ | |
53 | - 0x16e3d4be, /*FCLOSE*/ | |
54 | - 0x00058fcf, /*FEOF*/ | |
55 | - 0x00059895, /*FGET*/ | |
56 | - 0x00a67500, /*FGETC*/ | |
57 | - 0x00a7e061, /*FIELD*/ | |
58 | - 0x0005a3a2, /*FILE*/ | |
59 | - 0x177f0ca5, /*FINPUT*/ | |
60 | - 0x0005b1df, /*FLEN*/ | |
61 | - 0x00aa3445, /*FLOAT*/ | |
62 | - 0x00aa363b, /*FLOOR*/ | |
63 | - 0x0005b84d, /*FMOD*/ | |
64 | - 0x00ac5c9f, /*FOPEN*/ | |
65 | - 0x000121db, /*FOR*/ | |
66 | - 0x18352839, /*FPRINT*/ | |
67 | - 0x0005c865, /*FPUT*/ | |
68 | - 0x00ad2e40, /*FPUTC*/ | |
69 | - 0x00aefdec, /*FSEEK*/ | |
70 | - 0x00063b90, /*GCLS*/ | |
71 | - 0x1a808bcb, /*GCOLOR*/ | |
72 | - 0x1ab733b3, /*GETDIR*/ | |
73 | - 0x00c60f03, /*GOSUB*/ | |
74 | - 0x0006796c, /*GOTO*/ | |
75 | - 0x1bcfcc39, /*GPRINT*/ | |
76 | - 0x00012a99, /*HEX*/ | |
77 | - 0x0007ad12, /*IDLE*/ | |
78 | - 0x00010153, /*IF*/ | |
79 | - 0x00f8701a, /*INKEY*/ | |
80 | - 0x00f88ba5, /*INPUT*/ | |
81 | - 0x000130e9, /*INT*/ | |
82 | - 0x00092084, /*KEYS*/ | |
83 | - 0x013be43d, /*LABEL*/ | |
84 | - 0x00013ecf, /*LEN*/ | |
85 | - 0x00013ed5, /*LET*/ | |
86 | - 0x0009e96a, /*LINE*/ | |
87 | - 0x00014030, /*LOG*/ | |
88 | - 0x0145f324, /*LOG10*/ | |
89 | - 0x000a07f9, /*LOOP*/ | |
90 | - 0x000abca3, /*MODF*/ | |
91 | - 0x016418d4, /*MUSIC*/ | |
92 | - 0x000b4321, /*NEXT*/ | |
93 | - 0x000148f8, /*NEW*/ | |
94 | - 0x00014a5d, /*NOT*/ | |
95 | - 0x38a658d7, /*OPTION*/ | |
96 | - 0x000152c0, /*PCG*/ | |
97 | - 0x000cacec, /*PEEK*/ | |
98 | - 0x3b1c6aea, /*PEEK16*/ | |
99 | - 0x3b1c6b2e, /*PEEK32*/ | |
100 | - 0x00010252, /*PI*/ | |
101 | - 0x01ac8479, /*POINT*/ | |
102 | - 0x000ce05e, /*POKE*/ | |
103 | - 0x3c20dc0a, /*POKE16*/ | |
104 | - 0x3c20dc4e, /*POKE32*/ | |
105 | - 0x00015480, /*POW*/ | |
106 | - 0x01aea739, /*PRINT*/ | |
107 | - 0x000cf3d5, /*PSET*/ | |
108 | - 0x3cb45fa4, /*PUBLIC*/ | |
109 | - 0x3cc0fe21, /*PUTBMP*/ | |
110 | - 0x000e18d5, /*READ*/ | |
111 | - 0x00015d2e, /*REM*/ | |
112 | - 0x425c9703, /*RETURN*/ | |
113 | - 0x00015e69, /*RND*/ | |
114 | - 0x45c26d49, /*SCROLL*/ | |
115 | - 0x45f6e3b3, /*SETDIR*/ | |
116 | - 0x00016287, /*SGN*/ | |
117 | - 0x000162cf, /*SIN*/ | |
118 | - 0x000ee52d, /*SINH*/ | |
119 | - 0x01f9a429, /*SOUND*/ | |
120 | - 0x000f0e49, /*SQRT*/ | |
121 | - 0x47f711de, /*SYSTEM*/ | |
122 | - 0x000166bf, /*TAN*/ | |
123 | - 0x000f72ed, /*TANH*/ | |
124 | - 0x020ed5f3, /*TIMER*/ | |
125 | - 0x02182fee, /*TVRAM*/ | |
126 | - 0x022c2a2d, /*UNTIL*/ | |
127 | - 0x4e8887d0, /*USEPCG*/ | |
128 | - 0x4e88a5f3, /*USEVAR*/ | |
129 | - 0x000170dd, /*VAL*/ | |
130 | - 0x000170e3, /*VAR*/ | |
131 | - 0x00119505, /*WAIT*/ | |
132 | - 0x0011a9e9, /*WEND*/ | |
133 | - 0x025aef62, /*WHILE*/ | |
134 | - 0x025b8d75, /*WIDTH*/ | |
21 | + 0x0001070c, /*ABS*/ | |
22 | + 0x0002099d, /*ACOS*/ | |
23 | + 0x000258ac, /*ARGS*/ | |
24 | + 0x00010971, /*ASC*/ | |
25 | + 0x00025e4a, /*ASIN*/ | |
26 | + 0x0002627b, /*ATAN*/ | |
27 | + 0x00343bc9, /*ATAN2*/ | |
28 | + 0x004f5c95, /*BREAK*/ | |
29 | + 0x00038a2f, /*CALL*/ | |
30 | + 0x006110c1, /*CDATA*/ | |
31 | + 0x00039f24, /*CEIL*/ | |
32 | + 0x0001129b, /*CHR*/ | |
33 | + 0x0e7f3303, /*CIRCLE*/ | |
34 | + 0x0067525f, /*CLEAR*/ | |
35 | + 0x00011330, /*CLS*/ | |
36 | + 0x0069cb6b, /*COLOR*/ | |
37 | + 0x0001139f, /*COS*/ | |
38 | + 0x0003d60c, /*COSH*/ | |
39 | + 0x006bf57f, /*CREAD*/ | |
40 | + 0x0fd6b45b, /*CURSOR*/ | |
41 | + 0x00045129, /*DATA*/ | |
42 | + 0x00011776, /*DEC*/ | |
43 | + 0x122a52c0, /*DELETE*/ | |
44 | + 0x00011814, /*DIM*/ | |
45 | + 0x000100ac, /*DO*/ | |
46 | + 0x000551b8, /*ELSE*/ | |
47 | + 0x171a03a1, /*ELSEIF*/ | |
48 | + 0x00011e1d, /*END*/ | |
49 | + 0x00a20bbe, /*ENDIF*/ | |
50 | + 0x00058fdc, /*EXEC*/ | |
51 | + 0x00011f9b, /*EXP*/ | |
52 | + 0x0005da5b, /*FABS*/ | |
53 | + 0x1a358bdd, /*FCLOSE*/ | |
54 | + 0x0005f193, /*FEOF*/ | |
55 | + 0x0005fae1, /*FGET*/ | |
56 | + 0x00b94291, /*FGETC*/ | |
57 | + 0x00bacd24, /*FIELD*/ | |
58 | + 0x00060687, /*FILE*/ | |
59 | + 0x1ae2b2ef, /*FINPUT*/ | |
60 | + 0x00061598, /*FLEN*/ | |
61 | + 0x00bd52ae, /*FLOAT*/ | |
62 | + 0x00bd54b2, /*FLOOR*/ | |
63 | + 0x00061c59, /*FMOD*/ | |
64 | + 0x00bfaa2c, /*FOPEN*/ | |
65 | + 0x000123a9, /*FOR*/ | |
66 | + 0x1badd288, /*FPRINT*/ | |
67 | + 0x00062d52, /*FPUT*/ | |
68 | + 0x00c08ce6, /*FPUTC*/ | |
69 | + 0x00c286ca, /*FSEEK*/ | |
70 | + 0x0006ac5c, /*GCLS*/ | |
71 | + 0x1e59e7b7, /*GCOLOR*/ | |
72 | + 0x1e96cb44, /*GETDIR*/ | |
73 | + 0x00dc556c, /*GOSUB*/ | |
74 | + 0x0006edac, /*GOTO*/ | |
75 | + 0x1fcfed5d, /*GPRINT*/ | |
76 | + 0x00012cef, /*HEX*/ | |
77 | + 0x00083d61, /*IDLE*/ | |
78 | + 0x0001015c, /*IF*/ | |
79 | + 0x01149470, /*INKEY*/ | |
80 | + 0x0114b178, /*INPUT*/ | |
81 | + 0x00013391, /*INT*/ | |
82 | + 0x0009d063, /*KEYS*/ | |
83 | + 0x016022dc, /*LABEL*/ | |
84 | + 0x00014249, /*LEN*/ | |
85 | + 0x0001424f, /*LET*/ | |
86 | + 0x000aa9ff, /*LINE*/ | |
87 | + 0x000143b4, /*LOG*/ | |
88 | + 0x016b0db9, /*LOG10*/ | |
89 | + 0x000aca45, /*LOOP*/ | |
90 | + 0x000b8e81, /*MODF*/ | |
91 | + 0x018c8c85, /*MUSIC*/ | |
92 | + 0x000c21d6, /*NEXT*/ | |
93 | + 0x00014d04, /*NEW*/ | |
94 | + 0x00014e73, /*NOT*/ | |
95 | + 0x40e24fde, /*OPTION*/ | |
96 | + 0x0001575c, /*PCG*/ | |
97 | + 0x000daac8, /*PEEK*/ | |
98 | + 0x43be47b3, /*PEEK16*/ | |
99 | + 0x43be47f9, /*PEEK32*/ | |
100 | + 0x00010262, /*PI*/ | |
101 | + 0x01dd7f7a, /*POINT*/ | |
102 | + 0x000de11a, /*POKE*/ | |
103 | + 0x44e0c435, /*POKE16*/ | |
104 | + 0x44e0c47b, /*POKE32*/ | |
105 | + 0x00015928, /*POW*/ | |
106 | + 0x01dfd111, /*PRINT*/ | |
107 | + 0x000df5af, /*PSET*/ | |
108 | + 0x45858d00, /*PUBLIC*/ | |
109 | + 0x459341b1, /*PUTBMP*/ | |
110 | + 0x000f35e7, /*READ*/ | |
111 | + 0x0001625e, /*REM*/ | |
112 | + 0x4c0e4e9d, /*RETURN*/ | |
113 | + 0x000163a2, /*RND*/ | |
114 | + 0x4ff58ae0, /*SCROLL*/ | |
115 | + 0x50300d40, /*SETDIR*/ | |
116 | + 0x00016802, /*SGN*/ | |
117 | + 0x0001684c, /*SIN*/ | |
118 | + 0x0010130d, /*SINH*/ | |
119 | + 0x02338a69, /*SOUND*/ | |
120 | + 0x00103e75, /*SQRT*/ | |
121 | + 0x526b8f2e, /*SYSTEM*/ | |
122 | + 0x00016c7d, /*TAN*/ | |
123 | + 0x0010ae22, /*TANH*/ | |
124 | + 0x024b5425, /*TIMER*/ | |
125 | + 0x02557a82, /*TVRAM*/ | |
126 | + 0x026bf064, /*UNTIL*/ | |
127 | + 0x59f94768, /*USEPCG*/ | |
128 | + 0x59f9673f, /*USEVAR*/ | |
129 | + 0x0001772d, /*VAL*/ | |
130 | + 0x00017733, /*VAR*/ | |
131 | + 0x0012ff0c, /*WAIT*/ | |
132 | + 0x00131519, /*WEND*/ | |
133 | + 0x02a044ad, /*WHILE*/ | |
134 | + 0x02a0f0f8, /*WIDTH*/ | |
135 | 135 | // Additional names follow |
136 | 136 | ADDITIONAL_RESERVED_VAR_NAMES |
137 | 137 | }; |
@@ -150,16 +150,18 @@ int check_var_name(){ | ||
150 | 150 | int prevpos=g_srcpos; |
151 | 151 | next_position(); |
152 | 152 | b1=g_source[g_srcpos]; |
153 | - if (b1<'A' || 'Z'<b1) return -1; | |
153 | + // When changing here, see also get_label() | |
154 | + if ((b1<'A' || 'Z'<b1) && b1!='_') return -1; | |
154 | 155 | do { |
155 | - // First character must be A-Z | |
156 | - // From second, A-Z and 0-9 can be used. | |
157 | - i*=36; | |
156 | + // First character must be A-Z or _ | |
157 | + // From second, A-Z, _, and 0-9 can be used. | |
158 | + i*=37; | |
159 | + if (b1=='_') b1='Z'+1; | |
158 | 160 | if ('0'<=b1 && b1<='9') { |
159 | 161 | i+=b1-'0'; |
160 | 162 | } else if (g_srcpos==prevpos) { |
161 | - // First character must be A-Z. | |
162 | - // Subtract 9, resulting 1-26 but not 10-35. | |
163 | + // First character must be A-Z or _. | |
164 | + // Subtract 9, resulting 1-27 but not 10-36. | |
163 | 165 | // This subtraction is required to maintain |
164 | 166 | // final number being <0x80000000. |
165 | 167 | i+=b1-'A'+1; |
@@ -168,7 +170,7 @@ int check_var_name(){ | ||
168 | 170 | } |
169 | 171 | g_srcpos++; |
170 | 172 | b1=g_source[g_srcpos]; |
171 | - } while ('0'<= b1 && b1<='9' || 'A'<=b1 && b1<='Z'); | |
173 | + } while ('0'<= b1 && b1<='9' || 'A'<=b1 && b1<='Z' || b1=='_'); | |
172 | 174 | // Length of the label must be between 2 and 6. |
173 | 175 | if (g_srcpos-prevpos<2) { |
174 | 176 | // One letter var name, A-Z |
@@ -0,0 +1,170 @@ | ||
1 | +<クラスとオブジェクトの利用方法> | |
2 | + | |
3 | +ここでは、オブジェクト指向プログラミングについて述べます。MachiKaniaでは、クラス | |
4 | +ベースのオブジェクト指向プログラミングが可能です。次のような特徴があります。 | |
5 | + | |
6 | + 1)オブジェクトは、フィールド(public もしくは private)とメソッド(public のみ) | |
7 | + を持つ。 | |
8 | + 2)クラスの記述は別ファイルに於いて行ない、1ファイルに1クラスの記述とする。 | |
9 | + 3)複数のクラスを利用出来る。また、クラス中で別のクラスを利用出来る。 | |
10 | + 4)クラスの継承は、未実装。 | |
11 | + 5)フィールド名とメソッド名には、2文字以上6文字以内の英数字が指定出来る。 | |
12 | + | |
13 | +別ファイルとしてクラスを記述し、このファイルをクラス指定する事で、複数のファイル | |
14 | +からなるプログラムを作成する事が可能です。クラス間の接続はフィールドとメソッドを | |
15 | +介してのみ行なわれます。したがって、同じ名前の変数やラベルが複数のファイルに於い | |
16 | +て存在していたとしても、それぞれファイルごとに制御が行なわれますので、名前の衝突 | |
17 | +が起きる事はありません。 | |
18 | + | |
19 | +<クラスの記述の仕方> | |
20 | + | |
21 | +クラスを作成するには、"クラス名.BAS"の名でテキストファイルを準備します。ただし、 | |
22 | +クラス名は2文字以上6文字以内の英数字です。クラスファイルでは、FIELD, STATIC, | |
23 | +METHOD命令が必須です(どれか1種類だけでも使えます)。 | |
24 | + | |
25 | +FIELD [PUBLIC] x[,y[,z[, ... ]]] | |
26 | + クラスファイル中で、パブリックフィールドを宣言する。"PUBLIC"は省略可。 | |
27 | + x,y,z等はフィールド名を6文字以内の英数字で指定。ただし、フィールドを文字列型 | |
28 | + で使う場合は、「$」をフィールド名の後ろに付ける。 | |
29 | +FIELD PRIVATE x[,y[,z[, ... ]]] | |
30 | + クラスファイル中で、プライベートフィールドを宣言する。x,y,z等はフィールド | |
31 | + 名を6文字以内の英数字で指定。ただし、フィールドを文字列型で使う場合は「$」を | |
32 | + フィールド名の後ろに付け、配列として使う場合は「()」を付ける。 | |
33 | +STATIC [PUBLIC] x[,y[,z[, ... ]]] | |
34 | + クラスファイル中で、パブリックスなタティック変数を宣言する。"PUBLIC"は省略可。 | |
35 | +STATIC PRIVATE x[,y[,z[, ... ]]] | |
36 | + クラスファイル中で、プライベートなスタティック変数を宣言する。USEVARと同じ。 | |
37 | +METHOD x | |
38 | + クラスファイル中で、メソッドを宣言する。xは、メソッド名を6文字以内の英 | |
39 | + 数字で指定。 | |
40 | + | |
41 | +クラスファイル中でフィールド値(パブリック・プライベートの両方)にアクセスする場 | |
42 | +合は、FIELD指定した長い名前の変数に直接アクセス(読み込み及び書き込み)して下さい。 | |
43 | +「THIS」などの表記は必要ありません。 | |
44 | + | |
45 | +オブジェクトのフィールドではないスタティックな変数を扱いたい時は、STATICもしくは | |
46 | +USEVAR命令を使って下さい。ここで使用した長い名前の変数は、他のファイルでの同一名 | |
47 | +の変数の値に影響しません。ただし、変数A-Zの読み出し・変更は、他のファイルで使用 | |
48 | +する値に影響します。 | |
49 | + | |
50 | +METHOD命令で宣言されたメソッドは、すべてパブリックです。プライベートなサブルー | |
51 | +チン呼び出しには、LABEL命令とGOSUB命令/関数を用いて下さい。メソッド呼び出しの際 | |
52 | +の引数は、ARGS()関数で取り出す事が可能です。メソッド中で自身のオブジェクトへの | |
53 | +ポインターが必要な場合は、ARGS(-2)で取り出す事が出来ます。 | |
54 | + | |
55 | +コンストラクターを指定する場合は、「METHOD INIT」として下さい。このようにINIT | |
56 | +メソッドが指定された場合、オブジェクト作成時に、このメソッドが呼ばれます。INIT | |
57 | +メソッドに引数を与える事も可能です(引数は必須ではありません)。 | |
58 | + | |
59 | +クラス中でオブジェクトへのポインターが必要な場合は、ARGS(-2)で取り出す事が出来 | |
60 | +ます。 | |
61 | + | |
62 | +記述例(CLASS1.BASの名前で保存): | |
63 | + FIELD PUBLIC TEST1,TEST2 | |
64 | + FIELD PRIVATE TEST3 | |
65 | + STATIC PUBLIC TEST7 | |
66 | + METHOD INIT | |
67 | + IF ARGS(0)=2 THEN | |
68 | + TEST1=ARGS(1) | |
69 | + TEST2=ARGS(2) | |
70 | + ENDIF | |
71 | + RETURN | |
72 | + METHOD TEST4 | |
73 | + TEST1=ARGS(1) | |
74 | + TEST2=ARGS(2) | |
75 | + RETURN | |
76 | + METHOD TEST5 | |
77 | + TEST3=TEST1+TEST2+TEST7 | |
78 | + RETURN | |
79 | + METHOD TEST6 | |
80 | + RETURN TEST3 | |
81 | + METHOD TEST8 | |
82 | + RETURN TEST7 | |
83 | + | |
84 | +<オブジェクトの作成方法> | |
85 | + | |
86 | +オブジェクトを作成するためには、まずUSECLASS命令で使用するクラスを指定し、次に | |
87 | +NEW関数を用います。 | |
88 | + | |
89 | +USECLASS x[,y[,z[, ... ]]] | |
90 | + クラスの利用を宣言する。x,y,z等は、クラス名を6文字以内の英数字で指定。 | |
91 | +NEW(x[,y[,z[, ... ]]]) | |
92 | + クラスオブジェクトを作成し、オブジェクトへのポインターを返す。xはクラス名 | |
93 | + を指定。y,z等はコンストラクターがある際に利用される引数。 | |
94 | + | |
95 | +記述例1: | |
96 | + USECLASS CLASS1 | |
97 | + A=NEW(CLASS1) | |
98 | + | |
99 | +記述例2(コンストラクターに引数を指定する場合): | |
100 | + USECLASS CLASS1 | |
101 | + A=NEW(CLASS1,123,456) | |
102 | + | |
103 | +<オブジェクトの破棄方法> | |
104 | + | |
105 | +作成したオブジェクトは、DELETE命令を用いて破棄する事も出来ます。ただし、デストラ | |
106 | +クターは実装していませんので、必要ならば、それ用のメソッドを作成して破棄する直前に | |
107 | +呼び出して下さい。 | |
108 | + | |
109 | +オブジェクトのフィールドに文字列もしくは配列を用いている場合、オブジェクトを | |
110 | +DELETEするだけではこれらの領域は破棄されません。その場合、まずメソッド内でこれら | |
111 | +のフィールドを破棄(DELETE命令が使えます)してから、オブジェクトを破棄するようにし | |
112 | +て下さい。 | |
113 | + | |
114 | +記述例: | |
115 | + USECLASS CLASS1 | |
116 | + A=NEW(CLASS1) | |
117 | + DELETE A | |
118 | + | |
119 | +<フィールドへのアクセス方法> | |
120 | + | |
121 | +パブリックフィールドへアクセスする場合は、オブジェクトを含む変数に続けて「.」と | |
122 | +フィールド名を記述して下さい。フィールドが文字列の場合は「$」を、実数の場合は | |
123 | +「#」を、それぞれ後ろに付けて下さい。 | |
124 | + | |
125 | +記述例: | |
126 | + USECLASS CLASS1 | |
127 | + A=NEW(CLASS1) | |
128 | + A.TEST1=123 | |
129 | + PRINT A.TEST2 | |
130 | + | |
131 | +<メソッドへのアクセス方法> | |
132 | + | |
133 | +パブリックメソッドへアクセスする場合は、オブジェクトを含む変数に続けて「.」と | |
134 | +メソッド名、続けて「( )」を記述して下さい。メソッドが戻り値として文字列を返す場 | |
135 | +合、メソッド名の後ろに「$」を付けて下さい(実数の場合は「#」)。メソッドは関数 | |
136 | +と同じ扱いですが、戻り値を利用しない場合は、CALL命令により呼び出す事も出来ます。 | |
137 | + | |
138 | +CALL x | |
139 | + xで指定されたオブジェクトのメソッドを呼び出す。 | |
140 | + | |
141 | +記述例(579が表示される): | |
142 | + USECLASS CLASS1 | |
143 | + A=NEW(CLASS1) | |
144 | + CALL A.TEST4(123,456) | |
145 | + CALL A.TEST5() | |
146 | + PRINT A.TEST6() | |
147 | + | |
148 | +<スタティック変数・スタティックメソッドの利用> | |
149 | + | |
150 | +クラス中で"STATIC PUBLIC"で指定された変数は、外部から値を参照したり、値を変更 | |
151 | +したりすることが出来ます。この場合、クラス名に続けて「::」と変数名を記述して下 | |
152 | +さい。 | |
153 | + | |
154 | +また、それぞれのメソッドは、スタティックメソッドとして利用する事も出来ます。こ | |
155 | +の場合、クラス名に続けて「::」とメソッド名、続けて「( )」を記述して下さい。 | |
156 | + | |
157 | +記述例(123が表示される): | |
158 | + USECLASS CLASS1 | |
159 | + CLASS1::TEST6=123 | |
160 | + PRINT CLASS1::TEST7() | |
161 | + | |
162 | +<ライブラリーについて> | |
163 | + | |
164 | +クラスファイルは、カレントディレクトリーに「クラス名.BAS」ファイルが有れば、読み | |
165 | +出されます。もしカレントディレクトリーに無ければ、「\LIB\クラス名\クラス名.BAS」 | |
166 | +を探し、有ればそれが読み出されます。従って、「\LIB」ディレクトリーにクラス群を | |
167 | +配置しておけば、いつでも使用可能なライブラリーとして使えます。 | |
168 | + | |
169 | +<バージョン履歴> | |
170 | +・KM-1207/KM1302 2019年3月公開。 |
@@ -519,5 +519,9 @@ extern int g_int_vector[]; | ||
519 | 519 | #define div36_32(x) div32(x,0xe38e38e4,37) |
520 | 520 | #define rem36_32(x) (x-36*div36_32(x)) |
521 | 521 | |
522 | +// Divide by 37 (valid for 31 bits) | |
523 | +#define div37_31(x) div32(x,0xdd67c8a7,37) | |
524 | +#define rem37_31(x) (x-37*div37_31(x)) | |
525 | + | |
522 | 526 | // Check if within RAM |
523 | 527 | #define withinRAM(x) ((&RAM[0])<=((char*)(x)) && ((char*)(x))<(&RAM[RAMSIZE])) |
@@ -228,14 +228,11 @@ static const char initext[]= | ||
228 | 228 | "#PRINT\n"; |
229 | 229 | |
230 | 230 | static const char bastext[]= |
231 | -"I=1:WHILE I<=10\n" | |
232 | -"I=I+1:WEND\n" | |
231 | +"CLS\n" | |
232 | +"LABEL TEST_:i=0/0\n" | |
233 | +"\n" | |
233 | 234 | "\n" |
234 | -"I=1:DO\n" | |
235 | -"I=I+1:LOOP UNTIL I=11\n" | |
236 | 235 | "\n" |
237 | -"FOR I=1 TO 10\n" | |
238 | -"NEXT\n" | |
239 | 236 | "\n" |
240 | 237 | "\n" |
241 | 238 | "\n"; |
@@ -62,15 +62,16 @@ char* resolve_label(int s6){ | ||
62 | 62 | s6-=65536; |
63 | 63 | str[6]=0x00; |
64 | 64 | for(i=5;0<=i;i--){ |
65 | - if (s6<36) { | |
66 | - // First character must be A-Z, corresponding to 1-26 but not 10-35. | |
65 | + if (s6<37) { | |
66 | + // First character must be A-Z or _, corresponding to 1-27 but not 10-36. | |
67 | 67 | // See get_label() for the detail. |
68 | - str[i]=s6-1+'A'; | |
68 | + if (s6==27) str[i]='_'; | |
69 | + else str[i]=s6-1+'A'; | |
69 | 70 | break; |
70 | 71 | } else { |
71 | - // From second, 0-9 corresponds to 0-9 and A-Z corresponds to 10-35. | |
72 | - str[i]="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"[rem36_32(s6)]; | |
73 | - s6=div36_32(s6); | |
72 | + // From second, 0-9 corresponds to 0-9 and A-Z corresponds to 10-36. | |
73 | + str[i]="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_"[rem37_31(s6)]; | |
74 | + s6=div37_31(s6); | |
74 | 75 | } |
75 | 76 | } |
76 | 77 | return (char*)(str+i); |
@@ -26,10 +26,10 @@ | ||
26 | 26 | #define KEYRIGHT 0x0010 |
27 | 27 | #define KEYUP 0x0020 |
28 | 28 | #else |
29 | - #define KEYLEFT 0x0004 | |
30 | - #define KEYUP 0x0008 | |
31 | - #define KEYDOWN 0x0010 | |
32 | - #define KEYRIGHT 0x0020 | |
29 | + #define KEYRIGHT 0x0004 | |
30 | + #define KEYDOWN 0x0008 | |
31 | + #define KEYUP 0x0010 | |
32 | + #define KEYLEFT 0x0020 | |
33 | 33 | #endif |
34 | 34 | #define KEYSTART 0x0080 |
35 | 35 | #define KEYFIRE 0x0100 |
@@ -44,17 +44,19 @@ char* get_label(void){ | ||
44 | 44 | g_label=0; |
45 | 45 | return 0; |
46 | 46 | } |
47 | - } else if ('A'<=b1 && b1<='Z') { | |
47 | + } else if ('A'<=b1 && b1<='Z' || b1=='_') { | |
48 | 48 | // May be label |
49 | + // When changing here, see also chech_var_name() | |
49 | 50 | do { |
50 | - // First character must be A-Z | |
51 | - // From second, A-Z and 0-9 can be used. | |
52 | - i*=36; | |
51 | + // First character must be A-Z or _ | |
52 | + // From second, A-Z, _, and 0-9 can be used. | |
53 | + i*=37; | |
54 | + if (b1=='_') b1='Z'+1; | |
53 | 55 | if ('0'<=b1 && b1<='9') { |
54 | 56 | i+=b1-'0'; |
55 | 57 | } else if (g_srcpos==prevpos) { |
56 | - // First character must be A-Z. | |
57 | - // Subtract 9, resulting 1-26 but not 10-35. | |
58 | + // First character must be A-Z or _. | |
59 | + // Subtract 9, resulting in 1-27 but not 10-36. | |
58 | 60 | // This subtraction is required to maintain |
59 | 61 | // final number being <0x80000000. |
60 | 62 | i+=b1-'A'+1; |
@@ -63,7 +65,7 @@ char* get_label(void){ | ||
63 | 65 | } |
64 | 66 | g_srcpos++; |
65 | 67 | b1=g_source[g_srcpos]; |
66 | - } while ('0'<= b1 && b1<='9' || 'A'<=b1 && b1<='Z'); | |
68 | + } while ('0'<= b1 && b1<='9' || 'A'<=b1 && b1<='Z' || b1=='_'); | |
67 | 69 | // Length of the label must be between 2 and 6. |
68 | 70 | if (g_srcpos-prevpos<2 || 6<g_srcpos-prevpos) { |
69 | 71 | g_srcpos=prevpos; |
@@ -16,14 +16,15 @@ function name2int(name){ | ||
16 | 16 | var i=0; |
17 | 17 | var b1=g_source.charCodeAt(0); |
18 | 18 | do { |
19 | - // First character must be A-Z | |
20 | - // From second, A-Z and 0-9 can be used. | |
21 | - i*=36; | |
19 | + // First character must be A-Z or _ | |
20 | + // From second, A-Z, _, and 0-9 can be used. | |
21 | + i*=37; | |
22 | + if (b1=='_'.charCodeAt(0)) b1='Z'.charCodeAt(0)+1; | |
22 | 23 | if ('0'.charCodeAt(0)<=b1 && b1<='9'.charCodeAt(0)) { |
23 | 24 | i+=b1-'0'.charCodeAt(0); |
24 | 25 | } else if (g_srcpos==prevpos) { |
25 | - // First character must be A-Z. | |
26 | - // Subtract 9, resulting 1-26 but not 10-35. | |
26 | + // First character must be A-Z or _. | |
27 | + // Subtract 9, resulting in 1-27 but not 10-36. | |
27 | 28 | // This subtraction is required to maintain |
28 | 29 | // final number being <0x80000000. |
29 | 30 | i+=b1-'A'.charCodeAt(0)+1; |
@@ -32,10 +33,58 @@ function name2int(name){ | ||
32 | 33 | } |
33 | 34 | g_srcpos++; |
34 | 35 | b1=g_source.charCodeAt(g_srcpos); |
35 | - } while ('0'.charCodeAt(0)<= b1 && b1<='9'.charCodeAt(0) || 'A'.charCodeAt(0)<=b1 && b1<='Z'.charCodeAt(0)); | |
36 | + } while ('0'.charCodeAt(0)<= b1 && b1<='9'.charCodeAt(0) || b1=='_'.charCodeAt(0) || | |
37 | + 'A'.charCodeAt(0)<=b1 && b1<='Z'.charCodeAt(0)); | |
36 | 38 | return i+65536; |
37 | 39 | } |
38 | 40 | |
41 | +function int2name(s6){ | |
42 | + var rem37_31=function(s6){ | |
43 | + return s6 % 37; | |
44 | + }; | |
45 | + var div37_31=function(s6){ | |
46 | + return (s6-(s6 % 37))/37; | |
47 | + }; | |
48 | + var str=new Array(); | |
49 | + var i,res; | |
50 | + s6-=65536; | |
51 | + str[6]=0; | |
52 | + for(i=5;0<=i;i--){ | |
53 | + if (s6<37) { | |
54 | + // First character must be A-Z or _, corresponding to 1-27 but not 10-36. | |
55 | + // See get_label() for the detail. | |
56 | + if (s6==27) str[i]='_'.charCodeAt(0); | |
57 | + else str[i]=s6-1+'A'.charCodeAt(0); | |
58 | + break; | |
59 | + } else { | |
60 | + // From second, 0-9 corresponds to 0-9 and A-Z corresponds to 10-36. | |
61 | + str[i]="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_".charCodeAt(rem37_31(s6)); | |
62 | + s6=div37_31(s6); | |
63 | + } | |
64 | + } | |
65 | + //return (char*)(str+i); | |
66 | + for(res='';str[i];i++) { | |
67 | + res+=String.fromCharCode(str[i]); | |
68 | + } | |
69 | + return res; | |
70 | +} | |
71 | + | |
72 | +// Show max number by this system. | |
73 | +//WScript.Echo(name2int('______').toString(16)); | |
74 | + | |
75 | +// Test functions for 10000 times with randomized var names | |
76 | +for(i=0;i<10000;i++){ | |
77 | + t="ABCDEFGHIJKLMNOPQRSTUVWXYZ_".charAt(Math.random()*27); | |
78 | + for(j=0;j<1+Math.random()*4;j++){ | |
79 | + t+="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_".charAt(Math.random()*37); | |
80 | + } | |
81 | + j=name2int(t); | |
82 | + if (int2name(j)!=t || j<0 || 0x7fffffff<j) { | |
83 | + WScript.Echo('ERROR: '+t+' ('+j+'; 0x'+j.toString(16)+') '+i); | |
84 | + WScript.Quit(); | |
85 | + } | |
86 | +} | |
87 | + | |
39 | 88 | var namearray=[ |
40 | 89 | 'ABS', |
41 | 90 | 'ACOS', |
@@ -168,14 +217,16 @@ var namearray=[ | ||
168 | 217 | 'I2C', |
169 | 218 | ]; |
170 | 219 | var result=''; |
220 | +var commented=0; | |
171 | 221 | for(key in namearray){ |
172 | 222 | var nameint='0000'+name2int(namearray[key]).toString(16); |
173 | 223 | nameint=nameint.substr(nameint.length-8); |
174 | 224 | if (namearray[key].substr(0,2)=='//') { |
175 | 225 | // This is a comment |
176 | 226 | result+=namearray[key]+"\r\n"; |
227 | + commented=1; | |
177 | 228 | } else { |
178 | - result+="\t0x"+nameint+", /*"+namearray[key]+"*/\r\n"; | |
229 | + result+="\t0x"+nameint+", /*"+namearray[key]+"*/"+(commented ? " \\\r\n" : "\r\n"); | |
179 | 230 | } |
180 | 231 | } |
181 | 232 |
@@ -313,7 +313,7 @@ char* label_statement(){ | ||
313 | 313 | char* err; |
314 | 314 | char b1; |
315 | 315 | b1=g_source[g_srcpos]; |
316 | - if (b1<'A' || 'Z'<b1) return ERR_SYNTAX; // Number is not allowed here. | |
316 | + if ('0'<=b1 && b1<='9') return ERR_SYNTAX; // Number is not allowed here. | |
317 | 317 | err=get_label(); |
318 | 318 | if (err) return err; |
319 | 319 | // Check existing label with the same name here. |
@@ -18,120 +18,120 @@ | ||
18 | 18 | */ |
19 | 19 | |
20 | 20 | static const int reserved_var_names[]={ |
21 | - 0x000106b8, /*ABS*/ | |
22 | - 0x0001f67c, /*ACOS*/ | |
23 | - 0x0002414c, /*ARGS*/ | |
24 | - 0x0001090c, /*ASC*/ | |
25 | - 0x0002469f, /*ASIN*/ | |
26 | - 0x00024a8f, /*ATAN*/ | |
27 | - 0x002f7c1e, /*ATAN2*/ | |
28 | - 0x0047c31c, /*BREAK*/ | |
29 | - 0x00035869, /*CALL*/ | |
30 | - 0x00575afe, /*CDATA*/ | |
31 | - 0x00036c3d, /*CEIL*/ | |
32 | - 0x000111af, /*CHR*/ | |
33 | - 0x0cb1b682, /*CIRCLE*/ | |
34 | - 0x005d1ea3, /*CLEAR*/ | |
35 | - 0x00011240, /*CLS*/ | |
36 | - 0x005f66cb, /*COLOR*/ | |
37 | - 0x000112ac, /*COS*/ | |
38 | - 0x0003a041, /*COSH*/ | |
39 | - 0x00616415, /*CREAD*/ | |
40 | - 0x0de593fb, /*CURSOR*/ | |
41 | - 0x00040fbe, /*DATA*/ | |
42 | - 0x00011644, /*DEC*/ | |
43 | - 0x0fe19c42, /*DELETE*/ | |
44 | - 0x000116de, /*DIM*/ | |
45 | - 0x000100a8, /*DO*/ | |
46 | - 0x0004fd8e, /*ELSE*/ | |
47 | - 0x1434a177, /*ELSEIF*/ | |
48 | - 0x00011c99, /*END*/ | |
49 | - 0x0091c927, /*ENDIF*/ | |
50 | - 0x00053854, /*EXEC*/ | |
51 | - 0x00011e0d, /*EXP*/ | |
52 | - 0x000579c8, /*FABS*/ | |
53 | - 0x16e3d4be, /*FCLOSE*/ | |
54 | - 0x00058fcf, /*FEOF*/ | |
55 | - 0x00059895, /*FGET*/ | |
56 | - 0x00a67500, /*FGETC*/ | |
57 | - 0x00a7e061, /*FIELD*/ | |
58 | - 0x0005a3a2, /*FILE*/ | |
59 | - 0x177f0ca5, /*FINPUT*/ | |
60 | - 0x0005b1df, /*FLEN*/ | |
61 | - 0x00aa3445, /*FLOAT*/ | |
62 | - 0x00aa363b, /*FLOOR*/ | |
63 | - 0x0005b84d, /*FMOD*/ | |
64 | - 0x00ac5c9f, /*FOPEN*/ | |
65 | - 0x000121db, /*FOR*/ | |
66 | - 0x18352839, /*FPRINT*/ | |
67 | - 0x0005c865, /*FPUT*/ | |
68 | - 0x00ad2e40, /*FPUTC*/ | |
69 | - 0x00aefdec, /*FSEEK*/ | |
70 | - 0x00063b90, /*GCLS*/ | |
71 | - 0x1a808bcb, /*GCOLOR*/ | |
72 | - 0x1ab733b3, /*GETDIR*/ | |
73 | - 0x00c60f03, /*GOSUB*/ | |
74 | - 0x0006796c, /*GOTO*/ | |
75 | - 0x1bcfcc39, /*GPRINT*/ | |
76 | - 0x00012a99, /*HEX*/ | |
77 | - 0x0007ad12, /*IDLE*/ | |
78 | - 0x00010153, /*IF*/ | |
79 | - 0x00f8701a, /*INKEY*/ | |
80 | - 0x00f88ba5, /*INPUT*/ | |
81 | - 0x000130e9, /*INT*/ | |
82 | - 0x00092084, /*KEYS*/ | |
83 | - 0x013be43d, /*LABEL*/ | |
84 | - 0x00013ecf, /*LEN*/ | |
85 | - 0x00013ed5, /*LET*/ | |
86 | - 0x0009e96a, /*LINE*/ | |
87 | - 0x00014030, /*LOG*/ | |
88 | - 0x0145f324, /*LOG10*/ | |
89 | - 0x000a07f9, /*LOOP*/ | |
90 | - 0x000abca3, /*MODF*/ | |
91 | - 0x016418d4, /*MUSIC*/ | |
92 | - 0x000b4321, /*NEXT*/ | |
93 | - 0x000148f8, /*NEW*/ | |
94 | - 0x00014a5d, /*NOT*/ | |
95 | - 0x38a658d7, /*OPTION*/ | |
96 | - 0x000152c0, /*PCG*/ | |
97 | - 0x000cacec, /*PEEK*/ | |
98 | - 0x3b1c6aea, /*PEEK16*/ | |
99 | - 0x3b1c6b2e, /*PEEK32*/ | |
100 | - 0x00010252, /*PI*/ | |
101 | - 0x01ac8479, /*POINT*/ | |
102 | - 0x000ce05e, /*POKE*/ | |
103 | - 0x3c20dc0a, /*POKE16*/ | |
104 | - 0x3c20dc4e, /*POKE32*/ | |
105 | - 0x00015480, /*POW*/ | |
106 | - 0x01aea739, /*PRINT*/ | |
107 | - 0x000cf3d5, /*PSET*/ | |
108 | - 0x3cb45fa4, /*PUBLIC*/ | |
109 | - 0x3cc0fe21, /*PUTBMP*/ | |
110 | - 0x000e18d5, /*READ*/ | |
111 | - 0x00015d2e, /*REM*/ | |
112 | - 0x425c9703, /*RETURN*/ | |
113 | - 0x00015e69, /*RND*/ | |
114 | - 0x45c26d49, /*SCROLL*/ | |
115 | - 0x45f6e3b3, /*SETDIR*/ | |
116 | - 0x00016287, /*SGN*/ | |
117 | - 0x000162cf, /*SIN*/ | |
118 | - 0x000ee52d, /*SINH*/ | |
119 | - 0x01f9a429, /*SOUND*/ | |
120 | - 0x000f0e49, /*SQRT*/ | |
121 | - 0x47f711de, /*SYSTEM*/ | |
122 | - 0x000166bf, /*TAN*/ | |
123 | - 0x000f72ed, /*TANH*/ | |
124 | - 0x020ed5f3, /*TIMER*/ | |
125 | - 0x02182fee, /*TVRAM*/ | |
126 | - 0x022c2a2d, /*UNTIL*/ | |
127 | - 0x4e8887d0, /*USEPCG*/ | |
128 | - 0x4e88a5f3, /*USEVAR*/ | |
129 | - 0x000170dd, /*VAL*/ | |
130 | - 0x000170e3, /*VAR*/ | |
131 | - 0x00119505, /*WAIT*/ | |
132 | - 0x0011a9e9, /*WEND*/ | |
133 | - 0x025aef62, /*WHILE*/ | |
134 | - 0x025b8d75, /*WIDTH*/ | |
21 | + 0x0001070c, /*ABS*/ | |
22 | + 0x0002099d, /*ACOS*/ | |
23 | + 0x000258ac, /*ARGS*/ | |
24 | + 0x00010971, /*ASC*/ | |
25 | + 0x00025e4a, /*ASIN*/ | |
26 | + 0x0002627b, /*ATAN*/ | |
27 | + 0x00343bc9, /*ATAN2*/ | |
28 | + 0x004f5c95, /*BREAK*/ | |
29 | + 0x00038a2f, /*CALL*/ | |
30 | + 0x006110c1, /*CDATA*/ | |
31 | + 0x00039f24, /*CEIL*/ | |
32 | + 0x0001129b, /*CHR*/ | |
33 | + 0x0e7f3303, /*CIRCLE*/ | |
34 | + 0x0067525f, /*CLEAR*/ | |
35 | + 0x00011330, /*CLS*/ | |
36 | + 0x0069cb6b, /*COLOR*/ | |
37 | + 0x0001139f, /*COS*/ | |
38 | + 0x0003d60c, /*COSH*/ | |
39 | + 0x006bf57f, /*CREAD*/ | |
40 | + 0x0fd6b45b, /*CURSOR*/ | |
41 | + 0x00045129, /*DATA*/ | |
42 | + 0x00011776, /*DEC*/ | |
43 | + 0x122a52c0, /*DELETE*/ | |
44 | + 0x00011814, /*DIM*/ | |
45 | + 0x000100ac, /*DO*/ | |
46 | + 0x000551b8, /*ELSE*/ | |
47 | + 0x171a03a1, /*ELSEIF*/ | |
48 | + 0x00011e1d, /*END*/ | |
49 | + 0x00a20bbe, /*ENDIF*/ | |
50 | + 0x00058fdc, /*EXEC*/ | |
51 | + 0x00011f9b, /*EXP*/ | |
52 | + 0x0005da5b, /*FABS*/ | |
53 | + 0x1a358bdd, /*FCLOSE*/ | |
54 | + 0x0005f193, /*FEOF*/ | |
55 | + 0x0005fae1, /*FGET*/ | |
56 | + 0x00b94291, /*FGETC*/ | |
57 | + 0x00bacd24, /*FIELD*/ | |
58 | + 0x00060687, /*FILE*/ | |
59 | + 0x1ae2b2ef, /*FINPUT*/ | |
60 | + 0x00061598, /*FLEN*/ | |
61 | + 0x00bd52ae, /*FLOAT*/ | |
62 | + 0x00bd54b2, /*FLOOR*/ | |
63 | + 0x00061c59, /*FMOD*/ | |
64 | + 0x00bfaa2c, /*FOPEN*/ | |
65 | + 0x000123a9, /*FOR*/ | |
66 | + 0x1badd288, /*FPRINT*/ | |
67 | + 0x00062d52, /*FPUT*/ | |
68 | + 0x00c08ce6, /*FPUTC*/ | |
69 | + 0x00c286ca, /*FSEEK*/ | |
70 | + 0x0006ac5c, /*GCLS*/ | |
71 | + 0x1e59e7b7, /*GCOLOR*/ | |
72 | + 0x1e96cb44, /*GETDIR*/ | |
73 | + 0x00dc556c, /*GOSUB*/ | |
74 | + 0x0006edac, /*GOTO*/ | |
75 | + 0x1fcfed5d, /*GPRINT*/ | |
76 | + 0x00012cef, /*HEX*/ | |
77 | + 0x00083d61, /*IDLE*/ | |
78 | + 0x0001015c, /*IF*/ | |
79 | + 0x01149470, /*INKEY*/ | |
80 | + 0x0114b178, /*INPUT*/ | |
81 | + 0x00013391, /*INT*/ | |
82 | + 0x0009d063, /*KEYS*/ | |
83 | + 0x016022dc, /*LABEL*/ | |
84 | + 0x00014249, /*LEN*/ | |
85 | + 0x0001424f, /*LET*/ | |
86 | + 0x000aa9ff, /*LINE*/ | |
87 | + 0x000143b4, /*LOG*/ | |
88 | + 0x016b0db9, /*LOG10*/ | |
89 | + 0x000aca45, /*LOOP*/ | |
90 | + 0x000b8e81, /*MODF*/ | |
91 | + 0x018c8c85, /*MUSIC*/ | |
92 | + 0x000c21d6, /*NEXT*/ | |
93 | + 0x00014d04, /*NEW*/ | |
94 | + 0x00014e73, /*NOT*/ | |
95 | + 0x40e24fde, /*OPTION*/ | |
96 | + 0x0001575c, /*PCG*/ | |
97 | + 0x000daac8, /*PEEK*/ | |
98 | + 0x43be47b3, /*PEEK16*/ | |
99 | + 0x43be47f9, /*PEEK32*/ | |
100 | + 0x00010262, /*PI*/ | |
101 | + 0x01dd7f7a, /*POINT*/ | |
102 | + 0x000de11a, /*POKE*/ | |
103 | + 0x44e0c435, /*POKE16*/ | |
104 | + 0x44e0c47b, /*POKE32*/ | |
105 | + 0x00015928, /*POW*/ | |
106 | + 0x01dfd111, /*PRINT*/ | |
107 | + 0x000df5af, /*PSET*/ | |
108 | + 0x45858d00, /*PUBLIC*/ | |
109 | + 0x459341b1, /*PUTBMP*/ | |
110 | + 0x000f35e7, /*READ*/ | |
111 | + 0x0001625e, /*REM*/ | |
112 | + 0x4c0e4e9d, /*RETURN*/ | |
113 | + 0x000163a2, /*RND*/ | |
114 | + 0x4ff58ae0, /*SCROLL*/ | |
115 | + 0x50300d40, /*SETDIR*/ | |
116 | + 0x00016802, /*SGN*/ | |
117 | + 0x0001684c, /*SIN*/ | |
118 | + 0x0010130d, /*SINH*/ | |
119 | + 0x02338a69, /*SOUND*/ | |
120 | + 0x00103e75, /*SQRT*/ | |
121 | + 0x526b8f2e, /*SYSTEM*/ | |
122 | + 0x00016c7d, /*TAN*/ | |
123 | + 0x0010ae22, /*TANH*/ | |
124 | + 0x024b5425, /*TIMER*/ | |
125 | + 0x02557a82, /*TVRAM*/ | |
126 | + 0x026bf064, /*UNTIL*/ | |
127 | + 0x59f94768, /*USEPCG*/ | |
128 | + 0x59f9673f, /*USEVAR*/ | |
129 | + 0x0001772d, /*VAL*/ | |
130 | + 0x00017733, /*VAR*/ | |
131 | + 0x0012ff0c, /*WAIT*/ | |
132 | + 0x00131519, /*WEND*/ | |
133 | + 0x02a044ad, /*WHILE*/ | |
134 | + 0x02a0f0f8, /*WIDTH*/ | |
135 | 135 | // Additional names follow |
136 | 136 | ADDITIONAL_RESERVED_VAR_NAMES |
137 | 137 | }; |
@@ -150,16 +150,18 @@ int check_var_name(){ | ||
150 | 150 | int prevpos=g_srcpos; |
151 | 151 | next_position(); |
152 | 152 | b1=g_source[g_srcpos]; |
153 | - if (b1<'A' || 'Z'<b1) return -1; | |
153 | + // When changing here, see also get_label() | |
154 | + if ((b1<'A' || 'Z'<b1) && b1!='_') return -1; | |
154 | 155 | do { |
155 | - // First character must be A-Z | |
156 | - // From second, A-Z and 0-9 can be used. | |
157 | - i*=36; | |
156 | + // First character must be A-Z or _ | |
157 | + // From second, A-Z, _, and 0-9 can be used. | |
158 | + i*=37; | |
159 | + if (b1=='_') b1='Z'+1; | |
158 | 160 | if ('0'<=b1 && b1<='9') { |
159 | 161 | i+=b1-'0'; |
160 | 162 | } else if (g_srcpos==prevpos) { |
161 | - // First character must be A-Z. | |
162 | - // Subtract 9, resulting 1-26 but not 10-35. | |
163 | + // First character must be A-Z or _. | |
164 | + // Subtract 9, resulting 1-27 but not 10-36. | |
163 | 165 | // This subtraction is required to maintain |
164 | 166 | // final number being <0x80000000. |
165 | 167 | i+=b1-'A'+1; |
@@ -168,7 +170,7 @@ int check_var_name(){ | ||
168 | 170 | } |
169 | 171 | g_srcpos++; |
170 | 172 | b1=g_source[g_srcpos]; |
171 | - } while ('0'<= b1 && b1<='9' || 'A'<=b1 && b1<='Z'); | |
173 | + } while ('0'<= b1 && b1<='9' || 'A'<=b1 && b1<='Z' || b1=='_'); | |
172 | 174 | // Length of the label must be between 2 and 6. |
173 | 175 | if (g_srcpos-prevpos<2) { |
174 | 176 | // One letter var name, A-Z |
@@ -519,5 +519,9 @@ extern int g_int_vector[]; | ||
519 | 519 | #define div36_32(x) div32(x,0xe38e38e4,37) |
520 | 520 | #define rem36_32(x) (x-36*div36_32(x)) |
521 | 521 | |
522 | +// Divide by 37 (valid for 31 bits) | |
523 | +#define div37_31(x) div32(x,0xdd67c8a7,37) | |
524 | +#define rem37_31(x) (x-37*div37_31(x)) | |
525 | + | |
522 | 526 | // Check if within RAM |
523 | 527 | #define withinRAM(x) ((&RAM[0])<=((char*)(x)) && ((char*)(x))<(&RAM[RAMSIZE])) |
@@ -228,14 +228,11 @@ static const char initext[]= | ||
228 | 228 | "#PRINT\n"; |
229 | 229 | |
230 | 230 | static const char bastext[]= |
231 | -"I=1:WHILE I<=10\n" | |
232 | -"I=I+1:WEND\n" | |
231 | +"CLS\n" | |
232 | +"LABEL TEST_:i=0/0\n" | |
233 | +"\n" | |
233 | 234 | "\n" |
234 | -"I=1:DO\n" | |
235 | -"I=I+1:LOOP UNTIL I=11\n" | |
236 | 235 | "\n" |
237 | -"FOR I=1 TO 10\n" | |
238 | -"NEXT\n" | |
239 | 236 | "\n" |
240 | 237 | "\n" |
241 | 238 | "\n"; |
@@ -62,15 +62,16 @@ char* resolve_label(int s6){ | ||
62 | 62 | s6-=65536; |
63 | 63 | str[6]=0x00; |
64 | 64 | for(i=5;0<=i;i--){ |
65 | - if (s6<36) { | |
66 | - // First character must be A-Z, corresponding to 1-26 but not 10-35. | |
65 | + if (s6<37) { | |
66 | + // First character must be A-Z or _, corresponding to 1-27 but not 10-36. | |
67 | 67 | // See get_label() for the detail. |
68 | - str[i]=s6-1+'A'; | |
68 | + if (s6==27) str[i]='_'; | |
69 | + else str[i]=s6-1+'A'; | |
69 | 70 | break; |
70 | 71 | } else { |
71 | - // From second, 0-9 corresponds to 0-9 and A-Z corresponds to 10-35. | |
72 | - str[i]="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"[rem36_32(s6)]; | |
73 | - s6=div36_32(s6); | |
72 | + // From second, 0-9 corresponds to 0-9 and A-Z corresponds to 10-36. | |
73 | + str[i]="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_"[rem37_31(s6)]; | |
74 | + s6=div37_31(s6); | |
74 | 75 | } |
75 | 76 | } |
76 | 77 | return (char*)(str+i); |
@@ -44,17 +44,19 @@ char* get_label(void){ | ||
44 | 44 | g_label=0; |
45 | 45 | return 0; |
46 | 46 | } |
47 | - } else if ('A'<=b1 && b1<='Z') { | |
47 | + } else if ('A'<=b1 && b1<='Z' || b1=='_') { | |
48 | 48 | // May be label |
49 | + // When changing here, see also chech_var_name() | |
49 | 50 | do { |
50 | - // First character must be A-Z | |
51 | - // From second, A-Z and 0-9 can be used. | |
52 | - i*=36; | |
51 | + // First character must be A-Z or _ | |
52 | + // From second, A-Z, _, and 0-9 can be used. | |
53 | + i*=37; | |
54 | + if (b1=='_') b1='Z'+1; | |
53 | 55 | if ('0'<=b1 && b1<='9') { |
54 | 56 | i+=b1-'0'; |
55 | 57 | } else if (g_srcpos==prevpos) { |
56 | - // First character must be A-Z. | |
57 | - // Subtract 9, resulting 1-26 but not 10-35. | |
58 | + // First character must be A-Z or _. | |
59 | + // Subtract 9, resulting in 1-27 but not 10-36. | |
58 | 60 | // This subtraction is required to maintain |
59 | 61 | // final number being <0x80000000. |
60 | 62 | i+=b1-'A'+1; |
@@ -63,7 +65,7 @@ char* get_label(void){ | ||
63 | 65 | } |
64 | 66 | g_srcpos++; |
65 | 67 | b1=g_source[g_srcpos]; |
66 | - } while ('0'<= b1 && b1<='9' || 'A'<=b1 && b1<='Z'); | |
68 | + } while ('0'<= b1 && b1<='9' || 'A'<=b1 && b1<='Z' || b1=='_'); | |
67 | 69 | // Length of the label must be between 2 and 6. |
68 | 70 | if (g_srcpos-prevpos<2 || 6<g_srcpos-prevpos) { |
69 | 71 | g_srcpos=prevpos; |
@@ -16,14 +16,15 @@ function name2int(name){ | ||
16 | 16 | var i=0; |
17 | 17 | var b1=g_source.charCodeAt(0); |
18 | 18 | do { |
19 | - // First character must be A-Z | |
20 | - // From second, A-Z and 0-9 can be used. | |
21 | - i*=36; | |
19 | + // First character must be A-Z or _ | |
20 | + // From second, A-Z, _, and 0-9 can be used. | |
21 | + i*=37; | |
22 | + if (b1=='_'.charCodeAt(0)) b1='Z'.charCodeAt(0)+1; | |
22 | 23 | if ('0'.charCodeAt(0)<=b1 && b1<='9'.charCodeAt(0)) { |
23 | 24 | i+=b1-'0'.charCodeAt(0); |
24 | 25 | } else if (g_srcpos==prevpos) { |
25 | - // First character must be A-Z. | |
26 | - // Subtract 9, resulting 1-26 but not 10-35. | |
26 | + // First character must be A-Z or _. | |
27 | + // Subtract 9, resulting in 1-27 but not 10-36. | |
27 | 28 | // This subtraction is required to maintain |
28 | 29 | // final number being <0x80000000. |
29 | 30 | i+=b1-'A'.charCodeAt(0)+1; |
@@ -32,10 +33,58 @@ function name2int(name){ | ||
32 | 33 | } |
33 | 34 | g_srcpos++; |
34 | 35 | b1=g_source.charCodeAt(g_srcpos); |
35 | - } while ('0'.charCodeAt(0)<= b1 && b1<='9'.charCodeAt(0) || 'A'.charCodeAt(0)<=b1 && b1<='Z'.charCodeAt(0)); | |
36 | + } while ('0'.charCodeAt(0)<= b1 && b1<='9'.charCodeAt(0) || b1=='_'.charCodeAt(0) || | |
37 | + 'A'.charCodeAt(0)<=b1 && b1<='Z'.charCodeAt(0)); | |
36 | 38 | return i+65536; |
37 | 39 | } |
38 | 40 | |
41 | +function int2name(s6){ | |
42 | + var rem37_31=function(s6){ | |
43 | + return s6 % 37; | |
44 | + }; | |
45 | + var div37_31=function(s6){ | |
46 | + return (s6-(s6 % 37))/37; | |
47 | + }; | |
48 | + var str=new Array(); | |
49 | + var i,res; | |
50 | + s6-=65536; | |
51 | + str[6]=0; | |
52 | + for(i=5;0<=i;i--){ | |
53 | + if (s6<37) { | |
54 | + // First character must be A-Z or _, corresponding to 1-27 but not 10-36. | |
55 | + // See get_label() for the detail. | |
56 | + if (s6==27) str[i]='_'.charCodeAt(0); | |
57 | + else str[i]=s6-1+'A'.charCodeAt(0); | |
58 | + break; | |
59 | + } else { | |
60 | + // From second, 0-9 corresponds to 0-9 and A-Z corresponds to 10-36. | |
61 | + str[i]="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_".charCodeAt(rem37_31(s6)); | |
62 | + s6=div37_31(s6); | |
63 | + } | |
64 | + } | |
65 | + //return (char*)(str+i); | |
66 | + for(res='';str[i];i++) { | |
67 | + res+=String.fromCharCode(str[i]); | |
68 | + } | |
69 | + return res; | |
70 | +} | |
71 | + | |
72 | +// Show max number by this system. | |
73 | +//WScript.Echo(name2int('______').toString(16)); | |
74 | + | |
75 | +// Test functions for 10000 times with randomized var names | |
76 | +for(i=0;i<10000;i++){ | |
77 | + t="ABCDEFGHIJKLMNOPQRSTUVWXYZ_".charAt(Math.random()*27); | |
78 | + for(j=0;j<1+Math.random()*4;j++){ | |
79 | + t+="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_".charAt(Math.random()*37); | |
80 | + } | |
81 | + j=name2int(t); | |
82 | + if (int2name(j)!=t || j<0 || 0x7fffffff<j) { | |
83 | + WScript.Echo('ERROR: '+t+' ('+j+'; 0x'+j.toString(16)+') '+i); | |
84 | + WScript.Quit(); | |
85 | + } | |
86 | +} | |
87 | + | |
39 | 88 | var namearray=[ |
40 | 89 | 'ABS', |
41 | 90 | 'ACOS', |
@@ -168,14 +217,16 @@ var namearray=[ | ||
168 | 217 | 'I2C', |
169 | 218 | ]; |
170 | 219 | var result=''; |
220 | +var commented=0; | |
171 | 221 | for(key in namearray){ |
172 | 222 | var nameint='0000'+name2int(namearray[key]).toString(16); |
173 | 223 | nameint=nameint.substr(nameint.length-8); |
174 | 224 | if (namearray[key].substr(0,2)=='//') { |
175 | 225 | // This is a comment |
176 | 226 | result+=namearray[key]+"\r\n"; |
227 | + commented=1; | |
177 | 228 | } else { |
178 | - result+="\t0x"+nameint+", /*"+namearray[key]+"*/\r\n"; | |
229 | + result+="\t0x"+nameint+", /*"+namearray[key]+"*/"+(commented ? " \\\r\n" : "\r\n"); | |
179 | 230 | } |
180 | 231 | } |
181 | 232 |
@@ -313,7 +313,7 @@ char* label_statement(){ | ||
313 | 313 | char* err; |
314 | 314 | char b1; |
315 | 315 | b1=g_source[g_srcpos]; |
316 | - if (b1<'A' || 'Z'<b1) return ERR_SYNTAX; // Number is not allowed here. | |
316 | + if ('0'<=b1 && b1<='9') return ERR_SYNTAX; // Number is not allowed here. | |
317 | 317 | err=get_label(); |
318 | 318 | if (err) return err; |
319 | 319 | // Check existing label with the same name here. |
@@ -18,120 +18,120 @@ | ||
18 | 18 | */ |
19 | 19 | |
20 | 20 | static const int reserved_var_names[]={ |
21 | - 0x000106b8, /*ABS*/ | |
22 | - 0x0001f67c, /*ACOS*/ | |
23 | - 0x0002414c, /*ARGS*/ | |
24 | - 0x0001090c, /*ASC*/ | |
25 | - 0x0002469f, /*ASIN*/ | |
26 | - 0x00024a8f, /*ATAN*/ | |
27 | - 0x002f7c1e, /*ATAN2*/ | |
28 | - 0x0047c31c, /*BREAK*/ | |
29 | - 0x00035869, /*CALL*/ | |
30 | - 0x00575afe, /*CDATA*/ | |
31 | - 0x00036c3d, /*CEIL*/ | |
32 | - 0x000111af, /*CHR*/ | |
33 | - 0x0cb1b682, /*CIRCLE*/ | |
34 | - 0x005d1ea3, /*CLEAR*/ | |
35 | - 0x00011240, /*CLS*/ | |
36 | - 0x005f66cb, /*COLOR*/ | |
37 | - 0x000112ac, /*COS*/ | |
38 | - 0x0003a041, /*COSH*/ | |
39 | - 0x00616415, /*CREAD*/ | |
40 | - 0x0de593fb, /*CURSOR*/ | |
41 | - 0x00040fbe, /*DATA*/ | |
42 | - 0x00011644, /*DEC*/ | |
43 | - 0x0fe19c42, /*DELETE*/ | |
44 | - 0x000116de, /*DIM*/ | |
45 | - 0x000100a8, /*DO*/ | |
46 | - 0x0004fd8e, /*ELSE*/ | |
47 | - 0x1434a177, /*ELSEIF*/ | |
48 | - 0x00011c99, /*END*/ | |
49 | - 0x0091c927, /*ENDIF*/ | |
50 | - 0x00053854, /*EXEC*/ | |
51 | - 0x00011e0d, /*EXP*/ | |
52 | - 0x000579c8, /*FABS*/ | |
53 | - 0x16e3d4be, /*FCLOSE*/ | |
54 | - 0x00058fcf, /*FEOF*/ | |
55 | - 0x00059895, /*FGET*/ | |
56 | - 0x00a67500, /*FGETC*/ | |
57 | - 0x00a7e061, /*FIELD*/ | |
58 | - 0x0005a3a2, /*FILE*/ | |
59 | - 0x177f0ca5, /*FINPUT*/ | |
60 | - 0x0005b1df, /*FLEN*/ | |
61 | - 0x00aa3445, /*FLOAT*/ | |
62 | - 0x00aa363b, /*FLOOR*/ | |
63 | - 0x0005b84d, /*FMOD*/ | |
64 | - 0x00ac5c9f, /*FOPEN*/ | |
65 | - 0x000121db, /*FOR*/ | |
66 | - 0x18352839, /*FPRINT*/ | |
67 | - 0x0005c865, /*FPUT*/ | |
68 | - 0x00ad2e40, /*FPUTC*/ | |
69 | - 0x00aefdec, /*FSEEK*/ | |
70 | - 0x00063b90, /*GCLS*/ | |
71 | - 0x1a808bcb, /*GCOLOR*/ | |
72 | - 0x1ab733b3, /*GETDIR*/ | |
73 | - 0x00c60f03, /*GOSUB*/ | |
74 | - 0x0006796c, /*GOTO*/ | |
75 | - 0x1bcfcc39, /*GPRINT*/ | |
76 | - 0x00012a99, /*HEX*/ | |
77 | - 0x0007ad12, /*IDLE*/ | |
78 | - 0x00010153, /*IF*/ | |
79 | - 0x00f8701a, /*INKEY*/ | |
80 | - 0x00f88ba5, /*INPUT*/ | |
81 | - 0x000130e9, /*INT*/ | |
82 | - 0x00092084, /*KEYS*/ | |
83 | - 0x013be43d, /*LABEL*/ | |
84 | - 0x00013ecf, /*LEN*/ | |
85 | - 0x00013ed5, /*LET*/ | |
86 | - 0x0009e96a, /*LINE*/ | |
87 | - 0x00014030, /*LOG*/ | |
88 | - 0x0145f324, /*LOG10*/ | |
89 | - 0x000a07f9, /*LOOP*/ | |
90 | - 0x000abca3, /*MODF*/ | |
91 | - 0x016418d4, /*MUSIC*/ | |
92 | - 0x000b4321, /*NEXT*/ | |
93 | - 0x000148f8, /*NEW*/ | |
94 | - 0x00014a5d, /*NOT*/ | |
95 | - 0x38a658d7, /*OPTION*/ | |
96 | - 0x000152c0, /*PCG*/ | |
97 | - 0x000cacec, /*PEEK*/ | |
98 | - 0x3b1c6aea, /*PEEK16*/ | |
99 | - 0x3b1c6b2e, /*PEEK32*/ | |
100 | - 0x00010252, /*PI*/ | |
101 | - 0x01ac8479, /*POINT*/ | |
102 | - 0x000ce05e, /*POKE*/ | |
103 | - 0x3c20dc0a, /*POKE16*/ | |
104 | - 0x3c20dc4e, /*POKE32*/ | |
105 | - 0x00015480, /*POW*/ | |
106 | - 0x01aea739, /*PRINT*/ | |
107 | - 0x000cf3d5, /*PSET*/ | |
108 | - 0x3cb45fa4, /*PUBLIC*/ | |
109 | - 0x3cc0fe21, /*PUTBMP*/ | |
110 | - 0x000e18d5, /*READ*/ | |
111 | - 0x00015d2e, /*REM*/ | |
112 | - 0x425c9703, /*RETURN*/ | |
113 | - 0x00015e69, /*RND*/ | |
114 | - 0x45c26d49, /*SCROLL*/ | |
115 | - 0x45f6e3b3, /*SETDIR*/ | |
116 | - 0x00016287, /*SGN*/ | |
117 | - 0x000162cf, /*SIN*/ | |
118 | - 0x000ee52d, /*SINH*/ | |
119 | - 0x01f9a429, /*SOUND*/ | |
120 | - 0x000f0e49, /*SQRT*/ | |
121 | - 0x47f711de, /*SYSTEM*/ | |
122 | - 0x000166bf, /*TAN*/ | |
123 | - 0x000f72ed, /*TANH*/ | |
124 | - 0x020ed5f3, /*TIMER*/ | |
125 | - 0x02182fee, /*TVRAM*/ | |
126 | - 0x022c2a2d, /*UNTIL*/ | |
127 | - 0x4e8887d0, /*USEPCG*/ | |
128 | - 0x4e88a5f3, /*USEVAR*/ | |
129 | - 0x000170dd, /*VAL*/ | |
130 | - 0x000170e3, /*VAR*/ | |
131 | - 0x00119505, /*WAIT*/ | |
132 | - 0x0011a9e9, /*WEND*/ | |
133 | - 0x025aef62, /*WHILE*/ | |
134 | - 0x025b8d75, /*WIDTH*/ | |
21 | + 0x0001070c, /*ABS*/ | |
22 | + 0x0002099d, /*ACOS*/ | |
23 | + 0x000258ac, /*ARGS*/ | |
24 | + 0x00010971, /*ASC*/ | |
25 | + 0x00025e4a, /*ASIN*/ | |
26 | + 0x0002627b, /*ATAN*/ | |
27 | + 0x00343bc9, /*ATAN2*/ | |
28 | + 0x004f5c95, /*BREAK*/ | |
29 | + 0x00038a2f, /*CALL*/ | |
30 | + 0x006110c1, /*CDATA*/ | |
31 | + 0x00039f24, /*CEIL*/ | |
32 | + 0x0001129b, /*CHR*/ | |
33 | + 0x0e7f3303, /*CIRCLE*/ | |
34 | + 0x0067525f, /*CLEAR*/ | |
35 | + 0x00011330, /*CLS*/ | |
36 | + 0x0069cb6b, /*COLOR*/ | |
37 | + 0x0001139f, /*COS*/ | |
38 | + 0x0003d60c, /*COSH*/ | |
39 | + 0x006bf57f, /*CREAD*/ | |
40 | + 0x0fd6b45b, /*CURSOR*/ | |
41 | + 0x00045129, /*DATA*/ | |
42 | + 0x00011776, /*DEC*/ | |
43 | + 0x122a52c0, /*DELETE*/ | |
44 | + 0x00011814, /*DIM*/ | |
45 | + 0x000100ac, /*DO*/ | |
46 | + 0x000551b8, /*ELSE*/ | |
47 | + 0x171a03a1, /*ELSEIF*/ | |
48 | + 0x00011e1d, /*END*/ | |
49 | + 0x00a20bbe, /*ENDIF*/ | |
50 | + 0x00058fdc, /*EXEC*/ | |
51 | + 0x00011f9b, /*EXP*/ | |
52 | + 0x0005da5b, /*FABS*/ | |
53 | + 0x1a358bdd, /*FCLOSE*/ | |
54 | + 0x0005f193, /*FEOF*/ | |
55 | + 0x0005fae1, /*FGET*/ | |
56 | + 0x00b94291, /*FGETC*/ | |
57 | + 0x00bacd24, /*FIELD*/ | |
58 | + 0x00060687, /*FILE*/ | |
59 | + 0x1ae2b2ef, /*FINPUT*/ | |
60 | + 0x00061598, /*FLEN*/ | |
61 | + 0x00bd52ae, /*FLOAT*/ | |
62 | + 0x00bd54b2, /*FLOOR*/ | |
63 | + 0x00061c59, /*FMOD*/ | |
64 | + 0x00bfaa2c, /*FOPEN*/ | |
65 | + 0x000123a9, /*FOR*/ | |
66 | + 0x1badd288, /*FPRINT*/ | |
67 | + 0x00062d52, /*FPUT*/ | |
68 | + 0x00c08ce6, /*FPUTC*/ | |
69 | + 0x00c286ca, /*FSEEK*/ | |
70 | + 0x0006ac5c, /*GCLS*/ | |
71 | + 0x1e59e7b7, /*GCOLOR*/ | |
72 | + 0x1e96cb44, /*GETDIR*/ | |
73 | + 0x00dc556c, /*GOSUB*/ | |
74 | + 0x0006edac, /*GOTO*/ | |
75 | + 0x1fcfed5d, /*GPRINT*/ | |
76 | + 0x00012cef, /*HEX*/ | |
77 | + 0x00083d61, /*IDLE*/ | |
78 | + 0x0001015c, /*IF*/ | |
79 | + 0x01149470, /*INKEY*/ | |
80 | + 0x0114b178, /*INPUT*/ | |
81 | + 0x00013391, /*INT*/ | |
82 | + 0x0009d063, /*KEYS*/ | |
83 | + 0x016022dc, /*LABEL*/ | |
84 | + 0x00014249, /*LEN*/ | |
85 | + 0x0001424f, /*LET*/ | |
86 | + 0x000aa9ff, /*LINE*/ | |
87 | + 0x000143b4, /*LOG*/ | |
88 | + 0x016b0db9, /*LOG10*/ | |
89 | + 0x000aca45, /*LOOP*/ | |
90 | + 0x000b8e81, /*MODF*/ | |
91 | + 0x018c8c85, /*MUSIC*/ | |
92 | + 0x000c21d6, /*NEXT*/ | |
93 | + 0x00014d04, /*NEW*/ | |
94 | + 0x00014e73, /*NOT*/ | |
95 | + 0x40e24fde, /*OPTION*/ | |
96 | + 0x0001575c, /*PCG*/ | |
97 | + 0x000daac8, /*PEEK*/ | |
98 | + 0x43be47b3, /*PEEK16*/ | |
99 | + 0x43be47f9, /*PEEK32*/ | |
100 | + 0x00010262, /*PI*/ | |
101 | + 0x01dd7f7a, /*POINT*/ | |
102 | + 0x000de11a, /*POKE*/ | |
103 | + 0x44e0c435, /*POKE16*/ | |
104 | + 0x44e0c47b, /*POKE32*/ | |
105 | + 0x00015928, /*POW*/ | |
106 | + 0x01dfd111, /*PRINT*/ | |
107 | + 0x000df5af, /*PSET*/ | |
108 | + 0x45858d00, /*PUBLIC*/ | |
109 | + 0x459341b1, /*PUTBMP*/ | |
110 | + 0x000f35e7, /*READ*/ | |
111 | + 0x0001625e, /*REM*/ | |
112 | + 0x4c0e4e9d, /*RETURN*/ | |
113 | + 0x000163a2, /*RND*/ | |
114 | + 0x4ff58ae0, /*SCROLL*/ | |
115 | + 0x50300d40, /*SETDIR*/ | |
116 | + 0x00016802, /*SGN*/ | |
117 | + 0x0001684c, /*SIN*/ | |
118 | + 0x0010130d, /*SINH*/ | |
119 | + 0x02338a69, /*SOUND*/ | |
120 | + 0x00103e75, /*SQRT*/ | |
121 | + 0x526b8f2e, /*SYSTEM*/ | |
122 | + 0x00016c7d, /*TAN*/ | |
123 | + 0x0010ae22, /*TANH*/ | |
124 | + 0x024b5425, /*TIMER*/ | |
125 | + 0x02557a82, /*TVRAM*/ | |
126 | + 0x026bf064, /*UNTIL*/ | |
127 | + 0x59f94768, /*USEPCG*/ | |
128 | + 0x59f9673f, /*USEVAR*/ | |
129 | + 0x0001772d, /*VAL*/ | |
130 | + 0x00017733, /*VAR*/ | |
131 | + 0x0012ff0c, /*WAIT*/ | |
132 | + 0x00131519, /*WEND*/ | |
133 | + 0x02a044ad, /*WHILE*/ | |
134 | + 0x02a0f0f8, /*WIDTH*/ | |
135 | 135 | // Additional names follow |
136 | 136 | ADDITIONAL_RESERVED_VAR_NAMES |
137 | 137 | }; |
@@ -150,16 +150,18 @@ int check_var_name(){ | ||
150 | 150 | int prevpos=g_srcpos; |
151 | 151 | next_position(); |
152 | 152 | b1=g_source[g_srcpos]; |
153 | - if (b1<'A' || 'Z'<b1) return -1; | |
153 | + // When changing here, see also get_label() | |
154 | + if ((b1<'A' || 'Z'<b1) && b1!='_') return -1; | |
154 | 155 | do { |
155 | - // First character must be A-Z | |
156 | - // From second, A-Z and 0-9 can be used. | |
157 | - i*=36; | |
156 | + // First character must be A-Z or _ | |
157 | + // From second, A-Z, _, and 0-9 can be used. | |
158 | + i*=37; | |
159 | + if (b1=='_') b1='Z'+1; | |
158 | 160 | if ('0'<=b1 && b1<='9') { |
159 | 161 | i+=b1-'0'; |
160 | 162 | } else if (g_srcpos==prevpos) { |
161 | - // First character must be A-Z. | |
162 | - // Subtract 9, resulting 1-26 but not 10-35. | |
163 | + // First character must be A-Z or _. | |
164 | + // Subtract 9, resulting 1-27 but not 10-36. | |
163 | 165 | // This subtraction is required to maintain |
164 | 166 | // final number being <0x80000000. |
165 | 167 | i+=b1-'A'+1; |
@@ -168,7 +170,7 @@ int check_var_name(){ | ||
168 | 170 | } |
169 | 171 | g_srcpos++; |
170 | 172 | b1=g_source[g_srcpos]; |
171 | - } while ('0'<= b1 && b1<='9' || 'A'<=b1 && b1<='Z'); | |
173 | + } while ('0'<= b1 && b1<='9' || 'A'<=b1 && b1<='Z' || b1=='_'); | |
172 | 174 | // Length of the label must be between 2 and 6. |
173 | 175 | if (g_srcpos-prevpos<2) { |
174 | 176 | // One letter var name, A-Z |