diff --git a/src/script/block.rs b/src/script/block.rs index 6c7b55b..7bcf893 100644 --- a/src/script/block.rs +++ b/src/script/block.rs @@ -395,6 +395,8 @@ pub mod to_runnable { let switch_on_out = switch_on_v.1; if *force { + let mut types_not_covered_req_error = false; + let mut types_not_covered = VType { types: vec![] }; for val_type in switch_on_out.types.iter() { let val_type: VType = val_type.clone().into(); let mut linf2 = linfo.clone(); @@ -405,9 +407,13 @@ pub mod to_runnable { break 'force; } } - return Err(ToRunnableError::CaseForceButTypeNotCovered(val_type)); + types_not_covered_req_error = true; + types_not_covered = types_not_covered | val_type; } } + if types_not_covered_req_error { + return Err(ToRunnableError::CaseForceButTypeNotCovered(types_not_covered)); + } } RStatementEnum::Switch( RStatementEnum::Variable(switch_on_v.0, switch_on_out, false).to(), @@ -755,7 +761,7 @@ impl RStatementEnum { Self::Switch(switch_on, cases) => { let switch_on = switch_on.out().types; let mut might_return_empty = switch_on.is_empty(); - let mut out = VSingleType::Tuple(vec![]).into(); // if nothing is executed + let mut out = VType { types: vec![] }; // if nothing is executed for switch_on in switch_on { let switch_on: VType = switch_on.into(); 'search: { diff --git a/src/script/builtins.rs b/src/script/builtins.rs index 074fc41..58ca759 100644 --- a/src/script/builtins.rs +++ b/src/script/builtins.rs @@ -92,7 +92,64 @@ impl BuiltinFunction { }) } pub fn can_take(&self, input: &Vec) -> bool { - true // TODO! + match self { + Self::Print | Self::Println => { + if input.len() == 1 { + input[0].fits_in(&VSingleType::String.to()).is_empty() + } else { + false + } + } + Self::Debug => true, + Self::ToString => true, + Self::Format => { + if let Some(format_string) = input.first() { + format_string.fits_in(&VSingleType::String.to()).is_empty() + } else { + false + } + } + Self::Run | Self::Thread => { + if input.len() >= 1 { + input[0].types.iter().all(|v| { + if let VSingleType::Function(v) = v { + if v.iter().any(|(i, _)| i.len() == input.len()) { + eprintln!("Warn: Function inputs aren't type checked yet!)"); + // TODO! + true + } else { + false + } + } else { + false + } + }) + } else { + false + } + } + Self::Await => { + input.len() == 1 + && input[0] + .types + .iter() + .all(|v| matches!(v, VSingleType::Thread(_))) + } + Self::Sleep => { + input.len() == 1 + && input[0] + .fits_in(&VType { + types: vec![VSingleType::Int, VSingleType::Float], + }) + .is_empty() + } + Self::Exit => { + input.len() == 0 + || (input.len() == 1 && input[0].fits_in(&VSingleType::Int.to()).is_empty()) + } + // TODO! finish this + _ => true, + } } /// for invalid inputs, may panic pub fn returns(&self, input: Vec) -> VType { @@ -210,9 +267,28 @@ impl BuiltinFunction { ]), ], }, - Self::Add | Self::Sub | Self::Mul | Self::Div | Self::Mod | Self::Pow => VType { - types: vec![VSingleType::Int, VSingleType::Float], - }, + Self::Add | Self::Sub | Self::Mul | Self::Div | Self::Mod | Self::Pow => { + if input.len() == 2 { + match ( + ( + input[0].contains(&VSingleType::Int), + input[0].contains(&VSingleType::Float), + ), + ( + input[1].contains(&VSingleType::Int), + input[1].contains(&VSingleType::Float), + ), + ) { + ((true, false), (true, false)) => VSingleType::Int.to(), + ((true, _), (true, _)) => VType { + types: vec![VSingleType::Int, VSingleType::Float], + }, + _ => VSingleType::Float.to(), + } + } else { + unreachable!("called add/sub/mul/div/mod/pow with args != 2") + } + } Self::Push | Self::Insert => VSingleType::Tuple(vec![]).into(), Self::Len => VSingleType::Int.into(), }