refactor + wildcard

This commit is contained in:
tezlm 2023-10-02 19:03:58 -07:00
parent 0d81019cb1
commit 4854fb87f5
Signed by: tezlm
GPG key ID: 649733FCD94AFBBA
11 changed files with 84 additions and 74 deletions

View file

@ -69,6 +69,7 @@ pub enum Expr {
#[derive(Debug, Clone, PartialEq)]
pub enum Pattern {
Wildcard,
Literal(Literal),
}

View file

@ -199,15 +199,20 @@ impl Generator {
for (idx, (pat, expr)) in arms.iter().enumerate() {
match pat {
Pattern::Literal(lit) => match lit {
Pattern::Literal(lit) => {
match lit {
Literal::Integer(int) => writeln!(self.output, "i32.const {}", int)?,
Literal::Boolean(b) => writeln!(self.output, "i32.const {}", if *b { 1 } else { 0 })?,
_ => todo!(),
},
};
}
writeln!(self.output, "local.get $match")?;
writeln!(self.output, "i32.eq")?;
}
Pattern::Wildcard => {
writeln!(self.output, "i32.const 1")?;
}
};
writeln!(self.output, "(if (result i32) (then")?;
self.gen_expr(expr, parent_gctx, ctx)?;

View file

@ -17,69 +17,8 @@ pub use error::Error;
use generator::Generator;
fn main() {
// let mut lexer = lexer::Lexer::new("
// fn main() -> i32 {
// let foo = 8;
// let bar = foo * -3;
// match foo + bar < 10 {
// true => 123,
// false => 456,
// }
// }
// ".into());
// let mut lexer = lexer::Lexer::new("
// fn main() -> i32 {
// two() * three()
// }
// fn two() -> i32 {
// (2 * 2) / 2
// }
// fn three() -> i32 {
// 10 * 6 / 20
// }
// ".into());
let mut lexer = lexer::Lexer::new("
fn main() -> i32 {
let n = -1;
if is_three(add_four(n)) {
20
} else {
30
}
}
pub fn add_four(n: i32) -> i32 {
n + 4
}
fn is_three(n: i32) -> bool {
n == 3
}
fn add_four_float(n: f64) -> f64 {
n + 4.0
}
".into());
// let mut lexer = lexer::Lexer::new("
// fn main() -> i32 {
// let x = {
// let y = 20;
// y + 10
// };
// x
// }
// ".into());
// let mut lexer = lexer::Lexer::new(r#"
// fn main() {
// let x = "example string!\n";
// let y = "another str.\n";
// print(x);
// print(y);
// print("Hello, world!");
// }
// "#.into());
let source = std::fs::read_to_string(std::env::args().skip(1).next().expect("no filename!")).expect("no source!");
let mut lexer = lexer::Lexer::new(source);
let mut tokens = vec![];
loop {

View file

@ -297,6 +297,7 @@ impl Parser {
}
Token::False => Pattern::Literal(Literal::Boolean(false)),
Token::True => Pattern::Literal(Literal::Boolean(true)),
Token::Ident(s) if s == "_" => Pattern::Wildcard,
_ => todo!("no pattern for {:?} yet", tok),
};
Ok(pat)

View file

@ -27,8 +27,7 @@ impl Expr {
let item_ty = item.infer(ctx)?;
for (pat, expr) in arms {
let ty = expr.infer(ctx)?;
let pat_ty = pat.infer()?;
if item_ty != pat_ty {
if !pat.matches_type(&item_ty)? {
return Err(Error::ty("cannot compare different type"));
}
if match_ty.is_some_and(|mty| mty != ty) {
@ -155,9 +154,10 @@ impl Literal {
}
impl Pattern {
fn infer(&self) -> Result<Type, Error> {
fn matches_type(&self, ty: &Type) -> Result<bool, Error> {
match self {
Pattern::Literal(lit) => lit.infer(),
Pattern::Literal(lit) => Ok(&lit.infer()? == ty),
Pattern::Wildcard => Ok(true),
}
}
}

8
test/t1 Normal file
View file

@ -0,0 +1,8 @@
fn main() -> i32 {
let foo = 8;
let bar = foo * -3;
match foo + bar < 10 {
true => 123,
false => 456,
}
}

11
test/t2 Normal file
View file

@ -0,0 +1,11 @@
fn main() -> i32 {
two() * three()
}
fn two() -> i32 {
(2 * 2) / 2
}
fn three() -> i32 {
10 * 6 / 20
}

20
test/t3 Normal file
View file

@ -0,0 +1,20 @@
fn main() -> i32 {
let n = -1;
if is_three(add_four(n)) {
20
} else {
30
}
}
pub fn add_four(n: i32) -> i32 {
n + 4
}
fn is_three(n: i32) -> bool {
n == 3
}
fn add_four_float(n: f64) -> f64 {
n + 4.0
}

7
test/t4 Normal file
View file

@ -0,0 +1,7 @@
fn main() -> i32 {
let x = {
let y = 20;
y + 10
};
x
}

10
test/t5.broken Normal file
View file

@ -0,0 +1,10 @@
let mut lexer = lexer::Lexer::new(r#"
fn main() {
let x = "example string!\n";
let y = "another str.\n";
print(x);
print(y);
print("Hello, world!");
}
"#.into());

8
test/t6 Normal file
View file

@ -0,0 +1,8 @@
fn main() -> i32 {
let foo = 10;
match foo * 2 {
10 => 4,
30 => 5,
_ => 6,
}
}