Skip to content

Commit be73162

Browse files
authored
Merge pull request #270 from bext-lang/target-as-struct-of-function-pointers
Target as a Structure of Function Pointers
2 parents f4dbd59 + 5a9b1ea commit be73162

12 files changed

Lines changed: 354 additions & 333 deletions

File tree

src/b.rs

Lines changed: 28 additions & 152 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ pub mod arena;
3434
pub mod codegen;
3535
pub mod lexer;
3636
pub mod targets;
37+
pub mod params;
3738
pub mod ir;
3839
pub mod time;
3940
pub mod shlex;
@@ -52,8 +53,8 @@ use targets::*;
5253
use lexer::{Lexer, Loc, Token};
5354
use ir::*;
5455
use time::Instant;
55-
use codegen::*;
5656
use shlex::*;
57+
use params::*;
5758

5859
pub unsafe fn expect_tokens(l: *mut Lexer, tokens: *const [Token]) -> Option<()> {
5960
for i in 0..tokens.len() {
@@ -926,7 +927,6 @@ pub struct Compiler {
926927
/// need to reset the state of the Compiler, just reset all its
927928
/// Dynamic Arrays and this Arena.
928929
pub arena: Arena,
929-
pub target: Target,
930930
pub error_count: usize,
931931
pub historical: bool,
932932
}
@@ -1180,32 +1180,34 @@ pub unsafe fn get_garbage_base(path: *const c_char, target: Target) -> Option<*m
11801180
write_entire_file(gitignore_path, c!("*") as *const c_void, 1)?;
11811181
}
11821182

1183-
Some(temp_sprintf(c!("%s/%s.%s"), garbage_dir, filename, target.name()))
1183+
Some(temp_sprintf(c!("%s/%s.%s"), garbage_dir, filename, target.api.name))
11841184
}
11851185

1186-
pub unsafe fn print_available_targets() {
1186+
pub unsafe fn print_available_targets(targets: *const [Target]) {
11871187
fprintf(stderr(), c!("Compilation targets:\n"));
1188-
for i in 0..TARGET_ORDER.len() {
1189-
fprintf(stderr(), c!(" %s\n"), (*TARGET_ORDER)[i].name());
1188+
for i in 0..targets.len() {
1189+
fprintf(stderr(), c!(" %s\n"), (*targets)[i].api.name);
11901190
}
11911191
}
11921192

11931193
pub unsafe fn main(mut argc: i32, mut argv: *mut*mut c_char) -> Option<()> {
1194+
let targets = codegen::load_targets()?;
1195+
11941196
let default_target;
11951197
if cfg!(target_arch = "aarch64") && (cfg!(target_os = "linux") || cfg!(target_os = "android")) {
1196-
default_target = Some(Target::Gas_AArch64_Linux);
1198+
default_target = Some(Target::by_name(da_slice(targets), c!("gas-aarch64-linux")).expect("Default target for Linux on AArch64"));
11971199
} else if cfg!(target_arch = "aarch64") && cfg!(target_os = "macos") {
1198-
default_target = Some(Target::Gas_AArch64_Darwin);
1200+
default_target = Some(Target::by_name(da_slice(targets), c!("gas-aarch64-darwin")).expect("Default target for Darwin on AArch64"));
11991201
} else if cfg!(target_arch = "x86_64") && cfg!(target_os = "linux") {
1200-
default_target = Some(Target::Gas_x86_64_Linux);
1202+
default_target = Some(Target::by_name(da_slice(targets), c!("gas-x86_64-linux")).expect("Default target for Linux on x86_64"));
12011203
} else if cfg!(target_arch = "x86_64") && cfg!(target_os = "windows") {
1202-
default_target = Some(Target::Gas_x86_64_Windows);
1204+
default_target = Some(Target::by_name(da_slice(targets), c!("gas-x86_64-windows")).expect("Default target for Windows on x86_64"));
12031205
} else {
12041206
default_target = None;
12051207
}
12061208

12071209
let default_target_name = if let Some(default_target) = default_target {
1208-
default_target.name()
1210+
default_target.api.name
12091211
} else {
12101212
ptr::null()
12111213
};
@@ -1215,10 +1217,10 @@ pub unsafe fn main(mut argc: i32, mut argv: *mut*mut c_char) -> Option<()> {
12151217
let run = flag_bool(c!("run"), false, c!("Run the compiled program (if applicable for the target)"));
12161218
let nobuild = flag_bool(c!("nobuild"), false, temp_sprintf(c!("Skip the build step. Useful in conjunction with the -%s flag when you already have a built program and just want to run it on the specified target without rebuilding it."), flag_name(run)));
12171219
let help = flag_bool(c!("help"), false, c!("Print this help message"));
1218-
let codegen_args = flag_list(CODEGEN_FLAG_NAME, temp_sprintf(c!("Pass an argument to the codegen of the current target selected by the -%s flag. Pass argument `-%s help` to learn more about what current codegen provides. All sorts of linker flag parameters are probably there."), flag_name(target_name), CODEGEN_FLAG_NAME));
1220+
let codegen_args = flag_list(PARAM_FLAG_NAME, temp_sprintf(c!("Pass an argument to the codegen of the current target selected by the -%s flag. Pass argument `-%s help` to learn more about what current codegen provides. All sorts of linker flag parameters are probably there."), flag_name(target_name), PARAM_FLAG_NAME));
12191221
let linker = {
12201222
let name = c!("L");
1221-
flag_list(name, temp_sprintf(c!("DEPRECATED! Append a flag to the linker of the target platform. But not every target even has a linker! For backward compatibility we transform `-%s foo -%s bar -%s ...` into `-%s link-args='foo bar ...'` but do not expect every codegen to support that. Use `-%s help` to learn more about what your current codegen supports. Expect -%s to be removed entirely in the future."), name, name, name, CODEGEN_FLAG_NAME, CODEGEN_FLAG_NAME, name))
1223+
flag_list(name, temp_sprintf(c!("DEPRECATED! Append a flag to the linker of the target platform. But not every target even has a linker! For backward compatibility we transform `-%s foo -%s bar -%s ...` into `-%s link-args='foo bar ...'` but do not expect every codegen to support that. Use `-%s help` to learn more about what your current codegen supports. Expect -%s to be removed entirely in the future."), name, name, name, PARAM_FLAG_NAME, PARAM_FLAG_NAME, name))
12221224
};
12231225
let nostdlib = flag_bool(c!("nostdlib"), false, c!("Do not link with standard libraries like libb and/or libc on some platforms"));
12241226
let ir = flag_bool(c!("ir"), false, c!("Instead of compiling, dump the IR of the program to stdout"));
@@ -1262,19 +1264,18 @@ pub unsafe fn main(mut argc: i32, mut argv: *mut*mut c_char) -> Option<()> {
12621264
}
12631265

12641266
if strcmp(*target_name, c!("list")) == 0 {
1265-
print_available_targets();
1267+
print_available_targets(da_slice(targets));
12661268
return Some(());
12671269
}
12681270

1269-
let Some(target) = Target::by_name(*target_name) else {
1271+
let Some(target) = Target::by_name(da_slice(targets), *target_name) else {
12701272
usage();
1271-
print_available_targets();
1273+
print_available_targets(da_slice(targets));
12721274
log(Log_Level::ERROR, c!("Unknown target `%s`"), *target_name);
12731275
return None;
12741276
};
12751277

12761278
let mut c: Compiler = zeroed();
1277-
c.target = target;
12781279
c.historical = *historical;
12791280

12801281
if (*linker).count > 0 {
@@ -1285,19 +1286,10 @@ pub unsafe fn main(mut argc: i32, mut argv: *mut*mut c_char) -> Option<()> {
12851286
let codegen_arg = temp_sprintf(c!("link-args=%s"), shlex_join(&mut s));
12861287
da_append(codegen_args, codegen_arg);
12871288
shlex_free(&mut s);
1288-
log(Log_Level::WARNING, c!("Flag -%s is DEPRECATED! Interpreting it as `-%s %s` instead."), flag_name(linker), CODEGEN_FLAG_NAME, codegen_arg);
1289+
log(Log_Level::WARNING, c!("Flag -%s is DEPRECATED! Interpreting it as `-%s %s` instead."), flag_name(linker), PARAM_FLAG_NAME, codegen_arg);
12891290
}
12901291

1291-
let gen = match target {
1292-
Target::Gas_x86_64_Linux |
1293-
Target::Gas_x86_64_Windows |
1294-
Target::Gas_x86_64_Darwin => codegen::gas_x86_64::new(&mut c.arena, da_slice(*codegen_args)),
1295-
Target::Gas_AArch64_Linux |
1296-
Target::Gas_AArch64_Darwin => codegen::gas_aarch64::new(&mut c.arena, da_slice(*codegen_args)),
1297-
Target::Uxn => codegen::uxn::new(&mut c.arena, da_slice(*codegen_args)),
1298-
Target::Mos6502_Posix => codegen::mos6502::new(&mut c.arena, da_slice(*codegen_args)),
1299-
Target::ILasm_Mono => codegen::ilasm_mono::new(&mut c.arena, da_slice(*codegen_args)),
1300-
}?;
1292+
let gen = (target.api.new)(&mut c.arena, da_slice(*codegen_args))?;
13011293

13021294
if input_paths.count == 0 {
13031295
usage();
@@ -1381,12 +1373,12 @@ pub unsafe fn main(mut argc: i32, mut argv: *mut*mut c_char) -> Option<()> {
13811373
}
13821374

13831375
let program_path = if (*output_path).is_null() {
1384-
temp_sprintf(c!("%s%s"), temp_strip_file_ext(*input_paths.items), target.file_ext())
1376+
temp_sprintf(c!("%s%s"), temp_strip_file_ext(*input_paths.items), target.api.file_ext)
13851377
} else {
13861378
if get_file_ext(*output_path).is_some() {
13871379
*output_path
13881380
} else {
1389-
temp_sprintf(c!("%s%s"), *output_path, target.file_ext())
1381+
temp_sprintf(c!("%s%s"), *output_path, target.api.file_ext)
13901382
}
13911383
};
13921384

@@ -1404,129 +1396,13 @@ pub unsafe fn main(mut argc: i32, mut argv: *mut*mut c_char) -> Option<()> {
14041396
// to that object should be computed as `temp_sprintf("%s.o", garbase_base)`.
14051397
let garbage_base = get_garbage_base(program_path, target)?;
14061398

1407-
match target {
1408-
Target::Gas_AArch64_Linux => {
1409-
let os = targets::Os::Linux;
1410-
1411-
if !*nobuild {
1412-
codegen::gas_aarch64::generate_program(
1413-
gen, &c.program, program_path, garbage_base, os,
1414-
*nostdlib, *debug,
1415-
)?;
1416-
}
1417-
1418-
if *run {
1419-
codegen::gas_aarch64::run_program(
1420-
gen, program_path, da_slice(run_args), os,
1421-
)?;
1422-
}
1423-
}
1424-
Target::Gas_AArch64_Darwin => {
1425-
let os = targets::Os::Darwin;
1426-
1427-
if !*nobuild {
1428-
codegen::gas_aarch64::generate_program(
1429-
gen, &c.program, program_path, garbage_base, os,
1430-
*nostdlib, *debug,
1431-
)?;
1432-
}
1433-
1434-
if *run {
1435-
codegen::gas_aarch64::run_program(
1436-
gen, program_path, da_slice(run_args), os,
1437-
)?;
1438-
}
1439-
}
1440-
Target::Gas_x86_64_Linux => {
1441-
let os = targets::Os::Linux;
1442-
1443-
if !*nobuild {
1444-
codegen::gas_x86_64::generate_program(
1445-
gen, &c.program, program_path, garbage_base, os,
1446-
*nostdlib, *debug,
1447-
)?;
1448-
}
1449-
1450-
if *run {
1451-
codegen::gas_x86_64::run_program(
1452-
gen, program_path, da_slice(run_args), os,
1453-
)?;
1454-
}
1455-
}
1456-
Target::Gas_x86_64_Windows => {
1457-
let os = targets::Os::Windows;
1458-
1459-
if !*nobuild {
1460-
codegen::gas_x86_64::generate_program(
1461-
gen, &c.program, program_path, garbage_base, os,
1462-
*nostdlib, *debug,
1463-
)?;
1464-
}
1465-
1466-
if *run {
1467-
codegen::gas_x86_64::run_program(
1468-
gen, program_path, da_slice(run_args), os,
1469-
)?;
1470-
}
1471-
}
1472-
Target::Gas_x86_64_Darwin => {
1473-
let os = targets::Os::Darwin;
1474-
1475-
if !*nobuild {
1476-
codegen::gas_x86_64::generate_program(
1477-
gen, &c.program, program_path, garbage_base, os,
1478-
*nostdlib, *debug,
1479-
)?;
1480-
}
1481-
1482-
if *run {
1483-
codegen::gas_x86_64::run_program(
1484-
gen, program_path, da_slice(run_args), os,
1485-
)?;
1486-
}
1487-
}
1488-
Target::Uxn => {
1489-
if !*nobuild {
1490-
codegen::uxn::generate_program(
1491-
gen, &c.program, program_path, garbage_base,
1492-
*nostdlib, *debug,
1493-
)?;
1494-
}
1495-
1496-
if *run {
1497-
codegen::uxn::run_program(
1498-
gen, program_path, da_slice(run_args),
1499-
)?;
1500-
}
1501-
}
1502-
Target::Mos6502_Posix => {
1503-
if !*nobuild {
1504-
codegen::mos6502::generate_program(
1505-
gen, &c.program, program_path, garbage_base,
1506-
*nostdlib, *debug,
1507-
)?;
1508-
}
1509-
1510-
if *run {
1511-
codegen::mos6502::run_program(
1512-
gen, program_path, da_slice(run_args),
1513-
)?;
1514-
}
1515-
}
1516-
Target::ILasm_Mono => {
1517-
if !*nobuild {
1518-
codegen::ilasm_mono::generate_program(
1519-
gen, &c.program, program_path, garbage_base,
1520-
*nostdlib, *debug,
1521-
)?;
1522-
}
1399+
if !*nobuild {
1400+
(target.api.build)(gen, &c.program, program_path, garbage_base, *nostdlib, *debug)?;
1401+
}
15231402

1524-
if *run {
1525-
codegen::ilasm_mono::run_program(
1526-
gen, program_path, da_slice(run_args),
1527-
)?;
1528-
}
1529-
}
1403+
if *run {
1404+
(target.api.run)(gen, program_path, da_slice(run_args))?
15301405
}
1406+
15311407
Some(())
15321408
}

0 commit comments

Comments
 (0)