mirror of
https://github.com/Dummi26/mers.git
synced 2025-03-10 05:43:53 +01:00
- fixed a bug with switch syntax closing brace being recognized twice by the parser
- writing to a variable when the type that is being written doesn't fit will shadow the variable to prevent weird issues where a variable would be changed to a different type from within a block, then after that block it would still have data of that type but its type wouldn't reflect this, causing switch! to miss some cases. might remove shadowing in the future, who knows. - added run_command_get_bytes
This commit is contained in:
parent
369b37371c
commit
05ecc809c3
@ -266,6 +266,7 @@ fn parse_statement_adv(
|
||||
loop {
|
||||
file.skip_whitespaces();
|
||||
if let Some('}') = file.peek() {
|
||||
file.next();
|
||||
break;
|
||||
}
|
||||
cases.push((parse_type(file)?, parse_statement(file)?));
|
||||
|
@ -400,9 +400,19 @@ pub mod to_runnable {
|
||||
}
|
||||
.to();
|
||||
if let Some(opt) = &s.output_to {
|
||||
if let Some(var) = linfo.vars.get_mut(opt) {
|
||||
var.1 = var.1.clone() | statement.out();
|
||||
statement.output_to = Some(var.0);
|
||||
if let Some(var) = linfo.vars.get(opt) {
|
||||
let out = statement.out();
|
||||
let var_id = var.0;
|
||||
let var_out = &var.1;
|
||||
let inv_types = out.fits_in(&var_out);
|
||||
if !inv_types.is_empty() {
|
||||
eprintln!("Warn: shadowing variable {opt} because statement's output type {out} does not fit in the original variable's {var_out}. This might become an error in the future, or it might stop shadowing the variiable entirely - for stable scripts, avoid this by giving the variable a different name.");
|
||||
linfo.vars.insert(opt.clone(), (ginfo.vars, out));
|
||||
statement.output_to = Some(ginfo.vars);
|
||||
ginfo.vars += 1;
|
||||
} else {
|
||||
statement.output_to = Some(var_id);
|
||||
}
|
||||
} else {
|
||||
linfo
|
||||
.vars
|
||||
@ -728,8 +738,12 @@ impl Display for VSingleType {
|
||||
Self::String => write!(f, "string"),
|
||||
Self::Tuple(types) => {
|
||||
write!(f, "[")?;
|
||||
for t in types {
|
||||
write!(f, "{t}")?;
|
||||
for (i, t) in types.iter().enumerate() {
|
||||
if i != 0 {
|
||||
write!(f, " {t}")?;
|
||||
} else {
|
||||
write!(f, "{t}")?;
|
||||
}
|
||||
}
|
||||
write!(f, "]")?;
|
||||
Ok(())
|
||||
@ -829,8 +843,12 @@ impl Display for VDataEnum {
|
||||
Self::String(v) => write!(f, "{v}"),
|
||||
Self::Tuple(v) | Self::List(_, v) => {
|
||||
write!(f, "[")?;
|
||||
for v in v {
|
||||
write!(f, "{v}")?;
|
||||
for (i, v) in v.iter().enumerate() {
|
||||
if i != 0 {
|
||||
write!(f, " {v}")?;
|
||||
} else {
|
||||
write!(f, "{v}")?;
|
||||
}
|
||||
}
|
||||
match self {
|
||||
Self::List(..) => write!(f, "...")?,
|
||||
|
@ -38,6 +38,7 @@ pub enum BuiltinFunction {
|
||||
StringToBytes,
|
||||
// OS
|
||||
RunCommand,
|
||||
RunCommandGetBytes,
|
||||
}
|
||||
|
||||
impl BuiltinFunction {
|
||||
@ -60,6 +61,7 @@ impl BuiltinFunction {
|
||||
"bytes_to_string" => Self::BytesToString,
|
||||
"string_to_bytes" => Self::StringToBytes,
|
||||
"run_command" => Self::RunCommand,
|
||||
"run_command_get_bytes" => Self::RunCommandGetBytes,
|
||||
_ => return None,
|
||||
})
|
||||
}
|
||||
@ -120,6 +122,20 @@ impl BuiltinFunction {
|
||||
]),
|
||||
],
|
||||
},
|
||||
Self::RunCommandGetBytes => VType {
|
||||
types: vec![
|
||||
// error
|
||||
VSingleType::String.into(),
|
||||
// success: Option<ExitCode>, stdout, stderr
|
||||
VSingleType::Tuple(vec![
|
||||
VType {
|
||||
types: vec![VSingleType::Tuple(vec![]).into(), VSingleType::Int.into()],
|
||||
},
|
||||
VSingleType::List(VSingleType::Int.into()).into(),
|
||||
VSingleType::List(VSingleType::Int.into()).into(),
|
||||
]),
|
||||
],
|
||||
},
|
||||
}
|
||||
}
|
||||
pub fn run(&self, args: &Vec<RStatement>, vars: &Vec<Arc<Mutex<VData>>>) -> VData {
|
||||
@ -129,7 +145,7 @@ impl BuiltinFunction {
|
||||
print!("{}", arg);
|
||||
VDataEnum::Tuple(vec![]).to()
|
||||
} else {
|
||||
unreachable!()
|
||||
unreachable!("print function called with non-string arg")
|
||||
}
|
||||
}
|
||||
BuiltinFunction::Println => {
|
||||
@ -365,7 +381,7 @@ impl BuiltinFunction {
|
||||
unreachable!("string_to_bytes not 1 arg")
|
||||
}
|
||||
}
|
||||
Self::RunCommand => {
|
||||
Self::RunCommand | Self::RunCommandGetBytes => {
|
||||
if args.len() > 0 {
|
||||
if let VDataEnum::String(s) = args[0].run(vars).data {
|
||||
let mut command = std::process::Command::new(s);
|
||||
@ -390,13 +406,31 @@ impl BuiltinFunction {
|
||||
VDataEnum::Tuple(vec![])
|
||||
}
|
||||
.to(),
|
||||
VDataEnum::String(
|
||||
String::from_utf8_lossy(&out.stdout).into_owned(),
|
||||
)
|
||||
match self {
|
||||
Self::RunCommandGetBytes => VDataEnum::List(
|
||||
VSingleType::Int.into(),
|
||||
out.stdout
|
||||
.iter()
|
||||
.map(|v| VDataEnum::Int(*v as _).to())
|
||||
.collect(),
|
||||
),
|
||||
_ => VDataEnum::String(
|
||||
String::from_utf8_lossy(&out.stdout).into_owned(),
|
||||
),
|
||||
}
|
||||
.to(),
|
||||
VDataEnum::String(
|
||||
String::from_utf8_lossy(&out.stderr).into_owned(),
|
||||
)
|
||||
match self {
|
||||
Self::RunCommandGetBytes => VDataEnum::List(
|
||||
VSingleType::Int.into(),
|
||||
out.stderr
|
||||
.iter()
|
||||
.map(|v| VDataEnum::Int(*v as _).to())
|
||||
.collect(),
|
||||
),
|
||||
_ => VDataEnum::String(
|
||||
String::from_utf8_lossy(&out.stderr).into_owned(),
|
||||
),
|
||||
}
|
||||
.to(),
|
||||
])
|
||||
.to(),
|
||||
|
Loading…
Reference in New Issue
Block a user