aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorveradec <glitchmill.dyj3d@simplelogin.co>2026-09-11 00:36:52 +0530
committerveradec <glitchmill.dyj3d@simplelogin.co>2026-09-11 00:36:52 +0530
commitef4bce5a1d9c63f9ae8b1eba2796fa99c2d85ab2 (patch)
tree6853d8b53774613be71760184b2d2b5c5e7277ef
parent8191e911c4f9d412179db4fea8d6b98b9fd20259 (diff)
fix: restructuring for more readability and metadata to push to crates.io
-rw-r--r--Cargo.toml5
-rw-r--r--src/main.rs233
2 files changed, 122 insertions, 116 deletions
diff --git a/Cargo.toml b/Cargo.toml
index 0e5f267..f4c0985 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,5 +1,10 @@
[package]
name = "okaml-rs"
+description = "Rust Parser for Okaml Markup Language"
+readme = "README.md"
+repository = "https://github.com/lang-okaml/okaml-rs"
+license = "MIT"
+authors = ["Venkata Rao Dechiraju", "verade@duck.com"]
version = "0.1.0"
edition = "2024"
diff --git a/src/main.rs b/src/main.rs
index 944b405..4a0886b 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -19,36 +19,103 @@ struct Okml {
value: OkmlType,
}
-fn parse_list(tokens: Vec<&str>, mut index: usize) -> (Vec<Okml>, usize) {
- let mut parent: Vec<Okml> = Default::default();
- index = index +2;
- let mut current = tokens.get(index).unwrap();
- if current == &"}" {
- return (parent, index)
+impl Okml {
+ fn read_from_file(file_path: &str) -> Vec<Okml>{
+ let extension = &file_path[file_path.len()-4..file_path.len()];
+
+ if extension != "okml" {
+ error!("File is not in .okml {extension}");
+ std::process::exit(-1);
+ }
+ info!("Okml File Loaded: {}", file_path);
+
+ let mut content = fs::read_to_string(file_path)
+ .expect("Should've read the file");
+
+ let mut processed_content = pre_process(content.clone());
+
+ let re = Regex::new(r"[ \t\n]+").unwrap();
+ let tokens: Vec<&str> = re.split(&processed_content).filter(|s| !s.is_empty()).collect();
+ let (parsed_ast, _) = parse(tokens, 0);
+ parsed_ast
+ }
+ fn read_from_string(content: &str) -> Vec<Okml> {
+ let mut processed_content = pre_process(content.to_string());
+ let re = Regex::new(r"[ \t\n]+").unwrap();
+ let tokens: Vec<&str> = re.split(&processed_content).filter(|s| !s.is_empty()).collect();
+ let (parsed_ast, _) = parse(tokens, 0);
+ parsed_ast
}
- let mut value = tokens.get(index+1).unwrap();
- while current != &"}" {
- current = tokens.get(index).unwrap();
- value = tokens.get(index+1).unwrap();
- if current == &"}" || value == &"}" {
- break;
+}
+
+fn pre_process(mut content: String) -> String{
+ let mut chars: Vec<char> = content.chars().collect();
+ let mut result = Vec::with_capacity(chars.len());
+ let mut next_char: Option<&char>;
+ for (index, &current_char) in chars.iter().enumerate() {
+ next_char = chars.get(index+1);
+ if current_char == ' ' && next_char == Some(&':') {
+ continue;
+ }
+
+ if current_char == ':'
+ && next_char != Some(&' ')
+ && chars.get(index.wrapping_sub(1)) != Some(&'\\')
+ {
+ result.push(current_char);
+ result.push(' ');
+ } else if current_char == '{' && chars.get(index-1) != Some(&' '){
+ result.push(' ');
+ result.push(current_char);
+ } else if current_char == '`' && (next_char != Some(&'`')) {
+ result.push(current_char);
+ result.push('\n');
+ } else if current_char == '`' && (chars.get(index-1) != Some(&'\n')) {
+ // result.push('\n');
+ result.push(current_char);
+ }
+ else {
+ result.push(current_char);
}
+ }
+
+ chars = result;
+
+ let mut rc: String = chars.into_iter().collect();
+ return rc;
+}
+
+
+fn parse(tokens: Vec<&str>, index: usize) -> (Vec<Okml>, usize) {
+ let token_len = tokens.len();
+ let mut parent: Vec<Okml> = Default::default();
+ let count_braces: u64 = 0;
+ let mut index = 0;
+ while index < token_len-1 {
+ let current = tokens.get(index).unwrap();
+ let mut value = tokens.get(index+1).unwrap();
+ // parse (sub_list_key { )
if value == &"{" {
- let mut new_index: usize = 0;
let mut child: Vec<Okml> = Default::default();
+ let mut new_index = 0;
(child, new_index) = parse_list(tokens.clone(), index);
- parent.push(Okml {
+ let mut child_to_push: Okml = Okml {
key: current.to_string(),
value: OkmlType::SubList(child)
- });
+ };
+ parent.push(child_to_push);
index = new_index-1;
- } else {
- // println!("{} => {} ", current, value);
+ continue;
+ }
+
+
+ // parse (key: value)
+ if let Some(':') = current.chars().last() {
if value == &"```" {
let mut _current: &str;
let mut result: String = Default::default();
- while index < tokens.len(){
+ while index < token_len{
index = index+1;
_current = tokens.get(index+1).unwrap();
if _current == "```" {
@@ -62,8 +129,8 @@ fn parse_list(tokens: Vec<&str>, mut index: usize) -> (Vec<Okml>, usize) {
key: current.to_string(),
value: OkmlType::String(result.clone())
});
- // info!("{} => {}", current, result);
} else {
+
let mut return_value: OkmlType;
match value {
&"true" | &"yes" => return_value = OkmlType::Boolean(true),
@@ -85,44 +152,45 @@ fn parse_list(tokens: Vec<&str>, mut index: usize) -> (Vec<Okml>, usize) {
value: (return_value)
});
}
- }
- index = index+2;
- }
+ }
+ index +=1
+ }
-
- (parent, index)
+ return (parent, index)
}
-fn parse(tokens: Vec<&str>, index: usize) -> (Vec<Okml>, usize) {
- let token_len = tokens.len();
+
+fn parse_list(tokens: Vec<&str>, mut index: usize) -> (Vec<Okml>, usize) {
let mut parent: Vec<Okml> = Default::default();
- let count_braces: u64 = 0;
- let mut index = 0;
- while index < token_len-1 {
- let current = tokens.get(index).unwrap();
- let mut value = tokens.get(index+1).unwrap();
- // parse (sub_list_key { )
+ index = index +2;
+ let mut current = tokens.get(index).unwrap();
+ if current == &"}" {
+ return (parent, index)
+ }
+ let mut value = tokens.get(index+1).unwrap();
+ while current != &"}" {
+ current = tokens.get(index).unwrap();
+ value = tokens.get(index+1).unwrap();
+ if current == &"}" || value == &"}" {
+ break;
+ }
+
if value == &"{" {
+ let mut new_index: usize = 0;
let mut child: Vec<Okml> = Default::default();
- let mut new_index = 0;
(child, new_index) = parse_list(tokens.clone(), index);
- let mut child_to_push: Okml = Okml {
+ parent.push(Okml {
key: current.to_string(),
value: OkmlType::SubList(child)
- };
- parent.push(child_to_push);
+ });
index = new_index-1;
- continue;
- }
-
-
- // parse (key: value)
- if let Some(':') = current.chars().last() {
+ } else {
+ // println!("{} => {} ", current, value);
if value == &"```" {
let mut _current: &str;
let mut result: String = Default::default();
- while index < token_len{
+ while index < tokens.len(){
index = index+1;
_current = tokens.get(index+1).unwrap();
if _current == "```" {
@@ -136,9 +204,7 @@ fn parse(tokens: Vec<&str>, index: usize) -> (Vec<Okml>, usize) {
key: current.to_string(),
value: OkmlType::String(result.clone())
});
- info!("{} => {}", current, result);
} else {
-
let mut return_value: OkmlType;
match value {
&"true" | &"yes" => return_value = OkmlType::Boolean(true),
@@ -159,83 +225,18 @@ fn parse(tokens: Vec<&str>, index: usize) -> (Vec<Okml>, usize) {
key: current.to_string(),
value: (return_value)
});
- info!("{} => {}", current, value);
}
- } else {
- info!("{}", current);
}
- index +=1
- }
-
- return (parent, index)
-}
+ index = index+2;
+ }
-fn pre_process(mut content: String) -> String{
- let mut chars: Vec<char> = content.chars().collect();
- let mut result = Vec::with_capacity(chars.len());
- let mut next_char: Option<&char>;
- for (index, &current_char) in chars.iter().enumerate() {
- next_char = chars.get(index+1);
- if current_char == ' ' && next_char == Some(&':') {
- continue;
- }
-
- if current_char == ':'
- && next_char != Some(&' ')
- && chars.get(index.wrapping_sub(1)) != Some(&'\\')
- {
- result.push(current_char);
- result.push(' ');
- } else if current_char == '{' && chars.get(index-1) != Some(&' '){
- result.push(' ');
- result.push(current_char);
- } else if current_char == '`' && (next_char != Some(&'`')) {
- result.push(current_char);
- result.push('\n');
- } else if current_char == '`' && (chars.get(index-1) != Some(&'\n')) {
- // result.push('\n');
- result.push(current_char);
- }
- else {
- result.push(current_char);
- }
- }
- chars = result;
-
-
- // for c in chars {
- // print!("{c}", );
- // }
-
- let mut rc: String = chars.into_iter().collect();
- return rc;
+ (parent, index)
}
-fn load_from_file(file_path: &str) {
- let extension = &file_path[file_path.len()-4..file_path.len()];
-
- if extension != "okml" {
- error!("File is not in .okml {extension}");
- std::process::exit(-1);
- }
- info!("File: {}", file_path);
-
- let mut content = fs::read_to_string(file_path)
- .expect("Should've read the file");
-
- let mut processed_content = pre_process(content.clone());
-
- let re = Regex::new(r"[ \t\n]+").unwrap();
- let tokens: Vec<&str> = re.split(&processed_content).filter(|s| !s.is_empty()).collect();
- let (parsed_ast, _) = parse(tokens, 0);
- println!("{:#?}", parsed_ast);
-}
fn main() {
- env_logger::init();
-
- let args: Vec<String> = std::env::args().collect();
- let file_path = &args[1];
- load_from_file(file_path);
+ let file_path = "../example/syntax.okml";
+ let parsed_ast:Vec<Okml> = Okml::read_from_file(file_path);
+ println!("{:?}", parsed_ast);
}