refactor + wildcard
This commit is contained in:
parent
0d81019cb1
commit
4854fb87f5
11 changed files with 84 additions and 74 deletions
|
@ -69,6 +69,7 @@ pub enum Expr {
|
|||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub enum Pattern {
|
||||
Wildcard,
|
||||
Literal(Literal),
|
||||
}
|
||||
|
||||
|
|
|
@ -199,15 +199,20 @@ impl Generator {
|
|||
|
||||
for (idx, (pat, expr)) in arms.iter().enumerate() {
|
||||
match pat {
|
||||
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!(),
|
||||
},
|
||||
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, "local.get $match")?;
|
||||
writeln!(self.output, "i32.eq")?;
|
||||
writeln!(self.output, "(if (result i32) (then")?;
|
||||
self.gen_expr(expr, parent_gctx, ctx)?;
|
||||
|
||||
|
|
65
src/main.rs
65
src/main.rs
|
@ -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 {
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
8
test/t1
Normal 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
11
test/t2
Normal 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
20
test/t3
Normal 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
7
test/t4
Normal file
|
@ -0,0 +1,7 @@
|
|||
fn main() -> i32 {
|
||||
let x = {
|
||||
let y = 20;
|
||||
y + 10
|
||||
};
|
||||
x
|
||||
}
|
10
test/t5.broken
Normal file
10
test/t5.broken
Normal 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
8
test/t6
Normal file
|
@ -0,0 +1,8 @@
|
|||
fn main() -> i32 {
|
||||
let foo = 10;
|
||||
match foo * 2 {
|
||||
10 => 4,
|
||||
30 => 5,
|
||||
_ => 6,
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue