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)]
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
pub enum Pattern {
|
pub enum Pattern {
|
||||||
|
Wildcard,
|
||||||
Literal(Literal),
|
Literal(Literal),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -199,15 +199,20 @@ impl Generator {
|
||||||
|
|
||||||
for (idx, (pat, expr)) in arms.iter().enumerate() {
|
for (idx, (pat, expr)) in arms.iter().enumerate() {
|
||||||
match pat {
|
match pat {
|
||||||
Pattern::Literal(lit) => match lit {
|
Pattern::Literal(lit) => {
|
||||||
Literal::Integer(int) => writeln!(self.output, "i32.const {}", int)?,
|
match lit {
|
||||||
Literal::Boolean(b) => writeln!(self.output, "i32.const {}", if *b { 1 } else { 0 })?,
|
Literal::Integer(int) => writeln!(self.output, "i32.const {}", int)?,
|
||||||
_ => todo!(),
|
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")?;
|
writeln!(self.output, "(if (result i32) (then")?;
|
||||||
self.gen_expr(expr, parent_gctx, ctx)?;
|
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;
|
use generator::Generator;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
// let mut lexer = lexer::Lexer::new("
|
let source = std::fs::read_to_string(std::env::args().skip(1).next().expect("no filename!")).expect("no source!");
|
||||||
// fn main() -> i32 {
|
let mut lexer = lexer::Lexer::new(source);
|
||||||
// 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 mut tokens = vec![];
|
let mut tokens = vec![];
|
||||||
loop {
|
loop {
|
||||||
|
|
|
@ -297,6 +297,7 @@ impl Parser {
|
||||||
}
|
}
|
||||||
Token::False => Pattern::Literal(Literal::Boolean(false)),
|
Token::False => Pattern::Literal(Literal::Boolean(false)),
|
||||||
Token::True => Pattern::Literal(Literal::Boolean(true)),
|
Token::True => Pattern::Literal(Literal::Boolean(true)),
|
||||||
|
Token::Ident(s) if s == "_" => Pattern::Wildcard,
|
||||||
_ => todo!("no pattern for {:?} yet", tok),
|
_ => todo!("no pattern for {:?} yet", tok),
|
||||||
};
|
};
|
||||||
Ok(pat)
|
Ok(pat)
|
||||||
|
|
|
@ -27,8 +27,7 @@ impl Expr {
|
||||||
let item_ty = item.infer(ctx)?;
|
let item_ty = item.infer(ctx)?;
|
||||||
for (pat, expr) in arms {
|
for (pat, expr) in arms {
|
||||||
let ty = expr.infer(ctx)?;
|
let ty = expr.infer(ctx)?;
|
||||||
let pat_ty = pat.infer()?;
|
if !pat.matches_type(&item_ty)? {
|
||||||
if item_ty != pat_ty {
|
|
||||||
return Err(Error::ty("cannot compare different type"));
|
return Err(Error::ty("cannot compare different type"));
|
||||||
}
|
}
|
||||||
if match_ty.is_some_and(|mty| mty != ty) {
|
if match_ty.is_some_and(|mty| mty != ty) {
|
||||||
|
@ -155,9 +154,10 @@ impl Literal {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Pattern {
|
impl Pattern {
|
||||||
fn infer(&self) -> Result<Type, Error> {
|
fn matches_type(&self, ty: &Type) -> Result<bool, Error> {
|
||||||
match self {
|
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