diff --git a/Cargo.toml b/Cargo.toml index 5f466cb..91bbbb6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,3 +17,4 @@ pest = "2" pest_derive = "2.1" clap = "3" hex = "0.4" +regex = "1.10.5" diff --git a/src/main.rs b/src/main.rs index 38d2319..1653dc2 100644 --- a/src/main.rs +++ b/src/main.rs @@ -8,6 +8,7 @@ mod utils; use clap::{App, Arg}; use compiler::{compile_rust, transpile_file}; +use utils::match_code; fn main() { let matches = App::new("Wyst") @@ -64,7 +65,10 @@ fn main() { } } } else if matches.is_present("stdio") { - println!("stdio mode!"); + println!( + "{:?}", + match_code("void testme(int x) {}\ntest".to_string(), 1, 3).unwrap() + ); } else if matches.is_present("hex") { let ident = matches.value_of("hex").unwrap().to_string(); println!("_0x{}", hex::encode(ident)); diff --git a/src/transpiler.rs b/src/transpiler.rs index 1d5ec54..0a58e59 100644 --- a/src/transpiler.rs +++ b/src/transpiler.rs @@ -156,7 +156,7 @@ impl Transpiler { match pair.as_rule() { Rule::func_def => { res += format!( - "pub fn {}({}) -> {} \n{}\n", + "pub fn {}({}) -> {} {}\n", self.transpile(tokens[1].clone()), self.transpile_pairs(tokens[2].clone().into_inner()) .as_str() @@ -168,7 +168,7 @@ impl Transpiler { } Rule::ptr_fn_def => { res += format!( - "pub fn {}({}) -> &mut {} \n{}\n", + "pub fn {}({}) -> &mut {} {}\n", self.transpile(tokens[1].clone()), self.transpile_pairs(tokens[2].clone().into_inner()) .as_str() @@ -381,8 +381,29 @@ impl Transpiler { res += self.transpile_pairs(pair.into_inner()).as_str(); } + Rule::match_name => { + let to_match = tokens[0].clone().as_str(); + let match_id = tokens[1].clone().as_str(); + res += "\n"; + res += self.encode_ident(to_match).as_str(); + res += " { + for i in 0..tokens.len() { + let token = tokens[i].clone(); + if i % 2 == 0 { + res += self.transpile(token).as_str(); + } else { + res += token.as_str(); + } + } + } + _ => { - println!("\x1b[33mUnh: {}\x1b[0m", pair); + println!("\x1b[33mNot Handled: {}\x1b[0m", pair); res += " "; res += pair.as_str(); res += " "; diff --git a/src/utils.rs b/src/utils.rs index 08895fe..41b3a40 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -1,6 +1,8 @@ use crate::transpiler::{Rule, State, Transpiler, WystParser}; use dirs::home_dir; use pest::Parser; +use rand::random; +use regex::Regex; use serde::{Deserialize, Serialize}; use std::collections::HashMap; use std::fs; @@ -182,6 +184,42 @@ impl ModManager { problems } } +#[derive(Debug, Clone)] +#[allow(dead_code)] +pub struct MatchError { + msg: String, +} + +pub fn match_code(code: String, line: usize, column: usize) -> Result { + let re_include = Regex::new(r#"\#\s*include\s*(<|\")([a-zA-Z0-9_.-]*)$"#).unwrap(); + let re_ident = Regex::new(r#"(\:\:|[_a-zA-Z])(\:\:|[_a-zA-Z0-9])*$"#).unwrap(); + let mut lines: Vec<&str> = code.split("\n").collect(); + if lines.len() >= line { + let result = &lines[line][..column]; + if let Some(caps) = re_include.captures(&result) { + let match_id: u16 = random(); + return Ok(format!("", &caps[0], match_id)); + } else if let Some(caps) = re_ident.captures(&result) { + let match_id: u16 = random(); + let match_line = format!("", &caps[0], match_id); + lines[line] = match_line.as_str(); + let mut trsp = Transpiler::default(); + match trsp.transpile_code(lines.join("\n"), 0) { + Ok(rs_code) => { + return Ok(rs_code); + } + Err(_) => { + return Err(MatchError { + msg: "Syntax error".to_string(), + }); + } + } + } + } + Err(MatchError { + msg: "last resort empty".to_string(), + }) +} pub const LOGO: &str = r#" diff --git a/src/wyst.pest b/src/wyst.pest index 0327c44..0c1de27 100644 --- a/src/wyst.pest +++ b/src/wyst.pest @@ -18,6 +18,7 @@ char = { "'" ~ (escape | ANY) ~ "'" } bool = @{"true" | "false"} keyword = @{"struct"|"return"} map = { "#" ~ "map" ~ identifier ~ comma ~ identifier } +match_name = { "" } // [numbers] hex = @{ "0" ~ ("x"|"X") ~ ('0'..'9' | 'a'..'f' | 'A'..'F')*} @@ -51,8 +52,9 @@ refrence = { "&" ~ identifier } // [Operators] if_operator = {"&&"|"||"} -operator = {"=="} +operator = {"=="|"+"|"-"|"!="|">"|"<"|">="|"<="} if_expr = {expr ~ (if_operator ~ (("("~if_expr*~")")|expr))*} +operation = {(term ~ operator)+ ~ term} // [Statement] return_stm = { "return" ~ expr } @@ -75,11 +77,12 @@ term = { bool | identifier | string | - refrence + refrence | + match_name } expr = { - (term ~ operator ~ term)+ | + operation | (term ~ dot ~ identifier ~ round?) | term } @@ -108,7 +111,8 @@ top_expr = { struct_def | enum_def | map | - impl_def + impl_def | + match_name )* }