diff --git a/src/lexer.rs b/src/lexer.rs index b0144a8..b1b669a 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|cb)\b").unwrap()) + token_regex: Lazy::new(|| Regex::new(r"^(mut|try|catch|return|fn|let|use|cb|struct|impl|for|in)\b").unwrap()) }, Node { token_type: TokenType::Identifier, diff --git a/src/main.rs b/src/main.rs index 643b678..7a1134e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -5,6 +5,7 @@ mod compile; use std::fs; use clap::Parser; use lexer::LexerState; +use transpiler::Options; // Arguments for Wyst (short and long version) #[derive(Parser)] @@ -24,7 +25,7 @@ fn main() { let file_content = fs::read_to_string(&args.file) .expect("Error reading file"); - let transpiled_code = transpiler::transpile(file_content, 0, LexerState { line: 1, column: 0 }); + let transpiled_code = transpiler::transpile(file_content, 0, LexerState { line: 1, column: 0 }, Options::default()); match args.rust { Some(ref rust_file_name) => { diff --git a/src/parser.rs b/src/parser.rs index 419211c..11b4e07 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -6,6 +6,7 @@ use once_cell::sync::Lazy; #[derive(Clone, Debug, PartialEq, Eq)] pub enum AstType { FunctionDeceleration, + StructDeceleration, VoidFunctionDeceleration, VariableDeceleration, PointerDeceleration, @@ -78,6 +79,11 @@ impl Parser { ast_res.tokens.push(self.tokens[index].clone()); ast_res.tokens.push(self.tokens[index+2].clone()); self.index += 2; + } else if self.tokens.len()-index > 2 && self.tokens[index].value == "struct" && self.tokens[index+1].token_type==TokenType::Identifier && self.tokens[index+2].token_type==TokenType::Curly { + ast_res.tokens.push(self.tokens[index+1].clone()); + ast_res.tokens.push(self.tokens[index+2].clone()); + ast_res.ast_type = AstType::StructDeceleration; + self.index += 2; } else { match token.token_type { TokenType::Identifier => { diff --git a/src/transpiler.rs b/src/transpiler.rs index fb4d800..6c6ebde 100644 --- a/src/transpiler.rs +++ b/src/transpiler.rs @@ -1,7 +1,18 @@ use crate::lexer::{lex, LexerState, TokenType}; use crate::parser::{Ast, AstType, Parser}; -pub fn transpile(input: String, indent: u32, state: LexerState) -> String { +#[derive(Debug, PartialEq, Clone, Copy)] +pub struct Options { + auto_mut: bool +} + +impl Default for Options { + fn default() -> Options { + Options { auto_mut: true } + } +} + +pub fn transpile(input: String, indent: u32, state: LexerState, options: Options) -> String { let mut result = String::new(); if indent == 0 { @@ -35,7 +46,8 @@ pub fn transpile(input: String, indent: u32, state: LexerState) -> String { LexerState { line: ast.tokens[3].line, column: ast.tokens[3].column - } + }, + options ) ) .as_str(); @@ -53,13 +65,32 @@ pub fn transpile(input: String, indent: u32, state: LexerState) -> String { LexerState { line: ast.tokens[3].line, column: ast.tokens[3].column - } + }, + options.clone() ) ) .as_str(); + } else if ast.ast_type == AstType::StructDeceleration { + result += format!( + "struct {} {} {}", + ast.tokens[0].value, + "{\n", + transpile_round( + ast.tokens[1].value.clone(), + LexerState { + line: ast.tokens[1].line, + column: ast.tokens[1].column + } + ).trim_end() + ).replace("\n", ("\n".to_string() + " ".repeat(((indent+1) as usize)*2).as_str()).as_str()) + .as_str(); + result += "\n}\n"; } else if ast.ast_type == AstType::VariableDeceleration { - result += format!("let mut {}: {}", ast.tokens[1].value, ast.tokens[0].value).as_str(); - // result += format!("let {}: {}", ast.tokens[1].value, ast.tokens[0].value).as_str(); + if options.auto_mut { + result += format!("let mut {}: {}", ast.tokens[1].value, ast.tokens[0].value).as_str(); + } else { + result += format!("let {}: {}", ast.tokens[1].value, ast.tokens[0].value).as_str(); + } } else if ast.ast_type == AstType::MutVariableDeceleration { result += format!("let mut {}: {}", ast.tokens[1].value, ast.tokens[0].value).as_str(); } else if ast.tokens.len() == 1 && ast.tokens[0].token_type == TokenType::Round {