1
1
Fork 0
mirror of https://github.com/azur1s/bobbylisp.git synced 2024-09-28 07:17:41 +00:00

feat: array types in IR

This commit is contained in:
Natapat Samutpong 2022-02-06 14:16:39 +07:00
parent f939903df2
commit d0555cda52
2 changed files with 30 additions and 9 deletions

View file

@ -2,7 +2,7 @@ use regex::Regex;
use crate::vm::{instr::*, types::Type}; use crate::vm::{instr::*, types::Type};
const REGEX: &str = r###"[^\s\$";]+|"[^"]*"|;.*"###; const REGEX: &str = r###"\([^)]*\)|[^\s\$";]+|"[^"]*"|;.*"###;
macro_rules! value { ($s:expr) => { $s.parse::<Type>().unwrap() }; } macro_rules! value { ($s:expr) => { $s.parse::<Type>().unwrap() }; }
macro_rules! register { ($s:expr) => { $s.parse::<Register>().unwrap() }; } macro_rules! register { ($s:expr) => { $s.parse::<Register>().unwrap() }; }
@ -34,7 +34,7 @@ pub fn parse_instr(src: &str) -> Vec<Instr> {
"JMPL" => { result.push(Instr::JumpLabel { to: tokens[1].to_string() }); }, "JMPL" => { result.push(Instr::JumpLabel { to: tokens[1].to_string() }); },
"JMP" => { result.push(Instr::Jump { to: tokens[1].parse::<isize>().unwrap() }); }, "JMP" => { result.push(Instr::Jump { to: tokens[1].parse::<isize>().unwrap() }); },
"JMPF" => { result.push(Instr::JumpIfFalse { to: tokens[1].parse::<isize>().unwrap() }); }, "JMPF" => { result.push(Instr::JumpIfFalse { to: tokens[1].parse::<isize>().unwrap() }); },
"EQ" => { result.push(Instr::Equal); }, "EQ" => { result.push(Instr::Equal); },

View file

@ -10,6 +10,7 @@ pub enum Type {
Float(f64), Float(f64),
Boolean(bool), Boolean(bool),
String(String), String(String),
Cons(Vec<Type>),
} }
impl Type { impl Type {
@ -37,6 +38,16 @@ impl Type {
false => "false".to_string(), false => "false".to_string(),
}, },
Type::String(s) => s.clone(), 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)), "true" => Ok(Type::Boolean(true)),
"false" => Ok(Type::Boolean(false)), "false" => Ok(Type::Boolean(false)),
_ => { _ => {
let i = s.parse::<i64>(); if s.starts_with("(") {
if i.is_ok() { let elems = s[1..s.len() - 1]
Ok(Type::Int(i.unwrap())) .split(',')
.collect::<Vec<&str>>()
.iter()
.map(|s| s.trim().parse::<Type>())
.collect::<Result<Vec<Type>, Self::Err>>()?;
Ok(Type::Cons(elems))
} else { } else {
let fl = s.parse::<f64>(); let i = s.parse::<i64>();
if fl.is_ok() { if i.is_ok() {
Ok(Type::Float(fl.unwrap())) Ok(Type::Int(i.unwrap()))
} else { } else {
Ok(Type::String(s.to_string())) let fl = s.parse::<f64>();
if fl.is_ok() {
Ok(Type::Float(fl.unwrap()))
} else {
Ok(Type::String(s.to_string()))
}
} }
} }
} }