Added rust imports with header

This commit is contained in:
2024-06-23 17:53:46 +02:00
parent 9a614ef367
commit 15e0ff362c
10 changed files with 306 additions and 64 deletions
+76
View File
@@ -0,0 +1,76 @@
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<Self> {
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,
});
}
}
+147 -25
View File
@@ -1,6 +1,34 @@
use std::fs;
use std::{collections::HashMap, fs, path::Path};
use crate::{dllmgr::read_dll, transpiler::Transpiler, variable::Variables};
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 {
@@ -45,31 +73,125 @@ impl FileWriter {
self.files.push(module);
}
}
pub fn add(&mut self, filepath: String, variables: &mut Variables) -> String {
if filepath.ends_with(".dll") {
read_dll(filepath.clone());
return "xyz".to_string();
pub fn add(
&mut self,
filepath: String,
variables: &mut Variables,
global: bool,
) -> Result<String, Problem> {
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 module.mod_rs.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<String, Variable> =
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),
}),
}
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);
return module.mod_rs;
}
}
+8 -3
View File
@@ -1,8 +1,8 @@
use once_cell::sync::Lazy;
use regex::Regex;
use serde::Serialize;
use serde::{Deserialize, Serialize};
use std::fmt;
#[derive(Debug, PartialEq, Clone, Copy, Serialize)]
#[derive(Debug, PartialEq, Clone, Copy, Serialize, Deserialize)]
pub struct LexerState {
pub line: usize,
pub column: usize,
@@ -29,6 +29,7 @@ pub enum TokenType {
Include,
String,
Comment,
StaticExecution,
// EOF,
}
@@ -64,7 +65,7 @@ pub struct Node {
token_regex: Lazy<Regex>,
}
const SYNTAX: [Node; 16] = [
const SYNTAX: [Node; 17] = [
Node {
token_type: TokenType::Semicolon,
token_regex: Lazy::new(|| Regex::new(r"^\;").unwrap()),
@@ -133,6 +134,10 @@ const SYNTAX: [Node; 16] = [
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 {
+3 -1
View File
@@ -103,11 +103,13 @@ pub fn get_items(mut items: Variables, lname: String) -> Vec<CompletionItem> {
#[derive(Clone, Debug)]
pub enum ProblemType {
VariableNotFound,
FileNotFound,
HeaderSyntaxError,
}
#[derive(Clone, Debug)]
pub struct Problem {
pub code: u32,
//pub code: u32,
pub problem_type: ProblemType,
pub problem_msg: String,
}
+15 -5
View File
@@ -10,7 +10,7 @@ mod variable;
use clap::Parser;
use std::{fs, path::Path};
use transpiler::Transpiler;
use variable::{Variable, Variables};
use variable::{Variable, VariableType, Variables};
use crate::lsp::run_lsp_server;
@@ -50,8 +50,11 @@ fn main() {
transpiled_code += "std::process::exit(";
transpiled_code += vars.get_var("main".to_string(), &mut trsp).as_str();
transpiled_code += "())}";
for problem in trsp.problems {
println!("{}", problem.problem_msg)
for problem in &trsp.problems {
println!("{:?}: {}", problem.problem_type, problem.problem_msg)
}
if trsp.problems.len() > 0 {
return;
}
trsp.writer.write();
@@ -81,9 +84,15 @@ fn main() {
println!("{}", problem.problem_msg)
}
trsp.writer.write();
let mut dll_main = String::from("fn call_fn(params: Vec<Param>){");
let mut dll_main = String::from(
"mod wslib;use wslib::*;\nfn call_fn(fn_name: &str, params: Vec<Param>)->i32{match fn_name {",
);
for (name, var) in vars.vars.clone() {
if var.vtype != VariableType::Func {
continue;
}
let mut dparams = String::new();
println!("{:?}", var.params.vars);
for i in 0..var.params.vars.len() {
dparams += format!("params.get({}).expect(\"Err_prms\"),", i).as_str();
}
@@ -93,7 +102,8 @@ fn main() {
)
.as_str();
}
dll_main += "}";
dll_main += "}}\nfn main(){}";
//dll_main = "fn main(){}".to_string();
compile::write_to_rust_file(&transpiled_code, "build/wslib.rs")
.expect("Error writing to temporary Rust file");
compile::write_to_rust_file(&dll_main, "build/main.rs")
+7
View File
@@ -25,6 +25,7 @@ pub enum AstType {
CodeBlock,
Json,
Impl,
StaticExecution,
Other,
}
@@ -345,6 +346,12 @@ impl Parser {
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());
}
+41 -24
View File
@@ -1,7 +1,7 @@
use crate::{
file_writer::FileWriter,
lexer::{lex, LexerState, TokenType},
lspcom::Problem,
lspcom::{Problem, ProblemType},
parser::{is_decl, Ast, AstType, Parser},
variable::{VariableType, Variables},
};
@@ -260,30 +260,39 @@ impl Transpiler {
)
.as_str();
} else if ast.ast_type == AstType::Include {
let modname = self.writer.add(
Path::new("lib")
.join(&ast.tokens[0].value.clone())
.to_str()
.expect("ErrConvStr0")
.to_string(),
variables,
);
result += "mod ";
result += modname.as_str();
result += ";\n";
result += "use ";
result += modname.as_str();
result += "::*;\n";
self.modnum += 1;
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 {
let modname = self.writer.add(ast.tokens[0].value.clone(), variables);
result += "mod ";
result += modname.as_str();
result += ";\n";
result += "use ";
result += modname.as_str();
result += "::*;\n";
self.modnum += 1;
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!(
"{} {} {}",
@@ -342,6 +351,14 @@ impl Transpiler {
)
.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();
+4 -5
View File
@@ -1,7 +1,7 @@
use std::collections::HashMap;
use rand::Rng;
use serde::Serialize;
use serde::{Deserialize, Serialize};
use crate::{
lexer::LexerState,
@@ -9,7 +9,7 @@ use crate::{
transpiler::Transpiler,
};
#[derive(Clone, PartialEq, Debug, Serialize)]
#[derive(Clone, PartialEq, Debug, Serialize, Deserialize)]
pub enum VariableType {
Var,
Func,
@@ -18,7 +18,7 @@ pub enum VariableType {
Namespace,
}
#[derive(Clone, Debug, Serialize)]
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct Variable {
pub vtype: VariableType,
pub desc: String,
@@ -27,7 +27,7 @@ pub struct Variable {
pub rname: String,
}
#[derive(Clone, Debug, Serialize)]
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct Variables {
pub vars: HashMap<String, Variable>,
}
@@ -142,7 +142,6 @@ impl Variables {
return x.rname.clone();
} else {
root.problems.push(Problem {
code: 1,
problem_type: ProblemType::VariableNotFound,
problem_msg: format!("Variable '{}' doesn't exist", &name),
});