From 023ada1506a90e198a5cb881a7cfa6fe9a677e3b Mon Sep 17 00:00:00 2001 From: Leo dev Date: Sun, 14 Jul 2024 18:13:08 +0200 Subject: [PATCH] working transpiler --- Cargo.toml | 2 +- src/compiler.rs | 32 +++---- src/main.rs | 2 +- src/parser.rs | 22 ----- src/transpiler.rs | 139 ++++++++++++++-------------- src/utils.rs | 228 +--------------------------------------------- src/wyst.pest | 30 +++--- 7 files changed, 108 insertions(+), 347 deletions(-) delete mode 100644 src/parser.rs diff --git a/Cargo.toml b/Cargo.toml index 51411da..e2ca43b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,5 +14,5 @@ lsp-types = "0.97.0" zip = "2.1.3" dirs = "5.0.1" pest = "2" -pest_derive = "2" +pest_derive = "2.1" clap = "3" \ No newline at end of file diff --git a/src/compiler.rs b/src/compiler.rs index 27714b7..510e5a7 100644 --- a/src/compiler.rs +++ b/src/compiler.rs @@ -2,7 +2,7 @@ use std::{fs, path::Path, process::Command}; use crate::{ transpiler::{State, Transpiler}, - utils::{Problem, ProblemCap, ProblemType, Variables}, + utils::{Problem, ProblemCap, ProblemType}, }; pub fn transpile(input_file: String, output_file: String, is_main: bool) -> u8 { @@ -10,23 +10,23 @@ pub fn transpile(input_file: String, output_file: String, is_main: bool) -> u8 { let mut trsp = Transpiler { ..Default::default() }; - let mut vars = Variables::new(); if let Ok(file_contents) = fs::read_to_string(input_file) { - let mut output_code = trsp.transpile(file_contents, 0, &mut vars); + let output_code = trsp.transpile_code(file_contents, 0); + println!("{output_code}"); if is_main { - output_code += "fn main() {"; - output_code += vars - .get_var( - "main".to_string(), - &mut trsp, - State { - line: 0, - column: 0, - file: None, - }, - ) - .as_str(); - output_code += "();}"; + // output_code += "fn main() {"; + // output_code += vars + // .get_var( + // "main".to_string(), + // &mut trsp, + // State { + // line: 0, + // column: 0, + // file: None, + // }, + // ) + // .as_str(); + // output_code += "();}"; } if let Ok(_) = fs::write(Path::new("build").join(output_file), output_code) {} } else { diff --git a/src/main.rs b/src/main.rs index 0fe5c31..d61a7ea 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,9 +1,9 @@ use std::{fs, process}; mod compiler; -mod parser; mod transpiler; mod utils; + use clap::{App, Arg}; use compiler::{compile_rust, transpile}; diff --git a/src/parser.rs b/src/parser.rs deleted file mode 100644 index 6625ca9..0000000 --- a/src/parser.rs +++ /dev/null @@ -1,22 +0,0 @@ -use pest::Parser; -use pest_derive::Parser; - -#[derive(Parser)] -#[grammar = "wyst.pest"] -pub struct WystParser; - -pub fn parse(input: String, rule: Rule) { - match WystParser::parse(rule, &input) { - Ok(parsed) => { - for pair in parsed { - println!("---------START--------"); - println!("{:?}", pair); - println!("---------END--------"); - } - // println!("{:#?}", parsed); - } - Err(e) => { - println!("Ok: {}", e); - } - } -} diff --git a/src/transpiler.rs b/src/transpiler.rs index 00c7b11..9d1c307 100644 --- a/src/transpiler.rs +++ b/src/transpiler.rs @@ -1,9 +1,14 @@ -use crate::{ - parser::{self, Rule}, - utils::{ProblemCap, Variables}, -}; +use pest::iterators::{Pair, Pairs}; +use crate::utils::{ProblemCap}; use serde::{Deserialize, Serialize}; +// The Parser +use pest::Parser; +use pest_derive::Parser; +#[derive(Parser)] +#[grammar = "wyst.pest"] +pub struct WystParser; + #[derive(Deserialize, Serialize, Debug, Clone)] pub struct State { pub line: u32, @@ -13,7 +18,6 @@ pub struct State { #[derive(Deserialize, Serialize, Debug, Clone)] pub struct Transpiler { - pub matched_vars: Variables, pub problems: Vec, pub state: State, pub inject: Inject, @@ -40,7 +44,6 @@ impl Default for Inject { impl Default for Transpiler { fn default() -> Self { Transpiler { - matched_vars: Variables::new(), inject: Inject::default(), problems: Vec::new(), state: State { @@ -52,74 +55,72 @@ impl Default for Transpiler { } } +pub fn to_indexable(pairs: Pairs) -> Vec> { + let mut arr: Vec> = Vec::new(); + for pair in pairs {arr.push(pair)} + arr + +} + impl Transpiler { - pub fn transpile(&mut self, code: String, indent: usize, vars: &mut Variables) -> String { - // args: code, vars, &mut self.state.clone(), self - let ast = parser::parse(code, Rule::top_expr); + pub fn transpile_pairs(&mut self, pairs: Pairs) -> String { let mut res = String::new(); + for pair in pairs { + res+=self.transpile(pair).as_str(); + } + res + } + pub fn transpile(&mut self, pair: Pair) -> String { + let mut res = String::new(); + let tokens = to_indexable(pair.clone().into_inner()); + match pair.as_rule() { + Rule::func_def => { + res += format!("fn {}({}) -> {} {}", tokens[1].as_str(), + self.transpile_pairs(tokens[2].clone().into_inner()).as_str(), + tokens[0].as_str(), + self.transpile(tokens[3].clone()) + ).as_str(); + } + Rule::var_def => { + res += format!("let mut {}: {}", tokens[1].as_str(), tokens[0].as_str()).as_str(); + } + Rule::curly => { + res += "{"; + res += &self.transpile_pairs(pair.clone().into_inner()); + res += "}"; + } + Rule::code_expr => { + res += &self.transpile_pairs(pair.clone().into_inner()); + } + //TODO: use LibManager to manage the includes + Rule::include_global => {} + Rule::include => {} + + _ => { + res += " "; + res += pair.as_str(); + res += " "; + } + } + res + } + pub fn transpile_code(&mut self, code: String, indent: usize) -> String { + let mut res = String::new(); + match WystParser::parse(Rule::top_expr, &code) { + Ok(parsed) => { + for pair in parsed { + res += self.transpile_pairs(pair.into_inner()).as_str(); + } + } + Err(e) => { + // println!("err: {}", e.line()); + println!("{}", e); + } + } if indent > 0 { res += " ".repeat(indent * 2).as_str(); } - // for a in ast { - // let astval = extract_ast(a.clone()); - // if self.inject.inject { - // for val in astval { - // if val.contains("list_vx") { - // for (name, var) in vars.clone().iter_mut() { - // if self.inject.state.line > var.state.line - // || var.vtype != VariableType::Var - // { - // self.matched_vars.vars.insert(name.clone(), var.clone()); - // } - // } - // } - // } - // } - // match a { - // Ast::Variable(var_type, var_name) => { - // res += format!("let mut {}: {}", var_name, var_type).as_str(); - // } - // Ast::Function(var_type, var_name, round, curly) => { - // res += format!( - // "fn {}({}) -> {} {}\n{}{}\n", - // var_name, - // round, - // var_type, - // "{", - // self.transpile(curly, indent + 1, &mut vars.clone()), - // "}" - // ) - // .as_str(); - // } - // Ast::Struct(name, curly) => { - // res += format!( - // "struct {} {}\n{}{}\n", - // name, - // "{", - // self.transpile(curly, indent + 1, &mut vars.clone()), - // "}" - // ) - // .as_str() - // } - // Ast::Rust(rs) => { - // res += "{"; - // res += rs.as_str(); - // res += "}"; - // } - // Ast::Single(x) => { - // println!("{:?}", x); - // let vals = extract_values(x); - // match vals.0 { - // 2 => res += vars.get_var(vals.1, self, vals.2).as_str(), - // 3 => res += format!("({})", vals.1).as_str(), - // 8 => res += vals.1.as_str(), - // _ => { - // res += vals.1.as_str(); - // } - // } - // } - // } - // } + if indent > 0 { res += "\n"; res += " ".repeat((indent - 1) * 2).as_str(); diff --git a/src/utils.rs b/src/utils.rs index ad41986..169095a 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -1,8 +1,5 @@ use crate::transpiler::State; -use crate::transpiler::Transpiler; -use rand::Rng; use serde::{Deserialize, Serialize}; -use std::collections::HashMap; #[derive(Clone, Debug, Serialize, Deserialize)] pub enum ProblemType { @@ -22,227 +19,4 @@ pub struct Problem { pub problem_type: ProblemType, pub problem_msg: String, pub state: State, -} - -#[derive(Clone, PartialEq, Debug, Serialize, Deserialize)] -pub enum VariableType { - Var, - Func, - Keyword, - Struct, - Namespace, - Enum, -} - -#[derive(Clone, Debug, Serialize, Deserialize)] -pub struct Variable { - pub vtype: VariableType, - pub desc: String, - pub state: State, - pub params: Variables, - pub rname: String, -} - -#[derive(Clone, Debug, Serialize, Deserialize)] -pub struct Variables { - pub vars: HashMap, -} - -impl Variables { - pub fn new() -> Variables { - Variables { - vars: HashMap::from([ - ( - "void".to_string(), - Variable { - vtype: VariableType::Keyword, - desc: "".to_string(), - state: State { - line: 0, - column: 0, - file: None, - }, - params: Variables { - vars: HashMap::new(), - }, - rname: "".to_string(), - }, - ), - ( - "println".to_string(), - Variable { - vtype: VariableType::Keyword, - desc: "".to_string(), - state: State { - line: 0, - column: 0, - file: None, - }, - params: Variables { - vars: HashMap::new(), - }, - rname: "println".to_string(), - }, - ), - ]), - } - } - pub fn new_var(&mut self, name: String, state: State, desc: String) -> String { - let rname = generate_varname(); - self.vars.insert( - name, - Variable { - vtype: VariableType::Var, - desc, - state, - params: Variables { - vars: HashMap::new(), - }, - rname: rname.clone(), - }, - ); - rname - } - - pub fn new_namespace(&mut self, name: String, state: State, desc: String) -> String { - let rname = generate_varname(); - self.vars.insert( - name, - Variable { - vtype: VariableType::Namespace, - desc, - state, - params: Variables { - vars: HashMap::new(), - }, - rname: rname.clone(), - }, - ); - rname - } - - pub fn new_struct(&mut self, name: String, state: State, desc: String) -> String { - let rname = generate_varname(); - self.vars.insert( - name, - Variable { - vtype: VariableType::Struct, - desc, - state, - params: Variables { - vars: HashMap::new(), - }, - rname: rname.clone(), - }, - ); - rname - } - pub fn new_enum(&mut self, name: String, state: State, desc: String) -> String { - let rname = generate_varname(); - self.vars.insert( - name, - Variable { - vtype: VariableType::Enum, - desc, - state, - params: Variables { - vars: HashMap::new(), - }, - rname: rname.clone(), - }, - ); - rname - } - - // pub fn new_keyword(&mut self, name: String, state: State, desc: String) { - // self.vars.insert( - // name, - // Variable { - // vtype: VariableType::Keyword, - // desc, - // state, - // params: Variables { - // vars: HashMap::new(), - // }, - // rname: generate_varname(), - // }, - // ); - // } - - pub fn new_func(&mut self, name: String, state: State, desc: String) -> String { - let rname = generate_varname(); - self.vars.insert( - name, - Variable { - vtype: VariableType::Func, - desc, - state, - params: Variables { - vars: HashMap::new(), - }, - rname: rname.clone(), - }, - ); - rname - } - pub fn get_var(&mut self, name: String, root: &mut Transpiler, state: State) -> String { - if let Some(x) = self.get_mut(name.clone()) { - return x.rname.clone(); - } else { - root.problems.push(ProblemCap::Error(Problem { - problem_type: ProblemType::VariableNotFound, - problem_msg: format!("'{}' doesn't exist", &name), - state: state, - })); - return name; - } - } - pub fn iter_mut( - &mut self, - ) -> std::collections::hash_map::IterMut<'_, std::string::String, Variable> { - self.vars.iter_mut() - } - pub fn get_mut(&mut self, name: String) -> Option<&mut Variable> { - if !name.contains("::") { - return self.vars.get_mut(&name); - } - if let Some((x, _)) = name.split_once("::") { - println!("{x}"); - if let Some(v) = self.vars.get_mut(x) { - println!("{:?}", v); - let mut var = v; - for a in name.split("::") { - if let Some(b) = var.params.vars.get_mut(a) { - var = b; - } else { - return None; - } - } - return Some(var); - } - return None; - } - None - } - pub fn expand(&mut self, vars: Variables) { - for (x, y) in vars.vars { - self.vars.insert(x, y); - } - } -} - -pub fn generate_varname() -> String { - let mut rng = rand::thread_rng(); - let charset: &[u8] = b"ABCDEFGHIJKLMNOPQRSTUVWXYZ\ - abcdefghijklmnopqrstuvwxyz\ - 0123456789"; - let mut result = String::with_capacity(19); - result.push('_'); - result.push('0'); - result.push('x'); - for _ in 0..14 { - let random_char = charset[rng.gen_range(0..charset.len())] as char; - result.push(random_char); - } - result -} +} \ No newline at end of file diff --git a/src/wyst.pest b/src/wyst.pest index 34386e4..b910e59 100644 --- a/src/wyst.pest +++ b/src/wyst.pest @@ -1,18 +1,20 @@ WHITESPACE = _{ " " | "\t" | "\n" } +// [chars] +comma = {","} +semicolon = {";"} // [literals] -filepath = { ("/" | identifier | "-" | "." )+ } +filepath = { ("/"|('a'..'z' | 'a'..'z' | '0'..'9' | "_" | "-" | "."))+ } include = { "#" ~ "include" ~ "\"" ~ filepath ~ "\"" } include_global = { "#" ~ "include" ~ "<" ~ filepath ~ ">" } -round = { "(" ~ (expr)* ~ ")" } +round = { "(" ~ ((expr ~ comma)* ~ expr?) ~ ")" } curly = { "{" ~ (code_expr)* ~ "}" } escape = { "\\" ~ ANY } raw_string = { (!("\\" | "\"") ~ ANY)+ } string = { "\"" ~ (raw_string | escape )* ~ "\"" } char = { "'" ~ (escape | ANY) ~ "'" } bool = @{"true" | "false"} -semicolon = {";"} // [numbers] hex = @{ "0" ~ ("x"|"X") ~ ('0'..'9' | 'a'..'f' | 'A'..'F')*} @@ -20,14 +22,18 @@ float = @{ ('0'..'9')* ~ "." ~ ('0'..'9')+ } int = @{ '0'..'9'+ } // [identifiers] -identifier = @{ !(hex|float|int) ~ ("_" | 'a'..'z' | 'a'..'z') ~ ( "_" | 'a'..'z' | 'a'..'z' | int )* } +identifier = @{ !(hex|float|int) ~ ("." | "::" | "_" | 'a'..'z' | 'A'..'Z') ~ ( "." | "::" | "_" | 'a'..'z' | 'A'..'Z' | int )*} +def_identifier = {identifier ~ ("<" ~ ((def_identifier ~ comma)* ~ def_identifier?) ~ ">")?} // [definitions] -var_def = { identifier ~ identifier } -var_def_set = { var_def ~ "=" ~ expr ~ semicolon } -func_def = { identifier ~ identifier ~ round ~ curly } +round_def = { "(" ~ ((var_def ~ comma)* ~ var_def?) ~ ")" } +var_def = { def_identifier ~ identifier } +var_def_set = { var_def ~ "=" ~ expr } +var_set = { def_identifier ~ "=" ~ expr } +func_def = { def_identifier ~ identifier ~ round_def ~ curly } expr = { + (identifier ~ round) | round | curly | char | @@ -40,14 +46,16 @@ expr = { } code_expr = { - var_def_set | - (var_def ~ semicolon) + (var_def_set ~ semicolon) | + (var_def ~ semicolon) | + (var_set ~ semicolon) | + (expr ~ semicolon) } top_expr = { ( - func_def | include | - include_global + include_global | + func_def )+ } \ No newline at end of file