Tholp's bespoke website generator
at main 4.5 kB view raw
1use crate::{console::*, project::Project, stringtools::*, types::*}; 2 3fn for_each_base( 4 identifier: &String, 5 replacements: &[String], 6 proj_context: &mut Project, 7 origin_index: usize, 8 origin_line: usize, 9 scope: &[Token], 10) -> Vec<Token> { 11 let mut output = Vec::new(); 12 let block: Vec<Token> = scope.into(); 13 14 let mut replacement_count: usize = 0; 15 16 let mut replacement_pattern = find_pattern(scope, format!("[[{}..1]]", identifier)); 17 18 if replacement_pattern.is_none() { 19 warn_skid( 20 proj_context, 21 origin_index, 22 origin_line, 23 &format!( 24 "Macro `for_each_arg` given block with no \"[[{}..1]]\", intentional?", 25 identifier 26 ), 27 ); 28 } 29 30 while replacement_pattern.is_some() { 31 replacement_count += 1; 32 replacement_pattern = find_pattern( 33 scope, 34 format!("[[{}..{}]]", identifier, replacement_count + 1), 35 ); 36 } 37 38 if replacement_count == 0 { 39 for _i in 0..replacements.iter().count() { 40 output.append(&mut block.clone()); 41 } 42 return output; 43 } 44 45 if replacements.len() % replacement_count != 0 { 46 error_skid(proj_context, origin_index, origin_line, 47 &format!("`for_each_var` was not given a number of arguments({}) that was a multiple of its replacement posistions({}) (got {:?})", 48 replacements.len(), 49 replacement_count, 50 replacements)); 51 } 52 53 let mut replacement_index: usize = 0; 54 let mut arg_output: Vec<Token> = block.clone(); 55 for r in replacements { 56 let mut found_pattern = find_pattern( 57 &arg_output, 58 format!("[[{}..{}]]", identifier, replacement_index + 1), 59 ); 60 61 while found_pattern.is_some() { 62 let (start, len) = found_pattern.unwrap(); 63 let replacement = split_to_tokens(r.clone(), origin_index); 64 arg_output.splice(start..start + len, replacement); 65 found_pattern = find_pattern( 66 &arg_output, 67 format!("[[{}..{}]]", identifier, replacement_index + 1), 68 ); 69 //println!("{}", replacement_index + 1); 70 } 71 72 //println!("{} {}", replacement_index, replacement_count); 73 replacement_index += 1; 74 if replacement_index == replacement_count { 75 replacement_index = 0; 76 output.append(&mut arg_output.trim_whitespace().into()); 77 arg_output = block.clone(); 78 //println!("push"); 79 } 80 //println!("test"); 81 } 82 return output; 83} 84 85pub fn macro_for_each_arg( 86 origin_index: usize, 87 origin_line: usize, 88 proj_context: &mut Project, 89 _skid_context: &mut SkidContext, 90 args: &Vec<String>, 91 scope: &[Token], 92) -> Vec<Token> { 93 return for_each_base( 94 &args[0], 95 &args[1..], 96 proj_context, 97 origin_index, 98 origin_line, 99 scope, 100 ); 101} 102 103pub fn macro_for_each_file_in_group( 104 origin_index: usize, 105 origin_line: usize, 106 proj_context: &mut Project, 107 _skid_context: &mut SkidContext, 108 args: &Vec<String>, 109 scope: &[Token], 110) -> Vec<Token> { 111 let mut files: Vec<String> = Vec::new(); 112 for g in &proj_context.filegroups { 113 if g.name == args[1] { 114 for f in &g.files { 115 let path = f 116 .file_input 117 .strip_prefix(&proj_context.input_folder) 118 .unwrap(); 119 files.push(path.to_str().unwrap().into()); 120 } 121 } 122 } 123 return for_each_base( 124 &args[0], 125 &files, 126 proj_context, 127 origin_index, 128 origin_line, 129 scope, 130 ); 131} 132 133pub fn macro_for_each_file_in_group_reverse( 134 origin_index: usize, 135 origin_line: usize, 136 proj_context: &mut Project, 137 _skid_context: &mut SkidContext, 138 args: &Vec<String>, 139 scope: &[Token], 140) -> Vec<Token> { 141 let mut files: Vec<String> = Vec::new(); 142 for g in &proj_context.filegroups { 143 if g.name == args[1] { 144 for f in g.files.iter().rev() { 145 let path = f 146 .file_input 147 .strip_prefix(&proj_context.input_folder) 148 .unwrap(); 149 files.push(path.to_str().unwrap().into()); 150 } 151 } 152 } 153 return for_each_base( 154 &args[0], 155 &files, 156 proj_context, 157 origin_index, 158 origin_line, 159 scope, 160 ); 161}