diff --git a/src/compile.rs b/src/compile.rs deleted file mode 100644 index 032a5f1..0000000 --- a/src/compile.rs +++ /dev/null @@ -1,57 +0,0 @@ -use std::fs; -use std::io::{Error, ErrorKind}; -use std::path::Path; -use std::process::Command; - -pub fn write_to_rust_file(transpiled_code: &str, file_name: &str) -> Result<(), Error> { - // Determine the file extension based on the provided file_name - let mut output_file = String::from(file_name); - if let Some(extension) = Path::new(file_name).extension() { - if let Some(ext_str) = extension.to_str() { - // Replace the existing extension with ".rs" if it's not already ".rs" - if ext_str != "rs" { - output_file.push_str(".rs"); - } - } - } else { - // If no extension is provided, append ".rs" to the file_name - output_file.push_str(".rs"); - } - - // Write the transpiled_code to the determined output file - fs::write(&output_file, transpiled_code)?; - - Ok(()) -} - -pub fn compile_to_executable(output_exe: &str) -> Result<(), Error> { - let output = Command::new("rustc") - .arg("main.rs".to_string()) - .arg("-o") - .arg(output_exe) - .output()?; - - // Check if compilation was successful - if output.status.success() { - println!("Compilation successful!"); - } else { - if let Some(code) = output.status.code() { - eprintln!("Compilation failed with error code: {}", code); - } - if !output.stdout.is_empty() { - eprintln!( - "Compiler output:\n{}", - String::from_utf8_lossy(&output.stdout) - ); - } - if !output.stderr.is_empty() { - eprintln!( - "Compiler errors:\n{}", - String::from_utf8_lossy(&output.stderr) - ); - } - return Err(Error::new(ErrorKind::Other, "Compilation failed")); - } - - Ok(()) -} diff --git a/src/dllmgr.rs b/src/dllmgr.rs deleted file mode 100644 index c81f064..0000000 --- a/src/dllmgr.rs +++ /dev/null @@ -1,76 +0,0 @@ -use regex::Regex; -use std::fs; -use std::io::Write; -use std::{ - fs::File, - io::{BufReader, Read}, -}; -use zip::{write::SimpleFileOptions, ZipArchive, ZipWriter}; - -use crate::variable::Variables; - -pub fn read_dll(dll_path: String) -> Variables { - let mut vars = Variables::new(); - let dll_file = File::open(dll_path).expect("err_dll_read"); - let dll_reader = BufReader::new(dll_file); - let mut dll_zip = ZipArchive::new(dll_reader).expect("err_archive"); - for i in 0..dll_zip.len() { - let mut buf = Vec::new(); - let mut file = dll_zip.by_index(i).expect("err_dll_idx"); - let filename = file.name(); - if filename == "map.json" && file.is_file() { - file.read_to_end(&mut buf).expect("err_read_zip_file"); - println!( - "Filename: {}\nFileContents: {}", - file.name(), - String::from_utf8_lossy(&buf) - ); - } - } - vars -} - -pub fn write_dll(vars: Variables, exe_path: String, dll_path: String) { - let dll_file = File::create(&dll_path).expect("Err_DllCREATE"); - let mut dll = ZipWriter::new(dll_file); - dll.start_file("run", SimpleFileOptions::default()) - .expect("ERR_STARTFILE_RUN"); - let buf_vec = fs::read(exe_path).expect("ERR_READ_EXE"); - let buf_u8: &[u8] = buf_vec.as_slice(); - dll.write_all(buf_u8).expect("ERR_DLL_EXEWRITE"); - dll.start_file("map.json", SimpleFileOptions::default()) - .expect("ERR_STARTFILE_MAP"); - let json_data = serde_json::to_string(&vars.vars).expect("ERR_MAP_JSON"); - dll.write_all(json_data.as_bytes()) - .expect("ERR_DLL_JSONWRITE"); - println!("{:?}", serde_json::to_string(&vars.vars)); -} - -pub struct HeaderConfig { - pub file_path: String, - pub map_path: String, -} - -impl HeaderConfig { - // Function to parse the input string - pub fn new(input: String) -> Option { - let re = Regex::new(r#"FILE_PATH\s*=\s*"([^"]*)""#).expect("ERR_REGEX_HDR"); - let re1 = Regex::new(r#"MAP_PATH\s*=\s*"([^"]*)""#).expect("ERR_REGEX_HDR1"); - let mut fp: String = String::new(); - let mut mp: String = String::new(); - if let Some(caps) = re.captures(input.as_str()) { - fp = caps.get(1)?.as_str().to_string(); - } else { - return None; - } - if let Some(caps) = re1.captures(input.as_str()) { - mp = caps.get(1)?.as_str().to_string(); - } else { - return None; - } - return Some(HeaderConfig { - file_path: fp, - map_path: mp, - }); - } -} diff --git a/src/file_writer.rs b/src/file_writer.rs deleted file mode 100644 index 6559a5b..0000000 --- a/src/file_writer.rs +++ /dev/null @@ -1,197 +0,0 @@ -use std::{collections::HashMap, fs, path::Path}; - -use dirs::home_dir; - -use crate::{ - dllmgr::{read_dll, HeaderConfig}, - lspcom::{Problem, ProblemType}, - transpiler::Transpiler, - variable::{Variable, Variables}, -}; - -fn join_directories(dir1: &str, dir2: &str) -> String { - let mut main_seperator = '/'; - if cfg!(windows) { - main_seperator = '\\'; - } - let mut result = dir1.to_string(); - - if !result.ends_with(main_seperator) { - result.push(main_seperator); - } - - let dir2_trimmed = if dir2.starts_with(main_seperator) { - &dir2[1..] - } else { - dir2 - }; - - result.push_str(dir2_trimmed); - result -} - -#[derive(Clone, Debug)] -pub struct Module { - pub file_ws: String, - pub file_rs: String, - pub mod_rs: String, - pub _code: String, - pub code_rs: String, -} - -#[derive(Clone, Debug)] -pub struct FileWriter { - pub files: Vec, - pub mod_num: u32, - pub _projpath: String, -} - -impl FileWriter { - pub fn new(_projpath: String) -> FileWriter { - FileWriter { - files: Vec::new(), - mod_num: 0, - _projpath, - } - } - pub fn write(&mut self) { - for module in &self.files { - fs::write(&module.file_rs, &module.code_rs).expect("WriteErr: can't write to file"); - } - } - /*Checks if a path has already been imported*/ - pub fn check(&mut self, filepath: String) -> Option<&Module> { - for module in &self.files { - if filepath == module.file_ws { - return Some(module); - } - } - return None; - } - pub fn expand(&mut self, writer: FileWriter) { - for module in writer.files { - self.files.push(module); - } - } - pub fn add( - &mut self, - filepath: String, - variables: &mut Variables, - global: bool, - ) -> Result { - let mut filepath = filepath; - if global { - let homedir_ = home_dir().expect("Err_HOMEDIR_NOTFOUND"); - let homedir = homedir_.to_str().expect("ERR_HOMEDIR_STR"); - let gdir = join_directories(&homedir, &join_directories("wyst", "lib")); - let lpath = join_directories("lib", &filepath); - let gpath = join_directories(&gdir, &filepath); - if Path::new(&lpath).exists() { - filepath = lpath; - } else if Path::new(&gpath).exists() { - filepath = gpath; - } else { - return Err(Problem { - problem_type: ProblemType::FileNotFound, - problem_msg: format!("failed to import {}: Not found", filepath), - }); - } - } - if !Path::new(&filepath).exists() { - return Err(Problem { - problem_type: ProblemType::FileNotFound, - problem_msg: format!("failed to import {}: Not found", filepath), - }); - } - if let Some(module) = self.check(filepath.clone()) { - return Ok(module.mod_rs.clone()); - } - match filepath.rsplit_once('.').expect("Err_SPLIT").1 { - "wt" => { - let mut trsp = Transpiler { - writer: self.clone(), - ..Default::default() - }; - let mut vars = Variables::new(); - let code = fs::read_to_string(filepath.clone()).expect("failed to read"); - let code_rs = trsp.transpile(code.clone(), 0, &mut vars); - let module = Module { - file_ws: filepath, - mod_rs: format!("mod_{}", self.mod_num), - file_rs: format!("build/mod_{}.rs", self.mod_num), - _code: code, - code_rs, - }; - self.files.push(module.clone()); - self.expand(trsp.writer); - variables.expand(vars); - self.mod_num += 1; - Ok(module.mod_rs) - } - "h" => { - let hdr_code = fs::read_to_string(filepath.clone()).expect("failed to read"); - let mut parent = String::new(); - match Path::new(&filepath).parent() { - Some(p) => parent = format!("{}", p.display()), - None => {} - }; - match HeaderConfig::new(hdr_code) { - Some(hdrcnf) => { - let file_path = Path::new(&parent).join(hdrcnf.file_path.clone()); - let map_path = Path::new(&parent).join(hdrcnf.map_path.clone()); - match fs::read_to_string(file_path) { - Ok(code) => match fs::read_to_string(map_path) { - Ok(map_string) => { - let map: HashMap = - serde_json::from_str(&map_string) - .expect(format!("err_hdr.map: {}", filepath).as_str()); - let vars = Variables { vars: map }; - let module = Module { - file_ws: filepath, - mod_rs: format!("mod_{}", self.mod_num), - file_rs: format!("build/mod_{}.rs", self.mod_num), - _code: code.clone(), - code_rs: code, - }; - self.files.push(module.clone()); - variables.expand(vars); - Ok(module.mod_rs) - } - Err(_) => Err(Problem { - problem_type: ProblemType::FileNotFound, - problem_msg: format!( - "failed to import {}: Not found", - hdrcnf.map_path - ), - }), - }, - Err(_) => Err(Problem { - problem_type: ProblemType::FileNotFound, - problem_msg: format!( - "failed to import {}: Not found", - hdrcnf.file_path - ), - }), - } - } - None => Err(Problem { - problem_type: ProblemType::HeaderSyntaxError, - problem_msg: format!("failed to deserialize"), - }), - } - } - "dll" => { - read_dll(filepath.clone()); - return Ok("xyz".to_string()); - } - "rs" => Err(Problem { - problem_type: ProblemType::FileNotFound, - problem_msg: format!("failed to import {}: Not found", filepath), - }), - _ => Err(Problem { - problem_type: ProblemType::FileNotFound, - problem_msg: format!("failed to import {}: Not found", filepath), - }), - } - } -} diff --git a/src/lexer.rs b/src/lexer.rs deleted file mode 100644 index 76df225..0000000 --- a/src/lexer.rs +++ /dev/null @@ -1,440 +0,0 @@ -use once_cell::sync::Lazy; -use regex::Regex; -use serde::{Deserialize, Serialize}; -use std::fmt; -#[derive(Debug, PartialEq, Clone, Copy, Serialize, Deserialize)] -pub struct LexerState { - pub line: usize, - pub column: usize, -} - -// Define token types -#[derive(Debug, PartialEq, Clone, Copy)] -pub enum TokenType { - Keyword, - Keyword1, - Keyword2, - Newline, - Whitespace, - Number, - Identifier, - Ptr, - Operator, - SecondOperator, - Semicolon, - Round, - Curly, - Square, - Angle, - Include, - String, - Comment, - StaticExecution, - // EOF, -} - -#[derive(Clone)] -pub struct Token { - pub token_type: TokenType, - pub value: String, - pub line: usize, - pub column: usize, -} - -impl fmt::Debug for Token { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!( - f, - "(TokenType: {:?}, TokenValue: {}, Line: {}, Column {})", - self.token_type, - self.value.replace("\n", "\\n"), - self.line, - self.column - ) - } -} - -impl fmt::Display for Token { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "(\x1b[33mTokenType:\x1b[0m \x1b[35m{:?}\x1b[0m, \x1b[33mTokenValue:\x1b[0m \x1b[32m\"{}\"\x1b[0m, \x1b[33mLine:\x1b[0m \x1b[36m{}\x1b[0m, \x1b[33mColumn:\x1b[0m \x1b[36m{}\x1b[0m)", self.token_type, self.value.replace("\n", "\\n"), self.line, self.column) - } -} - -pub struct Node { - token_type: TokenType, - token_regex: Lazy, -} - -const SYNTAX: [Node; 17] = [ - Node { - token_type: TokenType::Semicolon, - token_regex: Lazy::new(|| Regex::new(r"^\;").unwrap()), - }, - Node { - token_type: TokenType::SecondOperator, - token_regex: Lazy::new(|| Regex::new(r"^,").unwrap()), - }, - Node { - token_type: TokenType::String, - token_regex: Lazy::new(|| Regex::new("^\"").unwrap()), - }, - Node { - token_type: TokenType::Whitespace, - token_regex: Lazy::new(|| Regex::new(r"^\s+").unwrap()), - }, - Node { - token_type: TokenType::Keyword, - token_regex: Lazy::new(|| { - Regex::new(r"^(pub|mut|try|catch|return|fn|let|use|cb|enum|struct|impl|in|as)\b") - .unwrap() - }), - }, - Node { - token_type: TokenType::Keyword1, - token_regex: Lazy::new(|| { - Regex::new(r"^(impl|namespace|if|for|while|else *if)\b").unwrap() - }), - }, - Node { - token_type: TokenType::Keyword2, - token_regex: Lazy::new(|| Regex::new(r"^(else)\b").unwrap()), - }, - Node { - token_type: TokenType::Identifier, - token_regex: Lazy::new(|| Regex::new(r"^[.:_a-zA-Z][a-zA-Z0-9_.:]*").unwrap()), - }, - Node { - token_type: TokenType::Number, - token_regex: Lazy::new(|| Regex::new(r"^\d+").unwrap()), - }, - Node { - token_type: TokenType::Ptr, - token_regex: Lazy::new(|| Regex::new(r"^->").unwrap()), - }, - Node { - token_type: TokenType::Operator, - token_regex: Lazy::new(|| Regex::new(r"^[\&\&|\-|\+|\*|\=|\!|\&|\:]").unwrap()), - }, - Node { - token_type: TokenType::Round, - token_regex: Lazy::new(|| Regex::new(r"^[\(|\)]").unwrap()), - }, - Node { - token_type: TokenType::Curly, - token_regex: Lazy::new(|| Regex::new(r"^[\{|\}]").unwrap()), - }, - Node { - token_type: TokenType::Square, - token_regex: Lazy::new(|| Regex::new(r"^[\[|\]]").unwrap()), - }, - Node { - token_type: TokenType::Include, - token_regex: Lazy::new(|| Regex::new(r"^#include *<(.*?)>").unwrap()), - }, - Node { - token_type: TokenType::Include, - token_regex: Lazy::new(|| Regex::new(r#"^#include *"(.*?)""#).unwrap()), - }, - Node { - token_type: TokenType::StaticExecution, - token_regex: Lazy::new(|| Regex::new(r"^#").unwrap()), - }, -]; - -fn get_first_char(value: &str) -> String { - value.chars().next().unwrap().to_string() -} - -pub fn lex( - mut code: &str, - use_whitespace: bool, - state: LexerState, -) -> Result, (LexerState, Vec)> { - let mut state = state; - let mut tokens: Vec = Vec::new(); - let mut brstr: String = String::new(); - let mut br_state: LexerState = LexerState { line: 0, column: 0 }; - let mut brtp: Vec = Vec::new(); - while !code.is_empty() { - let mut is_match = false; - let fch = get_first_char(code); - let brln = brtp.len(); - match fch.as_str() { - "/" => { - brstr += "/"; - code = code.strip_prefix(fch.as_str()).expect(""); - if brln == 0 { - if code.len() > 0 { - let sch = get_first_char(code); - if sch == "/" { - code = code.strip_prefix(sch.as_str()).expect(""); - brstr += &sch; - brtp.push(4); - if brln > 0 { - brstr += fch.as_str(); - } else { - br_state.line = state.line; - br_state.column = state.column; - } - } else if sch == "*" { - code = code.strip_prefix(sch.as_str()).expect(""); - brstr += &sch; - brtp.push(5); - if brln > 0 { - brstr += fch.as_str(); - } else { - br_state.line = state.line; - br_state.column = state.column; - } - } else if brln == 0 { - tokens.push(Token { - token_type: TokenType::Operator, - value: "/".to_string(), - column: state.column, - line: state.line, - }); - } - } else if brln == 0 { - tokens.push(Token { - token_type: TokenType::Operator, - value: "*".to_string(), - column: state.column, - line: state.line, - }); - } - } - } - "\"" => { - brstr += "\""; - code = code.strip_prefix(fch.as_str()).expect(""); - if brln > 0 && brtp[brln - 1] == 0 { - brtp.pop(); - tokens.push(Token { - token_type: TokenType::String, - value: brstr.clone(), - column: br_state.column, - line: br_state.line, - }); - brstr = String::new(); - } else if brln == 0 { - brtp.push(0); - br_state.line = state.line; - br_state.column = state.column; - } - } - "'" => { - brstr += "'"; - code = code.strip_prefix(fch.as_str()).expect(""); - if brln > 0 && brtp[brln - 1] == 1 { - brtp.pop(); - tokens.push(Token { - token_type: TokenType::String, - value: brstr.clone(), - column: br_state.column, - line: br_state.line, - }); - brstr = String::new(); - } else if brln == 0 { - brtp.push(1); - br_state.line = state.line; - br_state.column = state.column; - } - } - "(" => { - code = code.strip_prefix(fch.as_str()).expect(""); - if brln > 0 { - brstr += fch.as_str(); - } else { - br_state.line = state.line; - br_state.column = state.column; - } - brtp.push(2); - } - ")" => { - code = code.strip_prefix(fch.as_str()).expect(""); - if brln > 0 && brtp[brln - 1] == 2 { - brtp.pop(); - if brln == 1 { - tokens.push(Token { - token_type: TokenType::Round, - value: brstr.clone(), - column: br_state.column, - line: br_state.line, - }); - brstr = String::new(); - } else { - brstr += fch.as_str(); - } - } else { - brstr += fch.as_str(); - } - } - "{" => { - code = code.strip_prefix(fch.as_str()).expect(""); - if brln > 0 { - brstr += fch.as_str(); - } else { - br_state.line = state.line; - br_state.column = state.column; - } - brtp.push(3); - } - "}" => { - code = code.strip_prefix(fch.as_str()).expect(""); - if brln > 0 && brtp[brln - 1] == 3 { - brtp.pop(); - if brln == 1 { - tokens.push(Token { - token_type: TokenType::Curly, - value: brstr.clone(), - column: br_state.column, - line: br_state.line, - }); - brstr = String::new(); - } else { - brstr += fch.as_str(); - } - } else { - brstr += fch.as_str(); - } - } - "[" => { - code = code.strip_prefix(fch.as_str()).expect(""); - if brln > 0 { - brstr += fch.as_str(); - } else { - br_state.line = state.line; - br_state.column = state.column; - } - brtp.push(3); - } - "]" => { - code = code.strip_prefix(fch.as_str()).expect(""); - if brln > 0 && brtp[brln - 1] == 3 { - brtp.pop(); - if brln == 1 { - tokens.push(Token { - token_type: TokenType::Square, - value: brstr.clone(), - column: br_state.column, - line: br_state.line, - }); - brstr = String::new(); - } else { - brstr += fch.as_str(); - } - } else { - brstr += fch.as_str(); - } - } - "<" => { - code = code.strip_prefix(fch.as_str()).expect(""); - if brln > 0 { - brstr += fch.as_str(); - } else { - br_state.line = state.line; - br_state.column = state.column; - } - brtp.push(6); - } - ">" => { - code = code.strip_prefix(fch.as_str()).expect(""); - if brln > 0 && brtp[brln - 1] == 6 { - brtp.pop(); - if brln == 1 { - tokens.push(Token { - token_type: TokenType::Angle, - value: brstr.clone(), - column: br_state.column, - line: br_state.line, - }); - brstr = String::new(); - } else { - brstr += fch.as_str(); - } - } else { - brstr += fch.as_str(); - } - } - "\\" => { - brstr += "\\"; - code = code.strip_prefix(fch.as_str()).expect(""); - if code.len() > 0 { - let sch = get_first_char(code); - code = code.strip_prefix(sch.as_str()).expect(""); - brstr += &sch; - } - } - "\n" => { - code = code.strip_prefix(fch.as_str()).expect(""); - if brln > 0 { - brstr += "\n"; - } - if brln == 1 && brtp[0] == 4 { - brtp.pop(); - tokens.push(Token { - token_type: TokenType::Comment, - value: brstr.clone(), - column: br_state.column, - line: br_state.line, - }); - brstr = String::new(); - } - state.line += 1; - state.column = 0; - } - _ => { - if brln > 0 { - code = code.strip_prefix(fch.as_str()).expect(""); - brstr += fch.as_str(); - } else { - for s in &SYNTAX { - if let Some(caps) = s.token_regex.captures(code) { - is_match = true; - code = code.strip_prefix(&caps[0]).unwrap_or(code); - if (!use_whitespace && s.token_type != TokenType::Whitespace) - || use_whitespace - { - let cap = caps[0].to_string(); - match cap.as_str() { - "int" => { - tokens.push(Token { - token_type: s.token_type, - value: "i32".to_string(), - line: state.line, - column: state.column, - }); - } - "float" => { - tokens.push(Token { - token_type: s.token_type, - value: "f32".to_string(), - line: state.line, - column: state.column, - }); - } - _ => { - tokens.push(Token { - token_type: s.token_type, - value: cap, - line: state.line, - column: state.column, - }); - } - } - } - state.column += caps[0].len(); - } else { - continue; - }; - break; - } - if !is_match { - return Err((state, tokens)); - } - } - } - } - } - Ok(tokens) -} diff --git a/src/lsp.rs b/src/lsp.rs deleted file mode 100644 index af8dead..0000000 --- a/src/lsp.rs +++ /dev/null @@ -1,116 +0,0 @@ -use crate::{ - lspcom::{get_completion, get_items, request_methods, LspServer, TextDocumentChangeParams}, - variable::Variables, -}; -use lsp_types::*; -use once_cell::sync::Lazy; -use regex::Regex; -use serde_json::{self, json, Value}; -use std::{ - collections::HashMap, - fs, - io::{stdin, stdout, Read, Write}, - path::Path, -}; - -#[derive(Debug)] -pub struct Server { - documents: HashMap, -} - -impl LspServer for Server { - fn initialize(&mut self) -> InitializeResult { - InitializeResult { - capabilities: ServerCapabilities { - completion_provider: Some(CompletionOptions { - trigger_characters: Some(vec![".".to_string()]), - ..Default::default() - }), - ..Default::default() - }, - ..Default::default() - } - } - fn completion(&mut self, params: CompletionParams) -> CompletionResponse { - let text = self - .documents - .get(params.text_document_position.text_document.uri.as_str()) - .expect("err_textdoc"); - let items: Variables = get_completion( - text.clone(), - params.text_document_position.position.line as usize + 1, - params.text_document_position.position.character as usize, - ); - CompletionResponse::Array(get_items(items, "".to_string())) - } - fn did_change(&mut self, params: TextDocumentChangeParams) { - self.documents.insert(params.uri, params.text); - } -} - -pub fn run_lsp_server() { - if Path::new("/home/leo/work/wyst/log.txt").exists() { - fs::remove_file("/home/leo/work/wyst/log.txt").unwrap(); - } - let clpattern = Lazy::new(|| Regex::new(r"^Content-Length: (\d+)").unwrap()); - let mut reader = stdin(); - let mut server = Server { - documents: HashMap::new(), - }; - loop { - let mut input = String::new(); - if reader.read_line(&mut input).is_err() { - continue; - } - let stdout = stdout(); - let mut handle = stdout.lock(); - - if let Some(caps) = clpattern.captures(&input) { - let content_len = caps[1].parse::().unwrap() + 2; - let mut buf = vec![0u8; content_len]; - if reader.read_exact(&mut buf).is_err() { - continue; - } - let json_string = String::from_utf8(buf).expect("Our bytes should be valid utf8"); - let client_json: Value = serde_json::from_str(&json_string).expect("err_json"); - let response = match client_json["method"].as_str().unwrap() { - request_methods::INITIALIZE => { - serde_json::to_string(&json!({ - "jsonrpc": "2.0", - "id": client_json["id"].as_u64().unwrap(), - "result": server.initialize() - })) - .unwrap() - } - request_methods::COMPLETION => serde_json::to_string(&json!({ - "jsonrpc": "2.0", - "id": client_json["id"].as_u64().unwrap(), - "result": server.completion(serde_json::from_value(serde_json::to_value(client_json["params"].as_object()).expect("err_pars2")).unwrap()) - })) - .unwrap(), - request_methods::DID_CHANGE =>{ - server.did_change(serde_json::from_value(serde_json::to_value(client_json["params"].as_object()).expect("err_pars2")).expect("err_pars3")); - "None".to_string()}, - request_methods::INITIALIZED => "None".to_string(), - request_methods::SHUTDOWN => { - return; - } - _ => { - continue; - } - }; - if response != "None" { - let header = format!( - "Content-Length: {}\r\n\r\n{}", - response.trim().len(), - response.trim() - ); - handle - .write_all(header.as_bytes()) - .expect("err_write_stdin"); - handle.flush().expect("err_flush_stdin"); - } - } else { - } - } -} diff --git a/src/lspcom.rs b/src/lspcom.rs deleted file mode 100644 index 1ac6a7c..0000000 --- a/src/lspcom.rs +++ /dev/null @@ -1,115 +0,0 @@ -use crate::{ - transpiler::Transpiler, - variable::{VariableType, Variables}, -}; -use lsp_types::{ - CompletionItem, CompletionItemKind, CompletionParams, CompletionResponse, InitializeResult, -}; -use rand::{thread_rng, Rng}; -use serde::{Deserialize, Serialize}; - -pub fn place_at(input: String, in2: String, line_goal: usize, column_goal: usize) -> String { - let mut line: usize = 1; - let mut column: usize = 0; - let mut out = String::new(); - for c in input.chars() { - out += c.to_string().as_str(); - column += 1; - if c == '\n' { - line += 1; - column = 0; - } else if line == line_goal && column == column_goal { - out += in2.as_str(); - column += 1 - } - } - out -} - -pub fn get_completion(input: String, line: usize, column: usize) -> Variables { - let rand_id: u32 = thread_rng().gen(); - let rand_id: String = rand_id.to_string(); - let mut transpiler = Transpiler { - peek: rand_id.clone(), - ..Default::default() - }; - let mut vars = Variables::new(); - transpiler.transpile(place_at(input, rand_id, line, column), 0, &mut vars); - transpiler.matched_vars -} - -pub mod request_methods { - pub const INITIALIZE: &str = "initialize"; - pub const COMPLETION: &str = "textDocument/completion"; - pub const INITIALIZED: &str = "initialized"; - pub const SHUTDOWN: &str = "shutdown"; - pub const DID_CHANGE: &str = "textDocument/didChange"; -} - -pub trait LspServer { - fn did_change(&mut self, _params: TextDocumentChangeParams) {} - fn completion(&mut self, _params: CompletionParams) -> CompletionResponse { - CompletionResponse::Array(vec![]) - } - fn initialize(&mut self) -> InitializeResult { - InitializeResult::default() - } -} - -#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)] -pub struct TextDocumentChangeParams { - pub uri: String, - pub text: String, -} - -pub fn get_items(mut items: Variables, lname: String) -> Vec { - let mut completion_items: Vec = Vec::new(); - for (name, var) in items.iter_mut() { - let mut item = CompletionItem::new_simple(lname.clone() + &name, var.desc.clone()); - if var.vtype != VariableType::Func { - completion_items.extend( - get_items(var.params.clone(), name.to_owned() + "::") - .iter() - .cloned(), - ) - } else { - // item.documentation = Some(Documentation::MarkupContent(MarkupContent { - // kind: MarkupKind::Markdown, - // value: "Markup".to_string(), - // })); - } - match var.vtype { - VariableType::Func => { - item.kind = Some(CompletionItemKind::FUNCTION); - } - VariableType::Var => { - item.kind = Some(CompletionItemKind::VARIABLE); - } - VariableType::Keyword => { - item.kind = Some(CompletionItemKind::KEYWORD); - } - VariableType::Struct => { - item.kind = Some(CompletionItemKind::STRUCT); - } - VariableType::Namespace => { - item.kind = Some(CompletionItemKind::MODULE); - } - } - completion_items.push(item); - } - completion_items -} - -#[derive(Clone, Debug)] -pub enum ProblemType { - VariableNotFound, - FileNotFound, - HeaderSyntaxError, -} - -#[derive(Clone, Debug)] -pub struct Problem { - //pub code: u32, - pub problem_type: ProblemType, - pub problem_msg: String, -} diff --git a/src/main.rs b/src/main.rs index a7b7897..f525f77 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,255 +1,12 @@ -#[derive(Debug, PartialEq, Clone)] -enum Token { - Plus, - Minus, - Star, - Slash, - Equals, - Semicolon, - LParen, - RParen, - Identifier(String), - Number(i64), - EOF, -} +use variable::Variables; -fn tokenize(input: &str) -> Vec { - let mut tokens = Vec::new(); - let chars: Vec = input.chars().collect(); - let mut i = 0; - - while i < chars.len() { - match chars[i] { - ' ' | '\t' | '\n' | '\r' => i += 1, - '+' => { - tokens.push(Token::Plus); - i += 1; - } - '-' => { - tokens.push(Token::Minus); - i += 1; - } - '*' => { - tokens.push(Token::Star); - i += 1; - } - '/' => { - tokens.push(Token::Slash); - i += 1; - } - '=' => { - tokens.push(Token::Equals); - i += 1; - } - ';' => { - tokens.push(Token::Semicolon); - i += 1; - } - '(' => { - tokens.push(Token::LParen); - i += 1; - } - ')' => { - tokens.push(Token::RParen); - i += 1; - } - '0'..='9' => { - let mut num = 0; - while i < chars.len() && chars[i].is_digit(10) { - num = num * 10 + chars[i].to_digit(10).unwrap() as i64; - i += 1; - } - tokens.push(Token::Number(num)); - } - 'a'..='z' | 'A'..='Z' => { - let mut id = String::new(); - while i < chars.len() && (chars[i].is_alphanumeric() || chars[i] == '_') { - id.push(chars[i]); - i += 1; - } - match id.as_str() { - _ => tokens.push(Token::Identifier(id)), - } - } - _ => panic!("Unexpected character: {}", chars[i]), - } - } - - tokens.push(Token::EOF); - tokens -} - -#[derive(Debug)] -enum ASTNode { - Number(i64), - Identifier(String), - BinaryOp(Box, Token, Box), - Assignment(String, Box), - Print(Box), - Let(String, Box), - Sequence(Vec), -} - -struct Parser { - tokens: Vec, - current_token: Token, - pos: usize, -} - -impl Parser { - fn new(tokens: Vec) -> Self { - Self { - tokens: tokens.clone(), - current_token: tokens[0].clone(), - pos: 0, - } - } - - fn eat(&mut self, token: Token) { - if self.current_token == token { - self.pos += 1; - self.current_token = self.tokens[self.pos].clone(); - } else { - panic!("Unexpected token: {:?}", self.current_token); - } - } - - fn factor(&mut self) -> ASTNode { - match self.current_token.clone() { - Token::Number(value) => { - self.eat(Token::Number(value)); - ASTNode::Number(value) - } - Token::Identifier(name) => { - self.eat(Token::Identifier(name.clone())); - ASTNode::Identifier(name) - } - Token::LParen => { - self.eat(Token::LParen); - let expr = self.expression(); - self.eat(Token::RParen); - expr - } - _ => panic!("Unexpected token: {:?}", self.current_token), - } - } - - fn term(&mut self) -> ASTNode { - let mut node = self.factor(); - - while self.current_token == Token::Star || self.current_token == Token::Slash { - let token = self.current_token.clone(); - self.eat(token.clone()); - node = ASTNode::BinaryOp(Box::new(node), token, Box::new(self.factor())); - } - - node - } - - fn expression(&mut self) -> ASTNode { - let mut node = self.term(); - - while self.current_token == Token::Plus || self.current_token == Token::Minus { - let token = self.current_token.clone(); - self.eat(token.clone()); - node = ASTNode::BinaryOp(Box::new(node), token, Box::new(self.term())); - } - - node - } - - fn statement(&mut self) -> ASTNode { - match self.current_token.clone() { - Token::Identifier(name) => { - self.eat(Token::Identifier(name.clone())); - self.eat(Token::Equals); - let expr = self.expression(); - self.eat(Token::Semicolon); - ASTNode::Assignment(name, Box::new(expr)) - } - _ => panic!("Unexpected token: {:?}", self.current_token), - } - } - - fn parse(&mut self) -> ASTNode { - let mut statements = Vec::new(); - - while self.current_token != Token::EOF { - statements.push(self.statement()); - } - - ASTNode::Sequence(statements) - } -} - -use std::collections::HashMap; - -struct Interpreter { - symbol_table: HashMap, -} - -impl Interpreter { - fn new() -> Self { - Self { - symbol_table: HashMap::new(), - } - } - - fn evaluate(&mut self, node: &ASTNode) -> i64 { - match node { - ASTNode::Number(value) => *value, - ASTNode::Identifier(name) => *self.symbol_table.get(name).expect("Undefined variable"), - ASTNode::BinaryOp(left, token, right) => { - let left_val = self.evaluate(left); - let right_val = self.evaluate(right); - match token { - Token::Plus => left_val + right_val, - Token::Minus => left_val - right_val, - Token::Star => left_val * right_val, - Token::Slash => left_val / right_val, - _ => panic!("Unexpected binary operator"), - } - } - ASTNode::Assignment(name, expr) => { - let value = self.evaluate(expr); - self.symbol_table.insert(name.clone(), value); - value - } - ASTNode::Let(name, expr) => { - let value = self.evaluate(expr); - self.symbol_table.insert(name.clone(), value); - value - } - ASTNode::Print(expr) => { - let value = self.evaluate(expr); - println!("{}", value); - value - } - ASTNode::Sequence(statements) => { - for statement in statements { - self.evaluate(statement); - } - 0 - } - } - } -} +mod parser; +mod transpiler; +mod utils; +mod variable; fn main() { - let input = " - let x = 5; - let y = x + 3; - print y; - x = y * 2; - print x; - "; - let tokens = tokenize(input); - println!("Tokens: {:?}", tokens); - - let mut parser = Parser::new(tokens); - let ast = parser.parse(); - println!("AST: {:?}", ast); - - let mut interpreter = Interpreter::new(); - interpreter.evaluate(&ast); + let mut vars = Variables::new(); + let out = transpiler::Transpiler::default().transpile(r#"int x"#.to_string(), 0, &mut vars); + println!("{out}"); } diff --git a/src/parser.rs b/src/parser.rs index 6583f59..e5ecb21 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -1,387 +1,80 @@ -use crate::{ - lexer::{LexerState, Token, TokenType}, - variable::Variables, -}; -use once_cell::sync::Lazy; -use regex::Regex; -use std::fmt; +use crate::{transpiler::State, variable::Variables}; -#[derive(Clone, Debug, PartialEq, Eq)] -pub enum AstType { - Ref, - FunctionDeceleration, - StructDeceleration, - StructCall, - StructVar, - VoidFunctionDeceleration, - Namespace, - VariableDeceleration, - PointerDeceleration, - MutVariableDeceleration, - State3, - State2, - Include, - IncludeLocal, - CodeBlock, - Json, - Impl, - StaticExecution, - EnumDeceleration, - Other, +#[derive(Clone, Debug)] +pub enum Token { + Number(String), + Identifier(String), + // Curly(String), + // Round(String), + // Square(String), +} +pub enum Ast { + Variable(String, String), } -pub fn is_decl(ast: &Ast) -> bool { - ast.ast_type == AstType::FunctionDeceleration - || ast.ast_type == AstType::VoidFunctionDeceleration - || ast.ast_type == AstType::Namespace - || ast.ast_type == AstType::VariableDeceleration - || ast.ast_type == AstType::PointerDeceleration - || ast.ast_type == AstType::MutVariableDeceleration - || ast.ast_type == AstType::StructDeceleration -} - -pub struct Ast { - pub tokens: Vec, - pub ast_type: AstType, -} - -impl fmt::Display for Ast { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "\x1b[36m{:?}:\x1b[0m [\n", self.ast_type)?; - for (i, token) in self.tokens.iter().enumerate() { - if i < self.tokens.len() - 1 { - write!(f, " {},\n", token)?; - } else { - write!(f, " {}\n", token)?; - } - } - write!(f, "]") +pub fn get_token(v: String, t: u32) -> Token { + match t { + 1 => Token::Number(v), + 2 => Token::Identifier(v), + _ => Token::Number(String::from("")), } } -impl fmt::Debug for Ast { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{:?}: [\n", self.ast_type)?; - for (i, token) in self.tokens.iter().enumerate() { - if i < self.tokens.len() - 1 { - write!(f, " {:?},\n", token)?; - } else { - write!(f, " {:?}\n", token)?; +pub fn tokenize(code: String) -> Vec { + let mut code = code; + let mut tokens: Vec = Vec::new(); + let mut token_value: String = String::new(); + let mut token_type: u32 = 0; + while !code.is_empty() { + if let Some(c) = code.chars().next() { + code.remove(0); + let mut tval: char = c; + let mut t: u32 = 0; + match c { + '0'..='9' => { + if token_type == 2 { + t = 2; + } else { + t = 1; + } + } + 'a'..='z' | 'A'..='Z' => { + t = 2; + } + '\t' | ' ' => tval = ' ', + _ => {} + } + if t != token_type && token_type != 0 || tval == ' ' { + tokens.push(get_token(token_value.clone(), token_type)); + token_type = 0; + token_value = String::new(); + } + if tval != ' ' { + token_type = t; + token_value += tval.to_string().as_str(); } } - write!(f, "]") } + if token_type != 0 { + tokens.push(get_token(token_value.clone(), token_type)); + } + tokens } -pub struct Parser { - pub tokens: Vec, - pub index: u32, - pub include_regex: Lazy, - pub include_regex_local: Lazy, - pub variables: Variables, - pub json: bool, -} - -impl Parser { - pub fn new(tokens: Vec, variables: Variables) -> Parser { - Parser { - tokens: tokens, - index: 0, - include_regex: Lazy::new(|| Regex::new(r"^(#include *)<(.*?)>").unwrap()), - include_regex_local: Lazy::new(|| Regex::new(r#"^(#include *)"(.*?)""#).unwrap()), - variables: variables, - json: false, - } - } - pub fn parse(&mut self) -> Vec { - let mut full_ast: Vec = Vec::new(); - while self.tokens.len() > self.index as usize { - let mut ast_res: Ast = Ast { - tokens: vec![], - ast_type: AstType::Other, - }; - let index = self.index as usize; - if index == self.tokens.len() { - panic!("Reached the end of tokens") +pub fn parse(code: String, vars: &mut Variables) -> Vec { + let mut ast: Vec = Vec::new(); + let mut tokens = tokenize(code); + while tokens.len() > 0 { + let mut drain: usize = 0; + match tokens.as_slice() { + [Token::Identifier(var_type), Token::Identifier(var_name), ..] => { + ast.push(Ast::Variable(var_type.clone(), var_name.clone())); + drain += 2; + // vars.new_var(var_name, State {}, desc) } - let token = &self.tokens[index]; - 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 if self.tokens.len() - index > 1 - && self.tokens[index].value == "&" - && self.tokens[index + 1].token_type == TokenType::Identifier - { - ast_res.tokens.push(self.tokens[index + 1].clone()); - ast_res.ast_type = AstType::Ref; - self.index += 1; - } else if self.tokens.len() - index > 2 - && self.tokens[index].value == "enum" - && 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::EnumDeceleration; - self.index += 2; - let mut desc = String::new(); - if index > 0 && self.tokens[index - 1].token_type == TokenType::Comment { - desc = self.tokens[index - 1].value.clone() - } - self.variables.new_enum( - self.tokens[index + 1].clone().value, - LexerState { - line: self.tokens[index + 1].clone().line, - column: self.tokens[index + 1].clone().column, - }, - desc, - ); - } 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; - let mut desc = String::new(); - if index > 0 && self.tokens[index - 1].token_type == TokenType::Comment { - desc = self.tokens[index - 1].value.clone() - } - self.variables.new_struct( - self.tokens[index + 1].clone().value, - LexerState { - line: self.tokens[index + 1].clone().line, - column: self.tokens[index + 1].clone().column, - }, - desc, - ); - } else if self.tokens.len() - index > 2 - && self.tokens[index].value == "namespace" - && 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::Namespace; - self.index += 2; - let mut desc = String::new(); - if index > 0 && self.tokens[index - 1].token_type == TokenType::Comment { - desc = self.tokens[index - 1].value.clone() - } - self.variables.new_namespace( - self.tokens[index + 1].clone().value, - LexerState { - line: self.tokens[index + 1].clone().line, - column: self.tokens[index + 1].clone().column, - }, - desc, - ); - } else if self.tokens.len() - index > 2 - && self.tokens[index].value == "impl" - && 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::Impl; - self.index += 2; - } else if self.tokens.len() - index > 2 - && self.tokens[index].token_type == TokenType::Keyword1 - && self.tokens[index + 1].token_type == TokenType::Round - && self.tokens[index + 2].token_type == TokenType::Curly - { - ast_res.tokens.push(self.tokens[index].clone()); - ast_res.tokens.push(self.tokens[index + 1].clone()); - ast_res.tokens.push(self.tokens[index + 2].clone()); - ast_res.ast_type = AstType::State3; - self.index += 2; - } else if self.tokens.len() - index > 1 - && self.tokens[index].token_type == TokenType::Keyword2 - && self.tokens[index + 1].token_type == TokenType::Curly - { - ast_res.tokens.push(self.tokens[index].clone()); - ast_res.tokens.push(self.tokens[index + 1].clone()); - ast_res.ast_type = AstType::State2; - self.index += 1; - } 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; - let mut desc = String::new(); - if index > 0 && self.tokens[index - 1].token_type == TokenType::Comment - { - desc = self.tokens[index - 1].value.clone() - } - self.variables.new_func( - self.tokens[index + 1].clone().value, - LexerState { - line: self.tokens[index + 1].clone().line, - column: self.tokens[index + 1].clone().column, - }, - desc, - ); - } else if self.tokens.len() - index > 1 - && self.tokens[index + 1].token_type == TokenType::Curly - { - ast_res.tokens.push(self.tokens[index + 1].clone()); - ast_res.ast_type = AstType::StructCall; - self.index += 1; - } else if self.tokens.len() - index > 2 - && 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::StructVar; - self.index += 2; - let mut desc = String::new(); - if index > 0 && self.tokens[index - 1].token_type == TokenType::Comment - { - desc = self.tokens[index - 1].value.clone() - } - self.variables.new_var( - self.tokens[index + 1].clone().value, - LexerState { - line: self.tokens[index + 1].clone().line, - column: self.tokens[index + 1].clone().column, - }, - desc, - ); - } 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; - let mut desc = String::new(); - if index > 0 - && self.tokens[index - 1].token_type == TokenType::Comment - { - desc = self.tokens[index - 1].value.clone() - } - self.variables.new_var( - self.tokens[index + 1].clone().value, - LexerState { - line: self.tokens[index + 1].clone().line, - column: self.tokens[index + 1].clone().column, - }, - desc, - ); - } else if self.tokens.len() - index > 2 - && 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; - let mut desc = String::new(); - if index > 0 - && self.tokens[index - 1].token_type == TokenType::Comment - { - desc = self.tokens[index - 1].value.clone() - } - self.variables.new_var( - self.tokens[index + 1].clone().value, - LexerState { - line: self.tokens[index + 1].clone().line, - column: self.tokens[index + 1].clone().column, - }, - desc, - ); - } else if self.tokens.len() - index > 2 - && 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; - let mut desc = String::new(); - if index > 0 - && self.tokens[index - 1].token_type == TokenType::Comment - { - desc = self.tokens[index - 1].value.clone() - } - self.variables.new_var( - self.tokens[index + 1].clone().value, - LexerState { - line: self.tokens[index + 1].clone().line, - column: self.tokens[index + 1].clone().column, - }, - desc, - ); - } - } - } - 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 { - ast_res.tokens.push(token.clone()); - } - } - TokenType::StaticExecution => { - if self.tokens[index + 1].token_type == TokenType::Square { - ast_res.tokens.push(self.tokens[index + 1].clone()); - ast_res.ast_type = AstType::StaticExecution; - } - } - _ => { - ast_res.tokens.push(token.clone()); - } - } - } - self.index += 1; - full_ast.push(ast_res); + _ => {} } - full_ast + tokens.drain(0..drain); } + ast } diff --git a/src/transpiler.rs b/src/transpiler.rs index f794f88..56ae1b0 100644 --- a/src/transpiler.rs +++ b/src/transpiler.rs @@ -1,911 +1,46 @@ use crate::{ - file_writer::FileWriter, - lexer::{lex, LexerState, TokenType}, - lspcom::{Problem, ProblemType}, - parser::{is_decl, Ast, AstType, Parser}, - variable::{VariableType, Variables}, + parser::{self, Ast}, + utils::Problem, + variable::Variables, }; +use serde::{Deserialize, Serialize}; -use std::{fs, path::Path}; +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct State { + pub line: u32, + pub column: u32, +} -#[derive(Debug, Clone)] +#[derive(Clone, Debug, Serialize, Deserialize)] pub struct Transpiler { - pub state: LexerState, - pub auto_mut: bool, - pub auto_macro: bool, - pub auto_pub: bool, - pub macros: Vec, - pub modnum: u32, - pub peek: String, pub matched_vars: Variables, + pub peek: String, + // pub libmgr: LibManager, pub problems: Vec, - pub writer: FileWriter, } impl Default for Transpiler { - fn default() -> Transpiler { - let transpiler = Transpiler { - writer: FileWriter::new(".".to_string()), - state: LexerState { line: 1, column: 0 }, - auto_mut: true, - auto_macro: true, - auto_pub: false, - macros: vec![String::from("println")], - modnum: 0, - peek: String::new(), + fn default() -> Self { + Transpiler { matched_vars: Variables::new(), + peek: String::new(), + // libmgr: LibManager::new(".".to_string()), problems: Vec::new(), - }; - transpiler + } } } impl Transpiler { - pub fn transpile(&mut self, input: String, indent: u32, variables: &mut Variables) -> String { - let mut result = String::new(); - if indent == 0 { - // result += "type int = i32;\n"; - } else { - result += " ".repeat((indent as usize) * 2).as_str(); - } - let lexer_out = lex(input.as_str(), false, self.state); - - match lexer_out { - Ok(tokens) => { - let mut full_ast = Parser::new(tokens.clone(), variables.clone()); - let mut last_ast = Ast { - ast_type: AstType::Other, - tokens: vec![], - }; - let f_ast = full_ast.parse(); - //variables.expand(full_ast.variables.clone()); - *variables = full_ast.variables.clone(); - //let mut variables = full_ast.variables.clone(); - for ast in f_ast { - let mut ast = ast; - if ast.ast_type == AstType::Other - && ast.tokens[0].token_type == TokenType::Identifier - && ast.tokens[0].value.contains(&self.peek) - && self.peek != "" - { - let ctoken = &ast.tokens[0]; - // let pname = ctoken.value.split(&self.peek).next().unwrap(); - for (name, var) in variables.clone().iter_mut() { - if (ctoken.line > var.state.line && var.vtype == VariableType::Var) - || var.vtype != VariableType::Var - { - self.matched_vars.add( - var.vtype.clone(), - name.to_string(), - var.state, - var.desc.clone(), - ); - } - } - self.peek = String::new(); - continue; - } else { - for i in (if is_decl(&ast) { 1 } else { 0 })..ast.tokens.len() { - if ast.tokens[i].token_type == TokenType::Identifier { - if ast.tokens[i].value.contains(&self.peek) && self.peek != "" {} - let x = variables.get_var(ast.tokens[i].value.clone(), self); - ast.tokens[i].value = x; - } - } - } - if last_ast.tokens.len() > 0 { - let mut fl = 0; - for t in &last_ast.tokens { - fl += t.value.len() - } - if ast.tokens[ast.tokens.len() - 1].column - > last_ast.tokens[last_ast.tokens.len() - 1].column + fl - { - result += " " - .repeat( - ast.tokens[ast.tokens.len() - 1].column - - (last_ast.tokens[last_ast.tokens.len() - 1].column + fl), - ) - .as_str(); - } - } - last_ast = Ast { - ast_type: ast.ast_type.clone(), - tokens: ast.tokens.clone(), - }; - - if ast.ast_type == AstType::FunctionDeceleration { - if self.auto_pub { - result += "pub "; - } - let mut vars: Variables = variables.clone(); - let round = self.transpile_round(ast.tokens[2].value.clone(), &mut vars); - result += format!( - "fn {}({}) -> {} {}", - ast.tokens[1].value, - round, - ast.tokens[0].value, - self.transpile( - ast.tokens[3].value.clone(), - indent + 1, - &mut (vars.clone()) - ) - ) - .as_str(); - } else if ast.ast_type == AstType::VoidFunctionDeceleration { - if self.auto_pub { - result += "pub "; - } - let mut vars: Variables = variables.clone(); - let round = self.transpile_round(ast.tokens[2].value.clone(), &mut vars); - result += format!( - "fn {}({}) {}", - ast.tokens[1].value, - round, - self.transpile( - ast.tokens[3].value.clone(), - indent + 1, - &mut (vars.clone()) - ) - ) - .as_str(); - } else if ast.ast_type == AstType::StructDeceleration { - if self.auto_pub { - result += "pub "; - } - let mut vars: Variables = variables.clone(); - let round = self.transpile_round(ast.tokens[1].value.clone(), &mut vars); - result += format!( - "enum {} {} {}", - ast.tokens[0].value, - "{\n", - round.trim_end() - ) - .replace( - "\n", - ("\n".to_string() + " ".repeat(((indent + 1) as usize) * 2).as_str()) - .as_str(), - ) - .as_str(); - result += "\n}\n"; - let vvars = variables.clone(); - if let Some(v) = variables.get_mut(ast.tokens[0].value.clone()) { - for (name, var) in vars.iter_mut() { - if !(vvars.vars.contains_key(name)) { - v.params.new_var( - name.to_string(), - LexerState { line: 0, column: 0 }, - var.desc.clone(), - ); - } - } - } - } else if ast.ast_type == AstType::StructDeceleration { - if self.auto_pub { - result += "pub "; - } - let mut vars: Variables = variables.clone(); - let round = self.transpile_round(ast.tokens[1].value.clone(), &mut vars); - result += format!( - "struct {} {} {}", - ast.tokens[0].value, - "{\n", - round.trim_end() - ) - .replace( - "\n", - ("\n".to_string() + " ".repeat(((indent + 1) as usize) * 2).as_str()) - .as_str(), - ) - .as_str(); - result += "\n}\n"; - let vvars = variables.clone(); - if let Some(v) = variables.get_mut(ast.tokens[0].value.clone()) { - for (name, var) in vars.iter_mut() { - if !(vvars.vars.contains_key(name)) { - v.params.new_var( - name.to_string(), - LexerState { line: 0, column: 0 }, - var.desc.clone(), - ); - } - } - } - } else if ast.ast_type == AstType::VariableDeceleration { - if self.clone().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.ast_type == AstType::Other - && ast.tokens[0].token_type == TokenType::Round - { - result += format!( - "({})", - self.transpile_round( - ast.tokens[0].value.clone(), - &mut variables.clone() - ) - ) - .as_str(); - } else if ast.ast_type == AstType::Other - && ast.tokens[0].token_type == TokenType::Comment - { - result += ast.tokens[0].value.clone().as_str(); - result += " ".repeat((indent as usize) * 2).as_str(); - } else if ast.tokens.len() == 1 && ast.tokens[0].token_type == TokenType::Square - { - result += format!( - "[{}]", - self.transpile_square( - ast.tokens[0].value.clone(), - LexerState { - line: ast.tokens[0].line, - column: ast.tokens[0].column - }, - variables.clone() - ) - ) - .as_str(); - } else if ast.ast_type == AstType::CodeBlock { - result += "{"; - result += ast.tokens[0].value.as_str(); - result += "}"; - } else if ast.tokens.len() == 1 && ast.tokens[0].token_type == TokenType::Curly - { - result += self - .transpile_json( - ast.tokens[0].value.as_str().to_string(), - LexerState { - line: ast.tokens[0].line, - column: ast.tokens[0].column, - }, - variables.clone(), - ) - .as_str(); - // } - } else if ast.tokens.len() == 1 && ast.tokens[0].token_type == TokenType::Ptr { - result += "."; - } else if ast.ast_type == AstType::StructCall { - result += ast.tokens[0].value.as_str(); - result += " {"; - result += ast.tokens[1].value.as_str(); - result += "}"; - } else if ast.ast_type == AstType::StructVar { - result += format!( - "let mut {}: {} = {} {}{}{}", - ast.tokens[1].value.as_str(), - ast.tokens[0].value.as_str(), - ast.tokens[0].value.as_str(), - "{", - ast.tokens[2].value.as_str(), - "}" - ) - .as_str(); - } else if ast.ast_type == AstType::Include { - match self - .writer - .add(ast.tokens[0].value.clone(), variables, true) - { - Ok(modname) => { - result += "mod "; - result += modname.as_str(); - result += ";\n"; - result += "use "; - result += modname.as_str(); - result += "::*;\n"; - } - Err(ptype) => { - self.problems.push(ptype); - } - } - } else if ast.ast_type == AstType::IncludeLocal { - match self - .writer - .add(ast.tokens[0].value.clone(), variables, false) - { - Ok(modname) => { - result += "mod "; - result += modname.as_str(); - result += ";\n"; - result += "use "; - result += modname.as_str(); - result += "::*;\n"; - } - Err(ptype) => { - self.problems.push(ptype); - } - } - } else if ast.ast_type == AstType::State3 { - result += format!( - "{} {} {}", - ast.tokens[0].value.clone(), - self.transpile_round( - ast.tokens[1].value.clone(), - &mut variables.clone() - ), - self.transpile( - ast.tokens[2].value.clone(), - indent + 1, - &mut variables.clone() - ), - ) - .as_str(); - } else if ast.ast_type == AstType::State2 { - result += format!( - "{} {}", - ast.tokens[0].value.clone(), - self.transpile( - ast.tokens[1].value.clone(), - indent + 1, - &mut variables.clone() - ), - ) - .as_str(); - } else if ast.ast_type == AstType::Namespace { - result += format!( - "mod {} {}{}{}", - &ast.tokens[0].value.clone(), - "{", - self.transpile(ast.tokens[1].value.clone(), 0, &mut variables.clone()), - "}" - ) - .as_str(); - } else if ast.ast_type == AstType::Impl { - result += format!( - "impl {} {}{}{}", - &ast.tokens[0].value.clone(), - "{", - self.transpile(ast.tokens[1].value.clone(), 0, &mut variables.clone()), - "}" - ) - .as_str(); - } else if ast.ast_type == AstType::PointerDeceleration { - if self.auto_mut { - result += format!( - "let mut {}: &mut {}", - ast.tokens[1].value, ast.tokens[0].value - ) - .as_str(); - } else { - result += format!( - "let {}: &mut {}", - ast.tokens[1].value, ast.tokens[0].value - ) - .as_str(); - } - } else if ast.ast_type == AstType::StaticExecution { - result += r#"use serde::Deserialize; -use serde_json::Value; -#[derive(Deserialize, Debug)] -struct Request(i32, String, Vec<(bool, Value)>); -#[derive(Deserialize, Debug)] -struct Response(i32, Vec<(bool, Value)>); -"#; - } else if ast.ast_type == AstType::Ref { - result += "&mut "; - result += ast.tokens[0].value.as_str(); - } - // flp - else { - 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 if ast.tokens[0].token_type == TokenType::Semicolon { - result += ";\n"; - result += " ".repeat((indent as usize) * 2).as_str(); - } else { - result += ast.tokens[0].value.as_str(); - if self.auto_macro - && self - .macros - .contains(&ast.tokens[0].value.as_str().to_string()) - { - result += "!"; - } - } - } - } - result = result.trim_end().to_string(); - if indent > 0 { - result += "\n"; - result += " ".repeat((indent as usize - 1) * 2).as_str(); - return "{\n".to_owned() + result.as_str() + "}"; - } else { - return result; + pub fn transpile(&mut self, code: String, indent: u32, vars: &mut Variables) -> String { + let ast = parser::parse(code, vars); + let mut res = String::new(); + for a in ast { + match a { + Ast::Variable(var_type, var_name) => { + res += format!("let mut {}: {}", var_name, var_type).as_str(); } } - Err((state, _tokens)) => { - panic!("Invalid syntax at code.ws:{}:{}", state.line, state.column); - } - } - } - pub fn transpile_mod(&mut self, ast: Ast, s: &str) -> String { - let modfile = ast.tokens[0].value.as_str(); - let modname = format!( - "mod_{}", - // clean_incl(modfile.split(".").collect::>()[0]), - self.clone().modnum - ); - let file_content = fs::read_to_string(s.to_string() + modfile).expect("Error reading file"); - let transpiled_code = self.transpile(file_content, 0, &mut Variables::new()); - fs::write( - ("build/".to_string() + modname.as_str()) + ".rs", - transpiled_code, - ) - .expect("Error writing file"); - modname - } - pub fn transpile_round(&mut self, input: String, variables: &mut Variables) -> String { - let mut result = String::new(); - let lexer_out = lex(input.as_str(), false, self.state); - match lexer_out { - Ok(tokens) => { - let mut full_ast = Parser::new(tokens.clone(), variables.clone()); - let mut last_ast = Ast { - ast_type: AstType::Other, - tokens: vec![], - }; - let fast = full_ast.parse(); - *variables = full_ast.variables.clone(); - for ast in fast { - let mut ast = ast; - if ast.ast_type == AstType::Other - && ast.tokens[0].token_type == TokenType::Identifier - && ast.tokens[0].value.contains(&self.peek) - && self.peek != "" - { - let ctoken = &ast.tokens[0]; - // let pname = ctoken.value.split(&self.peek).next().unwrap(); - for (name, var) in variables.clone().iter_mut() { - if (ctoken.line > var.state.line && var.vtype == VariableType::Var) - || var.vtype != VariableType::Var - { - self.matched_vars.add( - var.vtype.clone(), - name.to_string(), - var.state, - var.desc.clone(), - ); - } - } - self.peek = String::new(); - continue; - } else { - for i in (if is_decl(&ast) { 1 } else { 0 })..ast.tokens.len() { - if ast.tokens[i].token_type == TokenType::Identifier { - if ast.tokens[i].value.contains(&self.peek) && self.peek != "" {} - let x = variables.get_var(ast.tokens[i].value.clone(), self); - ast.tokens[i].value = x; - } - } - } - if ast.ast_type == AstType::Other - && ast.tokens[0].token_type == TokenType::Identifier - && ast.tokens[0].value.contains(&self.peek) - && self.peek != "" - { - let ctoken = &ast.tokens[0]; - // let pname = ctoken.value.split(&self.peek).next().unwrap(); - for (name, var) in variables.clone().iter_mut() { - if ctoken.line > var.state.line || var.vtype != VariableType::Var { - self.matched_vars.add( - var.vtype.clone(), - name.to_string(), - var.state, - var.desc.clone(), - ); - } - } - self.peek = String::new(); - continue; - } - if last_ast.tokens.len() > 0 { - let mut fl = 0; - for t in &last_ast.tokens { - fl += t.value.len() - } - if ast.tokens[ast.tokens.len() - 1].column - > last_ast.tokens[last_ast.tokens.len() - 1].column + fl - { - result += " " - .repeat( - ast.tokens[ast.tokens.len() - 1].column - - (last_ast.tokens[last_ast.tokens.len() - 1].column + fl), - ) - .as_str(); - } - } - last_ast = Ast { - ast_type: ast.ast_type.clone(), - tokens: ast.tokens.clone(), - }; - if ast.ast_type == AstType::VariableDeceleration { - result += - format!("{}: {}", ast.tokens[1].value, ast.tokens[0].value).as_str(); - } else if ast.ast_type == AstType::MutVariableDeceleration { - result += format!("mut {}: {}", ast.tokens[1].value, ast.tokens[0].value) - .as_str(); - } else if ast.ast_type == AstType::PointerDeceleration { - result += format!("{}: &mut {}", ast.tokens[1].value, ast.tokens[0].value) - .as_str(); - } else if ast.tokens.len() == 1 && ast.tokens[0].token_type == TokenType::Round - { - result += format!( - "({})", - self.transpile_round( - ast.tokens[0].value.clone(), - &mut variables.clone() - ) - ) - .as_str(); - } else if ast.tokens.len() == 1 && ast.tokens[0].token_type == TokenType::Square - { - result += format!( - "[{}]", - self.transpile_square( - ast.tokens[0].value.clone(), - LexerState { - line: ast.tokens[0].line, - column: ast.tokens[0].column - }, - variables.clone() - ) - ) - .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 += self - .transpile_json( - ast.tokens[0].value.as_str().to_string(), - LexerState { - line: ast.tokens[0].line, - column: ast.tokens[0].column, - }, - variables.clone(), - ) - .as_str(); - } else if ast.ast_type == AstType::StructCall { - result += ast.tokens[0].value.as_str(); - result += " {"; - result += ast.tokens[1].value.as_str(); - result += "}"; - } else if ast.ast_type == AstType::Ref { - result += "&mut "; - result += ast.tokens[0].value.as_str(); - } - // flp - else { - result += ast.tokens[0].value.as_str(); - } - } - - result = result.trim_end().to_string(); - result - } - Err((state, _tokens)) => { - panic!("Invalid syntax at code.ws:{}:{}", state.line, state.column); - } - } - } - - pub fn transpile_square( - &mut self, - input: String, - state: LexerState, - variables: Variables, - ) -> 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(), variables.clone()); - let mut last_ast = Ast { - ast_type: AstType::Other, - tokens: vec![], - }; - let fast = full_ast.parse(); - let mut variables = full_ast.variables.clone(); - for ast in fast { - let mut ast = ast; - if ast.ast_type == AstType::Other - && ast.tokens[0].token_type == TokenType::Identifier - && ast.tokens[0].value.contains(&self.peek) - && self.peek != "" - { - let ctoken = &ast.tokens[0]; - // let pname = ctoken.value.split(&self.peek).next().unwrap(); - for (name, var) in variables.clone().iter_mut() { - if (ctoken.line > var.state.line && var.vtype == VariableType::Var) - || var.vtype != VariableType::Var - { - self.matched_vars.add( - var.vtype.clone(), - name.to_string(), - var.state, - var.desc.clone(), - ); - } - } - self.peek = String::new(); - continue; - } else { - for i in (if is_decl(&ast) { 1 } else { 0 })..ast.tokens.len() { - if ast.tokens[i].token_type == TokenType::Identifier { - if ast.tokens[i].value.contains(&self.peek) && self.peek != "" {} - let x = variables.get_var(ast.tokens[i].value.clone(), self); - ast.tokens[i].value = x; - } - } - } - if ast.ast_type == AstType::Other - && ast.tokens[0].token_type == TokenType::Identifier - && ast.tokens[0].value.contains(&self.peek) - && self.peek != "" - { - let ctoken = &ast.tokens[0]; - // let pname = ctoken.value.split(&self.peek).next().unwrap(); - for (name, var) in variables.iter_mut() { - if ctoken.line > var.state.line || var.vtype != VariableType::Var { - self.matched_vars.add( - var.vtype.clone(), - name.to_string(), - var.state, - var.desc.clone(), - ); - } - } - self.peek = String::new(); - continue; - } - if last_ast.tokens.len() > 0 { - let mut fl = 0; - for t in &last_ast.tokens { - fl += t.value.len() - } - if ast.tokens[ast.tokens.len() - 1].column - > last_ast.tokens[last_ast.tokens.len() - 1].column + fl - { - result += " " - .repeat( - ast.tokens[ast.tokens.len() - 1].column - - (last_ast.tokens[last_ast.tokens.len() - 1].column + fl), - ) - .as_str(); - } - } - last_ast = Ast { - ast_type: ast.ast_type.clone(), - tokens: ast.tokens.clone(), - }; - - if ast.ast_type == AstType::VariableDeceleration { - result += - format!("{}: {}", ast.tokens[1].value, ast.tokens[0].value).as_str(); - } else if ast.ast_type == AstType::MutVariableDeceleration { - result += format!("mut {}: {}", ast.tokens[1].value, ast.tokens[0].value) - .as_str(); - } else if ast.tokens.len() == 1 && ast.tokens[0].token_type == TokenType::Round - { - result += format!( - "({})", - self.transpile_round( - ast.tokens[0].value.clone(), - &mut variables.clone() - ) - ) - .as_str(); - } else if ast.tokens.len() == 1 && ast.tokens[0].token_type == TokenType::Square - { - result += format!( - "[{}]", - self.transpile_square( - ast.tokens[0].value.clone(), - LexerState { - line: ast.tokens[0].line, - column: ast.tokens[0].column - }, - variables.clone() - ) - ) - .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 += self - .transpile_json( - ast.tokens[0].value.as_str().to_string(), - LexerState { - line: ast.tokens[0].line, - column: ast.tokens[0].column, - }, - variables.clone(), - ) - .as_str(); - } else if ast.ast_type == AstType::StructCall { - result += ast.tokens[0].value.as_str(); - result += " {"; - result += ast.tokens[1].value.as_str(); - result += "}"; - } else if ast.ast_type == AstType::Ref { - result += "&mut "; - result += ast.tokens[0].value.as_str(); - } - // flp - else { - result += ast.tokens[0].value.as_str(); - } - } - - result = result.trim_end().to_string(); - result - } - Err((state, _tokens)) => { - panic!("Invalid syntax at code.ws:{}:{}", state.line, state.column); - } - } - } - - pub fn transpile_json( - &mut self, - input: String, - state: LexerState, - variables: Variables, - ) -> 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(), variables.clone()); - full_ast.json = true; - result += "HashMap::from(["; - let mut last_ast = Ast { - ast_type: AstType::Other, - tokens: vec![], - }; - let fast = full_ast.parse(); - let mut variables = full_ast.variables.clone(); - for ast in fast { - let mut ast = ast; - if ast.ast_type == AstType::Other - && ast.tokens[0].token_type == TokenType::Identifier - && ast.tokens[0].value.contains(&self.peek) - && self.peek != "" - { - let ctoken = &ast.tokens[0]; - // let pname = ctoken.value.split(&self.peek).next().unwrap(); - for (name, var) in variables.clone().iter_mut() { - if (ctoken.line > var.state.line && var.vtype == VariableType::Var) - || var.vtype != VariableType::Var - { - self.matched_vars.add( - var.vtype.clone(), - name.to_string(), - var.state, - var.desc.clone(), - ); - } - } - self.peek = String::new(); - continue; - } else { - for i in (if is_decl(&ast) { 1 } else { 0 })..ast.tokens.len() { - if ast.tokens[i].token_type == TokenType::Identifier { - if ast.tokens[i].value.contains(&self.peek) && self.peek != "" {} - let x = variables.get_var(ast.tokens[i].value.clone(), self); - ast.tokens[i].value = x; - } - } - } - if ast.ast_type == AstType::Other - && ast.tokens[0].token_type == TokenType::Identifier - && ast.tokens[0].value.contains(&self.peek) - && self.peek != "" - { - let ctoken = &ast.tokens[0]; - // let pname = ctoken.value.split(&self.peek).next().unwrap(); - for (name, var) in variables.iter_mut() { - if ctoken.line > var.state.line || var.vtype != VariableType::Var { - self.matched_vars.add( - var.vtype.clone(), - name.to_string(), - var.state, - var.desc.clone(), - ); - } - } - self.peek = String::new(); - continue; - } - if last_ast.tokens.len() > 0 { - let mut fl = 0; - for t in &last_ast.tokens { - fl += t.value.len() - } - if ast.tokens[ast.tokens.len() - 1].column - > last_ast.tokens[last_ast.tokens.len() - 1].column + fl - { - result += " " - .repeat( - ast.tokens[ast.tokens.len() - 1].column - - (last_ast.tokens[last_ast.tokens.len() - 1].column + fl), - ) - .as_str(); - } - } - last_ast = Ast { - ast_type: ast.ast_type.clone(), - tokens: ast.tokens.clone(), - }; - - 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!( - "({})", - self.transpile_round( - ast.tokens[0].value.clone(), - &mut variables.clone() - ) - ) - .as_str(); - } else if ast.tokens.len() == 1 && ast.tokens[0].token_type == TokenType::Square - { - result += format!( - "[{}]", - self.transpile_square( - ast.tokens[0].value.clone(), - LexerState { - line: ast.tokens[0].line, - column: ast.tokens[0].column - }, - variables.clone() - ) - ) - .as_str(); - } else if ast.tokens.len() == 1 && ast.tokens[0].token_type == TokenType::Curly - { - result += self - .transpile_json( - ast.tokens[0].value.as_str().to_string(), - LexerState { - line: ast.tokens[0].line, - column: ast.tokens[0].column, - }, - variables.clone(), - ) - .as_str(); - } else if ast.ast_type == AstType::Ref { - result += "&mut "; - result += ast.tokens[0].value.as_str(); - } else { - result += ast.tokens[0].value.as_str(); - } - } - result += "])"; - result = result.trim_end().to_string(); - result - } - Err((state, _tokens)) => { - panic!("Invalid syntax at code.ws:{}:{}", state.line, state.column); - } } + res } } diff --git a/src/variable.rs b/src/variable.rs index e48a660..91abf9f 100644 --- a/src/variable.rs +++ b/src/variable.rs @@ -4,9 +4,8 @@ use rand::Rng; use serde::{Deserialize, Serialize}; use crate::{ - lexer::LexerState, - lspcom::{Problem, ProblemType}, - transpiler::Transpiler, + transpiler::{State, Transpiler}, + utils::{Problem, ProblemType}, }; #[derive(Clone, PartialEq, Debug, Serialize, Deserialize)] @@ -23,7 +22,7 @@ pub enum VariableType { pub struct Variable { pub vtype: VariableType, pub desc: String, - pub state: LexerState, + pub state: State, pub params: Variables, pub rname: String, } @@ -41,7 +40,7 @@ impl Variables { Variable { vtype: VariableType::Keyword, desc: "".to_string(), - state: LexerState { line: 0, column: 0 }, + state: State { line: 0, column: 0 }, params: Variables { vars: HashMap::new(), }, @@ -50,7 +49,7 @@ impl Variables { )]), } } - pub fn new_var(&mut self, name: String, state: LexerState, desc: String) { + pub fn new_var(&mut self, name: String, state: State, desc: String) { self.vars.insert( name, Variable { @@ -65,7 +64,7 @@ impl Variables { ); } - pub fn new_namespace(&mut self, name: String, state: LexerState, desc: String) { + pub fn new_namespace(&mut self, name: String, state: State, desc: String) { self.vars.insert( name, Variable { @@ -80,7 +79,7 @@ impl Variables { ); } - pub fn new_struct(&mut self, name: String, state: LexerState, desc: String) { + pub fn new_struct(&mut self, name: String, state: State, desc: String) { self.vars.insert( name, Variable { @@ -94,7 +93,7 @@ impl Variables { }, ); } - pub fn new_enum(&mut self, name: String, state: LexerState, desc: String) { + pub fn new_enum(&mut self, name: String, state: State, desc: String) { self.vars.insert( name, Variable { @@ -109,7 +108,7 @@ impl Variables { ); } - // pub fn new_keyword(&mut self, name: String, state: LexerState, desc: String) { + // pub fn new_keyword(&mut self, name: String, state: State, desc: String) { // self.vars.insert( // name, // Variable { @@ -124,7 +123,7 @@ impl Variables { // ); // } - pub fn new_func(&mut self, name: String, state: LexerState, desc: String) { + pub fn new_func(&mut self, name: String, state: State, desc: String) { self.vars.insert( name, Variable { @@ -138,7 +137,7 @@ impl Variables { }, ); } - pub fn add(&mut self, vtype: VariableType, name: String, state: LexerState, desc: String) { + pub fn add(&mut self, vtype: VariableType, name: String, state: State, desc: String) { self.vars.insert( name, Variable {