| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,372 @@ | ||
| // This file is part of Visual D | ||
| // | ||
| // Visual D integrates the D programming language into Visual Studio | ||
| // Copyright (c) 2010-2011 by Rainer Schuetze, All Rights Reserved | ||
| // | ||
| // Distributed under the Boost Software License, Version 1.0. | ||
| // See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt | ||
|
|
||
| module stdext.string; | ||
|
|
||
| import std.utf; | ||
| import std.string; | ||
| import std.ascii; | ||
| import std.conv; | ||
| import std.array; | ||
|
|
||
| size_t endofStringCStyle(string text, size_t pos, dchar term = '\"', dchar esc = '\\') | ||
| { | ||
| while(pos < text.length) | ||
| { | ||
| dchar ch = decode(text, pos); | ||
| if(ch == esc) | ||
| { | ||
| if (pos >= text.length) | ||
| break; | ||
| ch = decode(text, pos); | ||
| } | ||
| else if(ch == term) | ||
| return pos; | ||
| } | ||
| return pos; | ||
| } | ||
|
|
||
| string[] tokenizeArgs(string text, bool semi_is_seperator = true, bool space_is_seperator = true) | ||
| { | ||
| string[] args; | ||
| size_t pos = 0; | ||
| while(pos < text.length) | ||
| { | ||
| size_t startpos = pos; | ||
| dchar ch = decode(text, pos); | ||
| if(isWhite(ch)) | ||
| continue; | ||
|
|
||
| size_t endpos = pos; | ||
| while(pos < text.length) | ||
| { | ||
| if(ch == '\"') | ||
| { | ||
| pos = endofStringCStyle(text, pos, '\"', 0); | ||
| ch = 0; | ||
| } | ||
| else | ||
| { | ||
| ch = decode(text, pos); | ||
| } | ||
| if(isWhite(ch) && (space_is_seperator || ch != ' ')) | ||
| break; | ||
| if(semi_is_seperator && ch == ';') | ||
| break; | ||
| endpos = pos; | ||
| } | ||
| args ~= text[startpos .. endpos]; | ||
| } | ||
| return args; | ||
| } | ||
|
|
||
| string unquoteArgument(string arg) | ||
| { | ||
| if(arg.length <= 0 || arg[0] != '\"') | ||
| return arg; | ||
|
|
||
| if (endofStringCStyle(arg, 1, '\"', 0) != arg.length) | ||
| return arg; | ||
|
|
||
| return arg[1..$-1]; | ||
| } | ||
|
|
||
| string replaceCrLfSemi(string s) | ||
| { | ||
| return replace(replace(s, "\n", ";"), "\r", ""); | ||
| } | ||
|
|
||
| string replaceSemiCrLf(string s) | ||
| { | ||
| return replace(s, ";", "\r\n"); | ||
| } | ||
|
|
||
| string insertCr(string s) | ||
| { | ||
| string ns; | ||
| while(s.length > 0) | ||
| { | ||
| auto p = s.indexOf('\n'); | ||
| if(p < 0) | ||
| break; | ||
| if(p > 0 && s[p-1] == '\r') | ||
| ns ~= s[0 .. p+1]; | ||
| else | ||
| ns ~= s[0 .. p] ~ "\r\n"; | ||
| s = s[p+1 .. $]; | ||
| } | ||
| return ns ~ s; | ||
| } | ||
|
|
||
| version(unittest) | ||
| unittest | ||
| { | ||
| string t = insertCr("a\nb\r\ncd\n\ne\n\r\nf"); | ||
| assert(t == "a\r\nb\r\ncd\r\n\r\ne\r\n\r\nf"); | ||
| } | ||
|
|
||
| S escapeString(S)(S s) | ||
| { | ||
| s = replace(s, "\\"w, "\\\\"w); | ||
| s = replace(s, "\t"w, "\\t"w); | ||
| s = replace(s, "\r"w, "\\r"w); | ||
| s = replace(s, "\n"w, "\\n"w); | ||
| return s; | ||
| } | ||
|
|
||
| int countVisualSpaces(S)(S txt, int tabSize, int* txtpos = null) | ||
| { | ||
| int p = 0; | ||
| int n = 0; | ||
| while(n < txt.length && isWhite(txt[n])) | ||
| { | ||
| if(txt[n] == '\t') | ||
| p = p + tabSize - (p % tabSize); | ||
| else | ||
| p++; | ||
| n++; | ||
| } | ||
| if(txtpos) | ||
| *txtpos = n; | ||
| return p; | ||
| } | ||
|
|
||
| int visiblePosition(S)(S txt, int tabSize, int idx) | ||
| { | ||
| if(idx > txt.length) | ||
| idx = txt.length; | ||
|
|
||
| int p = 0; | ||
|
|
||
| for(int n = 0; n < idx; n++) | ||
| if(txt[n] == '\t') | ||
| p = p + tabSize - (p % tabSize); | ||
| else | ||
| p++; | ||
|
|
||
| return p; | ||
| } | ||
|
|
||
| S createVisualSpaces(S)(int n, int tabSize, int tabOff = 0) | ||
| { | ||
| S s; | ||
| if(tabSize < 2) | ||
| { | ||
| for(int i = 0; i < n; i++) | ||
| s ~= " "; | ||
| } | ||
| else | ||
| { | ||
| while (n > 0 && tabOff > 0 && tabOff < tabSize) | ||
| { | ||
| s ~= " "; | ||
| tabOff++; | ||
| n--; | ||
| } | ||
| while(n >= tabSize) | ||
| { | ||
| s ~= "\t"; | ||
| n -= tabSize; | ||
| } | ||
| while(n > 0) | ||
| { | ||
| s ~= " "; | ||
| n--; | ||
| } | ||
| } | ||
| return s; | ||
| } | ||
|
|
||
| // extract value from a series of #define values | ||
| string extractDefine(string s, string def) | ||
| { | ||
| for(int p = 0; p < s.length; p++) | ||
| { | ||
| while(p < s.length && (s[p] == ' ' || s[p] == '\t')) | ||
| p++; | ||
| int q = p; | ||
| while(q < s.length && s[q] != '\n' && s[q] != '\r') | ||
| q++; | ||
|
|
||
| if(_startsWith(s[p .. $], "#define") && (s[p+7] == ' ' || s[p+7] == '\t')) | ||
| { | ||
| p += 7; | ||
| while(p < s.length && (s[p] == ' ' || s[p] == '\t')) | ||
| p++; | ||
| if(_startsWith(s[p .. $], def) && (s[p+def.length] == ' ' || s[p+def.length] == '\t')) | ||
| { | ||
| p += def.length; | ||
| while(p < s.length && (s[p] == ' ' || s[p] == '\t')) | ||
| p++; | ||
| return s[p .. q]; | ||
| } | ||
| } | ||
| p = q; | ||
| } | ||
| return ""; | ||
| } | ||
|
|
||
| string extractDefines(string s) | ||
| { | ||
| string m; | ||
| for(int p = 0; p < s.length; p++) | ||
| { | ||
| while(p < s.length && (s[p] == ' ' || s[p] == '\t')) | ||
| p++; | ||
| int q = p; | ||
| while(q < s.length && s[q] != '\n' && s[q] != '\r') | ||
| q++; | ||
|
|
||
| if(_startsWith(s[p .. $], "#define") && (s[p+7] == ' ' || s[p+7] == '\t')) | ||
| { | ||
| p += 7; | ||
| int b = p; | ||
| while(p < q && (s[p] == ' ' || s[p] == '\t')) | ||
| p++; | ||
| int r = p; | ||
| while(r < q && !isWhite(s[r])) | ||
| r++; | ||
| if(r < q) | ||
| { | ||
| m ~= "const " ~ s[p..r] ~ " = " ~ s[r..q] ~ ";\n"; | ||
| } | ||
| } | ||
| p = q; | ||
| } | ||
| return m; | ||
| } | ||
|
|
||
| // endsWith does not work reliable and crashes on page end | ||
| bool _endsWith(string s, string e) | ||
| { | ||
| return (s.length >= e.length && s[$-e.length .. $] == e); | ||
| } | ||
|
|
||
| // startsWith causes compile error when used in ctfe | ||
| bool _startsWith(string s, string w) | ||
| { | ||
| return (s.length >= w.length && s[0 .. w.length] == w); | ||
| } | ||
|
|
||
| //alias startsWith _startsWith; | ||
|
|
||
| bool parseLong(ref char[] txt, out long res) | ||
| { | ||
| munch(txt, " \t\n\r"); | ||
| int n = 0; | ||
| while(n < txt.length && isDigit(txt[n])) | ||
| n++; | ||
| if(n <= 0) | ||
| return false; | ||
| res = to!long(txt[0..n]); | ||
| txt = txt[n..$]; | ||
| return true; | ||
| } | ||
|
|
||
| char[] parseNonSpace(ref char[] txt) | ||
| { | ||
| munch(txt, " \t\n\r"); | ||
| int n = 0; | ||
| while(n < txt.length && !isWhite(txt[n])) | ||
| n++; | ||
| char[] res = txt[0..n]; | ||
| txt = txt[n..$]; | ||
| return res; | ||
| } | ||
|
|
||
| T[] firstLine(T)(T[] s) | ||
| { | ||
| for(size_t i = 0; i < s.length; i++) | ||
| if(s[i] == '\n' || s[i] == '\r') | ||
| return s[0..i]; | ||
| return s; | ||
| } | ||
|
|
||
| char kInvalidUTF8Replacement = '?'; | ||
|
|
||
| string toUTF8Safe(const(char)[] text) | ||
| { | ||
| char[] modtext; | ||
| for(size_t p = 0; p < text.length; p++) | ||
| { | ||
| ubyte ch = text[p]; | ||
| if((ch & 0xc0) == 0xc0) | ||
| { | ||
| auto q = p; | ||
| for(int s = 0; s < 5 && ((ch << s) & 0xc0) == 0xc0; s++, q++) | ||
| if(q >= text.length || (text[q] & 0xc0) != 0x80) | ||
| goto L_invalid; | ||
| p = q; | ||
| } | ||
| else if(ch & 0x80) | ||
| { | ||
| L_invalid: | ||
| if(modtext.length == 0) | ||
| modtext = text.dup; | ||
| modtext[p] = kInvalidUTF8Replacement; | ||
| } | ||
| } | ||
| if(modtext.length) | ||
| return cast(string) modtext; | ||
| return cast(string) text; | ||
| } | ||
|
|
||
| string toUTF8Safe(const(wchar)[] text) | ||
| { | ||
| wchar[] modtext; | ||
| void invalidChar(size_t pos) | ||
| { | ||
| if(modtext.length == 0) | ||
| modtext = text.dup; | ||
| modtext[pos] = kInvalidUTF8Replacement; | ||
| } | ||
|
|
||
| for(size_t p = 0; p < text.length; p++) | ||
| { | ||
| ushort ch = text[p]; | ||
| if(ch >= 0xD800 && ch <= 0xDFFF) | ||
| { | ||
| if(p + 1 >= text.length) | ||
| invalidChar(p); | ||
| else | ||
| { | ||
| if (text[p+1] < 0xD800 || text[p+1] > 0xDFFF) | ||
| { | ||
| invalidChar(p); // invalid surragate pair | ||
| invalidChar(p+1); | ||
| } | ||
| p++; | ||
| } | ||
| } | ||
| } | ||
| return toUTF8(modtext.length ? modtext : text); | ||
| } | ||
|
|
||
| string toUTF8Safe(const(dchar)[] text) | ||
| { | ||
| dchar[] modtext; | ||
| for(size_t p = 0; p < text.length; p++) | ||
| if(!isValidDchar(text[p])) | ||
| { | ||
| if(modtext.length == 0) | ||
| modtext = text.dup; | ||
| modtext[p] = kInvalidUTF8Replacement; | ||
| } | ||
| return toUTF8(modtext.length ? modtext : text); | ||
| } | ||
|
|
||
| dchar decodeBwd(Char)(const(Char) txt, ref size_t pos) | ||
| { | ||
| assert(pos > 0); | ||
| uint len = strideBack(txt, pos); | ||
| pos -= len; | ||
| size_t p = pos; | ||
| dchar ch = decode(txt, p); | ||
| assert(pos + len == p); | ||
| return ch; | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,31 @@ | ||
| // This file is part of Visual D | ||
| // | ||
| // Visual D integrates the D programming language into Visual Studio | ||
| // Copyright (c) 2010-2011 by Rainer Schuetze, All Rights Reserved | ||
| // | ||
| // Distributed under the Boost Software License, Version 1.0. | ||
| // See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt | ||
|
|
||
| module stdext.util; | ||
|
|
||
| //////////////////////////////////////////////////////////////// | ||
| inout(T) static_cast(T, S = Object)(inout(S) p) | ||
| { | ||
| if(!p) | ||
| return null; | ||
| if(__ctfe) | ||
| return cast(inout(T)) p; | ||
| assert(cast(inout(T)) p); | ||
| void* vp = cast(void*)p; | ||
| return cast(inout(T)) vp; | ||
| } | ||
|
|
||
| //////////////////////////////////////////////////////////////// | ||
| bool isIn(T...)(T values) | ||
| { | ||
| T[0] needle = values[0]; | ||
| foreach(v; values[1..$]) | ||
| if(v == needle) | ||
| return true; | ||
| return false; | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| // This file is part of Visual D | ||
| // | ||
| // Visual D integrates the D programming language into Visual Studio | ||
| // Copyright (c) 2010-2011 by Rainer Schuetze, All Rights Reserved | ||
| // | ||
| // Distributed under the Boost Software License, Version 1.0. | ||
| // See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt | ||
|
|
||
| module vdc.ast.all; | ||
|
|
||
| public import vdc.ast.aggr; | ||
| public import vdc.ast.decl; | ||
| public import vdc.ast.expr; | ||
| public import vdc.ast.iasm; | ||
| public import vdc.ast.misc; | ||
| public import vdc.ast.mod; | ||
| public import vdc.ast.node; | ||
| public import vdc.ast.stmt; | ||
| public import vdc.ast.tmpl; | ||
| public import vdc.ast.type; | ||
| public import vdc.ast.writer; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,200 @@ | ||
| // This file is part of Visual D | ||
| // | ||
| // Visual D integrates the D programming language into Visual Studio | ||
| // Copyright (c) 2010-2011 by Rainer Schuetze, All Rights Reserved | ||
| // | ||
| // Distributed under the Boost Software License, Version 1.0. | ||
| // See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt | ||
|
|
||
| module vdc.ast.iasm; | ||
|
|
||
| import vdc.util; | ||
| import vdc.lexer; | ||
| import vdc.ast.node; | ||
| import vdc.ast.writer; | ||
|
|
||
| class AsmInstruction : Node | ||
| { | ||
| mixin ForwardCtor!(); | ||
|
|
||
| Token[] tokens; | ||
|
|
||
| void addToken(Token tok) | ||
| { | ||
| Token ntok = new Token; | ||
| ntok.copy(tok); | ||
| tokens ~= ntok; | ||
| } | ||
|
|
||
| override void toD(CodeWriter writer) | ||
| { | ||
| foreach(t; tokens) | ||
| { | ||
| writer(t.txt, " "); | ||
| } | ||
| } | ||
| } | ||
|
|
||
|
|
||
| //AsmInstruction: | ||
| // Identifier : AsmInstruction | ||
| // "align" IntegerExpression | ||
| // "even" | ||
| // "naked" | ||
| // "db" Operands | ||
| // "ds" Operands | ||
| // "di" Operands | ||
| // "dl" Operands | ||
| // "df" Operands | ||
| // "dd" Operands | ||
| // "de" Operands | ||
| // Opcode | ||
| // Opcode Operands | ||
| // | ||
| //Operands: | ||
| // Operand | ||
| // Operand , Operands | ||
| // | ||
| //IntegerExpression: | ||
| // IntegerLiteral | ||
| // Identifier | ||
| // | ||
| //Operand: | ||
| // AsmExp | ||
| // | ||
| //AsmExp: | ||
| // AsmLogOrExp | ||
| // AsmLogOrExp ? AsmExp : AsmExp | ||
| // | ||
| //AsmLogOrExp: | ||
| // AsmLogAndExp | ||
| // AsmLogAndExp || AsmLogAndExp | ||
| // | ||
| //AsmLogAndExp: | ||
| // AsmOrExp | ||
| // AsmOrExp && AsmOrExp | ||
| // | ||
| //AsmOrExp: | ||
| // AsmXorExp | ||
| // AsmXorExp | AsmXorExp | ||
| // | ||
| //AsmXorExp: | ||
| // AsmAndExp | ||
| // AsmAndExp ^ AsmAndExp | ||
| // | ||
| //AsmAndExp: | ||
| // AsmEqualExp | ||
| // AsmEqualExp & AsmEqualExp | ||
| // | ||
| //AsmEqualExp: | ||
| // AsmRelExp | ||
| // AsmRelExp == AsmRelExp | ||
| // AsmRelExp != AsmRelExp | ||
| // | ||
| //AsmRelExp: | ||
| // AsmShiftExp | ||
| // AsmShiftExp < AsmShiftExp | ||
| // AsmShiftExp <= AsmShiftExp | ||
| // AsmShiftExp > AsmShiftExp | ||
| // AsmShiftExp >= AsmShiftExp | ||
| // | ||
| //AsmShiftExp: | ||
| // AsmAddExp | ||
| // AsmAddExp << AsmAddExp | ||
| // AsmAddExp >> AsmAddExp | ||
| // AsmAddExp >>> AsmAddExp | ||
| // | ||
| //AsmAddExp: | ||
| // AsmMulExp | ||
| // AsmMulExp + AsmMulExp | ||
| // AsmMulExp - AsmMulExp | ||
| // | ||
| //AsmMulExp: | ||
| // AsmBrExp | ||
| // AsmBrExp * AsmBrExp | ||
| // AsmBrExp / AsmBrExp | ||
| // AsmBrExp % AsmBrExp | ||
| // | ||
| //AsmBrExp: | ||
| // AsmUnaExp | ||
| // AsmBrExp [ AsmExp ] | ||
| // | ||
| //AsmUnaExp: | ||
| // AsmTypePrefix AsmExp | ||
| // "offsetof" AsmExp | ||
| // "seg" AsmExp | ||
| // + AsmUnaExp | ||
| // - AsmUnaExp | ||
| // ! AsmUnaExp | ||
| // ~ AsmUnaExp | ||
| // AsmPrimaryExp | ||
| // | ||
| //AsmPrimaryExp: | ||
| // IntegerLiteral | ||
| // FloatLiteral | ||
| // "__LOCAL_SIZE" | ||
| // $ | ||
| // Register | ||
| // DotIdentifier | ||
| // | ||
| //DotIdentifier: | ||
| // Identifier | ||
| // Identifier . DotIdentifier | ||
| // | ||
| //AsmTypePrefix: | ||
| // "near" "ptr" | ||
| // "far" "ptr" | ||
| // byte "ptr" | ||
| // short "ptr" | ||
| // int "ptr" | ||
| // "word" "ptr" | ||
| // "dword" "ptr" | ||
| // "qword" "ptr" | ||
| // float "ptr" | ||
| // double "ptr" | ||
| // real "ptr" | ||
| // | ||
| //Register: | ||
| // TOK_register | ||
| // | ||
| //Opcode: | ||
| // TOK_opcode | ||
| // | ||
| //Identifier: | ||
| // TOK_Identifier | ||
| // | ||
| //Integer: | ||
| // IntegerLiteral | ||
| // | ||
| //IntegerLiteral: | ||
| // TOK_IntegerLiteral | ||
| // | ||
| //FloatLiteral: | ||
| // TOK_FloatLiteral | ||
| // | ||
| //StringLiteral: | ||
| // TOK_StringLiteral | ||
| // | ||
| //CharacterLiteral: | ||
| // TOK_CharacterLiteral | ||
| // | ||
| //// removed from grammar: | ||
| //// | ||
| ////Register: | ||
| //// AL AH AX EAX | ||
| //// BL BH BX EBX | ||
| //// CL CH CX ECX | ||
| //// DL DH DX EDX | ||
| //// BP EBP | ||
| //// SP ESP | ||
| //// DI EDI | ||
| //// SI ESI | ||
| //// ES CS SS DS GS FS | ||
| //// CR0 CR2 CR3 CR4 | ||
| //// DR0 DR1 DR2 DR3 DR6 DR7 | ||
| //// TR3 TR4 TR5 TR6 TR7 | ||
| //// ST | ||
| //// ST(0) ST(1) ST(2) ST(3) ST(4) ST(5) ST(6) ST(7) | ||
| //// MM0 MM1 MM2 MM3 MM4 MM5 MM6 MM7 | ||
| //// XMM0 XMM1 XMM2 XMM3 XMM4 XMM5 XMM6 XMM7 | ||
| //// |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,306 @@ | ||
| // This file is part of Visual D | ||
| // | ||
| // Visual D integrates the D programming language into Visual Studio | ||
| // Copyright (c) 2010-2011 by Rainer Schuetze, All Rights Reserved | ||
| // | ||
| // Distributed under the Boost Software License, Version 1.0. | ||
| // See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt | ||
|
|
||
| module vdc.ast.writer; | ||
|
|
||
| import vdc.lexer; | ||
| import vdc.util; | ||
| import vdc.parser.expr; | ||
| import vdc.parser.decl; | ||
| import vdc.parser.stmt; | ||
| import vdc.parser.aggr; | ||
| import vdc.parser.misc; | ||
| import vdc.parser.mod; | ||
| import ast = vdc.ast.all; | ||
|
|
||
| import std.stdio; | ||
| import std.array; | ||
|
|
||
| //////////////////////////////////////////////////////////////// | ||
| void delegate(string s) getStringSink(ref string s) | ||
| { | ||
| void stringSink(string txt) | ||
| { | ||
| s ~= txt; | ||
| } | ||
| return &stringSink; | ||
| } | ||
|
|
||
| void delegate(string s) getConsoleSink() | ||
| { | ||
| void consoleSink(string txt) | ||
| { | ||
| write(txt); | ||
| } | ||
| return &consoleSink; | ||
| } | ||
|
|
||
| class CodeWriter | ||
| { | ||
| alias void delegate(string s) Sink; | ||
|
|
||
| Sink sink; | ||
|
|
||
| bool writeDeclarations = true; | ||
| bool writeImplementations = true; | ||
| bool writeClassImplementations = true; | ||
| bool writeReferencedOnly = false; | ||
| bool newline; | ||
| bool lastLineEmpty; | ||
|
|
||
| string indentation; | ||
|
|
||
| this(Sink snk) | ||
| { | ||
| sink = snk; | ||
| } | ||
|
|
||
| abstract void writeNode(ast.Node node); | ||
|
|
||
| void write(T...)(T args) | ||
| { | ||
| if(newline) | ||
| { | ||
| sink(indentation); | ||
| newline = false; | ||
| } | ||
| foreach(t; args) | ||
| static if(is(typeof(t) : ast.Node)) | ||
| writeNode(t); | ||
| else static if(is(typeof(t) : int)) | ||
| writeKeyword(t); | ||
| else | ||
| sink(t); | ||
| } | ||
|
|
||
| void opCall(T...)(T args) | ||
| { | ||
| write(args); | ||
| } | ||
|
|
||
| void indent(int n) | ||
| { | ||
| if(n > 0) | ||
| indentation ~= replicate(" ", n); | ||
| else | ||
| indentation = indentation[0..$+n*2]; | ||
| } | ||
|
|
||
| void writeArray(T)(T[] members, string sep = ", ", bool beforeFirst = false, bool afterLast = false) | ||
| { | ||
| bool writeSep = beforeFirst; | ||
| foreach(m; members) | ||
| { | ||
| if(writeSep) | ||
| write(sep); | ||
| writeSep = true; | ||
| write(m); | ||
| } | ||
| if(afterLast) | ||
| write(sep); | ||
| } | ||
|
|
||
| @property void nl(bool force = true) | ||
| { | ||
| if(!lastLineEmpty) | ||
| force = true; | ||
|
|
||
| if(force) | ||
| { | ||
| sink("\n"); | ||
| lastLineEmpty = newline; | ||
| newline = true; | ||
| } | ||
| } | ||
|
|
||
| void writeKeyword(int id) | ||
| { | ||
| write(tokenString(id)); | ||
| } | ||
|
|
||
| void writeIdentifier(string ident) | ||
| { | ||
| write(ident); | ||
| } | ||
|
|
||
| bool writeAttributes(Attribute attr, bool spaceBefore = false) | ||
| { | ||
| if(!attr) | ||
| return false; | ||
| while(attr) | ||
| { | ||
| Attribute a = attr & -attr; | ||
| if(spaceBefore) | ||
| write(" "); | ||
| write(attrToString(a)); | ||
| if(!spaceBefore) | ||
| write(" "); | ||
| attr -= a; | ||
| } | ||
| return true; | ||
| } | ||
|
|
||
| bool writeAnnotations(Annotation annot, bool spaceBefore = false) | ||
| { | ||
| if(!annot) | ||
| return false; | ||
| while(annot) | ||
| { | ||
| Annotation a = annot & -annot; | ||
| if(spaceBefore) | ||
| write(" "); | ||
| write(annotationToString(a)); | ||
| if(!spaceBefore) | ||
| write(" "); | ||
| annot -= a; | ||
| } | ||
| return true; | ||
| } | ||
|
|
||
| void writeAttributesAndAnnotations(Attribute attr, Annotation annot, bool spaceBefore = false) | ||
| { | ||
| writeAttributes(attr, spaceBefore); | ||
| writeAnnotations(annot, spaceBefore); | ||
| } | ||
| } | ||
|
|
||
| class DCodeWriter : CodeWriter | ||
| { | ||
| this(Sink snk) | ||
| { | ||
| super(snk); | ||
| } | ||
|
|
||
| override void writeNode(ast.Node node) | ||
| { | ||
| node.toD(this); | ||
| } | ||
| } | ||
|
|
||
| class CCodeWriter : CodeWriter | ||
| { | ||
| this(Sink snk) | ||
| { | ||
| super(snk); | ||
| } | ||
|
|
||
| override void writeNode(ast.Node node) | ||
| { | ||
| node.toC(this); | ||
| } | ||
|
|
||
| override void writeKeyword(int id) | ||
| { | ||
| // Compiler-specific | ||
| switch(id) | ||
| { | ||
| case TOK_long: write("__int64"); break; | ||
| case TOK_alias: write("typedef"); break; | ||
| case TOK_in: write("const"); break; | ||
| default: | ||
| write(tokenString(id)); | ||
| } | ||
| } | ||
|
|
||
| override void writeIdentifier(string ident) | ||
| { | ||
| // check whether it conflicts with a C++ keyword | ||
| // Compiler-specific | ||
| switch(ident) | ||
| { | ||
| case "__int64": | ||
| case "__int32": | ||
| case "__int16": | ||
| case "__int8": | ||
| case "unsigned": | ||
| case "signed": | ||
| write(ident, "__D"); | ||
| break; | ||
| default: | ||
| write(ident); | ||
| break; | ||
| } | ||
| } | ||
|
|
||
| override bool writeAttributes(Annotation attr, bool spaceBefore = false) | ||
| { | ||
| if(!attr) | ||
| return false; | ||
| while(attr) | ||
| { | ||
| Attribute a = attr & -attr; | ||
| string cs = attrToStringC(a); | ||
| if(cs.length > 0) | ||
| { | ||
| if(spaceBefore) | ||
| write(" "); | ||
| write(cs); | ||
| if(!spaceBefore) | ||
| write(" "); | ||
| } | ||
| attr -= a; | ||
| } | ||
| return true; | ||
| } | ||
|
|
||
| override bool writeAnnotations(Annotation annot, bool spaceBefore = false) | ||
| { | ||
| return true; | ||
| } | ||
| } | ||
|
|
||
| struct CodeIndenter | ||
| { | ||
| CodeWriter writer; | ||
| int indent; | ||
|
|
||
| this(CodeWriter _writer, int n = 1) | ||
| { | ||
| writer = _writer; | ||
| indent = n; | ||
|
|
||
| writer.indent(n); | ||
| } | ||
| ~this() | ||
| { | ||
| writer.indent(-indent); | ||
| } | ||
| } | ||
|
|
||
| string writeD(ast.Node n) | ||
| { | ||
| string txt; | ||
| DCodeWriter writer = new DCodeWriter(getStringSink(txt)); | ||
| writer.writeImplementations = false; | ||
| writer.writeClassImplementations = false; | ||
| writer(n); | ||
| return txt; | ||
| } | ||
|
|
||
| //////////////////////////////////////////////////////////////// | ||
|
|
||
| version(all) { | ||
| import vdc.parser.engine; | ||
|
|
||
| void verifyParseWrite(string filename = __FILE__, int lno = __LINE__)(string txt) | ||
| { | ||
| Parser p = new Parser; | ||
| p.filename = filename; | ||
| ast.Node n = p.parseModule(txt); | ||
|
|
||
| string ntxt; | ||
| DCodeWriter writer = new DCodeWriter(getStringSink(ntxt)); | ||
| writer(n); | ||
|
|
||
| ast.Node m = p.parseModule(ntxt); | ||
| bool eq = n.compare(m); | ||
| assert(eq); | ||
| } | ||
|
|
||
| //////////////////////////////////////////////////////////////// | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,111 @@ | ||
| // This file is part of Visual D | ||
| // | ||
| // Visual D integrates the D programming language into Visual Studio | ||
| // Copyright (c) 2010-2011 by Rainer Schuetze, All Rights Reserved | ||
| // | ||
| // Distributed under the Boost Software License, Version 1.0. | ||
| // See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt | ||
|
|
||
| module vdc.logger; | ||
|
|
||
| import std.stdio; | ||
| import std.datetime; | ||
| import std.conv; | ||
| import std.string; | ||
| import std.array; | ||
|
|
||
| extern(Windows) void OutputDebugStringA(const char* lpOutputString); | ||
| extern(Windows) uint GetCurrentThreadId(); | ||
|
|
||
| import core.sys.windows.windows; | ||
|
|
||
| __gshared int gLogIndent = 0; | ||
| __gshared bool gLogFirst = true; | ||
| __gshared const string gLogFile = "c:/tmp/parser.log"; | ||
|
|
||
| //debug version = enableLog; | ||
|
|
||
| version(enableLog) { | ||
|
|
||
| struct LogIndent | ||
| { | ||
| this(int n) | ||
| { | ||
| indent = n; | ||
| gLogIndent += indent; | ||
| } | ||
| ~this() | ||
| { | ||
| gLogIndent -= indent; | ||
| } | ||
| int indent; | ||
| } | ||
|
|
||
| mixin template logIndent(int n = 1) | ||
| { | ||
| LogIndent indent = LogIndent(n); | ||
| } | ||
|
|
||
| class logSync {} | ||
|
|
||
| void logInfo(...) | ||
| { | ||
| auto buffer = new char[17 + 1]; | ||
| SysTime now = Clock.currTime(); | ||
| uint tid = GetCurrentThreadId(); | ||
| auto len = sprintf(buffer.ptr, "%02d:%02d:%02d - %04x - ", | ||
| now.hour, now.minute, now.second, tid); | ||
| string s = to!string(buffer[0..len]); | ||
| s ~= replicate(" ", gLogIndent); | ||
|
|
||
| void putc(dchar c) | ||
| { | ||
| s ~= c; | ||
| } | ||
|
|
||
| try { | ||
| std.format.doFormat(&putc, _arguments, _argptr); | ||
| } | ||
| catch(Exception e) | ||
| { | ||
| string msg = e.toString(); | ||
| s ~= " EXCEPTION"; | ||
| } | ||
|
|
||
| log_string(s); | ||
| } | ||
|
|
||
| void log_string(string s) | ||
| { | ||
| s ~= "\n"; | ||
| if(gLogFile.length == 0) | ||
| OutputDebugStringA(toStringz(s)); | ||
| else | ||
| synchronized(logSync.classinfo) | ||
| { | ||
| if(gLogFirst) | ||
| { | ||
| gLogFirst = false; | ||
| s = "\n" ~ replicate("=", 80) ~ "\n" ~ s; | ||
| } | ||
| std.file.append(gLogFile, s); | ||
| } | ||
| } | ||
| } | ||
| else | ||
| { | ||
| import core.vararg; | ||
|
|
||
| struct LogIndent | ||
| { | ||
| this(int n) | ||
| { | ||
| } | ||
| } | ||
| void logInfo(...) | ||
| { | ||
| } | ||
| void log_string(string s) | ||
| { | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,204 @@ | ||
| // This file is part of Visual D | ||
| // | ||
| // Visual D integrates the D programming language into Visual Studio | ||
| // Copyright (c) 2010-2011 by Rainer Schuetze, All Rights Reserved | ||
| // | ||
| // Distributed under the Boost Software License, Version 1.0. | ||
| // See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt | ||
|
|
||
| module vdc.parser.iasm; | ||
|
|
||
| import vdc.util; | ||
| import vdc.lexer; | ||
| import vdc.parser.engine; | ||
|
|
||
| import ast = vdc.ast.all; | ||
|
|
||
| class AsmInstruction | ||
| { | ||
| static Action enter(Parser p) | ||
| { | ||
| p.pushNode(new ast.AsmInstruction(p.tok)); | ||
| return shift(p); | ||
| } | ||
|
|
||
| static Action shift(Parser p) | ||
| { | ||
| switch(p.tok.id) | ||
| { | ||
| case TOK_EOF: | ||
| return p.parseError("end of file in asm block"); | ||
| case TOK_semicolon: | ||
| case TOK_rcurly: | ||
| return Forward; | ||
| default: | ||
| p.topNode!(ast.AsmInstruction).addToken(p.tok); | ||
| p.pushState(&shift); | ||
| return Accept; | ||
| } | ||
| } | ||
| } | ||
|
|
||
| //-- GRAMMAR_BEGIN -- | ||
| //AsmInstruction: | ||
| // Identifier : AsmInstruction | ||
| // "align" IntegerExpression | ||
| // "even" | ||
| // "naked" | ||
| // "db" Operands | ||
| // "ds" Operands | ||
| // "di" Operands | ||
| // "dl" Operands | ||
| // "df" Operands | ||
| // "dd" Operands | ||
| // "de" Operands | ||
| // Opcode | ||
| // Opcode Operands | ||
| // | ||
| //Operands: | ||
| // Operand | ||
| // Operand , Operands | ||
| // | ||
| //IntegerExpression: | ||
| // IntegerLiteral | ||
| // Identifier | ||
| // | ||
| //Operand: | ||
| // AsmExp | ||
| // | ||
| //AsmExp: | ||
| // AsmLogOrExp | ||
| // AsmLogOrExp ? AsmExp : AsmExp | ||
| // | ||
| //AsmLogOrExp: | ||
| // AsmLogAndExp | ||
| // AsmLogAndExp || AsmLogAndExp | ||
| // | ||
| //AsmLogAndExp: | ||
| // AsmOrExp | ||
| // AsmOrExp && AsmOrExp | ||
| // | ||
| //AsmOrExp: | ||
| // AsmXorExp | ||
| // AsmXorExp | AsmXorExp | ||
| // | ||
| //AsmXorExp: | ||
| // AsmAndExp | ||
| // AsmAndExp ^ AsmAndExp | ||
| // | ||
| //AsmAndExp: | ||
| // AsmEqualExp | ||
| // AsmEqualExp & AsmEqualExp | ||
| // | ||
| //AsmEqualExp: | ||
| // AsmRelExp | ||
| // AsmRelExp == AsmRelExp | ||
| // AsmRelExp != AsmRelExp | ||
| // | ||
| //AsmRelExp: | ||
| // AsmShiftExp | ||
| // AsmShiftExp < AsmShiftExp | ||
| // AsmShiftExp <= AsmShiftExp | ||
| // AsmShiftExp > AsmShiftExp | ||
| // AsmShiftExp >= AsmShiftExp | ||
| // | ||
| //AsmShiftExp: | ||
| // AsmAddExp | ||
| // AsmAddExp << AsmAddExp | ||
| // AsmAddExp >> AsmAddExp | ||
| // AsmAddExp >>> AsmAddExp | ||
| // | ||
| //AsmAddExp: | ||
| // AsmMulExp | ||
| // AsmMulExp + AsmMulExp | ||
| // AsmMulExp - AsmMulExp | ||
| // | ||
| //AsmMulExp: | ||
| // AsmBrExp | ||
| // AsmBrExp * AsmBrExp | ||
| // AsmBrExp / AsmBrExp | ||
| // AsmBrExp % AsmBrExp | ||
| // | ||
| //AsmBrExp: | ||
| // AsmUnaExp | ||
| // AsmBrExp [ AsmExp ] | ||
| // | ||
| //AsmUnaExp: | ||
| // AsmTypePrefix AsmExp | ||
| // "offsetof" AsmExp | ||
| // "seg" AsmExp | ||
| // + AsmUnaExp | ||
| // - AsmUnaExp | ||
| // ! AsmUnaExp | ||
| // ~ AsmUnaExp | ||
| // AsmPrimaryExp | ||
| // | ||
| //AsmPrimaryExp: | ||
| // IntegerLiteral | ||
| // FloatLiteral | ||
| // "__LOCAL_SIZE" | ||
| // $ | ||
| // Register | ||
| // DotIdentifier | ||
| // | ||
| //DotIdentifier: | ||
| // Identifier | ||
| // Identifier . DotIdentifier | ||
| // | ||
| //AsmTypePrefix: | ||
| // "near" "ptr" | ||
| // "far" "ptr" | ||
| // byte "ptr" | ||
| // short "ptr" | ||
| // int "ptr" | ||
| // "word" "ptr" | ||
| // "dword" "ptr" | ||
| // "qword" "ptr" | ||
| // float "ptr" | ||
| // double "ptr" | ||
| // real "ptr" | ||
| // | ||
| //Register: | ||
| // TOK_register | ||
| // | ||
| //Opcode: | ||
| // TOK_opcode | ||
| // | ||
| //Identifier: | ||
| // TOK_Identifier | ||
| // | ||
| //Integer: | ||
| // IntegerLiteral | ||
| // | ||
| //IntegerLiteral: | ||
| // TOK_IntegerLiteral | ||
| // | ||
| //FloatLiteral: | ||
| // TOK_FloatLiteral | ||
| // | ||
| //StringLiteral: | ||
| // TOK_StringLiteral | ||
| // | ||
| //CharacterLiteral: | ||
| // TOK_CharacterLiteral | ||
| // | ||
| //// removed from grammar: | ||
| //// | ||
| ////Register: | ||
| //// AL AH AX EAX | ||
| //// BL BH BX EBX | ||
| //// CL CH CX ECX | ||
| //// DL DH DX EDX | ||
| //// BP EBP | ||
| //// SP ESP | ||
| //// DI EDI | ||
| //// SI ESI | ||
| //// ES CS SS DS GS FS | ||
| //// CR0 CR2 CR3 CR4 | ||
| //// DR0 DR1 DR2 DR3 DR6 DR7 | ||
| //// TR3 TR4 TR5 TR6 TR7 | ||
| //// ST | ||
| //// ST(0) ST(1) ST(2) ST(3) ST(4) ST(5) ST(6) ST(7) | ||
| //// MM0 MM1 MM2 MM3 MM4 MM5 MM6 MM7 | ||
| //// XMM0 XMM1 XMM2 XMM3 XMM4 XMM5 XMM6 XMM7 | ||
| //// |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,124 @@ | ||
| // This file is part of Visual D | ||
| // | ||
| // Visual D integrates the D programming language into Visual Studio | ||
| // Copyright (c) 2010-2011 by Rainer Schuetze, All Rights Reserved | ||
| // | ||
| // Distributed under the Boost Software License, Version 1.0. | ||
| // See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt | ||
|
|
||
| module vdc.versions; | ||
|
|
||
| __gshared int[string] predefinedVersions; | ||
| alias AssociativeArray!(string, int) _wa1; // fully instantiate type info | ||
|
|
||
| static @property int[string] sPredefinedVersions() | ||
| { | ||
| if(!predefinedVersions) | ||
| { | ||
| // see http://dlang.org/version.html | ||
| // 1: always defined | ||
| // -1: always undefined | ||
| // 0: to be determined by compiler option | ||
| predefinedVersions = | ||
| [ | ||
| "DigitalMars" : 0, | ||
| "GNU" : 0, | ||
| "LDC" : 0, | ||
| "SDC" : -1, | ||
| "D_NET" : -1, | ||
|
|
||
| "Windows" : 1, | ||
| "Win32" : 0, | ||
| "Win64" : 0, | ||
| "linux" : -1, | ||
| "OSX" : -1, | ||
| "FreeBSD" : -1, | ||
| "OpenBSD" : -1, | ||
| "NetBSD" : -1, | ||
| "DragonFlyBSD" : -1, | ||
| "BSD" : -1, | ||
| "Solaris" : -1, | ||
| "Posix" : -1, | ||
| "AIX" : -1, | ||
| "Haiku" : -1, | ||
| "SkyOS" : -1, | ||
| "SysV3" : -1, | ||
| "SysV4" : -1, | ||
| "Hurd" : -1, | ||
| "Android" : -1, | ||
| "Cygwin" : -1, | ||
| "MinGW" : -1, | ||
|
|
||
| "X86" : 0, | ||
| "X86_64" : 0, | ||
| "ARM" : -1, | ||
| "ARM_Thumb" : -1, | ||
| "ARM_SoftFloat" : -1, | ||
| "ARM_SoftFP" : -1, | ||
| "ARM_HardFloat" : -1, | ||
| "AArch64" : -1, | ||
| "Epiphany" : -1, | ||
| "PPC" : -1, | ||
| "PPC_SoftFloat" : -1, | ||
| "PPC_HardFloat" : -1, | ||
| "PPC64" : -1, | ||
| "IA64" : -1, | ||
| "MIPS32" : -1, | ||
| "MIPS64" : -1, | ||
| "MIPS_O32" : -1, | ||
| "MIPS_N32" : -1, | ||
| "MIPS_O64" : -1, | ||
| "MIPS_N64" : -1, | ||
| "MIPS_EABI" : -1, | ||
| "MIPS_SoftFloat" : -1, | ||
| "MIPS_HardFloat" : -1, | ||
| "NVPTX" : -1, | ||
| "NVPTX64" : -1, | ||
| "SPARC" : -1, | ||
| "SPARC_V8Plus" : -1, | ||
| "SPARC_SoftFloat" : -1, | ||
| "SPARC_HardFloat" : -1, | ||
| "SPARC64" : -1, | ||
| "S390" : -1, | ||
| "S390X" : -1, | ||
| "HPPA" : -1, | ||
| "HPPA64" : -1, | ||
| "SH" : -1, | ||
| "SH64" : -1, | ||
| "Alpha" : -1, | ||
| "Alpha_SoftFloat" : -1, | ||
| "Alpha_HardFloat" : -1, | ||
|
|
||
| "LittleEndian" : 1, | ||
| "BigEndian" : -1, | ||
|
|
||
| "ELFv1" : -1, | ||
| "ELFv2" : -1, | ||
|
|
||
| "CRuntime_DigitalMars" : 0, | ||
| "CRuntime_Microsoft" : 0, | ||
| "CRuntime_Glibc" : -1, | ||
|
|
||
| "D_Coverage" : 0, | ||
| "D_Ddoc" : 0, | ||
| "D_InlineAsm_X86" : 0, | ||
| "D_InlineAsm_X86_64" : 0, | ||
| "D_LP64" : 0, | ||
| "D_X32" : -1, | ||
| "D_HardFloat" : 1, | ||
| "D_SoftFloat" : -1, | ||
| "D_PIC" : -1, | ||
| "D_SIMD" : 1, | ||
|
|
||
| "D_Version2" : 1, | ||
| "D_NoBoundsChecks" : 0, | ||
|
|
||
| "unittest" : 0, | ||
| "assert" : 0, | ||
|
|
||
| "none" : -1, | ||
| "all" : 1, | ||
| ]; | ||
| } | ||
| return predefinedVersions; | ||
| } |