From 02245401b9f53e8fe1e0bccf51923c38c082d4e3 Mon Sep 17 00:00:00 2001 From: Leo Dev Date: Sun, 12 May 2024 17:15:38 +0200 Subject: [PATCH] added json. By using HashMap --- src/lexer.rs | 32 +++++++++++++- src/parser.rs | 109 ++++++++++++++++++++++++++-------------------- src/transpiler.rs | 92 ++++++++++++++++++++++++++++++++++---- 3 files changed, 175 insertions(+), 58 deletions(-) diff --git a/src/lexer.rs b/src/lexer.rs index 622e046..b0144a8 100644 --- a/src/lexer.rs +++ b/src/lexer.rs @@ -72,7 +72,7 @@ const SYNTAX: [Node; 14] = [ }, Node { token_type: TokenType::Keyword, - token_regex: Lazy::new(|| Regex::new(r"^(mut|try|catch|return|fn|let|use)\b").unwrap()) + token_regex: Lazy::new(|| Regex::new(r"^(mut|try|catch|return|fn|let|use|cb)\b").unwrap()) }, Node { token_type: TokenType::Identifier, @@ -80,7 +80,7 @@ const SYNTAX: [Node; 14] = [ }, Node { token_type: TokenType::Number, - token_regex: Lazy::new(|| Regex::new(r"^(:?.)?(:?0[x|X])?\d+(:?.\d+)?\b").unwrap()) + token_regex: Lazy::new(|| Regex::new(r"^\d+").unwrap()) }, Node { token_type: TokenType::Ptr, @@ -153,7 +153,21 @@ pub fn lex(mut code: &str, use_whitespace: bool, state: LexerState) -> Result Result { diff --git a/src/parser.rs b/src/parser.rs index d97826b..419211c 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -13,6 +13,7 @@ pub enum AstType { Include, IncludeLocal, CodeBlock, + Json, Other } @@ -53,7 +54,8 @@ pub struct Parser { pub tokens: Vec, pub index: u32, pub include_regex: Lazy, - pub include_regex_local: Lazy + pub include_regex_local: Lazy, + pub json: bool } impl Parser { @@ -62,7 +64,8 @@ impl Parser { tokens: tokens, index: 0, include_regex: Lazy::new(|| Regex::new(r"^(#include *)<(.*?)>").unwrap()), - include_regex_local: Lazy::new(|| Regex::new(r#"^(#include *)"(.*?)""#).unwrap()) + include_regex_local: Lazy::new(|| Regex::new(r#"^(#include *)"(.*?)""#).unwrap()), + json: false } } pub fn next(&mut self) -> Ast { @@ -70,61 +73,73 @@ impl Parser { let index = self.index as usize; if index == self.tokens.len() {panic!("Reached the end of tokens")} let token = &self.tokens[index]; - match token.token_type { - TokenType::Identifier => { - ast_res.tokens.push(self.tokens[index].clone()); - if self.tokens.len()-index > 3 && self.tokens[index+1].token_type==TokenType::Identifier && self.tokens[index+2].token_type==TokenType::Round && self.tokens[index+3].token_type==TokenType::Curly { - ast_res.tokens.push(self.tokens[index+1].clone()); - ast_res.tokens.push(self.tokens[index+2].clone()); - ast_res.tokens.push(self.tokens[index+3].clone()); - if token.value == "void" { - ast_res.ast_type = AstType::VoidFunctionDeceleration; - } else { - ast_res.ast_type = AstType::FunctionDeceleration; + if self.json && self.tokens.len() - (self.index as usize) > 2 && self.tokens[index+1].value == ":" { + ast_res.ast_type = AstType::Json; + ast_res.tokens.push(self.tokens[index].clone()); + ast_res.tokens.push(self.tokens[index+2].clone()); + self.index += 2; + } else { + match token.token_type { + TokenType::Identifier => { + ast_res.tokens.push(self.tokens[index].clone()); + if self.tokens.len()-index > 3 && self.tokens[index+1].token_type==TokenType::Identifier && self.tokens[index+2].token_type==TokenType::Round && self.tokens[index+3].token_type==TokenType::Curly { + ast_res.tokens.push(self.tokens[index+1].clone()); + ast_res.tokens.push(self.tokens[index+2].clone()); + ast_res.tokens.push(self.tokens[index+3].clone()); + if token.value == "void" { + ast_res.ast_type = AstType::VoidFunctionDeceleration; + } else { + ast_res.ast_type = AstType::FunctionDeceleration; + } + self.index += 3; + } else if self.tokens.len()-index > 1 { + if self.tokens[index+1].token_type==TokenType::Identifier { + ast_res.tokens.push(self.tokens[index+1].clone()); + ast_res.ast_type = AstType::VariableDeceleration; + self.index += 1; + } else if self.tokens[index+2].token_type==TokenType::Identifier && self.tokens[index+1].token_type==TokenType::Angle { + ast_res.tokens.push(self.tokens[index+2].clone()); + ast_res.tokens[0].value += "<"; + ast_res.tokens[0].value += self.tokens[index+1].value.as_str(); + ast_res.tokens[0].value += ">"; + ast_res.ast_type = AstType::VariableDeceleration; + self.index += 2; + } else if self.tokens[index+1].value=="mut" && self.tokens[index+2].token_type==TokenType::Identifier { + ast_res.tokens.push(self.tokens[index+2].clone()); + ast_res.ast_type = AstType::MutVariableDeceleration; + self.index += 2; + } else if self.tokens[index+1].value=="*" && self.tokens[index+2].token_type==TokenType::Identifier { + ast_res.tokens.push(self.tokens[index+2].clone()); + ast_res.ast_type = AstType::PointerDeceleration; + self.index += 2; + } } - self.index += 3; - } else if self.tokens.len()-index > 1 { + } + TokenType::Include => { + if let Some(caps) = self.include_regex.captures(&token.value) { + ast_res.tokens.push(Token {token_type: TokenType::String, value: caps[2].to_owned().to_string(), line: 0, column: 0}); + ast_res.ast_type = AstType::Include; + } else if let Some(caps) = self.include_regex_local.captures(&token.value) { + ast_res.tokens.push(Token {token_type: TokenType::String, value: caps[2].to_owned().to_string(), line: 0, column: 0}); + ast_res.ast_type = AstType::IncludeLocal; + } else { + ast_res.tokens.push(token.clone()); + ast_res.ast_type = AstType::Include; + } + } + TokenType::Keyword => { if token.value == "cb" && self.tokens[index+1].token_type == TokenType::Curly { ast_res.tokens.push(self.tokens[index+1].clone()); ast_res.ast_type = AstType::CodeBlock; self.index += 1; - } else if self.tokens[index+1].token_type==TokenType::Identifier { - ast_res.tokens.push(self.tokens[index+1].clone()); - ast_res.ast_type = AstType::VariableDeceleration; - self.index += 1; - } else if self.tokens[index+2].token_type==TokenType::Identifier && self.tokens[index+1].token_type==TokenType::Angle { - ast_res.tokens.push(self.tokens[index+2].clone()); - ast_res.tokens[0].value += "<"; - ast_res.tokens[0].value += self.tokens[index+1].value.as_str(); - ast_res.tokens[0].value += ">"; - ast_res.ast_type = AstType::VariableDeceleration; - self.index += 2; - } else if self.tokens[index+1].value=="mut" && self.tokens[index+2].token_type==TokenType::Identifier { - ast_res.tokens.push(self.tokens[index+2].clone()); - ast_res.ast_type = AstType::MutVariableDeceleration; - self.index += 2; - } else if self.tokens[index+1].value=="*" && self.tokens[index+2].token_type==TokenType::Identifier { - ast_res.tokens.push(self.tokens[index+2].clone()); - ast_res.ast_type = AstType::PointerDeceleration; - self.index += 2; + } else { + ast_res.tokens.push(token.clone()); } } - } - TokenType::Include => { - if let Some(caps) = self.include_regex.captures(&token.value) { - ast_res.tokens.push(Token {token_type: TokenType::String, value: caps[2].to_owned().to_string(), line: 0, column: 0}); - ast_res.ast_type = AstType::Include; - } else if let Some(caps) = self.include_regex_local.captures(&token.value) { - ast_res.tokens.push(Token {token_type: TokenType::String, value: caps[2].to_owned().to_string(), line: 0, column: 0}); - ast_res.ast_type = AstType::IncludeLocal; - } else { + _ => { ast_res.tokens.push(token.clone()); - ast_res.ast_type = AstType::Include; } } - _ => { - ast_res.tokens.push(token.clone()); - } } self.index += 1; ast_res diff --git a/src/transpiler.rs b/src/transpiler.rs index 83df2eb..95c2056 100644 --- a/src/transpiler.rs +++ b/src/transpiler.rs @@ -80,15 +80,24 @@ pub fn transpile(input: String, indent: u32, state: LexerState) -> String { }) ) .as_str(); + } else if ast.ast_type == AstType::CodeBlock { + println!("this is fine"); + result+="{"; + result+=ast.tokens[0].value.as_str(); + result+="}"; } else if ast.tokens.len() == 1 && ast.tokens[0].token_type == TokenType::Curly { - if ast.tokens[0].token_type == TokenType::Newline { - result += (ast.tokens[0].value.as_str().to_owned() - + (" ".repeat((indent as usize) * 2).as_str())) - .as_str(); - } else { - result += ast.tokens[0].value.as_str(); - } - } else if ast.tokens.len() == 1 && ast.tokens[0].token_type == TokenType::Ptr { + // if ast.tokens[0].token_type == TokenType::Newline { + // result += (ast.tokens[0].value.as_str().to_owned() + // + (" ".repeat((indent as usize) * 2).as_str())) + // .as_str(); + // } else { + // result += ast.tokens[0].value.as_str(); + result += transpile_json(ast.tokens[0].value.as_str().to_string(), LexerState { + line: ast.tokens[0].line, + column: ast.tokens[0].column + }).as_str(); + // } + } else if ast.tokens.len() == 1 && ast.tokens[0].token_type == TokenType::Ptr { result+="."; } // flp else { @@ -141,7 +150,6 @@ pub fn transpile_round(input: String, state: LexerState) -> String { match lexer_out { Ok(tokens) => { let mut full_ast = Parser::new(tokens.clone()); - while full_ast.tokens.len() > full_ast.index as usize { let ast = full_ast.next(); if ast.ast_type == AstType::VariableDeceleration { @@ -170,6 +178,11 @@ pub fn transpile_round(input: String, state: LexerState) -> String { .as_str(); } else if ast.tokens.len() == 1 && ast.tokens[0].token_type == TokenType::Ptr { result+="."; + } else if ast.tokens.len() == 1 && ast.tokens[0].token_type == TokenType::Curly { + result += transpile_json(ast.tokens[0].value.as_str().to_string(), LexerState { + line: ast.tokens[0].line, + column: ast.tokens[0].column + }).as_str(); } // flp else { result += ast.tokens[0].value.as_str(); @@ -224,6 +237,11 @@ pub fn transpile_square(input: String, state: LexerState) -> String { .as_str(); } else if ast.tokens.len() == 1 && ast.tokens[0].token_type == TokenType::Ptr { result+="."; + } else if ast.tokens.len() == 1 && ast.tokens[0].token_type == TokenType::Curly { + result += transpile_json(ast.tokens[0].value.as_str().to_string(), LexerState { + line: ast.tokens[0].line, + column: ast.tokens[0].column + }).as_str(); } // flp else { result += ast.tokens[0].value.as_str(); @@ -238,4 +256,60 @@ pub fn transpile_square(input: String, state: LexerState) -> String { panic!("Invalid syntax at code.ws:{}:{}", state.line, state.column); } } +} + +pub fn transpile_json(input: String, state: LexerState) -> String { + let mut result = String::new(); + let lexer_out = lex(input.as_str(), false, state); + + match lexer_out { + Ok(tokens) => { + let mut full_ast = Parser::new(tokens.clone()); + full_ast.json = true; + result += "HashMap::from(["; + while full_ast.tokens.len() > full_ast.index as usize { + let ast = full_ast.next(); + println!("{ast}"); + if ast.ast_type == AstType::Json { + result += "("; + result += ast.tokens[0].value.as_str(); + result += ","; + result += ast.tokens[1].value.as_str(); + result += ")"; + } else if ast.tokens.len() == 1 && ast.tokens[0].token_type == TokenType::Round { + result += format!( + "({})", + transpile_round(ast.tokens[0].value.clone(), LexerState { + line: ast.tokens[0].line, + column: ast.tokens[0].column + }) + ) + .as_str(); + } else if ast.tokens.len() == 1 && ast.tokens[0].token_type == TokenType::Square { + result += format!( + "[{}]", + transpile_square(ast.tokens[0].value.clone(), LexerState { + line: ast.tokens[0].line, + column: ast.tokens[0].column + }) + ) + .as_str(); + } else if ast.tokens.len() == 1 && ast.tokens[0].token_type == TokenType::Curly { + result += transpile_json(ast.tokens[0].value.as_str().to_string(), LexerState { + line: ast.tokens[0].line, + column: ast.tokens[0].column + }).as_str(); + } else { + result += ast.tokens[0].value.as_str(); + result += " "; + } + } + result += "])"; + result = result.trim_end().to_string(); + result + } + Err((state, _tokens)) => { + panic!("Invalid syntax at code.ws:{}:{}", state.line, state.column); + } + } } \ No newline at end of file