diff --git a/src/b.rs b/src/b.rs index 0193e3da..da46dfb8 100644 --- a/src/b.rs +++ b/src/b.rs @@ -161,8 +161,7 @@ pub unsafe fn scope_pop(vars: *mut Array>) { } pub unsafe fn find_var_near(vars: *const Array, name: *const c_char) -> *const Var { - for i in 0..(*vars).count { - let var = (*vars).items.add(i); + for var in (*vars).iter_mut() { if strcmp((*var).name, name) == 0 { return var } @@ -173,7 +172,7 @@ pub unsafe fn find_var_near(vars: *const Array, name: *const c_char) -> *co pub unsafe fn find_var_deep(vars: *const Array>, name: *const c_char) -> *const Var { let mut i = (*vars).count; while i > 0 { - let var = find_var_near((*vars).items.add(i-1), name); + let var = find_var_near((*vars).at(i-1), name); if !var.is_null() { return var; } @@ -214,8 +213,7 @@ pub struct Goto { } pub unsafe fn find_goto_label(labels: *const Array, name: *const c_char) -> *const GotoLabel { - for i in 0..(*labels).count { - let label = (*labels).items.add(i); + for label in (*labels).iter_mut() { if strcmp((*label).name, name) == 0 { return label } @@ -656,8 +654,8 @@ pub unsafe fn compile_block(l: *mut Lexer, c: *mut Compiler) -> Option<()> { } pub unsafe fn name_declare_if_not_exists(names: *mut Array<*const c_char>, name: *const c_char) { - for i in 0..(*names).count { - if strcmp(*(*names).items.add(i), name) == 0 { + for existing_name in (*names).iter() { + if strcmp(existing_name, name) == 0 { return; } } @@ -970,7 +968,7 @@ pub unsafe fn compile_program(l: *mut Lexer, c: *mut Compiler) -> Option<()> { get_and_expect_token_but_continue(l, c, Token::ID)?; let func = arena::strdup(&mut (*c).arena, (*l).string); let func_loc = (*l).loc; - if let Some(existing_variadic) = assoc_lookup_cstr(da_slice((*c).program.variadics), func) { + if let Some(existing_variadic) = assoc_lookup_cstr((*c).program.variadics, func) { // TODO: report all the duplicate variadics maybe? diagf!(func_loc, c!("ERROR: duplicate variadic declaration `%s`\n"), func); diagf!((*existing_variadic).loc, c!("NOTE: the first declaration is located here\n")); @@ -1033,15 +1031,14 @@ pub unsafe fn compile_program(l: *mut Lexer, c: *mut Compiler) -> Option<()> { compile_statement(l, c)?; scope_pop(&mut (*c).vars); // end function scope - for i in 0..(*c).func_gotos.count { - let used_label = *(*c).func_gotos.items.add(i); + for used_label in (*c).func_gotos.iter() { let existing_label = find_goto_label(&(*c).func_goto_labels, used_label.name); if existing_label.is_null() { diagf!(used_label.loc, c!("ERROR: label `%s` used but not defined\n"), used_label.name); bump_error_count(c)?; continue; } - (*(*c).func_body.items.add(used_label.addr)).opcode = Op::JmpLabel {label: (*existing_label).label}; + (*(*c).func_body.at(used_label.addr)).opcode = Op::JmpLabel {label: (*existing_label).label}; } da_append(&mut (*c).program.funcs, Func { @@ -1193,10 +1190,10 @@ pub unsafe fn get_garbage_base(path: *const c_char, target: Target) -> Option<*m Some(temp_sprintf(c!("%s/%s.%s"), garbage_dir, filename, target.api.name())) } -pub unsafe fn print_available_targets(targets: *const [Target]) { +pub unsafe fn print_available_targets(targets: Array) { fprintf(stderr(), c!("Compilation targets:\n")); - for i in 0..targets.len() { - fprintf(stderr(), c!(" %s\n"), (*targets)[i].api.name()); + for target in targets.iter() { + fprintf(stderr(), c!(" %s\n"), target.api.name()); } } @@ -1206,13 +1203,13 @@ pub unsafe fn main(mut argc: i32, mut argv: *mut*mut c_char) -> Option<()> { let default_target; // TODO: maybe instead of gas_ the prefix should be gnu_, 'cause that makes more sense. if cfg!(target_arch = "aarch64") && (cfg!(target_os = "linux") || cfg!(target_os = "android")) { - default_target = Some(Target::by_name(da_slice(targets), c!("gas-aarch64-linux")).expect("Default target for Linux on AArch64")); + default_target = Some(Target::by_name(targets, c!("gas-aarch64-linux")).expect("Default target for Linux on AArch64")); } else if cfg!(target_arch = "aarch64") && cfg!(target_os = "macos") { - default_target = Some(Target::by_name(da_slice(targets), c!("gas-aarch64-darwin")).expect("Default target for Darwin on AArch64")); + default_target = Some(Target::by_name(targets, c!("gas-aarch64-darwin")).expect("Default target for Darwin on AArch64")); } else if cfg!(target_arch = "x86_64") && cfg!(target_os = "linux") { - default_target = Some(Target::by_name(da_slice(targets), c!("gas-x86_64-linux")).expect("Default target for Linux on x86_64")); + default_target = Some(Target::by_name(targets, c!("gas-x86_64-linux")).expect("Default target for Linux on x86_64")); } else if cfg!(target_arch = "x86_64") && cfg!(target_os = "windows") { - default_target = Some(Target::by_name(da_slice(targets), c!("gas-x86_64-windows")).expect("Default target for Windows on x86_64")); + default_target = Some(Target::by_name(targets, c!("gas-x86_64-windows")).expect("Default target for Windows on x86_64")); } else { default_target = None; } @@ -1276,13 +1273,13 @@ pub unsafe fn main(mut argc: i32, mut argv: *mut*mut c_char) -> Option<()> { } if strcmp(*target_name, c!("list")) == 0 || *tlist { - print_available_targets(da_slice(targets)); + print_available_targets(targets); return Some(()); } - let Some(target) = Target::by_name(da_slice(targets), *target_name) else { + let Some(target) = Target::by_name(targets, *target_name) else { usage(); - print_available_targets(da_slice(targets)); + print_available_targets(targets); log(Log_Level::ERROR, c!("Unknown target `%s`"), *target_name); return None; }; @@ -1293,8 +1290,8 @@ pub unsafe fn main(mut argc: i32, mut argv: *mut*mut c_char) -> Option<()> { if (*linker).count > 0 { let mut s: Shlex = zeroed(); - for i in 0..(*linker).count { - shlex_append_quoted(&mut s, *(*linker).items.add(i)); + for arg in (*linker).iter() { + shlex_append_quoted(&mut s, arg); } let codegen_arg = temp_sprintf(c!("link-args=%s"), shlex_join(&mut s)); da_append(codegen_args, codegen_arg); @@ -1324,8 +1321,7 @@ pub unsafe fn main(mut argc: i32, mut argv: *mut*mut c_char) -> Option<()> { } let mut sb: String_Builder = zeroed(); - for i in 0..input_paths.count { - let input_path = *input_paths.items.add(i); + for (i, input_path) in input_paths.iter().enumerate() { if i > 0 { sb_appendf(&mut sb, c!(", ")); } sb_appendf(&mut sb, c!("%s"), input_path); } @@ -1338,20 +1334,16 @@ pub unsafe fn main(mut argc: i32, mut argv: *mut*mut c_char) -> Option<()> { scope_push(&mut c.vars); // begin global scope - for i in 0..input_paths.count { - let input_path = *input_paths.items.add(i); - + for input_path in input_paths.iter() { input.count = 0; read_entire_file(input_path, &mut input)?; - let mut l: Lexer = lexer::new(input_path, input.items, input.items.add(input.count), *historical); + let mut l: Lexer = lexer::new(input_path, input.items, input.at(input.count), *historical); compile_program(&mut l, &mut c)?; } - for i in 0..c.used_funcs.count { - let used_global = *c.used_funcs.items.add(i); - + for used_global in c.used_funcs.iter() { if find_var_deep(&mut c.vars, used_global.name).is_null() { diagf!(used_global.loc, c!("ERROR: could not find name `%s`\n"), used_global.name); bump_error_count(&mut c)?; diff --git a/src/bgen.rs b/src/bgen.rs index aa7818a8..b9ea66cd 100644 --- a/src/bgen.rs +++ b/src/bgen.rs @@ -25,8 +25,7 @@ pub unsafe fn aggregate_to_libb(folder_path: *const c_char) -> Option<()> { if !read_entire_dir(folder_path, &mut children) { return None; } - for i in 0..children.count { - let child = *children.items.add(i); + for child in children.iter() { if *child == '.' as c_char { continue; } let child_path = temp_sprintf(c!("%s/%s"), folder_path, child); if temp_strip_suffix(child, c!(".b")).is_none() { @@ -56,8 +55,7 @@ pub unsafe fn reset_libb() -> Option<()> { let folder_path = BUILD_LIBB_PATH; if !read_entire_dir(folder_path, &mut children) { return None; } - for i in 0..children.count { - let child = *children.items.add(i); + for child in children.iter() { if strcmp(child, c!(".")) == 0 { continue; } if strcmp(child, c!("..")) == 0 { continue; } let child_path = temp_sprintf(c!("%s/%s"), folder_path, child); @@ -82,8 +80,7 @@ pub unsafe fn main(mut _argc: i32, mut _argv: *mut*mut c_char) -> Option<()> { qsort(children.items as *mut c_void, children.count, size_of::<*const c_char>(), compar_cstr); let mut sb: String_Builder = zeroed(); sb_appendf(&mut sb, c!("codegens! {\n")); - for i in 0..children.count { - let child = *children.items.add(i); + for child in children.iter() { if *child == '.' as c_char { continue; } if strcmp(child, c!("mod.rs")) == 0 { continue; } // TODO: skip the modules that have invalid Rust names. diff --git a/src/btest.rs b/src/btest.rs index e05b5c0b..75b051d7 100644 --- a/src/btest.rs +++ b/src/btest.rs @@ -225,11 +225,9 @@ pub unsafe fn print_report_stats(stats: ReportStats) { printf(c!("\n")); } -pub unsafe fn print_top_labels(targets: *const [Target], stats_by_target: *const [ReportStats], row_width: usize, col_width: usize) { - assert!(targets.len() == stats_by_target.len()); - for j in 0..targets.len() { - let target = (*targets)[j]; - let stats = (*stats_by_target)[j]; +pub unsafe fn print_top_labels(targets: Array, stats_by_target: Array, row_width: usize, col_width: usize) { + assert!(targets.count == stats_by_target.count); + for (j, (target, stats)) in targets.iter().zip(stats_by_target.iter()).enumerate() { printf(c!("%*s"), row_width + 2, c!("")); for _ in 0..j { printf(c!("│ ")); @@ -240,11 +238,9 @@ pub unsafe fn print_top_labels(targets: *const [Target], stats_by_target: *const } } -pub unsafe fn print_bottom_labels(targets: *const [Target], stats_by_target: *const [ReportStats], row_width: usize, col_width: usize) { - assert!(targets.len() == stats_by_target.len()); - for j in (0..targets.len()).rev() { - let target = (*targets)[j]; - let stats = (*stats_by_target)[j]; +pub unsafe fn print_bottom_labels(targets: Array, stats_by_target: Array, row_width: usize, col_width: usize) { + assert!(targets.count == stats_by_target.count); + for (j, (target, stats)) in targets.iter().zip(stats_by_target.iter()).enumerate().rev() { printf(c!("%*s"), row_width + 2, c!("")); for _ in 0..j { printf(c!("│ ")); @@ -275,7 +271,7 @@ pub unsafe fn matches_glob(pattern: *const c_char, text: *const c_char) -> Optio pub unsafe fn record_tests( // Inputs - test_folder: *const c_char, cases: *const [*const c_char], targets: *const [Target], tt: *mut TestTable, quiet: bool, + test_folder: *const c_char, cases: Array<*const c_char>, targets: Array, tt: *mut TestTable, quiet: bool, // Outputs cmd: *mut Cmd, sb: *mut String_Builder, reports: *mut Array, stats_by_target: *mut Array, @@ -283,15 +279,13 @@ pub unsafe fn record_tests( // TODO: Parallelize the test runner. // Probably using `cmd_run_async_and_reset`. // Also don't forget to add the `-j` flag. - for i in 0..cases.len() { - let case_name = (*cases)[i]; + for case_name in cases.iter() { let mut report = Report { name: case_name, statuses: zeroed(), }; - for j in 0..targets.len() { - let target = (*targets)[j]; + for target in targets.iter() { if let Some(test_row) = test_table_find_row(tt, case_name, target) { match (*test_row).state { TestState::Enabled => { @@ -356,33 +350,30 @@ pub unsafe fn record_tests( da_append(reports, report); } - collect_stats_by_target(targets, da_slice(*reports), stats_by_target); - generate_report(da_slice(*reports), da_slice(*stats_by_target), targets); + collect_stats_by_target(targets, *reports, stats_by_target); + generate_report(*reports, *stats_by_target, targets); Some(()) } -pub unsafe fn collect_stats_by_target(targets: *const [Target], reports: *const [Report], stats_by_target: *mut Array) { - for j in 0..targets.len() { +pub unsafe fn collect_stats_by_target(targets: Array, reports: Array, stats_by_target: *mut Array) { + for j in 0..targets.count { let mut stats: ReportStats = zeroed(); - for i in 0..reports.len() { - let report = (*reports)[i]; - stats.entries[*report.statuses.items.add(j) as usize] += 1; + for report in reports.iter() { + stats.entries[*report.statuses.at(j) as usize] += 1; } da_append(stats_by_target, stats); } } -pub unsafe fn generate_report(reports: *const [Report], stats_by_target: *const [ReportStats], targets: *const [Target]) { +pub unsafe fn generate_report(reports: Array, stats_by_target: Array, targets: Array) { let mut row_width = 0; - for i in 0..reports.len() { - let report = (*reports)[i]; + for report in reports.iter() { row_width = cmp::max(row_width, strlen(report.name)); } let mut col_width = 0; - for j in 0..targets.len() { - let target = (*targets)[j]; + for (j, target) in targets.iter().enumerate() { let width = 2*(j + 1) + strlen(target.api.name()); col_width = cmp::max(col_width, width); } @@ -390,11 +381,9 @@ pub unsafe fn generate_report(reports: *const [Report], stats_by_target: *const print_legend(row_width); printf(c!("\n")); print_top_labels(targets, stats_by_target, row_width, col_width); - for i in 0..reports.len() { - let report = (*reports)[i]; + for report in reports.iter() { printf(c!("%*s:"), row_width, report.name); - for j in 0..report.statuses.count { - let status = *report.statuses.items.add(j); + for status in report.statuses.iter() { printf(c!(" %s%s%s"), status.color(), status.letter(), RESET); } printf(c!("\n")); @@ -404,6 +393,7 @@ pub unsafe fn generate_report(reports: *const [Report], stats_by_target: *const print_legend(row_width); } +#[derive(Clone, Copy)] pub struct TestRow { pub case_name: *const c_char, pub target: Target, @@ -421,8 +411,7 @@ type TestTable = Array; // maybe sort this array on loading it from the JSON file and do Binary Search. Sorting has additional benefit of keeping // the JSON file tidy. pub unsafe fn test_table_find_row(tt: *mut TestTable, case_name: *const c_char, target: Target) -> Option<*mut TestRow> { - for i in 0..(*tt).count { - let row = (*tt).items.add(i); + for row in (*tt).iter_mut() { if strcmp((*row).target.api.name(), target.api.name()) == 0 && strcmp((*row).case_name, case_name) == 0 { return Some(row) } @@ -431,7 +420,7 @@ pub unsafe fn test_table_find_row(tt: *mut TestTable, case_name: *const c_char, } pub unsafe fn load_tt_from_json_file_if_exists( - all_targets: *const [Target], json_path: *const c_char, test_folder: *const c_char, + all_targets: Array, json_path: *const c_char, test_folder: *const c_char, sb: *mut String_Builder, jimp: *mut Jimp ) -> Option { let mut tt: TestTable = zeroed(); @@ -551,21 +540,19 @@ pub unsafe fn save_tt_to_json_file( log(Log_Level::INFO, c!("saving file %s..."), json_path); jim_begin(jim); jim_array_begin(jim); - for i in 0..tt.count { - let row = tt.items.add(i); - + for row in tt.iter() { jim_object_begin(jim); jim_member_key(jim, c!("case")); - jim_string(jim, (*row).case_name); + jim_string(jim, row.case_name); jim_member_key(jim, c!("target")); - jim_string(jim, (*row).target.api.name()); + jim_string(jim, row.target.api.name()); jim_member_key(jim, c!("expected_stdout")); - jim_string(jim, (*row).expected_stdout); + jim_string(jim, row.expected_stdout); jim_member_key(jim, c!("state")); - jim_string(jim, (*row).state.name()); + jim_string(jim, row.state.name()); jim_member_key(jim, c!("comment")); - jim_string(jim, (*row).comment); + jim_string(jim, row.comment); jim_object_end(jim); } @@ -577,7 +564,7 @@ pub unsafe fn save_tt_to_json_file( pub unsafe fn replay_tests( // TODO: The Inputs and the Outputs want to be their own entity. But what should they be called? // Inputs - test_folder: *const c_char, cases: *const [*const c_char], targets: *const [Target], mut tt: TestTable, quiet: bool, + test_folder: *const c_char, cases: Array<*const c_char>, targets: Array, mut tt: TestTable, quiet: bool, // Outputs cmd: *mut Cmd, sb: *mut String_Builder, reports: *mut Array, stats_by_target: *mut Array, jim: *mut Jim, ) -> Option<()> { @@ -585,15 +572,13 @@ pub unsafe fn replay_tests( // TODO: Parallelize the test runner. // Probably using `cmd_run_async_and_reset`. // Also don't forget to add the `-j` flag. - for i in 0..cases.len() { - let case_name = (*cases)[i]; + for case_name in cases.iter() { let mut report = Report { name: case_name, statuses: zeroed(), }; - for j in 0..targets.len() { - let target = (*targets)[j]; + for target in targets.iter() { if let Some(row) = test_table_find_row(&mut tt, case_name, target) { match (*row).state { TestState::Enabled => { @@ -644,8 +629,8 @@ pub unsafe fn replay_tests( da_append(reports, report); } - collect_stats_by_target(targets, da_slice(*reports), stats_by_target); - generate_report(da_slice(*reports), da_slice(*stats_by_target), targets); + collect_stats_by_target(targets, *reports, stats_by_target); + generate_report(*reports, *stats_by_target, targets); Some(()) } @@ -771,11 +756,9 @@ pub unsafe fn main(argc: i32, argv: *mut*mut c_char) -> Option<()> { if (*target_flags).count == 0 { da_append_many(&mut selected_targets, da_slice(all_targets)); } else { - for j in 0..(*target_flags).count { + for pattern in (*target_flags).iter() { let mut added_anything = false; - let pattern = *(*target_flags).items.add(j); - for j in 0..all_targets.count { - let target = *all_targets.items.add(j); + for target in all_targets.iter() { let name = target.api.name(); if matches_glob(pattern, name)? { da_append(&mut selected_targets, target); @@ -789,11 +772,9 @@ pub unsafe fn main(argc: i32, argv: *mut*mut c_char) -> Option<()> { } } let mut targets: Array = zeroed(); - for i in 0..selected_targets.count { - let target = *selected_targets.items.add(i); + for target in selected_targets.iter() { let mut matches_any = false; - 'exclude: for j in 0..(*exclude_target_flags).count { - let pattern = *(*exclude_target_flags).items.add(j); + 'exclude: for pattern in (*exclude_target_flags).iter() { if matches_glob(pattern, target.api.name())? { matches_any = true; break 'exclude; @@ -810,8 +791,7 @@ pub unsafe fn main(argc: i32, argv: *mut*mut c_char) -> Option<()> { if !read_entire_dir(*test_folder, &mut test_files) { return None; } qsort(test_files.items as *mut c_void, test_files.count, size_of::<*const c_char>(), compar_cstr); - for i in 0..test_files.count { - let test_file = *test_files.items.add(i); + for test_file in test_files.iter() { if *test_file == '.' as c_char { continue; } let Some(case_name) = temp_strip_suffix(test_file, c!(".b")) else { continue; }; da_append(&mut all_cases, case_name); @@ -821,11 +801,9 @@ pub unsafe fn main(argc: i32, argv: *mut*mut c_char) -> Option<()> { if (*cases_flags).count == 0 { selected_cases = all_cases; } else { - for i in 0..(*cases_flags).count { + for pattern in (*cases_flags).iter() { let saved_count = selected_cases.count; - let pattern = *(*cases_flags).items.add(i); - for i in 0..all_cases.count { - let case_name = *all_cases.items.add(i); + for case_name in all_cases.iter() { if matches_glob(pattern, case_name)? { da_append(&mut selected_cases, case_name); } @@ -837,11 +815,9 @@ pub unsafe fn main(argc: i32, argv: *mut*mut c_char) -> Option<()> { } } let mut cases: Array<*const c_char> = zeroed(); - for i in 0..selected_cases.count { - let case = *selected_cases.items.add(i); + for case in selected_cases.iter() { let mut matches_any = false; - 'exclude: for j in 0..(*exclude_cases_flags).count { - let pattern = *(*exclude_cases_flags).items.add(j); + 'exclude: for pattern in (*exclude_cases_flags).iter() { if matches_glob(pattern, case)? { matches_any = true; break 'exclude; @@ -856,8 +832,7 @@ pub unsafe fn main(argc: i32, argv: *mut*mut c_char) -> Option<()> { if *list_targets { fprintf(stderr(), c!("Compilation targets:\n")); - for i in 0..targets.count { - let target = *targets.items.add(i); + for target in targets.iter() { fprintf(stderr(), c!(" %s\n"), target.api.name()); } return Some(()); @@ -865,8 +840,7 @@ pub unsafe fn main(argc: i32, argv: *mut*mut c_char) -> Option<()> { if *list_cases { fprintf(stderr(), c!("Test cases:\n")); - for i in 0..cases.count { - let case = *cases.items.add(i); + for case in cases.iter() { fprintf(stderr(), c!(" %s\n"), case); } return Some(()); @@ -881,46 +855,42 @@ pub unsafe fn main(argc: i32, argv: *mut*mut c_char) -> Option<()> { match action { Action::Record => { - let mut tt = load_tt_from_json_file_if_exists(da_slice(all_targets), json_path, *test_folder, &mut sb, &mut jimp)?; + let mut tt = load_tt_from_json_file_if_exists(all_targets, json_path, *test_folder, &mut sb, &mut jimp)?; record_tests( // Inputs - *test_folder, da_slice(cases), da_slice(targets), &mut tt, *quiet, + *test_folder, cases, targets, &mut tt, *quiet, // Outputs &mut cmd, &mut sb, &mut reports, &mut stats_by_target, )?; save_tt_to_json_file(json_path, tt, &mut jim)?; } Action::Replay => { - let tt = load_tt_from_json_file_if_exists(da_slice(all_targets), json_path, *test_folder, &mut sb, &mut jimp)?; + let tt = load_tt_from_json_file_if_exists(all_targets, json_path, *test_folder, &mut sb, &mut jimp)?; replay_tests( // Inputs - *test_folder, da_slice(cases), da_slice(targets), tt, *quiet, + *test_folder, cases, targets, tt, *quiet, // Outputs &mut cmd, &mut sb, &mut reports, &mut stats_by_target, &mut jim, ); } Action::Prune => { - let tt = load_tt_from_json_file_if_exists(da_slice(all_targets), json_path, *test_folder, &mut sb, &mut jimp)?; + let tt = load_tt_from_json_file_if_exists(all_targets, json_path, *test_folder, &mut sb, &mut jimp)?; save_tt_to_json_file(json_path, tt, &mut jim)?; } Action::Disable => { let mut case_width = 0; - for i in 0..cases.count { - let case_name = *cases.items.add(i); + for case_name in cases.iter() { case_width = cmp::max(case_width, strlen(case_name)); } let mut target_width = 0; - for j in 0..targets.count { - let target = *targets.items.add(j); + for target in targets.iter() { target_width = cmp::max(target_width, strlen(target.api.name())); } - let mut tt = load_tt_from_json_file_if_exists(da_slice(all_targets), json_path, *test_folder, &mut sb, &mut jimp)?; - for i in 0..cases.count { - let case_name = *cases.items.add(i); - for j in 0..targets.count { - let target = *targets.items.add(j); + let mut tt = load_tt_from_json_file_if_exists(all_targets, json_path, *test_folder, &mut sb, &mut jimp)?; + for case_name in cases.iter() { + for target in targets.iter() { log(Log_Level::INFO, c!("disabling %-*s for %-*s"), case_width, case_name, target_width, target.api.name()); if let Some(row) = test_table_find_row(&mut tt, case_name, target) { (*row).state = TestState::Disabled; @@ -945,7 +915,7 @@ pub unsafe fn main(argc: i32, argv: *mut*mut c_char) -> Option<()> { save_tt_to_json_file(json_path, tt, &mut jim)?; } Action::Count => { - let tt = load_tt_from_json_file_if_exists(da_slice(all_targets), json_path, *test_folder, &mut sb, &mut jimp)?; + let tt = load_tt_from_json_file_if_exists(all_targets, json_path, *test_folder, &mut sb, &mut jimp)?; printf(c!("%zu\n"), tt.count); } } diff --git a/src/codegen/gas_aarch64/mod.rs b/src/codegen/gas_aarch64/mod.rs index 99b8020b..ed832924 100644 --- a/src/codegen/gas_aarch64/mod.rs +++ b/src/codegen/gas_aarch64/mod.rs @@ -127,7 +127,7 @@ pub unsafe fn load_arg_to_reg(arg: Arg, reg: *const c_char, output: *mut String_ }; } -pub unsafe fn generate_function(name: *const c_char, _name_loc: Loc, params_count: usize, auto_vars_count: usize, os: Os, variadics: *const [(*const c_char, Variadic)], body: *const [OpWithLocation], output: *mut String_Builder) { +pub unsafe fn generate_function(name: *const c_char, _name_loc: Loc, params_count: usize, auto_vars_count: usize, os: Os, variadics: Array<(*const c_char, Variadic)>, body: Array, output: *mut String_Builder) { let stack_size = align_bytes(auto_vars_count*8, 16); match os { Os::Linux => { @@ -163,8 +163,7 @@ pub unsafe fn generate_function(name: *const c_char, _name_loc: Loc, params_coun sb_appendf(output, c!(" str %s, [x29, -%zu]\n"), reg, below_index*8); } - for i in 0..body.len() { - let op = (*body)[i]; + for op in body.iter() { match op.opcode { Op::Bogus => unreachable!("bogus-amogus"), Op::Return {arg} => { @@ -335,7 +334,7 @@ pub unsafe fn generate_function(name: *const c_char, _name_loc: Loc, params_coun }; for i in 0..reg_args_count { let reg = (*REGISTERS)[i]; - load_arg_to_reg(*args.items.add(i), reg, output, op.loc, os); + load_arg_to_reg(*args.at(i), reg, output, op.loc, os); } let stack_args_count = args.count - reg_args_count; @@ -343,7 +342,7 @@ pub unsafe fn generate_function(name: *const c_char, _name_loc: Loc, params_coun sb_appendf(output, c!(" sub sp, sp, %zu\n"), stack_args_size); for i in reg_args_count..args.count { let above_index = i - reg_args_count; - load_arg_to_reg(*args.items.add(i), c!("x8"), output, op.loc, os); + load_arg_to_reg(*args.at(i), c!("x8"), output, op.loc, os); sb_appendf(output, c!(" str x8, [sp, %zu]\n"), above_index*8); } @@ -353,8 +352,7 @@ pub unsafe fn generate_function(name: *const c_char, _name_loc: Loc, params_coun sb_appendf(output, c!(" add sp, sp, %zu\n"), stack_args_size); }, Op::Asm {stmts} => { - for i in 0..stmts.count { - let stmt = *stmts.items.add(i); + for stmt in stmts.iter() { sb_appendf(output, c!(" %s\n"), stmt.line); } } @@ -395,34 +393,33 @@ pub unsafe fn generate_function(name: *const c_char, _name_loc: Loc, params_coun sb_appendf(output, c!(" ret\n")); } -pub unsafe fn generate_funcs(output: *mut String_Builder, funcs: *const [Func], variadics: *const [(*const c_char, Variadic)], os: Os) { +pub unsafe fn generate_funcs(output: *mut String_Builder, funcs: Array, variadics: Array<(*const c_char, Variadic)>, os: Os) { sb_appendf(output, c!(".text\n")); - for i in 0..funcs.len() { - generate_function((*funcs)[i].name, (*funcs)[i].name_loc, (*funcs)[i].params_count, (*funcs)[i].auto_vars_count, os, variadics, da_slice((*funcs)[i].body), output); + for func in funcs.iter() { + generate_function(func.name, func.name_loc, func.params_count, func.auto_vars_count, os, variadics, func.body, output); } } -pub unsafe fn generate_data_section(output: *mut String_Builder, data: *const [u8]) { - if data.len() > 0 { +pub unsafe fn generate_data_section(output: *mut String_Builder, data: Array) { + if data.count > 0 { sb_appendf(output, c!(".data\n")); sb_appendf(output, c!(".dat: .byte ")); - for i in 0..data.len() { + for (i, byte) in data.iter().enumerate() { if i > 0 { sb_appendf(output, c!(",")); } - sb_appendf(output, c!("0x%02X"), (*data)[i] as c_uint); + sb_appendf(output, c!("0x%02X"), byte as c_uint); } sb_appendf(output, c!("\n")); } } -pub unsafe fn generate_globals(output: *mut String_Builder, globals: *const [Global], os: Os) { - if globals.len() > 0 { +pub unsafe fn generate_globals(output: *mut String_Builder, globals: Array, os: Os) { + if globals.count > 0 { // TODO: consider splitting globals into bss and data sections, // depending on whether it's zero sb_appendf(output, c!(".data\n")); - for i in 0..globals.len() { - let global = (*globals)[i]; + for global in globals.iter() { match os { Os::Linux => { sb_appendf(output, c!(".global %s\n"), global.name); @@ -441,8 +438,8 @@ pub unsafe fn generate_globals(output: *mut String_Builder, globals: *const [Glo if global.is_vec { sb_appendf(output, c!(" .quad .+8\n"), global.name); } - for j in 0..global.values.count { - match *global.values.items.add(j) { + for value in global.values.iter() { + match value { ImmediateValue::Literal(lit) => { sb_appendf(output, c!(" .quad %zu\n"), lit); } @@ -469,9 +466,8 @@ pub unsafe fn generate_globals(output: *mut String_Builder, globals: *const [Glo } } -pub unsafe fn generate_asm_funcs(output: *mut String_Builder, asm_funcs: *const [AsmFunc], os: Os) { - for i in 0..asm_funcs.len() { - let asm_func = (*asm_funcs)[i]; +pub unsafe fn generate_asm_funcs(output: *mut String_Builder, asm_funcs: Array, os: Os) { + for asm_func in asm_funcs.iter() { match os { Os::Linux => { sb_appendf(output, c!(".global %s\n"), asm_func.name); @@ -485,8 +481,7 @@ pub unsafe fn generate_asm_funcs(output: *mut String_Builder, asm_funcs: *const } Os::Windows => missingf!(asm_func.name_loc, c!("AArch64 is not supported on windows\n")), } - for j in 0..asm_func.body.count { - let stmt = *asm_func.body.items.add(j); + for stmt in asm_func.body.iter() { sb_appendf(output, c!(" %s\n"), stmt.line); } } @@ -572,10 +567,10 @@ pub unsafe fn generate_program( if debug { todo!("Debug information for aarch64") } - generate_funcs(output, da_slice((*program).funcs), da_slice((*program).variadics), os); - generate_asm_funcs(output, da_slice((*program).asm_funcs), os); - generate_globals(output, da_slice((*program). globals), os); - generate_data_section(output, da_slice((*program).data)); + generate_funcs(output, (*program).funcs, (*program).variadics, os); + generate_asm_funcs(output, (*program).asm_funcs, os); + generate_globals(output, (*program).globals, os); + generate_data_section(output, (*program).data); let output_asm_path = temp_sprintf(c!("%s.s"), garbage_base); write_entire_file(output_asm_path, (*output).items as *const c_void, (*output).count)?; diff --git a/src/codegen/gas_x86_64/mod.rs b/src/codegen/gas_x86_64/mod.rs index 4d918594..13142b10 100644 --- a/src/codegen/gas_x86_64/mod.rs +++ b/src/codegen/gas_x86_64/mod.rs @@ -56,7 +56,7 @@ pub unsafe fn load_arg_to_reg(arg: Arg, reg: *const c_char,output: *mut String_B }; } -pub unsafe fn generate_function(name: *const c_char, name_loc: Loc, func_index: usize, params_count: usize, auto_vars_count: usize, body: *const [OpWithLocation], scope_events: *const [ScopeEvent], debug: bool, output: *mut String_Builder, os: Os) { +pub unsafe fn generate_function(name: *const c_char, name_loc: Loc, func_index: usize, params_count: usize, auto_vars_count: usize, body: Array, scope_events: Array, debug: bool, output: *mut String_Builder, os: Os) { let stack_size = align_bytes(auto_vars_count * 8, 16); match os { Os::Linux | Os::Windows => { @@ -112,15 +112,13 @@ pub unsafe fn generate_function(name: *const c_char, name_loc: Loc, func_index: } let mut proccessed_scope_events = 0; - for i in 0..body.len() { - let op = (*body)[i]; - + for op in body.iter() { if debug { sb_appendf(output, c!(" .loc %lld %lld\n"), func_index, op.loc.line_number); for j in proccessed_scope_events..op.scope_events_count { // TODO: duplicate code - match (*scope_events)[j] { + match *scope_events.at(j) { ScopeEvent::Declare { .. } => {} ScopeEvent::BlockBegin { index } => { match os { @@ -228,7 +226,7 @@ pub unsafe fn generate_function(name: *const c_char, name_loc: Loc, func_index: let reg_args_count = cmp::min(args.count, registers.len()); for i in 0..reg_args_count { let reg = (*registers)[i]; - load_arg_to_reg(*args.items.add(i), reg, output, os); + load_arg_to_reg(*args.at(i), reg, output, os); } let stack_args_count = args.count - reg_args_count; @@ -236,7 +234,7 @@ pub unsafe fn generate_function(name: *const c_char, name_loc: Loc, func_index: if stack_args_count > 0 { sb_appendf(output, c!(" subq $%zu, %%rsp\n"), stack_args_size); for i in 0..stack_args_count { - load_arg_to_reg(*args.items.add(reg_args_count + i), c!("rax"), output, os); + load_arg_to_reg(*args.at(reg_args_count + i), c!("rax"), output, os); sb_appendf(output, c!(" movq %%rax, %zu(%%rsp)\n"), i * 8); } } @@ -264,8 +262,7 @@ pub unsafe fn generate_function(name: *const c_char, name_loc: Loc, func_index: sb_appendf(output, c!(" movq %%rax, -%zu(%%rbp)\n"), result * 8); } Op::Asm { stmts } => { - for i in 0..stmts.count { - let stmt = *stmts.items.add(i); + for stmt in stmts.iter() { sb_appendf(output, c!(" %s\n"), stmt.line); } } @@ -310,9 +307,9 @@ pub unsafe fn generate_function(name: *const c_char, name_loc: Loc, func_index: Os::Darwin => sb_appendf(output, c!( "L%s_end:\n"), name), }; - for i in proccessed_scope_events..scope_events.len() { + for i in proccessed_scope_events..scope_events.count { // TODO: duplicate code - match (*scope_events)[i] { + match *scope_events.at(i) { ScopeEvent::Declare { .. } => {} ScopeEvent::BlockBegin { index } => { match os { @@ -331,16 +328,14 @@ pub unsafe fn generate_function(name: *const c_char, name_loc: Loc, func_index: } } -pub unsafe fn generate_funcs(output: *mut String_Builder, funcs: *const [Func], debug: bool, os: Os) { - for i in 0..funcs.len() { - let func = (*funcs)[i]; - generate_function(func.name, func.name_loc, i, func.params_count, func.auto_vars_count, da_slice(func.body), da_slice(func.scope_events), debug, output, os); +pub unsafe fn generate_funcs(output: *mut String_Builder, funcs: Array, debug: bool, os: Os) { + for (i, func) in funcs.iter().enumerate() { + generate_function(func.name, func.name_loc, i, func.params_count, func.auto_vars_count, func.body, func.scope_events, debug, output, os); } } -pub unsafe fn generate_asm_funcs(output: *mut String_Builder, asm_funcs: *const [AsmFunc], os: Os) { - for i in 0..asm_funcs.len() { - let asm_func = (*asm_funcs)[i]; +pub unsafe fn generate_asm_funcs(output: *mut String_Builder, asm_funcs: Array, os: Os) { + for asm_func in asm_funcs.iter() { match os { Os::Linux | Os::Windows => { sb_appendf(output, c!(".global %s\n"), asm_func.name); @@ -353,16 +348,14 @@ pub unsafe fn generate_asm_funcs(output: *mut String_Builder, asm_funcs: *const sb_appendf(output, c!("_%s:\n"), asm_func.name); } } - for j in 0..asm_func.body.count { - let stmt = *asm_func.body.items.add(j); + for stmt in asm_func.body.iter() { sb_appendf(output, c!(" %s\n"), stmt.line); } } } -pub unsafe fn generate_globals(output: *mut String_Builder, globals: *const [Global], os: Os) { - for i in 0..globals.len() { - let global = (*globals)[i]; +pub unsafe fn generate_globals(output: *mut String_Builder, globals: Array, os: Os) { + for global in globals.iter() { match os { Os::Linux | Os::Windows => { sb_appendf(output, c!(".global %s\n"), global.name); @@ -382,11 +375,11 @@ pub unsafe fn generate_globals(output: *mut String_Builder, globals: *const [Glo if global.values.count > 0 { sb_appendf(output, c!(".quad ")); - for j in 0..global.values.count { + for (j, value) in global.values.iter().enumerate() { if j > 0 { sb_appendf(output, c!(",")); } - match *global.values.items.add(j) { + match value { ImmediateValue::Literal(lit) => sb_appendf(output, c!("0x%llX"), lit), ImmediateValue::Name(name) => match os { Os::Linux | Os::Windows => sb_appendf(output, c!("%s"), name), @@ -406,14 +399,14 @@ pub unsafe fn generate_globals(output: *mut String_Builder, globals: *const [Glo } } -pub unsafe fn generate_data_section(output: *mut String_Builder, data: *const [u8]) { - if data.len() > 0 { +pub unsafe fn generate_data_section(output: *mut String_Builder, data: Array) { + if data.count > 0 { sb_appendf(output, c!("dat: .byte ")); - for i in 0..data.len() { + for (i, byte) in data.iter().enumerate() { if i > 0 { sb_appendf(output, c!(",")); } - sb_appendf(output, c!("0x%02X"), (*data)[i] as c_uint); + sb_appendf(output, c!("0x%02X"), byte as c_uint); } sb_appendf(output, c!("\n")); } @@ -557,8 +550,7 @@ pub unsafe fn generate_debuginfo(output: *mut String_Builder, funcs: Array } pub unsafe fn generate_globals_debuginfo(output: *mut String_Builder, globals: Array, os: Os) { - for i in 0..globals.count { - let global = *globals.items.add(i); + for global in globals.iter() { sb_appendf(output, c!(".uleb128 %lld\n"), dwarf::TEMPLATE_variable); sb_appendf(output, c!(".string \"%s\"\n"), global.name); sb_appendf(output, c!(".long debug_info_word_type_offset\n")); @@ -584,9 +576,7 @@ pub unsafe fn sleb128_length(mut n: i64) -> u64 { } pub unsafe fn generate_funcs_debuginfo(output: *mut String_Builder, funcs: Array, os: Os) { - for i in 0..funcs.count { - let func = *funcs.items.add(i); - + for func in funcs.iter() { sb_appendf(output, c!(".uleb128 %lld\n"), dwarf::TEMPLATE_function); sb_appendf(output, c!(".string \"%s\"\n"), func.name); sb_appendf(output, c!(".quad %s\n"), func.name); @@ -597,8 +587,8 @@ pub unsafe fn generate_funcs_debuginfo(output: *mut String_Builder, funcs: Array sb_appendf(output, c!(".uleb128 0x1\n")); // .byte (1) = 1 sb_appendf(output, c!(".byte %lld\n"), dwarf::OP_call_frame_cfa); - for j in 0..func.scope_events.count { - match *func.scope_events.items.add(j) { + for event in func.scope_events.iter() { + match event { ScopeEvent::Declare { name, index } => { sb_appendf(output, c!(".uleb128 %lld\n"), dwarf::TEMPLATE_variable); sb_appendf(output, c!(".string \"%s\"\n"), name); @@ -720,14 +710,14 @@ pub unsafe fn generate_program( Os::Darwin => sb_appendf(output, c!(".text\n")), Os::Linux | Os::Windows => sb_appendf(output, c!(".section .text\n")), }; - generate_funcs(output, da_slice((*program).funcs), debug, os); - generate_asm_funcs(output, da_slice((*program).asm_funcs), os); + generate_funcs(output, (*program).funcs, debug, os); + generate_asm_funcs(output, (*program).asm_funcs, os); match os { Os::Darwin => sb_appendf(output, c!(".data\n")), Os::Linux | Os::Windows => sb_appendf(output, c!(".section .data\n")), }; - generate_data_section(output, da_slice((*program).data)); - generate_globals(output, da_slice((*program).globals), os); + generate_data_section(output, (*program).data); + generate_globals(output, (*program).globals, os); let output_asm_path = temp_sprintf(c!("%s.s"), garbage_base); write_entire_file(output_asm_path, (*output).items as *const c_void, (*output).count)?; diff --git a/src/codegen/mod.rs b/src/codegen/mod.rs index 4dee6f85..0c067357 100644 --- a/src/codegen/mod.rs +++ b/src/codegen/mod.rs @@ -12,7 +12,7 @@ macro_rules! codegens { $( crate::codegen::$codegen::get_apis(&mut apis); - register_apis(&mut targets, da_slice(apis), c!(stringify!($codegen)))?; + register_apis(&mut targets, apis, c!(stringify!($codegen)))?; apis.count = 0; )* diff --git a/src/codegen/mos6502.rs b/src/codegen/mos6502.rs index e877e88f..b96e78e5 100644 --- a/src/codegen/mos6502.rs +++ b/src/codegen/mos6502.rs @@ -238,8 +238,7 @@ pub struct External { } pub unsafe fn add_external(name: *const c_char, addr: u16, loc: Loc, asm: *mut Assembler) -> Option<()> { - for i in 0..(*asm).externals.count { - let ext = *(*asm).externals.items.add(i); + for ext in (*asm).externals.iter() { if strcmp(ext.name, name) == 0 { diagf!(loc, c!("ERROR: redefinition of name `%s`\n"), name); diagf!(ext.loc, c!("INFO: previously defined here\n")); @@ -273,7 +272,7 @@ pub unsafe fn write_word(out: *mut String_Builder, word: u16) { write_byte(out, (word >> 8) as u8); } pub unsafe fn write_byte_at(out: *mut String_Builder, byte: u8, addr: u16) { - *((*out).items.add(addr as usize)) = byte as c_char; + *((*out).at(addr as usize)) = byte as c_char; } pub unsafe fn write_word_at(out: *mut String_Builder, word: u16, addr: u16) { write_byte_at(out, word as u8, addr); @@ -326,10 +325,10 @@ pub unsafe fn create_address_label_here(out: *const String_Builder, asm: *mut As // TODO: inform the caller, that `addr' is relative to code_start pub unsafe fn link_address_label(label: usize, addr: u16, asm: *mut Assembler) { - *(*asm).addresses.items.add(label) = addr; + *(*asm).addresses.at(label) = addr; } pub unsafe fn link_address_label_here(label: usize, out: *const String_Builder, asm: *mut Assembler) { - *(*asm).addresses.items.add(label) = (*out).count as u16; + *(*asm).addresses.at(label) = (*out).count as u16; } pub unsafe fn load_auto_var(out: *mut String_Builder, index: usize, asm: *mut Assembler) { @@ -819,7 +818,7 @@ mod ops { } pub unsafe fn generate_function(name: *const c_char, loc: Loc, params_count: usize, auto_vars_count: usize, - body: *const [OpWithLocation], out: *mut String_Builder, + body: Array, out: *mut String_Builder, asm: *mut Assembler) { (*asm).frame_sz = 0; let fun_addr = (*out).count as u16; @@ -827,7 +826,7 @@ pub unsafe fn generate_function(name: *const c_char, loc: Loc, params_count: usi // prepare function labels for each op and the end of the function let mut op_addresses: Array = zeroed(); - for _ in 0..=body.len() { + for _ in 0..=body.count { let idx = (*asm).addresses.count; da_append(&mut op_addresses, idx); @@ -860,11 +859,10 @@ pub unsafe fn generate_function(name: *const c_char, loc: Loc, params_count: usi instr16(out, STA, ABS_X, STACK_PAGE + stack_size as u16 - 2*i); } - for i in 0..body.len() { - let addr_idx = *op_addresses.items.add(i); - *(*asm).addresses.items.add(addr_idx) = (*out).count as u16; // update op address + for (i, op) in body.iter().enumerate() { + let addr_idx = *op_addresses.at(i); + *(*asm).addresses.at(addr_idx) = (*out).count as u16; // update op address - let op = (*body)[i]; match op.opcode { Op::Bogus => unreachable!("bogus-amogus"), Op::Return {arg} => { @@ -874,7 +872,7 @@ pub unsafe fn generate_function(name: *const c_char, loc: Loc, params_count: usi // jump to ret statement instr0(out, JMP, ABS); - add_reloc(out, RelocationKind::Address{idx: *op_addresses.items.add(body.len()), + add_reloc(out, RelocationKind::Address{idx: *op_addresses.at(body.count), relative: false}, asm); }, Op::Store {index, arg} => { @@ -1283,8 +1281,8 @@ pub unsafe fn generate_function(name: *const c_char, loc: Loc, params_count: usi } } - for i in (0..args.count).rev() { - load_arg(*args.items.add(i), op.loc, out, asm); + for (i, arg) in args.iter().enumerate().rev() { + load_arg(arg, op.loc, out, asm); // first arg in Y:A to be compatible with wozmon routines if i != 0 { push16(out, asm); @@ -1323,8 +1321,7 @@ pub unsafe fn generate_function(name: *const c_char, loc: Loc, params_count: usi store_auto(out, result, asm); }, Op::Asm {stmts} => { - for i in 0..stmts.count { - let stmt = *stmts.items.add(i); + for stmt in stmts.iter() { assemble_statement(out, stmt.line, stmt.loc, asm); } }, @@ -1382,8 +1379,8 @@ pub unsafe fn generate_function(name: *const c_char, loc: Loc, params_count: usi instr8(out, LDA, IMM, 0); instr(out, TAY); - let addr_idx = *op_addresses.items.add(body.len()); - *(*asm).addresses.items.add(addr_idx) = (*out).count as u16; + let addr_idx = *op_addresses.at(body.count); + *(*asm).addresses.at(addr_idx) = (*out).count as u16; if stack_size > 0 { // seriously... we don't have enough registers to save A to... @@ -1394,15 +1391,14 @@ pub unsafe fn generate_function(name: *const c_char, loc: Loc, params_count: usi instr(out, RTS); } -pub unsafe fn generate_funcs(out: *mut String_Builder, funcs: *const [Func], asm: *mut Assembler) { - for i in 0..funcs.len() { - generate_function((*funcs)[i].name, (*funcs)[i].name_loc, (*funcs)[i].params_count, (*funcs)[i].auto_vars_count, da_slice((*funcs)[i].body), out, asm); +pub unsafe fn generate_funcs(out: *mut String_Builder, funcs: Array, asm: *mut Assembler) { + for func in funcs.iter() { + generate_function(func.name, func.name_loc, func.params_count, func.auto_vars_count, func.body, out, asm); } } pub unsafe fn apply_relocations(out: *mut String_Builder, data_start: u16, asm: *mut Assembler) { - 'reloc_loop: for i in 0..(*asm).relocs.count { - let reloc = *(*asm).relocs.items.add(i); + 'reloc_loop: for reloc in (*asm).relocs.iter() { let caddr = reloc.addr; match reloc.kind { RelocationKind::DataOffset{off, byte} => { @@ -1414,8 +1410,7 @@ pub unsafe fn apply_relocations(out: *mut String_Builder, data_start: u16, asm: } }, RelocationKind::Label{func_name: name, label} => { - for i in 0..(*asm).op_labels.count { - let op_label = *(*asm).op_labels.items.add(i); + for op_label in (*asm).op_labels.iter() { if strcmp(op_label.func_name, name) == 0 && op_label.label == label { write_word_at(out, (*asm).code_start + op_label.addr, caddr); continue 'reloc_loop; @@ -1425,8 +1420,7 @@ pub unsafe fn apply_relocations(out: *mut String_Builder, data_start: u16, asm: unreachable!(); }, RelocationKind::External{name, offset, byte, relative} => { - for i in 0..(*asm).externals.count { - let label = *(*asm).externals.items.add(i); + for label in (*asm).externals.iter() { if strcmp(label.name, name) == 0 { let faddr = (*asm).code_start + label.addr + offset as u16; if relative { @@ -1446,40 +1440,36 @@ pub unsafe fn apply_relocations(out: *mut String_Builder, data_start: u16, asm: unreachable!(); }, RelocationKind::Address{idx, relative: true} => { - let jaddr = *(*asm).addresses.items.add(idx); + let jaddr = *(*asm).addresses.at(idx); let rel: i16 = jaddr as i16 - (caddr + 1) as i16; assert!(rel < 128 && rel >= -128); write_byte_at(out, rel as u8, caddr); }, RelocationKind::Address{idx, relative: false} => { - let saddr = *(*asm).addresses.items.add(idx) + (*asm).code_start; + let saddr = *(*asm).addresses.at(idx) + (*asm).code_start; write_word_at(out, saddr, caddr); }, } } } -pub unsafe fn generate_extrns(_out: *mut String_Builder, extrns: *const [*const c_char], - funcs: *const [Func], globals: *const [Global], - asm_funcs: *const [AsmFunc], _asm: *mut Assembler) { - 'skip_function_or_global: for i in 0..extrns.len() { +pub unsafe fn generate_extrns(_out: *mut String_Builder, extrns: Array<*const c_char>, + funcs: Array, globals: Array, + asm_funcs: Array, _asm: *mut Assembler) { + 'skip_function_or_global: for name in extrns.iter() { // assemble a few "stdlib" functions which can't be programmed in B - let name = (*extrns)[i]; - for j in 0..funcs.len() { - let func = (*funcs)[j].name; - if strcmp(func, name) == 0 { + for func in funcs.iter() { + if strcmp(func.name, name) == 0 { continue 'skip_function_or_global } } - for j in 0..globals.len() { - let global = (*globals)[j].name; - if strcmp(global, name) == 0 { + for global in globals.iter() { + if strcmp(global.name, name) == 0 { continue 'skip_function_or_global } } - for j in 0..asm_funcs.len() { - let func = (*asm_funcs)[j].name; - if strcmp(func, name) == 0 { + for func in asm_funcs.iter() { + if strcmp(func.name, name) == 0 { continue 'skip_function_or_global } } @@ -1489,9 +1479,8 @@ pub unsafe fn generate_extrns(_out: *mut String_Builder, extrns: *const [*const } } -pub unsafe fn generate_globals(out: *mut String_Builder, globals: *mut [Global], asm: *mut Assembler) { - for i in 0..globals.len() { - let global = (*globals)[i]; +pub unsafe fn generate_globals(out: *mut String_Builder, globals: Array, asm: *mut Assembler) { + for global in globals.iter() { add_external(global.name, (*out).count as u16, global.name_loc, asm); if global.is_vec { @@ -1499,8 +1488,8 @@ pub unsafe fn generate_globals(out: *mut String_Builder, globals: *mut [Global], add_reloc(out, RelocationKind::Address{idx: address, relative: false}, asm); link_address_label_here(address, out, asm); } - for j in 0..global.values.count { - match *global.values.items.add(j) { + for value in global.values.iter() { + match value { ImmediateValue::Literal(lit) => write_word(out, lit as u16), ImmediateValue::Name(name) => add_reloc(out, RelocationKind::External{name, byte: Byte::Both, offset: 0, relative: false}, asm), @@ -1516,9 +1505,9 @@ pub unsafe fn generate_globals(out: *mut String_Builder, globals: *mut [Global], } } -pub unsafe fn generate_data_section(out: *mut String_Builder, data: *const [u8]) { - for i in 0..data.len() { - write_byte(out, (*data)[i]); +pub unsafe fn generate_data_section(out: *mut String_Builder, data: Array) { + for byte in data.iter() { + write_byte(out, byte); } } @@ -1529,16 +1518,13 @@ pub unsafe fn generate_entry(out: *mut String_Builder, asm: *mut Assembler) { instr16(out, JMP, IND, 0xFFFC); } -pub unsafe fn generate_asm_funcs(out: *mut String_Builder, asm_funcs: *const [AsmFunc], +pub unsafe fn generate_asm_funcs(out: *mut String_Builder, asm_funcs: Array, asm: *mut Assembler) { - for i in 0..asm_funcs.len() { - let asm_func = (*asm_funcs)[i]; - + for asm_func in asm_funcs.iter() { let fun_addr = (*out).count as u16; add_external(asm_func.name, fun_addr, asm_func.name_loc, asm); - for j in 0..asm_func.body.count { - let stmt = *asm_func.body.items.add(j); + for stmt in asm_func.body.iter() { assemble_statement(out, stmt.line, stmt.loc, asm); } } @@ -1611,13 +1597,13 @@ pub unsafe fn generate_program( generate_entry(out, &mut asm); asm.code_start = (*gen).load_offset as u16; - generate_funcs(out, da_slice((*p).funcs), &mut asm); - generate_asm_funcs(out, da_slice((*p).asm_funcs), &mut asm); - generate_extrns(out, da_slice((*p).extrns), da_slice((*p).funcs), da_slice((*p).globals), da_slice((*p).asm_funcs), &mut asm); + generate_funcs(out, (*p).funcs, &mut asm); + generate_asm_funcs(out, (*p).asm_funcs, &mut asm); + generate_extrns(out, (*p).extrns, (*p).funcs, (*p).globals, (*p).asm_funcs, &mut asm); let data_start = (*gen).load_offset as u16 + (*out).count as u16; - generate_data_section(out, da_slice((*p).data)); - generate_globals(out, da_slice((*p).globals), &mut asm); + generate_data_section(out, (*p).data); + generate_globals(out, (*p).globals, &mut asm); log(Log_Level::INFO, c!("Generated size: 0x%x"), (*out).count as c_uint); apply_relocations(out, data_start, &mut asm); diff --git a/src/codegen/uxn/mod.rs b/src/codegen/uxn/mod.rs index 48995ad9..cbceadca 100644 --- a/src/codegen/uxn/mod.rs +++ b/src/codegen/uxn/mod.rs @@ -56,10 +56,9 @@ pub enum PatchKind { } pub unsafe fn get_or_create_label_by_name(a: *mut Assembler, name: *const c_char) -> usize { - for i in 0..(*a).named_labels.count { - let named_label = (*a).named_labels.items.add(i); - if strcmp((*named_label).name, name) == 0 { - return (*named_label).label; + for named_label in (*a).named_labels.iter() { + if strcmp(named_label.name, name) == 0 { + return named_label.label; } } let new_label = create_label(a); @@ -75,16 +74,14 @@ pub unsafe fn create_label(a: *mut Assembler) -> usize { } pub unsafe fn link_label(a: *mut Assembler, label: usize, addr: usize) { - *(*a).resolved_addresses.items.add(label) = addr as u16; + *(*a).resolved_addresses.at(label) = addr as u16; } pub unsafe fn apply_patches(output: *mut String_Builder, a: *mut Assembler) -> Option<()> { - for i in 0..(*a).patches.count { - let patch = *(*a).patches.items.add(i); - let addr = *(*a).resolved_addresses.items.add(patch.label); + for patch in (*a).patches.iter() { + let addr = *(*a).resolved_addresses.at(patch.label); if addr == 0 { - for j in 0..(*a).named_labels.count { - let named_label = *(*a).named_labels.items.add(j); + for named_label in (*a).named_labels.iter() { if named_label.label == patch.label { log(Log_Level::ERROR, c!("uxn: Label '%s' was never linked"), named_label.name); return None; @@ -100,7 +97,7 @@ pub unsafe fn apply_patches(output: *mut String_Builder, a: *mut Assembler) -> O PatchKind::UpperRelative => ((addr + offset).wrapping_sub(patch.addr).wrapping_sub(2) >> 8) & 0xff, PatchKind::LowerRelative => ((addr + offset).wrapping_sub(patch.addr).wrapping_sub(1)) & 0xff, }; - *(*output).items.add(patch.addr as usize) = byte as c_char; + *(*output).at(patch.addr as usize) = byte as c_char; } Some(()) } @@ -109,11 +106,10 @@ const SP: u8 = 0; const BP: u8 = 2; const FIRST_ARG: u8 = 4; -pub unsafe fn generate_asm_funcs(output: *mut String_Builder, asm_funcs: *const [AsmFunc], assembler: *mut Assembler) -> Option<()> { - for i in 0..asm_funcs.len() { - let asm_func = (*asm_funcs)[i]; +pub unsafe fn generate_asm_funcs(output: *mut String_Builder, asm_funcs: Array, assembler: *mut Assembler) -> Option<()> { + for asm_func in asm_funcs.iter() { link_label(assembler, get_or_create_label_by_name(assembler, asm_func.name), (*output).count); - process_asm_statements(output, da_slice(asm_func.body), assembler)?; + process_asm_statements(output, asm_func.body, assembler)?; } Some(()) } @@ -236,9 +232,8 @@ pub unsafe fn generate_program( write_lit_stz2(output, SP); // call main or _start, _start having a priority let mut main_proc = c!("main"); - for i in 0..(*program).funcs.count { - let name = (*(*program).funcs.items.add(i)).name; - if strcmp(name, c!("_start")) == 0 { + for func in (*program).funcs.iter() { + if strcmp(func.name, c!("_start")) == 0 { main_proc = c!("_start"); break; } @@ -253,11 +248,11 @@ pub unsafe fn generate_program( write_label_abs(output, vector_return_label, &mut assembler, 0); write_op(output, UxnOp::BRK); - generate_funcs(output, da_slice((*program).funcs), &mut assembler)?; - generate_asm_funcs(output, da_slice((*program).asm_funcs), &mut assembler)?; - generate_extrns(da_slice((*program).extrns), da_slice((*program).funcs), da_slice((*program).asm_funcs), da_slice((*program).globals))?; - generate_data_section(output, da_slice((*program).data), &mut assembler); - generate_globals(output, da_slice((*program).globals), &mut assembler); + generate_funcs(output, (*program).funcs, &mut assembler)?; + generate_asm_funcs(output, (*program).asm_funcs, &mut assembler)?; + generate_extrns((*program).extrns, (*program).funcs, (*program).asm_funcs, (*program).globals)?; + generate_data_section(output, (*program).data, &mut assembler); + generate_globals(output, (*program).globals, &mut assembler); apply_patches(output, &mut assembler)?; @@ -278,14 +273,14 @@ pub unsafe fn run_program( Some(()) } -pub unsafe fn generate_funcs(output: *mut String_Builder, funcs: *const [Func], assembler: &mut Assembler) -> Option<()> { - for i in 0..funcs.len() { - generate_function((*funcs)[i].name, (*funcs)[i].name_loc, (*funcs)[i].params_count, (*funcs)[i].auto_vars_count, da_slice((*funcs)[i].body), output, assembler)?; +pub unsafe fn generate_funcs(output: *mut String_Builder, funcs: Array, assembler: &mut Assembler) -> Option<()> { + for func in funcs.iter() { + generate_function(func.name, func.name_loc, func.params_count, func.auto_vars_count, func.body, output, assembler)?; } Some(()) } -pub unsafe fn generate_function(name: *const c_char, name_loc: Loc, params_count: usize, auto_vars_count: usize, body: *const [OpWithLocation], output: *mut String_Builder, assembler: *mut Assembler) -> Option<()> { +pub unsafe fn generate_function(name: *const c_char, name_loc: Loc, params_count: usize, auto_vars_count: usize, body: Array, output: *mut String_Builder, assembler: *mut Assembler) -> Option<()> { link_label(assembler, get_or_create_label_by_name(assembler, name), (*output).count); const MAX_ARGS: usize = (256 - FIRST_ARG as usize) / 2; @@ -321,8 +316,7 @@ pub unsafe fn generate_function(name: *const c_char, name_loc: Loc, params_count // prepare our labels for each IR label let mut labels: Array = zeroed(); - for i in 0..body.len() { - let op = (*body)[i]; + for op in body.iter() { match op.opcode { Op::Label {..} => { da_append(&mut labels, create_label(assembler)); @@ -332,8 +326,7 @@ pub unsafe fn generate_function(name: *const c_char, name_loc: Loc, params_count } // emit code - for i in 0..body.len() { - let op = (*body)[i]; + for op in body.iter() { match op.opcode { Op::Bogus => unreachable!("bogus-amogus"), Op::UnaryNot {result, arg} => { @@ -594,8 +587,8 @@ pub unsafe fn generate_function(name: *const c_char, name_loc: Loc, params_count if args.count > MAX_ARGS.into() { missingf!(op.loc, c!("Too many function call arguments. We support only %d but %zu were provided\n"), MAX_ARGS, args.count); } - for i in 0..args.count { - load_arg(*args.items.add(i), op.loc, output, assembler); + for (i, arg) in args.iter().enumerate() { + load_arg(arg, op.loc, output, assembler); write_lit_stz2(output, FIRST_ARG + (i as u8) * 2) } @@ -604,21 +597,21 @@ pub unsafe fn generate_function(name: *const c_char, name_loc: Loc, params_count store_auto(output, result); } Op::Asm {stmts} => { - process_asm_statements(output, da_slice(stmts), assembler)?; + process_asm_statements(output, stmts, assembler)?; } Op::Label {label} => { - link_label(assembler, *labels.items.add(label), (*output).count); + link_label(assembler, *labels.at(label), (*output).count); } Op::JmpLabel {label} => { write_op(output, UxnOp::JMI); - write_label_rel(output, *labels.items.add(label), assembler, 0); + write_label_rel(output, *labels.at(label), assembler, 0); } Op::JmpIfNotLabel {label, arg} => { load_arg(arg, op.loc, output, assembler); write_lit2(output, 0); write_op(output, UxnOp::EQU2); write_op(output, UxnOp::JCI); - write_label_rel(output, *labels.items.add(label), assembler, 0); + write_label_rel(output, *labels.at(label), assembler, 0); } Op::Return {arg} => { // Put return value in the FIRST_ARG @@ -820,25 +813,21 @@ pub unsafe fn store_auto(output: *mut String_Builder, index: usize) { write_op(output, UxnOp::STA2); } -pub unsafe fn generate_extrns(extrns: *const [*const c_char], funcs: *const [Func], asm_funcs: *const[AsmFunc], globals: *const [Global]) -> Option<()> { - 'skip_function_or_global: for i in 0..extrns.len() { +pub unsafe fn generate_extrns(extrns: Array<*const c_char>, funcs: Array, asm_funcs: Array, globals: Array) -> Option<()> { + 'skip_function_or_global: for name in extrns.iter() { // assemble a few "stdlib" functions which can't be programmed in B - let name = (*extrns)[i]; - for j in 0..funcs.len() { - let func = (*funcs)[j]; + for func in funcs.iter() { if strcmp(func.name, name) == 0 { continue 'skip_function_or_global } } - for j in 0..asm_funcs.len() { - let func = (*asm_funcs)[j]; + for func in asm_funcs.iter() { if strcmp(func.name, name) == 0 { continue 'skip_function_or_global } } - for j in 0..globals.len() { - let global = (*globals)[j].name; - if strcmp(global, name) == 0 { + for global in globals.iter() { + if strcmp(global.name, name) == 0 { continue 'skip_function_or_global } } @@ -848,17 +837,16 @@ pub unsafe fn generate_extrns(extrns: *const [*const c_char], funcs: *const [Fun Some(()) } -pub unsafe fn generate_globals(output: *mut String_Builder, globals: *const [Global], assembler: *mut Assembler) { - for i in 0..globals.len() { - let global = (*globals)[i]; +pub unsafe fn generate_globals(output: *mut String_Builder, globals: Array, assembler: *mut Assembler) { + for global in globals.iter() { link_label(assembler, get_or_create_label_by_name(assembler, global.name), (*output).count); if global.is_vec { let label = create_label(assembler); write_label_abs(output, label, assembler, 0); link_label(assembler, label, (*output).count); } - for j in 0..global.values.count { - match *global.values.items.add(j) { + for value in global.values.iter() { + match value { ImmediateValue::Literal(lit) => { write_short(output, lit as u16); } @@ -876,10 +864,10 @@ pub unsafe fn generate_globals(output: *mut String_Builder, globals: *const [Glo } } -pub unsafe fn generate_data_section(output: *mut String_Builder, data: *const [u8], assembler: *mut Assembler) { +pub unsafe fn generate_data_section(output: *mut String_Builder, data: Array, assembler: *mut Assembler) { link_label(assembler, (*assembler).data_section_label, (*output).count); - for i in 0..data.len() { - write_byte(output, (*data)[i]); + for byte in data.iter() { + write_byte(output, byte); } } @@ -1218,9 +1206,8 @@ pub unsafe fn has_immediate(op: UxnOp) -> bool { has_byte_immediate(op) || has_short_immediate(op) } -pub unsafe fn process_asm_statements(output: *mut String_Builder, asm_stmts: *const [AsmStmt], assembler: *mut Assembler) -> Option<()> { - for i in 0..asm_stmts.len() { - let asm_stmt = (*asm_stmts)[i]; +pub unsafe fn process_asm_statements(output: *mut String_Builder, asm_stmts: Array, assembler: *mut Assembler) -> Option<()> { + for asm_stmt in asm_stmts.iter() { process_asm_statement(output, asm_stmt, assembler)?; } Some(()) diff --git a/src/crust.rs b/src/crust.rs index bd231d16..04064ad2 100644 --- a/src/crust.rs +++ b/src/crust.rs @@ -1,5 +1,6 @@ // This is a module that facilitates Crust-style programming - https://github.com/tsoding/crust use crate::crust::libc::*; +use crate::nob::Array; use core::panic::PanicInfo; use core::ffi::*; @@ -47,10 +48,10 @@ pub unsafe fn assoc_lookup_cstr_mut(assoc: *mut [(*const c_char, Value)], None } -pub unsafe fn assoc_lookup_cstr(assoc: *const [(*const c_char, Value)], needle: *const c_char) -> Option<*const Value> { - for i in 0..assoc.len() { - if strcmp((*assoc)[i].0, needle) == 0 { - return Some(&(*assoc)[i].1); +pub unsafe fn assoc_lookup_cstr(assoc: Array<(*const c_char, Value)>, needle: *const c_char) -> Option<*const Value> { + for entry in assoc.iter() { + if strcmp(entry.0, needle) == 0 { + return Some(&entry.1); } } None diff --git a/src/ir.rs b/src/ir.rs index 75a4f13b..71a7c2b1 100644 --- a/src/ir.rs +++ b/src/ir.rs @@ -222,16 +222,15 @@ pub unsafe fn dump_op(op: OpWithLocation, output: *mut String_Builder) { Op::Funcall{result, fun, args} => { sb_appendf(output, c!(" auto[%zu] = "), result); dump_arg_call(fun, output); - for i in 0..args.count { + for arg in args.iter() { sb_appendf(output, c!(", ")); - dump_arg(output, *args.items.add(i)); + dump_arg(output, arg); } sb_appendf(output, c!(")\n")); } Op::Asm {stmts} => { sb_appendf(output, c!(" __asm__(\n")); - for i in 0..stmts.count { - let stmt = *stmts.items.add(i); + for stmt in stmts.iter() { sb_appendf(output, c!(" %s\n"), stmt.line); } sb_appendf(output, c!(")\n")); @@ -258,44 +257,43 @@ pub unsafe fn dump_op(op: OpWithLocation, output: *mut String_Builder) { } } -pub unsafe fn dump_function(name: *const c_char, params_count: usize, auto_vars_count: usize, body: *const [OpWithLocation], output: *mut String_Builder) { +pub unsafe fn dump_function(name: *const c_char, params_count: usize, auto_vars_count: usize, body: Array, output: *mut String_Builder) { sb_appendf(output, c!("%s(%zu, %zu):\n"), name, params_count, auto_vars_count); - for i in 0..body.len() { - dump_op((*body)[i], output) + for op in body.iter() { + dump_op(op, output) } } -pub unsafe fn dump_funcs(output: *mut String_Builder, funcs: *const [Func]) { +pub unsafe fn dump_funcs(output: *mut String_Builder, funcs: Array) { sb_appendf(output, c!("-- Functions --\n")); sb_appendf(output, c!("\n")); - for i in 0..funcs.len() { - dump_function((*funcs)[i].name, (*funcs)[i].params_count, (*funcs)[i].auto_vars_count, da_slice((*funcs)[i].body), output); + for func in funcs.iter() { + dump_function(func.name, func.params_count, func.auto_vars_count, func.body, output); } } -pub unsafe fn dump_extrns(output: *mut String_Builder, extrns: *const [*const c_char]) { +pub unsafe fn dump_extrns(output: *mut String_Builder, extrns: Array<*const c_char>) { sb_appendf(output, c!("\n")); sb_appendf(output, c!("-- External Symbols --\n\n")); - for i in 0..extrns.len() { - sb_appendf(output, c!(" %s\n"), (*extrns)[i]); + for extrn in extrns.iter() { + sb_appendf(output, c!(" %s\n"), extrn); } } -pub unsafe fn dump_globals(output: *mut String_Builder, globals: *const [Global]) { +pub unsafe fn dump_globals(output: *mut String_Builder, globals: Array) { sb_appendf(output, c!("\n")); sb_appendf(output, c!("-- Global Variables --\n\n")); - for i in 0..globals.len() { - let global = (*globals)[i]; + for global in globals.iter() { sb_appendf(output, c!("%s"), global.name); if global.is_vec { sb_appendf(output, c!("[%zu]"), global.minimum_size); } sb_appendf(output, c!(": ")); - for j in 0..global.values.count { + for (j, value) in global.values.iter().enumerate() { if j > 0 { sb_appendf(output, c!(", ")); } - match *global.values.items.add(j) { + match value { ImmediateValue::Literal(lit) => sb_appendf(output, c!("%zu"), lit), ImmediateValue::Name(name) => sb_appendf(output, c!("%s"), name), ImmediateValue::DataOffset(offset) => sb_appendf(output, c!("data[%zu]"), offset), @@ -305,27 +303,27 @@ pub unsafe fn dump_globals(output: *mut String_Builder, globals: *const [Global] } } -pub unsafe fn dump_data_section(output: *mut String_Builder, data: *const [u8]) { - if data.len() > 0 { +pub unsafe fn dump_data_section(output: *mut String_Builder, data: Array) { + if data.count > 0 { sb_appendf(output, c!("\n")); sb_appendf(output, c!("-- Data Section --\n")); sb_appendf(output, c!("\n")); const ROW_SIZE: usize = 12; - for i in (0..data.len()).step_by(ROW_SIZE) { + for i in (0..data.count).step_by(ROW_SIZE) { sb_appendf(output, c!("%04X:"), i as c_uint); for j in i..(i+ROW_SIZE) { - if j < data.len() { + if j < data.count { sb_appendf(output, c!(" ")); - sb_appendf(output, c!("%02X"), (*data)[j] as c_uint); + sb_appendf(output, c!("%02X"), data.at(j) as c_uint); } else { sb_appendf(output, c!(" ")); } } sb_appendf(output, c!(" | ")); - for j in i..(i+ROW_SIZE).min(data.len()) { - let ch = (*data)[j] as char; + for j in i..(i+ROW_SIZE).min(data.count) { + let ch = *data.at(j) as char; let c = if ch.is_ascii_whitespace() { // display all whitespace as a regular space // stops '\t', '\n', '\b' from messing up the formatting @@ -344,21 +342,19 @@ pub unsafe fn dump_data_section(output: *mut String_Builder, data: *const [u8]) } } -pub unsafe fn dump_asm_funcs(output: *mut String_Builder, asm_funcs: *const [AsmFunc]) { - for i in 0..asm_funcs.len() { - let asm_func = (*asm_funcs)[i]; +pub unsafe fn dump_asm_funcs(output: *mut String_Builder, asm_funcs: Array) { + for asm_func in asm_funcs.iter() { sb_appendf(output, c!("%s(asm):\n"), asm_func.name); - for j in 0..asm_func.body.count { - let stmt = *asm_func.body.items.add(j); + for stmt in asm_func.body.iter() { sb_appendf(output, c!(" %s\n"), stmt.line); } } } pub unsafe fn dump_program(output: *mut String_Builder, p: *const Program) { - dump_funcs(output, da_slice((*p).funcs)); - dump_asm_funcs(output, da_slice((*p).asm_funcs)); - dump_extrns(output, da_slice((*p).extrns)); - dump_globals(output, da_slice((*p).globals)); - dump_data_section(output, da_slice((*p).data)); + dump_funcs(output, (*p).funcs); + dump_asm_funcs(output, (*p).asm_funcs); + dump_extrns(output, (*p).extrns); + dump_globals(output, (*p).globals); + dump_data_section(output,(*p).data); } diff --git a/src/lexer.rs b/src/lexer.rs index 926d6472..ffc47ee9 100644 --- a/src/lexer.rs +++ b/src/lexer.rs @@ -597,9 +597,9 @@ pub unsafe fn get_token(l: *mut Lexer) -> Option<()> { return None; } (*l).int_number = 0; - for i in 0..(*l).string_storage.count { + for char in (*l).string_storage.iter() { (*l).int_number *= 0x100; - (*l).int_number += *(*l).string_storage.items.add(i) as u64; + (*l).int_number += char as u64; } return Some(()); } diff --git a/src/nob.rs b/src/nob.rs index 2b2d2a76..38f4783d 100644 --- a/src/nob.rs +++ b/src/nob.rs @@ -1,6 +1,7 @@ use core::ffi::*; use core::slice; use crate::crust::*; +#[allow(unused)] use crate::enum_with_order; #[repr(C)] @@ -11,17 +12,38 @@ pub struct Array { pub capacity: usize, } -pub unsafe fn da_last(xs: *const Array) -> Option<*const T> { +impl Array { + pub unsafe fn at(self, index: usize) -> *mut T { + // Not sure whether this method should do bounds checking or not + // since there's a common-ish use case of `xs.at(xs.count)` + self.items.add(index) + } +} + +impl Array { + // We use `&mut [T]` implmentation of `IntoIterator` then cast back to the appropriate type. + // since the `Iterator` trait uses refrences in it's signature `fn next(&self) -> ...` + // it can't be implemented directly because that's against the rules of Crust™. + + pub unsafe fn iter(self) -> impl Iterator + ExactSizeIterator + DoubleEndedIterator { + (&mut *da_slice(self)).into_iter().map(|e| *e) + } + pub unsafe fn iter_mut(self) -> impl Iterator + ExactSizeIterator + DoubleEndedIterator { + (&mut *da_slice(self)).into_iter().map(|e| e as _) + } +} + +pub unsafe fn da_last(xs: *const Array) -> Option<*const T> { if (*xs).count > 0 { - Some((*xs).items.add((*xs).count-1)) + Some((*xs).at((*xs).count-1)) } else { None } } -pub unsafe fn da_last_mut(xs: *mut Array) -> Option<*mut T> { +pub unsafe fn da_last_mut(xs: *mut Array) -> Option<*mut T> { if (*xs).count > 0 { - Some((*xs).items.add((*xs).count-1)) + Some((*xs).at((*xs).count-1)) } else { None } @@ -40,7 +62,7 @@ pub unsafe fn da_slice(xs: Array) -> *mut [T] { } } -pub unsafe fn da_append(xs: *mut Array, item: T) { +pub unsafe fn da_append(xs: *mut Array, item: T) { if (*xs).count >= (*xs).capacity { if (*xs).capacity == 0 { (*xs).capacity = 256; @@ -51,9 +73,9 @@ pub unsafe fn da_append(xs: *mut Array, item: T) { // ZERO INITILIZE NEWLY ALLOCATED MEMORY let size = size_of::() * ((*xs).capacity - (*xs).count); - libc::memset((*xs).items.add((*xs).count) as _ , 0, size); + libc::memset((*xs).at((*xs).count) as _ , 0, size); } - *((*xs).items.add((*xs).count)) = item; + *((*xs).at((*xs).count)) = item; (*xs).count += 1; } diff --git a/src/targets.rs b/src/targets.rs index e6baa1bd..ff331380 100644 --- a/src/targets.rs +++ b/src/targets.rs @@ -14,9 +14,8 @@ pub struct Target { } impl Target { - pub unsafe fn by_name(targets: *const [Target], name: *const c_char) -> Option { - for i in 0..targets.len() { - let target = (*targets)[i]; + pub unsafe fn by_name(targets: Array, name: *const c_char) -> Option { + for target in targets.iter() { if strcmp(target.name(), name) == 0 { return Some(target); } @@ -61,11 +60,9 @@ impl Target { } } -pub unsafe fn register_apis(targets: *mut Array, apis: *const [TargetAPI], codegen_name: *const c_char) -> Option<()> { - for i in 0..apis.len() { - let api = (*apis)[i]; - for j in 0..(*targets).count { - let target = *(*targets).items.add(j); +pub unsafe fn register_apis(targets: *mut Array, apis: Array, codegen_name: *const c_char) -> Option<()> { + for api in apis.iter() { + for target in (*targets).iter() { if strcmp(target.name(), api.name()) == 0 { if strcmp(target.codegen_name, codegen_name) == 0 { log(Log_Level::ERROR, c!("TARGET NAME CONFLICT: Codegen %s defines target %s more than once"), codegen_name, api.name());