diff --git a/blspc/src/vm/parser.rs b/blspc/src/vm/parser.rs index 3365a01..6f04036 100644 --- a/blspc/src/vm/parser.rs +++ b/blspc/src/vm/parser.rs @@ -2,7 +2,7 @@ use regex::Regex; use crate::vm::{instr::*, types::Type}; -const REGEX: &str = r###"[^\s\$";]+|"[^"]*"|;.*"###; +const REGEX: &str = r###"\([^)]*\)|[^\s\$";]+|"[^"]*"|;.*"###; macro_rules! value { ($s:expr) => { $s.parse::().unwrap() }; } macro_rules! register { ($s:expr) => { $s.parse::().unwrap() }; } @@ -34,7 +34,7 @@ pub fn parse_instr(src: &str) -> Vec { "JMPL" => { result.push(Instr::JumpLabel { to: tokens[1].to_string() }); }, "JMP" => { result.push(Instr::Jump { to: tokens[1].parse::().unwrap() }); }, - "JMPF" => { result.push(Instr::JumpIfFalse { to: tokens[1].parse::().unwrap() }); }, + "JMPF" => { result.push(Instr::JumpIfFalse { to: tokens[1].parse::().unwrap() }); }, "EQ" => { result.push(Instr::Equal); }, diff --git a/blspc/src/vm/types.rs b/blspc/src/vm/types.rs index 4669dc2..e359938 100644 --- a/blspc/src/vm/types.rs +++ b/blspc/src/vm/types.rs @@ -10,6 +10,7 @@ pub enum Type { Float(f64), Boolean(bool), String(String), + Cons(Vec), } impl Type { @@ -37,6 +38,16 @@ impl Type { false => "false".to_string(), }, Type::String(s) => s.clone(), + Type::Cons(v) => { + let mut s = String::new(); + s.push('('); + for (i, t) in v.iter().enumerate() { + if i != 0 { s.push(','); } + s.push_str(&t.fmt()); + } + s.push(')'); + s + } } } } @@ -129,15 +140,25 @@ impl FromStr for Type { "true" => Ok(Type::Boolean(true)), "false" => Ok(Type::Boolean(false)), _ => { - let i = s.parse::(); - if i.is_ok() { - Ok(Type::Int(i.unwrap())) + if s.starts_with("(") { + let elems = s[1..s.len() - 1] + .split(',') + .collect::>() + .iter() + .map(|s| s.trim().parse::()) + .collect::, Self::Err>>()?; + Ok(Type::Cons(elems)) } else { - let fl = s.parse::(); - if fl.is_ok() { - Ok(Type::Float(fl.unwrap())) + let i = s.parse::(); + if i.is_ok() { + Ok(Type::Int(i.unwrap())) } else { - Ok(Type::String(s.to_string())) + let fl = s.parse::(); + if fl.is_ok() { + Ok(Type::Float(fl.unwrap())) + } else { + Ok(Type::String(s.to_string())) + } } } }