123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310 |
- import toml;
- public{
- import std.stdio : writeln;
- import std.file : read;
- import std.array;
- import std.string;
- import std.uni : isWhite, isAlpha, isAlphaNum;
- import std.ascii : isDigit;
- import std.conv : to;
- import std.algorithm;
- import std.sumtype : SumType;
- }
- import dopp_lexer : tokenize, isKeyword;
- import dopp_parser : parse;
- TOMLDocument toml_s;
- export enum TokenType{
- Identifier, // todo split to Type - Function - Variable
- Keyword,
- Integer,
- Float,
- String,
- Symbol,
- Whitespace, // maybe todo add equals and other (=, >=, <=, ==) - needs or not ?
- Comment_Line,
- New_Line,
- Match_Any
- }
- export struct Token{
- TokenType type;
- string lexeme;
-
- // for debug
- string toString(){
- import std.format : format;
- //return "Token(type: %d, lexeme: %s)".format(type, lexeme);
- //return "Token = type: %d, lexeme: %s\n".format(type, lexeme);
- return "Token = type: %d, lexeme: %s\n".format(type, ( (TokenType.New_Line == type) ? `\n` : lexeme) );
- }
- }
- // ./dopp -t == shortened for test (onto single .de -> .d module)
- // ./dopp -d "/test" -o "/test2" == input dir path + output dir path (default output dir = input dir)
- // ./dopp -f test.de -o test.d == input file name + output file name (default output file name = input file name [but .d instead .de] )
- // ./dopp -f "/test/test.de" -o "/result/test.d" == input file path + output file path (default output file name and path = input file name and path [but .d instead .de] )
- bool is_valid_argv(ref string[] argv){
- ulong num = argv.length; // uint64
- if(num != 1 && num != 2 && num != 4){
- return false;
-
- }else if(num == 1){ // one argument only (just filename or /path/filename) == shortened ./dopp -f test.de = ./dopp test.de; or -t == shortened for test (onto single .de -> .d module)
- if( (argv[0] == "-t") || (argv[0].length >= 4 && argv[0][$-3 .. $] == ".de") ){
- return true;
- }else{
- return false;
- }
-
- }else if(num == 2){ // two arguments = input file name/path or input dir path
- if(argv[0] != "-d" && argv[0] != "-f"){
- return false;
-
- }else if(argv[0] == "-f"){ // must be file
- if(argv[1].length >= 4 && argv[1][$-3 .. $] == ".de"){
- return true;
- }else{
- return false;
- }
-
- }else{ // dir
- if(argv[1].length > 0){
- return true;
- }else{
- return false;
- }
- }
-
- }else{ // num == 4
- string[] argv2 = argv[0 .. 2];
- if( is_valid_argv(argv2) ){ // valid first 2
- string[] argv4 = argv[2 .. $];
- if( argv[2] != "-o" ){ // valid next - last 2
- return false;
- }else if(argv[0] == "-f"){ // must be file
- if(argv[3].length >= 3 && argv[3][$-2 .. $] == ".d"){
- return true;
- }else{
- return false;
- }
-
- }else{ // dir
- if(argv[3].length > 0){
- return true;
- }else{
- return false;
- }
- }
-
- }else{
- return false;
- }
- }
- }
- //alias Config_Value = SumType!(string, int, ubyte, bool);
- alias Config_Value = SumType!(string, ubyte, bool);
- Config_Value get_config_value(ref TOMLDocument toml_s, string key){
- if(key == "indent_matter"){
- ubyte default_indent_matter = 4;
- if(("indent_matter" in toml_s) != null){
- if(toml_s[key].type == TOMLType.INTEGER){
- ubyte indent_matter = cast(ubyte) toml_s[key].integer; // long (int64) -> ubyte (uint8) // todo add alias
- if(indent_matter > 0){
- return Config_Value(indent_matter);
- }
- }
- }
- writeln("Warning: use default indent_matter = ", default_indent_matter); // todo add config key-value "no_warn" = false | true for silence
- return Config_Value(default_indent_matter);
-
- }else if(key == "indent_out"){
- ubyte default_indent_out = 2;
- if(("indent_out" in toml_s) != null){
- if(toml_s[key].type == TOMLType.INTEGER){
- ubyte indent_out = cast(ubyte) toml_s[key].integer; // long (int64) -> ubyte (uint8)
- if(indent_out > 0){
- return Config_Value(indent_out);
- }
- }
- }
- writeln("Warning: use default indent_out = ", default_indent_out);
- return Config_Value(default_indent_out);
-
- }else if(key == "indent_type"){ // 0 = whitespaces, 1 = tabs
- ubyte default_indent_type = 0;
- if(("indent_type" in toml_s) != null){
- if(toml_s[key].type == TOMLType.INTEGER){
- ubyte indent_type = cast(ubyte) toml_s[key].integer; // long (int64) -> ubyte (uint8)
- if(indent_type < 2){ // 0 | 1
- return Config_Value(indent_type);
- }
- }
- }
- writeln("Warning: use default indent_type = ", default_indent_type);
- return Config_Value(default_indent_type);
-
- //}else{}
-
- }
- return Config_Value(0);
- }
- //void main(string[] argv){
- int main(string[] argv){
-
- toml_s = parseTOML(cast(string)read("dopp.toml"));
-
- /*
- writeln("indent_matter: ", toml_s["indent_matter"]); // 4
- //writeln("xyz: ", toml_s["xyz"]); // Address boundary error || Segmentation fault (core dumped)
- writeln("indent_matter in: ", "indent_matter" in toml_s); // hex like 7F27C2992040
- writeln("indent_matter is null: ", ("indent_matter" in toml_s) == null); // fasle
- writeln("indent_matter is TOMLType.INTEGER: ", (toml_s["indent_matter"].type == TOMLType.INTEGER)); // true
- writeln("xyz in: ", "xyz" in toml_s); // null
- writeln("xyz is null: ", ("xyz" in toml_s) == null); // true
- */
-
-
- auto indent_type = get_config_value(toml_s, "indent_type");
- //writeln("config: indent_type = ", indent_type); // 0 // todo add config key-value "no_warn" = false | true for silence
-
- auto indent_matter = get_config_value(toml_s, "indent_matter");
- //writeln("config: indent_matter = ", indent_matter); // 4
-
- auto indent_out = get_config_value(toml_s, "indent_out");
- //writeln("config: indent_out = ", indent_out); // 2
-
-
- /*
- int i = 0;
- foreach(string s; argv[1 .. $]){
- writeln(s);
- i++;
- }
- writeln("i = ", i);
- */
-
- string[] argv1 = argv[1 .. $]; // argv[0] always = program name ( ./dopp in my case in linux )
- bool valid_argv = is_valid_argv(argv1);
- // writeln("valid_argv = ", valid_argv); // todo add config key-value "no_warn" = false | true for silence
-
- if(!valid_argv){
- return 0;
- }
-
-
-
- //string source = `if (x > 0) { writeln("Positive"); }`;
- /+
- string source = q"[
- if (x > 0) {
- writeln("Pos`it`i've'");
- }
- ]";
- +/
-
- //string str1 = "this is test"; // valid in dlang
- //string str1 = "this \"is\" test"; // valid in dlang
- //string str1 = "this `is` test"; // valid in dlang
- //string str1 = `this "is" test`; // valid in dlang
- // //string str1 = `this `is` test`; // not valid in dlang - but valid in my lexer-parser
- //string str1 = `this ` ~ "`is`" ~ ` test`; // valid in dlang
- // todo add to lexer r" .. ";
- // todo add to lexer multiline q"[ .. ]";
- // todo add to lexer //string str1 = x"48 65 6C 6C 6F"; // valid in dlang - hex string // Hello
- //writeln(str1);
-
- //writeln("hey" ~ '\n' ~ "hello");
-
- string source = q"[
- auto y1 = "this is test";
- auto y2 = "this \"is\" test";
- auto y3 = `this "is" test`; // this is single line comment
- auto y4 = `this is test`;
- auto y5 = `this `is` test`;
- ]"; // "
-
- /+
- string source = q"[
- auto x = 5;
- auto x2 = 5_001;
- auto y1 = "this is test";
- auto y2 = "this \"is\" test";
- auto y3 = `this "is" test`;
- auto z = 1;
- ]"; // "
- +/
-
- /+
- string source = q"[
- void main(){
- auto x = 5;
- auto y = ptn x
- 1 = 1
- 5 = 5 * 2
- 9 = 9 * 3
- _ = x * 4
- }
- ]";
- +/
-
- auto tokens = tokenize(source, 0, 2); // indent_type = 0 = whitespace; indent_matter = 2 (whitespaces)
- writeln(tokens);
- auto result = parse(tokens); // indent_out = 2 (whitespaces in output-generated code)
- writeln(result);
-
- /+
- void main(){
- auto x = 5;
- if(x == 1){
- y = 1;
- }else if(x == 5){
- y = 5 * 2; // return x * 2;
- }else if(x == 9){
- y = 9 * 3; // return x * 3;
- }else{ // other cases
- y = x * 4;
- }
- }
- +/
-
-
- return 1;
- }
- unittest{
- assert( is_valid_argv([]) == false );
- assert( is_valid_argv([""]) == false );
- assert( is_valid_argv(["-t"]) == true );
- assert( is_valid_argv(["-d"]) == false );
- assert( is_valid_argv(["-d", ""]) == false );
- assert( is_valid_argv(["-d", "/test"]) == true );
- assert( is_valid_argv(["-d", "/test", "-o", "/test2"]) == true );
- assert( is_valid_argv(["test.de"]) == true );
- assert( is_valid_argv(["-f", "test.de"]) == true );
- assert( is_valid_argv(["-f", "test.de", "-o", "test.d"]) == true );
- assert( is_valid_argv(["test.txt"]) == false );
- assert( is_valid_argv(["-f", "test.txt"]) == false );
- assert( is_valid_argv(["-f", "test.txt", "-o", "test.d"]) == false );
- assert( is_valid_argv(["-f", "test.de", "-o", "test.txt"]) == false );
- }
- // ./dopp -t == shortened for test (onto single .de -> .d module)
- // ./dopp -d "/test" -o "/test2" == input dir path + output dir path (default output dir = input dir)
- // ./dopp -f test.de -o test.d == input file name + output file name (default output file name = input file name [but .d instead .de] )
- // ./dopp -f "/test/test.de" -o "/result/test.d" == input file path + output file path (default output file name and path = input file name and path [but .d instead .de] )
|