root/attic/minid_old.d

Revision 22, 135.5 kB (checked in by JarrettBillingsley, 2 years ago)

Moved remotely

Line 
1 module minid;
2
3 import std.c.stdlib;
4 import std.conv;
5 import std.perf;
6 import std.stdio;
7 import std.stream;
8 import std.string;
9 import std.utf;
10
11 /*
12 Calling a closure (of any type):
13     ocall ox, 0
14
15 Calling methods with "this":
16     ocall ox, index
17     
18 Downcalling dynamic closures:
19     ecall index
20
21 Calling static functions / Sidecalling dynamic closures:
22     rcall index
23
24 Referencing static functions / Sidereferencing dynamic closures:
25     rfuncref index
26
27 Downreferencing dynamic closures:
28     efuncref index
29
30 Downclosing a function:
31     eclose index
32
33 Sideclosing a function
34     rclose index
35
36 Closing/referencing methods with "this" (delegation):
37     oclose ox, index
38
39 Create closures at a static function level.
40 */
41
42 /*
43 the minid module:
44
45 class Object
46 {
47     int opCmp(Object other);
48     bool opEquals(Object other);
49     int getHash();
50     char[] toString();
51 }
52
53 // Cut down on duplication of effort with RTTI!
54 // But that involves either subverting the typesafe compiler or adding in a new "feature" to allow an "any" type.
55 // How about instead of converting arrays to __Arrays right away, save that for the codegen, or somewhere between
56 // semantic and codegen?  That would work.
57
58 class __Array : Object
59 {
60     this(TypeInfo ti, int length);
61
62     int opCmp(__Array other);
63     bool opEquals(__Array other);
64     int getHash();
65     char[] toString();
66
67     // These return an "int", but the return type is really dictated by the compiler.
68     int opIndex(int index);
69
70     // These all take "ints", but again, it's type-dependent.
71     int opIndexAssign(int value, int index);
72
73     __Array opSlice();
74     __Array opSlice(int lo, int hi);
75     __Array opSliceAssign(int value);
76     __Array opSliceAssign(int value, int lo, int hi);
77     __IntArray dup();
78     void sort();
79     void reverse();
80     
81     namespace length
82     {
83         int opGet();
84         int opSet(int l);
85     }
86     
87     __IntArray opCat(__IntArray other);
88     __IntArray opCatEq(__IntArray other);
89 }
90 */
91
92 void main()
93 {
94     BufferedFile f = new BufferedFile(`testscript.txt`, FileMode.In);
95
96     auto Compiler c = new Compiler();
97
98     c.compile(`testscript.txt`, f);
99    
100     f.close();
101     delete f;
102 }
103
104 class Compiler
105 {
106     public this()
107     {
108
109     }
110
111     public void compile(char[] name, Stream source)
112     {
113         auto Lexer l = new Lexer();
114         auto HighPerformanceCounter hpc = new HighPerformanceCounter();
115         hpc.start();
116         Token* tokens = l.lex(name, source);
117         Module m = Module.parse(tokens);
118         m.semantic();
119         hpc.stop();
120         writefln("Took ", hpc.microseconds() / 1000.0, "ms\n");
121         m.showChildren();
122         //writefln(m);
123     }
124 }
125
126 int toInt(char[] s, int base)
127 {
128     assert(base >= 2 && base <= 36);
129
130     static char[] transTable =
131     [
132         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
133         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
134         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
135         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
136         0, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72,
137         73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 0, 0, 0, 0, 0,
138         0, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72,
139         73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 0, 0, 0, 0, 0,
140         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
141         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
142         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
143         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
144         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
145         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
146         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
147         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
148     ];
149
150     int length = s.length;
151
152     if(!length)
153         throw new ConvError(s);
154
155     int sign = 0;
156     int v = 0;
157    
158     char maxDigit = '0' + base - 1;
159
160     for(int i = 0; i < length; i++)
161     {
162         char c = transTable[s[i]];
163
164         if(c >= '0' && c <= maxDigit)
165         {
166             uint v1 = v;
167             v = v * base + (c - '0');
168
169             if(cast(uint)v < v1)
170                 throw new ConvOverflowError(s);
171         }
172         else if(c == '-' && i == 0)
173         {
174             sign = -1;
175
176             if(length == 1)
177                 throw new ConvError(s);
178         }
179         else if(c == '+' && i == 0)
180         {
181             if(length == 1)
182                 throw new ConvError(s);
183         }
184         else
185             throw new ConvError(s);
186     }
187
188     if(sign == -1)
189     {
190         if(cast(uint)v > 0x80000000)
191             throw new ConvOverflowError(s);
192
193         v = -v;
194     }
195     else
196     {
197         if(cast(uint)v > 0x7FFFFFFF)
198             throw new ConvOverflowError(s);
199     }
200
201     return v;
202 }
203
204 struct Token
205 {
206     public static enum Type
207     {
208         Assert,
209         Bool,
210         Break,
211         Case,
212         Cast,
213         Char,
214         Class,
215         Closure,
216         Continue,
217         Def,
218         Default,
219         Delete,
220         Do,
221         Else,
222         False,
223         Float,
224         For,
225         Foreach,
226         Function,
227         If,
228         Import,
229         Int,
230         Main,
231         Module,
232         Namespace,
233         New,
234         Null,
235         Return,
236         Super,
237         Switch,
238         This,
239         True,
240         Vararg,
241         Void,
242         While,
243
244         Add,
245         AddEq,
246         Sub,
247         SubEq,
248         Mul,
249         MulEq,
250         Div,
251         DivEq,
252         Mod,
253         ModEq,
254         Pow,
255         PowEq,
256         Cat,
257         CatEq,
258         Assign,
259
260         AndAnd,
261         OrOr,
262
263         Inc,
264         Dec,
265
266         LT,
267         LE,
268         GT,
269         GE,
270         EQ,
271         NE,
272         Is,
273
274         Not,
275
276         LParen,
277         RParen,
278         LBracket,
279         RBracket,
280         LBrace,
281         RBrace,
282
283         Colon,
284         Comma,
285         Semicolon,
286
287         Dot,
288         DotDot,
289
290         Ident,
291         BoolLiteral,
292         StringLiteral,
293         CharLiteral,
294         IntLiteral,
295         FloatLiteral,
296         EOF
297     }
298
299     public static const char[][] tokenStrings =
300     [
301         "assert",
302         "bool",
303         "break",
304         "case",
305         "cast",
306         "char",
307         "class",
308         "closure",
309         "continue",
310         "def",
311         "default",
312         "delete",
313         "do",
314         "else",
315         "false",
316         "float",
317         "for",
318         "foreach",
319         "function",
320         "if",
321         "import",
322         "int",
323         "main",
324         "module",
325         "namespace"
326         "new",
327         "null",
328         "return",
329         "super",
330         "switch",
331         "this",
332         "true",
333         "vararg",
334         "void",
335         "while",
336
337         "+",
338         "+=",
339         "-",
340         "-=",
341         "*",
342         "*=",
343         "/",
344         "/=",
345         "%",
346         "%=",
347         "^",
348         "^=",
349         "~",
350         "~=",
351         "=",
352
353         "&&",
354         "||",
355
356         "++",
357         "--",
358
359         "<",
360         "<=",
361         ">",
362         ">=",
363         "==",
364         "!=",
365         "is",
366
367         "!",
368
369         "(",
370         ")",
371         "[",
372         "]",
373         "{",
374         "}",
375
376         ":",
377         ",",
378         ";",
379
380         ".",
381         "..",
382        
383         "Identifier",
384         "Bool Literal",
385         "String Literal",
386         "Char Literal",
387         "Int Literal",
388         "Float Literal",
389         "<EOF>"
390     ];
391    
392     public static Type[char[]] stringToType;
393    
394     static this()
395     {
396         stringToType["assert"] = Type.Assert;
397         stringToType["bool"] = Type.Bool;
398         stringToType["break"] = Type.Break;
399         stringToType["case"] = Type.Case;
400         stringToType["cast"] = Type.Cast;
401         stringToType["char"] = Type.Char;
402         stringToType["class"] = Type.Class;
403         stringToType["closure"] = Type.Closure;
404         stringToType["continue"] = Type.Continue;
405         stringToType["def"] = Type.Def;
406         stringToType["default"] = Type.Default;
407         stringToType["delete"] = Type.Delete;
408         stringToType["do"] = Type.Do;
409         stringToType["else"] = Type.Else;
410         stringToType["false"] = Type.False;
411         stringToType["float"] = Type.Float;
412         stringToType["for"] = Type.For;
413         stringToType["foreach"] = Type.Foreach;
414         stringToType["function"] = Type.Function;
415         stringToType["if"] = Type.If;
416         stringToType["is"] = Type.Is;
417         stringToType["import"] = Type.Import;
418         stringToType["int"] = Type.Int;
419         stringToType["main"] = Type.Main;
420         stringToType["module"] = Type.Module;
421         stringToType["namespace"] = Type.Namespace;
422         stringToType["new"] = Type.New;
423         stringToType["null"] = Type.Null;
424         stringToType["return"] = Type.Return;
425         stringToType["super"] = Type.Super;
426         stringToType["switch"] = Type.Switch;
427         stringToType["this"] = Type.This;
428         stringToType["true"] = Type.True;
429         stringToType["vararg"] = Type.Vararg;
430         stringToType["void"] = Type.Void;
431         stringToType["while"] = Type.While;
432         stringToType["("] = Type.LParen;
433         stringToType[")"] = Type.RParen;
434         stringToType["["] = Type.LBracket;
435         stringToType["]"] = Type.RBracket;
436         stringToType["{"] = Type.LBrace;
437         stringToType["}"] = Type.RBrace;
438         stringToType[":"] = Type.Colon;
439         stringToType[","] = Type.Comma;
440         stringToType[";"] = Type.Semicolon;
441
442         stringToType.rehash;
443     }
444    
445     public char[] toString()
446     {
447         char[] ret;
448
449         switch(type)
450         {
451             case Type.Ident:
452                 ret ~= "Ident: " ~ stringValue;
453                 break;
454                
455             case Type.BoolLiteral:
456                 ret ~= (boolValue ? "true" : "false");
457
458             case Type.StringLiteral:
459                 ret ~= '"' ~ stringValue ~ '"';
460                 break;
461                
462             case Type.CharLiteral:
463                 ret ~= "'" ~ stringValue ~ "'";
464
465             case Type.IntLiteral:
466                 ret ~= "Int: " ~ std.string.toString(intValue);
467                 break;
468
469             case Type.FloatLiteral:
470                 ret ~= "Float: " ~ std.string.toString(floatValue);
471                 break;
472
473             default:
474                 ret ~= tokenStrings[cast(uint)type];
475                 break;
476         }
477        
478         return ret;
479     }
480    
481     public static char[] toString(Type type)
482     {
483         return tokenStrings[type];
484     }
485    
486     public void check(Type t)
487     {
488         if(type != t)
489             throw new MDCompileException("'" ~ tokenStrings[t] ~ "' expected; found '" ~ tokenStrings[type] ~ "' instead", location);
490     }
491
492     public Type type;
493    
494     union
495     {
496         public bool boolValue;
497         public char[] stringValue;
498         public int intValue;
499         public float floatValue;
500     }
501
502     public Location location;
503
504     public Token* nextToken;
505 }
506
507 struct Location
508 {
509     public uint line = 1;
510     public uint column = 1;
511     public char[] fileName;
512
513     public static Location opCall(char[] fileName, uint line = 1, uint column = 1)
514     {
515         Location l;
516         l.fileName = fileName;
517         l.line = line;
518         l.column = column;
519         return l;
520     }
521
522     public char[] toString()
523     {
524         return fileName ~ "(" ~ .toString(line) ~ ":" ~ .toString(column) ~ ")";
525     }
526 }
527
528 class MDException : Exception
529 {
530     public this(char[] msg)
531     {
532         super(msg);
533     }
534 }
535
536 class MDCompileException : MDException
537 {
538     public this(char[] msg, Location loc)
539     {
540         super(loc.toString() ~ ": " ~ msg);
541     }
542 }
543
544 class MDSymbolConflictException : MDCompileException
545 {
546     public this(Symbol sym1, Symbol sym2)
547     {
548         super("'" ~ sym1.toPrettyString() ~ "' conflicts with '" ~ sym2.toPrettyString() ~ "'(" ~ sym2.mLocation.toString() ~ ")", sym1.mLocation);
549     }
550 }
551
552 class MDShadowingException : MDCompileException
553 {
554     public this(Symbol sym1, Symbol sym2)
555     {
556         super("'" ~ sym1.toPrettyString() ~ "' shadows '" ~ sym2.toPrettyString() ~ "'(" ~ sym2.mLocation.toString() ~ ")", sym1.mLocation);   
557     }
558 }
559
560 class MDTypeConvException : MDCompileException
561 {
562     public this(Expression from, Expression to)
563     {
564         super("Cannot implicitly convert expression '" ~ from.toString() ~ "' of type '" ~ from.mSemType.toString() ~ "' to type '" ~ to.mSemType.toString() ~ "'", from.mLocation);
565     }
566 }
567
568 class Lexer
569 {
570     protected Stream mSource;
571     protected Location mLoc;
572     protected char mCharacter;
573
574     public this()
575     {
576
577     }
578
579     public Token* lex(char[] name, Stream source)
580     {
581         if(!source.readable)
582             throw new MDException(name ~ ": Source code stream is not readable");
583
584         mLoc = Location(name);
585
586         mSource = source;
587
588         nextChar();
589
590         Token* firstToken = nextToken();
591         Token* t = firstToken;
592
593         while(t.type != Token.Type.EOF)
594         {
595             Token* next = nextToken();
596
597             t.nextToken = next;
598             t = t.nextToken;
599         }
600
601         return firstToken;
602     }
603
604     protected static bool isEOF(char c)
605     {
606         return (c == '\0') || (c == char.init);
607     }
608
609     protected static bool isEOL(char c)
610     {
611         return isNewline(c) || isEOF(c);
612     }
613
614     protected static bool isWhitespace(char c)
615     {
616         return (c == ' ') || (c == '\t') || (c == '\v') || (c == '\u000C') || isEOL(c);
617     }
618    
619     protected static bool isNewline(char c)
620     {
621         return (c == '\r') || (c == '\n');
622     }
623    
624     protected static bool isBinaryDigit(char c)
625     {
626         return (c == '0') || (c == '1');
627     }
628    
629     protected static bool isOctalDigit(char c)
630     {
631         return (c >= '0') && (c <= '7');
632     }
633
634     protected static bool isHexDigit(char c)
635     {
636         return ((c >= '0') && (c <= '9')) || ((c >= 'a') && (c <= 'f')) || ((c >= 'A') && (c <= 'F'));
637     }
638
639     protected static bool isDecimalDigit(char c)
640     {
641         return (c >= '0') && (c <= '9');
642     }
643    
644     protected static bool isAlpha(char c)
645     {
646         return ((c >= 'a') && (c <= 'z')) || ((c >= 'A') && (c <= 'Z'));
647     }
648
649     protected void nextChar()
650     {
651         mCharacter = mSource.getc();
652         mLoc.column++;
653   &nb