added header wrappers and stdlib

This commit is contained in:
2024-07-24 14:12:37 +02:00
parent 1aab723c3f
commit c48cad6817
6 changed files with 181 additions and 45 deletions
View File
+23
View File
@@ -0,0 +1,23 @@
use std::alloc::{alloc, Layout};
use std::ptr::null_mut;
// Malloc
pub fn _0x6d616c6c6f63(size: usize) -> *mut u8 {
if size == 0 {
return null_mut();
}
// Create a memory layout for the requested size
let layout = Layout::from_size_align(size, std::mem::align_of::<u8>()).unwrap();
// Allocate the memory
unsafe {
let ptr = alloc(layout);
if ptr.is_null() {
// Allocation failed
null_mut()
} else {
ptr
}
}
}
+11 -2
View File
@@ -13,7 +13,7 @@ fn main() {
.about("The wyst compiler") .about("The wyst compiler")
.arg( .arg(
Arg::with_name("file") Arg::with_name("file")
.required(true) .required_unless_one(&["stdio", "hex"])
.help("Sets the input file to use"), .help("Sets the input file to use"),
) )
.arg( .arg(
@@ -35,10 +35,19 @@ fn main() {
.long("stdio") .long("stdio")
.help("LSP Mode"), .help("LSP Mode"),
) )
.arg(
Arg::with_name("hex")
.short('h')
.long("hex")
.takes_value(true)
.help("Turn an identifier into hex"),
)
.get_matches(); .get_matches();
if matches.is_present("stdio") { if matches.is_present("stdio") {
println!("stdio mode!"); println!("stdio mode!");
} else if matches.is_present("hex") {
let ident = matches.value_of("hex").unwrap().to_string();
println!("_0x{}", hex::encode(ident));
} else { } else {
let file = matches.value_of("file").unwrap().to_string(); let file = matches.value_of("file").unwrap().to_string();
let output = matches.value_of("output").unwrap_or("out").to_string(); let output = matches.value_of("output").unwrap_or("out").to_string();
+54 -14
View File
@@ -68,6 +68,50 @@ pub fn to_indexable(pairs: Pairs<Rule>) -> Vec<Pair<Rule>> {
} }
impl Transpiler { impl Transpiler {
pub fn encode_ident(&mut self, ident: &str) -> String {
match WystParser::parse(Rule::def_identifier, ident) {
Ok(parsed) => {
let mut output = String::new();
for pair in parsed {
let tokens = to_indexable(pair.clone().into_inner());
for t in tokens {
match t.as_rule() {
Rule::identifier => {
let ident = t.as_str().trim();
let ident_rs = format!("_0x{}", hex::encode(ident.as_bytes()));
if self.mod_manager.macros.contains(&ident_rs) {
output += ident_rs.as_str();
output += "!";
} else {
output += match ident {
"void" => "()",
"int" => "i32",
"float" => "f64",
"Vec" => "Vec",
_ => {
if self.mod_manager.map.contains_key(ident) {
self.mod_manager.map.get(ident).unwrap()
} else {
ident_rs.as_str()
}
}
};
}
}
Rule::def_identifier => {
output += "<";
output += self.encode_ident(t.as_str()).as_str();
output += ">";
}
_ => {}
}
}
}
output
}
Err(_) => String::new(),
}
}
pub fn transpile_pairs(&mut self, pairs: Pairs<Rule>) -> String { pub fn transpile_pairs(&mut self, pairs: Pairs<Rule>) -> String {
let mut res = String::new(); let mut res = String::new();
for pair in pairs { for pair in pairs {
@@ -119,7 +163,7 @@ impl Transpiler {
res += "#[allow(unused_imports)]\nuse "; res += "#[allow(unused_imports)]\nuse ";
res += self res += self
.mod_manager .mod_manager
.add(tokens[0].as_str().to_string(), true) .add(&mut self.clone(), tokens[0].as_str().to_string(), true)
.as_str(); .as_str();
res += "::*;\n"; res += "::*;\n";
} }
@@ -127,24 +171,13 @@ impl Transpiler {
res += "#[allow(unused_imports)]\nuse "; res += "#[allow(unused_imports)]\nuse ";
res += self res += self
.mod_manager .mod_manager
.add(tokens[0].as_str().to_string(), false) .add(&mut self.clone(), tokens[0].as_str().to_string(), false)
.as_str(); .as_str();
res += "::*;\n"; res += "::*;\n";
} }
Rule::identifier | Rule::def_identifier => { Rule::identifier | Rule::def_identifier => {
let ident = pair.as_str().trim(); res += self.encode_ident(pair.as_str().trim()).as_str();
let ident_rs = format!("_0x{}", hex::encode(ident.as_bytes()));
if self.mod_manager.macros.contains(&ident_rs) {
res += ident_rs.as_str();
res += "!";
} else {
res += match ident {
"void" => "()",
"int" => "i32",
_ => ident_rs.as_str(),
};
}
} }
Rule::call => { Rule::call => {
@@ -183,6 +216,13 @@ impl Transpiler {
res += pair.as_str(); res += pair.as_str();
} }
Rule::map => {
self.mod_manager.map.insert(
tokens[0].as_str().to_string(),
tokens[2].as_str().to_string(),
);
}
_ => { _ => {
res += " "; res += " ";
res += pair.as_str(); res += pair.as_str();
+84 -26
View File
@@ -1,9 +1,10 @@
use std::fs;
use std::path::Path;
use crate::transpiler::{Rule, State, Transpiler, WystParser}; use crate::transpiler::{Rule, State, Transpiler, WystParser};
use serde::{Deserialize, Serialize};
use dirs::home_dir; use dirs::home_dir;
use pest::Parser; use pest::Parser;
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use std::fs;
use std::path::Path;
#[derive(Clone, Debug, Serialize, Deserialize)] #[derive(Clone, Debug, Serialize, Deserialize)]
pub enum ProblemType { pub enum ProblemType {
@@ -29,18 +30,23 @@ pub struct Problem {
pub struct Module { pub struct Module {
pub rs_mod: String, pub rs_mod: String,
pub file_path: String, pub file_path: String,
pub code: String pub code: String,
} }
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct ModManager { pub struct ModManager {
pub modules: Vec<Module>, pub modules: Vec<Module>,
pub macros: Vec<String> pub macros: Vec<String>,
pub map: HashMap<String, String>,
} }
impl ModManager { impl ModManager {
pub fn new() -> ModManager { pub fn new() -> ModManager {
ModManager {modules: Vec::new(), macros: Vec::new()} ModManager {
modules: Vec::new(),
macros: Vec::new(),
map: HashMap::new(),
}
} }
pub fn check(&mut self, path: String) -> Option<Module> { pub fn check(&mut self, path: String) -> Option<Module> {
for module in self.modules.clone() { for module in self.modules.clone() {
@@ -50,37 +56,83 @@ impl ModManager {
} }
None None
} }
pub fn add(&mut self, file_path: String, global: bool) -> String { pub fn add(&mut self, root: &mut Transpiler, file_path: String, global: bool) -> String {
let mut problems: Vec<ProblemCap> = Vec::new(); let mut problems: Vec<ProblemCap> = Vec::new();
let mod_name = format!("mod_{}", self.modules.len()); let mod_name = format!("mod_{}", self.modules.len());
let home_dirpb = home_dir().unwrap(); let home_dirpb = home_dir().unwrap();
let home_dir = home_dirpb.to_str().unwrap(); let home_dir = home_dirpb.to_str().unwrap();
let mut file_path = file_path; let mut file_path = file_path;
if global { if global {
let mut tmp = Path::new(home_dir).join("wyst").join("lib").join(file_path.clone()).to_str().unwrap().to_string(); let mut tmp = Path::new(home_dir)
if !Path::new(&tmp).exists() { .join("wyst")
tmp = Path::new("lib").join(file_path).to_str().unwrap().to_string(); .join("lib")
} .join(file_path.clone())
file_path = tmp; .to_str()
.unwrap()
.to_string();
if !Path::new(&tmp).exists() {
tmp = Path::new("lib")
.join(file_path)
.to_str()
.unwrap()
.to_string();
}
file_path = tmp;
} }
if let Some(modl) = self.check(file_path.clone()) { if let Some(modl) = self.check(file_path.clone()) {
return modl.rs_mod; return modl.rs_mod;
} }
if let Ok(code) = fs::read_to_string(file_path.clone()) { if let Ok(code) = fs::read_to_string(file_path.clone()) {
self.modules.push(Module { rs_mod: mod_name.clone(), file_path: file_path.clone(), code: code.clone() });
match file_path.rsplit_once('.').unwrap_or(("", "")).1 { match file_path.rsplit_once('.').unwrap_or(("", "")).1 {
"rs" => { "rs" => match WystParser::parse(Rule::rust_code, &code) {
match WystParser::parse(Rule::rust_code, &code) { Ok(parsed) => {
Ok(parsed) => { self.modules.push(Module {
for pair in parsed { rs_mod: mod_name.clone(),
for p in pair.into_inner() { file_path: file_path.clone(),
if p.as_rule() == Rule::rust_macro_lint { code: code.clone(),
self.macros.push(p.into_inner().as_str().to_string()); });
} for pair in parsed {
for p in pair.into_inner() {
if p.as_rule() == Rule::rust_macro_lint {
self.macros.push(p.into_inner().as_str().to_string());
} }
} }
} }
Err(_) => {} }
Err(_) => {}
},
"h" => {
file_path = file_path.rsplit_once('.').unwrap_or(("", "")).0.to_string();
file_path += ".rs";
let parsed = WystParser::parse(Rule::header_expr, &code).unwrap();
for pair in parsed {
root.transpile_pairs(pair.into_inner());
}
self.map.extend(root.mod_manager.map.clone().into_iter());
if let Ok(code1) = fs::read_to_string(file_path.clone()) {
let parsed = WystParser::parse(Rule::rust_code, &code1).unwrap();
self.modules.push(Module {
rs_mod: mod_name.clone(),
file_path: file_path.clone(),
code: code1.clone(),
});
for pair in parsed {
for p in pair.into_inner() {
if p.as_rule() == Rule::rust_macro_lint {
self.macros.push(p.into_inner().as_str().to_string());
}
}
}
} else {
problems.push(ProblemCap::Error(Problem {
problem_msg: format!("Sub Header not found '{}'", file_path),
problem_type: ProblemType::FileNotFound,
state: State {
line: 0,
column: 0,
file: None,
},
}))
} }
} }
_ => {} _ => {}
@@ -109,14 +161,20 @@ impl ModManager {
..Default::default() ..Default::default()
}; };
let rust_code = trsp.transpile_code(module.code, 0).expect(""); let rust_code = trsp.transpile_code(module.code, 0).expect("");
fs::write(Path::new("build").join((module.rs_mod+".rs").as_str()), rust_code).expect("Error writing rust file: "); fs::write(
Path::new("build").join((module.rs_mod + ".rs").as_str()),
rust_code,
)
.expect("Error writing rust file: ");
problems.append(&mut trsp.problems); problems.append(&mut trsp.problems);
self.modules = trsp.mod_manager.modules; self.modules = trsp.mod_manager.modules;
} }
"rs" => { "rs" => fs::write(
fs::write(Path::new("build").join((module.rs_mod+".rs").as_str()), &module.code).unwrap() Path::new("build").join((module.rs_mod + ".rs").as_str()),
} &module.code,
)
.unwrap(),
_ => {} _ => {}
} }
+8 -2
View File
@@ -1,4 +1,4 @@
WHITESPACE = _{ " " | "\t" | "\n" } WHITESPACE = _{ ("//" ~ (!"\n" ~ ANY)*) | ("/*" ~ (!"*/" ~ ANY)*) | " " | "\t" | "\n" }
wspc = { " " | "\t" | "\n" } wspc = { " " | "\t" | "\n" }
// [chars] // [chars]
@@ -17,6 +17,7 @@ string = { "\"" ~ (raw_string | escape )* ~ "\"" }
char = { "'" ~ (escape | ANY) ~ "'" } char = { "'" ~ (escape | ANY) ~ "'" }
bool = @{"true" | "false"} bool = @{"true" | "false"}
keyword = @{"struct"} keyword = @{"struct"}
map = { "#" ~ "map" ~ identifier ~ comma ~ identifier }
// [numbers] // [numbers]
hex = @{ "0" ~ ("x"|"X") ~ ('0'..'9' | 'a'..'f' | 'A'..'F')*} hex = @{ "0" ~ ("x"|"X") ~ ('0'..'9' | 'a'..'f' | 'A'..'F')*}
@@ -75,6 +76,11 @@ top_expr = {
include | include |
include_global | include_global |
func_def | func_def |
struct_def struct_def |
map
)* ~ !ANY )* ~ !ANY
} }
header_expr = {
map*
}