221V 1 месяц назад
Родитель
Сommit
675b73501d
3 измененных файлов с 129 добавлено и 12 удалено
  1. 14 12
      source/dopp.d
  2. 61 0
      source/dopp_lexer.d
  3. 54 0
      source/dopp_parser.d

+ 14 - 12
source/dopp.d

@@ -13,8 +13,8 @@ public{
   import std.sumtype : SumType;
 }
 
-//import dopp_lexer : tokenize, isKeyword;
-//import dopp_parser : parse;
+import dopp_lexer : tokenize, isKeyword;
+import dopp_parser : parse;
 
 
 TOMLDocument toml_s;
@@ -175,13 +175,13 @@ int main(string[] argv){
   
   
   auto indent_type = get_config_value(toml_s, "indent_type");
-  writeln("config: indent_type = ", indent_type); // 0
+  //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
+  //writeln("config: indent_matter = ", indent_matter); // 4
   
   auto indent_out = get_config_value(toml_s, "indent_out");
-  writeln("config: indent_out = ", indent_out); // 2
+  //writeln("config: indent_out = ", indent_out); // 2
   
   
   /*
@@ -194,19 +194,21 @@ int main(string[] argv){
   */
   
   string[] argv1 = argv[1 .. $]; // argv[0] always = program name ( ./dopp in my case in linux )
-  bool valid1 = is_valid_argv(argv1);
-  writeln("valid1 = ", valid1);
+  bool valid_argv = is_valid_argv(argv1);
+  // writeln("valid_argv = ", valid_argv); // todo add config key-value "no_warn" = false | true for silence
   
-  if(!valid1){
+  if(!valid_argv){
     return 0;
   }
   
   
   
-  //string source = `if (x > 0) { writeln("Positive"); }`;
-  //auto tokens = tokenize(source);
-  //writeln(tokens);
-  //parse(tokens);
+  string source = `if (x > 0) { writeln("Positive"); }`;
+  auto tokens = tokenize(source);
+  writeln(tokens);
+  parse(tokens);
+  
+  
   
   return 1;
 }

+ 61 - 0
source/dopp_lexer.d

@@ -0,0 +1,61 @@
+
+import dopp;
+
+// helper - is lexeme keyword
+export bool isKeyword(string lexeme){
+  static immutable keywords = ["if", "else", "while", "for", "return"];
+  return keywords.canFind(lexeme);
+}
+
+
+// lexer - Tokenizer makes tokens from text
+export Token[] tokenize(string source){
+  Token[] tokens;
+  int i = 0;
+  while(i < source.length){
+    
+    if(source[i].isWhite){ // skip whitespaces
+      i++;
+    
+    }else if(source[i].isAlpha || source[i] == '_'){
+      auto start = i;
+      while(i < source.length && (source[i].isAlphaNum || source[i] == '_')){
+        i++;
+      }
+      string lexeme = source[start .. i];
+      tokens ~= Token(lexeme.isKeyword ? TokenType.Keyword : TokenType.Identifier, lexeme);
+    
+    }else if(source[i].isDigit){
+      auto start = i;
+      while(i < source.length && source[i].isDigit){
+        i++;
+      }
+      if(i < source.length && source[i] == '.'){ // include dot for float
+        i++;
+        while(i < source.length && source[i].isDigit){
+          i++;
+        }
+        tokens ~= Token(TokenType.Float, source[start .. i]);
+      
+      }else{
+        tokens ~= Token(TokenType.Integer, source[start .. i]);
+      }
+    
+    }else if(source[i] == '"'){
+      auto start = i++;
+      while(i < source.length && source[i] != '"'){
+        i++;
+      }
+      if(i < source.length){ // close quotes
+        i++;
+      }
+      tokens ~= Token(TokenType.String, source[start .. i]);
+    
+    }else{ // common symbols as tokens
+      tokens ~= Token(TokenType.Symbol, source[i].to!string);
+      i++;
+    }
+  }
+  return tokens;
+}
+

+ 54 - 0
source/dopp_parser.d

@@ -0,0 +1,54 @@
+
+import dopp;
+
+// Parser checks tokens for correct program
+export void parse(Token[] tokens){
+  auto i = 0;
+  while(i < tokens.length){
+    if(tokens[i].type == TokenType.Keyword && tokens[i].lexeme == "if"){
+      if(i + 2 < tokens.length && tokens[i+1].type == TokenType.Symbol && tokens[i+1].lexeme == "("){ // if begins
+        writeln("Found 'if' statement");
+        i++; // goto (
+        // here parsing inside ( .. ) can be extended
+        while(i < tokens.length && tokens[i].lexeme != ")"){
+          i++;
+        }
+        
+        if(i < tokens.length && tokens[i].lexeme == ")"){
+          i++; // goto )
+          
+          if(i < tokens.length && tokens[i].lexeme == "{"){ // block of code
+            writeln("Opening block for if statement");
+            
+            // here parsing inside { .. } can be extended
+            while(i < tokens.length && tokens[i].lexeme != "}"){
+              i++;
+            }
+            
+            if(i < tokens.length && tokens[i].lexeme == "}"){
+              writeln("Closing block for if statement");
+              i++;
+            }else{
+              writeln("Error: Missing closing brace for if block");
+              return;
+            }
+          
+          }else{
+            writeln("Error: Expected opening brace after if condition");
+            return;
+          }
+        
+        }else{
+          writeln("Error: Missing closing parenthesis for if condition");
+          return;
+        }
+      
+      }else{
+        writeln("Error: Invalid if statement syntax");
+        return;
+      }
+    }
+    i++; // goto next token
+  }
+}
+