@@ -34,6 +34,7 @@ pub mod arena;
3434pub mod codegen;
3535pub mod lexer;
3636pub mod targets;
37+ pub mod params;
3738pub mod ir;
3839pub mod time;
3940pub mod shlex;
@@ -52,8 +53,8 @@ use targets::*;
5253use lexer:: { Lexer , Loc , Token } ;
5354use ir:: * ;
5455use time:: Instant ;
55- use codegen:: * ;
5656use shlex:: * ;
57+ use params:: * ;
5758
5859pub 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
11931193pub 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