Last active
May 21, 2016 13:34
-
-
Save rikkimax/160547d2fba5042e0893f9dd03a3d4ff to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module dcf.phase1; | |
import std.range.interfaces : InputRange; | |
final class DCFPhase1 : InputRange!char { | |
private { | |
InputRange!char source; | |
char next; | |
byte bufLeft; | |
char[3] buf; | |
} | |
this(InputRange!char source) { | |
this.source = source; | |
popFront; | |
} | |
@property { | |
bool empty() { | |
return source.empty && bufLeft == 0; | |
} | |
char front() { | |
return next; | |
} | |
} | |
char moveFront() { | |
scope(exit) popFront; | |
return next; | |
} | |
void popFront() { | |
if (bufLeft == -1) { | |
bufLeft = 0; | |
return; | |
} | |
// ensures our buffer is as full as it can be | |
while(bufLeft < 3 && !source.empty) { | |
if (bufLeft == 2) { | |
buf[2] = source.front; | |
source.popFront; | |
bufLeft = 3; | |
} else if (bufLeft == 1) { | |
buf[1] = source.front; | |
source.popFront; | |
bufLeft = 2; | |
} else if (bufLeft == 0) { | |
buf[0] = source.front; | |
source.popFront; | |
bufLeft = 1; | |
} | |
} | |
void replaceDigraph(char v) { | |
buf[0] = v; | |
if (bufLeft == 3) { | |
buf[1] = buf[2]; | |
bufLeft = 2; | |
} else if (bufLeft == 2) | |
bufLeft = 1; | |
} | |
if (bufLeft >= 2) { | |
switch(buf[0 .. 2]) { | |
case ['<', '%']: | |
replaceDigraph('{'); | |
break; | |
case ['%', '>']: | |
replaceDigraph('}'); | |
break; | |
case ['<', ':']: | |
replaceDigraph('['); | |
break; | |
case [':', '>']: | |
replaceDigraph(']'); | |
break; | |
case ['%', ':']: | |
replaceDigraph('#'); | |
break; | |
case ['\r', '\n']: | |
replaceDigraph('\n'); | |
break; | |
case ['\n', '\r']: | |
replaceDigraph('\n'); | |
break; | |
default: | |
break; | |
} | |
} | |
void replaceTrigraph(char v) { | |
buf[0] = v; | |
bufLeft = 1; | |
} | |
if (bufLeft == 3) { | |
switch(buf) { | |
case ['?', '?', '<']: | |
replaceTrigraph('{'); | |
break; | |
case ['?', '?', '>']: | |
replaceTrigraph('}'); | |
break; | |
case ['?', '?', '(']: | |
replaceTrigraph('['); | |
break; | |
case ['?', '?', ')']: | |
replaceTrigraph(']'); | |
break; | |
case ['?', '?', '=']: | |
replaceTrigraph('#'); | |
break; | |
case ['?', '?', '/']: | |
replaceTrigraph('\\'); | |
break; | |
case ['?', '?', '\'']: | |
replaceTrigraph('^'); | |
break; | |
case ['?', '?', '!']: | |
replaceTrigraph('|'); | |
break; | |
case ['?', '?', '-']: | |
replaceTrigraph('~'); | |
break; | |
default: | |
break; | |
} | |
} | |
if (bufLeft > 0) { | |
next = buf[0]; | |
bufLeft--; | |
} | |
if (bufLeft == 1) { | |
buf[0] = buf[1]; | |
} else if (bufLeft == 2) { | |
buf[0] = buf[1]; | |
buf[1] = buf[2]; | |
} | |
if (source.empty && bufLeft == 0) | |
bufLeft = -1; | |
} | |
int opApply(int delegate(char) dg) @trusted { | |
int result = 0; | |
while(!empty) { | |
result = dg(front); | |
popFront; | |
if (result) | |
break; | |
} | |
return result; | |
} | |
int opApply(int delegate(size_t i, char) dg) @trusted { | |
int result = 0; | |
size_t i; | |
while(!empty) { | |
result = dg(i, front); | |
popFront; | |
if (result) | |
break; | |
i++; | |
} | |
return result; | |
} | |
} | |
unittest { | |
import dcf.defs : stringInputRange; | |
import std.algorithm : equal; | |
string input = """ | |
%:include <stdlib.h> | |
%:include <stdio.h> | |
%:include <iso646.h> | |
int main(int argc, char** argv) | |
??< | |
if (argc > 1 and argv<:1:> not_eq NULL) | |
<% | |
printf(\"Hello%s\\n\", argv<:1:>); | |
%> | |
return EXIT_SUCCESS; | |
??> | |
"""; | |
DCFPhase1 range = new DCFPhase1(input.stringInputRange); | |
assert(range.equal(""" | |
#include <stdlib.h> | |
#include <stdio.h> | |
#include <iso646.h> | |
int main(int argc, char** argv) | |
{ | |
if (argc > 1 and argv[1] not_eq NULL) | |
{ | |
printf(\"Hello%s\\n\", argv[1]); | |
} | |
return EXIT_SUCCESS; | |
} | |
""")); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module alphacodegen.lang_d.test; | |
void main() { | |
import alphacodegen.common.lang.defs; | |
final class Token : IToken { | |
TokenIdentifier tokenId; | |
dstring text; | |
@property { | |
TokenIdentifier tokenIdentifier() { | |
return tokenId; | |
} | |
const(dchar[]) tokenText() { | |
return text; | |
} | |
} | |
} | |
alias Lex = LexicalPhaseGenerator!(() { | |
LexicalPhaseConfig config; | |
config.tokenCreator = q{ | |
auto ret = new Token; | |
ret.tokenId = identifier; | |
return ret; | |
}; | |
config.errorHandler = q{ | |
//throw new Exception("ICE: " ~ errorMessage); | |
}; | |
config.enable_c_singleline_comment = true; | |
config.enable_c_multiline_comment = true; | |
config.enable_D_multiline_comment = true; | |
config.enable_number_negative = true; | |
config.enable_number_floating = true; | |
config.enable_number_decimal = true; | |
config.enable_number_hexadecimal = true; | |
config.enable_number_octal = true; | |
config.enable_string_array = true; | |
config.enable_c_u8_stringhint = true; | |
config.enable_c_header_string = true; | |
config.enable_c_string_u = true; | |
config.enable_c_string_U = true; | |
config.enable_c_string_L = true; | |
config.enable_char_literal = true; | |
config.enable_c_char_u = true; | |
config.enable_c_char_U = true; | |
config.enable_c_char_L = true; | |
return config; | |
}(), char[], Token); | |
Lex lexer; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment