diff --git a/Cargo.lock b/Cargo.lock index eeb5a5a..bbf2270 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -62,6 +62,18 @@ dependencies = [ "windows-sys", ] +[[package]] +name = "anyhow" +version = "1.0.71" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c7d0618f0e0b7e8ff11427422b64564d5fb0be1940354bfe2e0529b18a9d9b8" + +[[package]] +name = "arbitrary" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2d098ff73c1ca148721f37baad5ea6a465a13f9573aba8641fbbbae8164a54e" + [[package]] name = "ariadne" version = "0.2.0" @@ -72,6 +84,12 @@ dependencies = [ "yansi", ] +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + [[package]] name = "bin" version = "0.1.0" @@ -79,6 +97,7 @@ dependencies = [ "ariadne", "chumsky", "clap", + "com", "ir", "syntax", "typing", @@ -90,6 +109,12 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +[[package]] +name = "bumpalo" +version = "3.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3e2c3daef883ecc1b5d58c15adae93470a91d425f3532ba1695849656af3fc1" + [[package]] name = "cc" version = "1.0.79" @@ -108,7 +133,7 @@ version = "1.0.0-alpha.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "379cdc19530b72a1e76d94a350676eaea1455375533eb38f18dfa712f9996902" dependencies = [ - "hashbrown", + "hashbrown 0.13.2", "stacker", ] @@ -160,6 +185,149 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" +[[package]] +name = "com" +version = "0.1.0" +dependencies = [ + "chumsky", + "cranelift", + "cranelift-jit", + "cranelift-module", + "cranelift-native", + "syntax", + "typing", +] + +[[package]] +name = "cranelift" +version = "0.96.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "128089b15e74e782e4e1a51c4b5b3bd4fbc35755777988aff24300dfa120f1c9" +dependencies = [ + "cranelift-codegen", + "cranelift-frontend", +] + +[[package]] +name = "cranelift-bforest" +version = "0.96.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c064a534a914eb6709d198525321a386dad50627aecfaf64053f369993a3e5a" +dependencies = [ + "cranelift-entity", +] + +[[package]] +name = "cranelift-codegen" +version = "0.96.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "619ed4d24acef0bd58b16a1be39077c0b36c65782e6c933892439af5e799110e" +dependencies = [ + "bumpalo", + "cranelift-bforest", + "cranelift-codegen-meta", + "cranelift-codegen-shared", + "cranelift-control", + "cranelift-entity", + "cranelift-isle", + "gimli", + "hashbrown 0.13.2", + "log", + "regalloc2", + "smallvec", + "target-lexicon", +] + +[[package]] +name = "cranelift-codegen-meta" +version = "0.96.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c777ce22678ae1869f990b2f31e0cd7ca109049213bfc0baf3e2205a18b21ebb" +dependencies = [ + "cranelift-codegen-shared", +] + +[[package]] +name = "cranelift-codegen-shared" +version = "0.96.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb65884d17a1fa55990dd851c43c140afb4c06c3312cf42cfa1222c3b23f9561" + +[[package]] +name = "cranelift-control" +version = "0.96.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a0cea8abc90934d0a7ee189a29fd35fecd5c40f59ae7e6aab1805e8ab1a535e" +dependencies = [ + "arbitrary", +] + +[[package]] +name = "cranelift-entity" +version = "0.96.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2e50bebc05f2401a1320169314b62f91ad811ef20163cac00151d78e0684d4c" + +[[package]] +name = "cranelift-frontend" +version = "0.96.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b82ccfe704d53f669791399d417928410785132d809ec46f5e2ce069e9d17c8" +dependencies = [ + "cranelift-codegen", + "log", + "smallvec", + "target-lexicon", +] + +[[package]] +name = "cranelift-isle" +version = "0.96.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2515d8e7836f9198b160b2c80aaa1f586d7749d57d6065af86223fb65b7e2c3" + +[[package]] +name = "cranelift-jit" +version = "0.96.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e3830a0c5c18c5ddf1c6d4a3dc049a3723d4606e24699796116963ac5bb0404" +dependencies = [ + "anyhow", + "cranelift-codegen", + "cranelift-control", + "cranelift-entity", + "cranelift-module", + "cranelift-native", + "libc", + "log", + "region", + "target-lexicon", + "wasmtime-jit-icache-coherence", + "windows-sys", +] + +[[package]] +name = "cranelift-module" +version = "0.96.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2709ba70d7340ef9ffc408df1905bfd02f33eddeb6f8a7198d93c1d0c1154c3" +dependencies = [ + "anyhow", + "cranelift-codegen", + "cranelift-control", +] + +[[package]] +name = "cranelift-native" +version = "0.96.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bcb47ffdcdac7e9fed6e4a618939773a4dc4a412fa7da9e701ae667431a10af3" +dependencies = [ + "cranelift-codegen", + "libc", + "target-lexicon", +] + [[package]] name = "errno" version = "0.3.1" @@ -181,6 +349,29 @@ dependencies = [ "libc", ] +[[package]] +name = "fallible-iterator" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7" + +[[package]] +name = "gimli" +version = "0.27.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad0a93d233ebf96623465aad4046a8d3aa4da22d4f4beba5388838c8a434bbb4" +dependencies = [ + "fallible-iterator", + "indexmap", + "stable_deref_trait", +] + +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" + [[package]] name = "hashbrown" version = "0.13.2" @@ -202,6 +393,16 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286" +[[package]] +name = "indexmap" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" +dependencies = [ + "autocfg", + "hashbrown 0.12.3", +] + [[package]] name = "io-lifetimes" version = "1.0.10" @@ -246,6 +447,21 @@ version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "36eb31c1778188ae1e64398743890d0877fef36d11521ac60406b42016e8c2cf" +[[package]] +name = "log" +version = "0.4.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b06a4cde4c0f271a446782e3eff8de789548ce57dbc8eca9292c27f4a42004b4" + +[[package]] +name = "mach" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b823e83b2affd8f40a9ee8c29dbc56404c1e34cd2710921f2801e2cf29527afa" +dependencies = [ + "libc", +] + [[package]] name = "once_cell" version = "1.17.1" @@ -279,6 +495,37 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "regalloc2" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4a52e724646c6c0800fc456ec43b4165d2f91fba88ceaca06d9e0b400023478" +dependencies = [ + "hashbrown 0.13.2", + "log", + "rustc-hash", + "slice-group-by", + "smallvec", +] + +[[package]] +name = "region" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877e54ea2adcd70d80e9179344c97f93ef0dffd6b03e1f4529e6e83ab2fa9ae0" +dependencies = [ + "bitflags", + "libc", + "mach", + "winapi", +] + +[[package]] +name = "rustc-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + [[package]] name = "rustix" version = "0.37.14" @@ -293,6 +540,24 @@ dependencies = [ "windows-sys", ] +[[package]] +name = "slice-group-by" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "826167069c09b99d56f31e9ae5c99049e932a98c9dc2dac47645b08dbbf76ba7" + +[[package]] +name = "smallvec" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" + +[[package]] +name = "stable_deref_trait" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" + [[package]] name = "stacker" version = "0.1.15" @@ -330,6 +595,12 @@ dependencies = [ "chumsky", ] +[[package]] +name = "target-lexicon" +version = "0.12.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd1ba337640d60c3e96bc6f0638a939b9c9a7f2c316a1598c279828b3d1dc8c5" + [[package]] name = "typing" version = "0.1.0" @@ -362,6 +633,17 @@ version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +[[package]] +name = "wasmtime-jit-icache-coherence" +version = "9.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "374ff63b3eb41db57c56682a9ef7737d2c9efa801f5dbf9da93941c9dd436a06" +dependencies = [ + "cfg-if", + "libc", + "windows-sys", +] + [[package]] name = "winapi" version = "0.3.9" diff --git a/Cargo.toml b/Cargo.toml index 2384fd5..bcc25ef 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,4 +5,5 @@ members = [ "syntax", "typing", "ir", + "com", ] \ No newline at end of file diff --git a/bin/Cargo.toml b/bin/Cargo.toml index 9e4c661..d003340 100644 --- a/bin/Cargo.toml +++ b/bin/Cargo.toml @@ -10,6 +10,7 @@ clap = { version = "4.2.4", features = ["derive"] } syntax = { path = "../syntax" } typing = { path = "../typing" } ir = { path = "../ir" } +com = { path = "../com" } [[bin]] name = "hc" diff --git a/bin/src/args.rs b/bin/src/args.rs index 485fbd3..c6856b0 100644 --- a/bin/src/args.rs +++ b/bin/src/args.rs @@ -5,6 +5,9 @@ pub struct Args { /// The path to the file to be compiled. #[arg(required = true)] pub file: String, + /// Only run the type checker. + #[arg(short = 'c', long = "check")] + pub typecheck: bool, } pub fn get_args() -> Args { diff --git a/bin/src/main.rs b/bin/src/main.rs index 778b065..1c55519 100644 --- a/bin/src/main.rs +++ b/bin/src/main.rs @@ -54,6 +54,10 @@ fn main() { }); // Else go to the next stage } else { + if args.typecheck { + ast.iter().for_each(|node| println!("{:?}", node.0)); + return; + } // ast.iter().for_each(|node| println!("{:?}", node.0)); let mut l = Lowerer::new(); let irs = l.lower_texprs(ast); diff --git a/com/Cargo.toml b/com/Cargo.toml new file mode 100644 index 0000000..e6f2479 --- /dev/null +++ b/com/Cargo.toml @@ -0,0 +1,13 @@ +[package] +name = "com" +version = "0.1.0" +edition = "2021" + +[dependencies] +chumsky = "1.0.0-alpha.3" +cranelift = "0.96.3" +cranelift-jit = "0.96.3" +cranelift-module = "0.96.3" +cranelift-native = "0.96.3" +syntax = { path = "../syntax" } +typing = { path = "../typing" } \ No newline at end of file diff --git a/com/src/lib.rs b/com/src/lib.rs new file mode 100644 index 0000000..e69de29 diff --git a/fizz.hlm b/fizz.hlm new file mode 100644 index 0000000..151af1b --- /dev/null +++ b/fizz.hlm @@ -0,0 +1,11 @@ +let fizz = fun (n) -> if n % 3 == 0 && n % 5 == 0 + then "FizzBuzz" + else if n % 3 == 0 + then "Fizz" + else if n % 5 == 0 + then "Buzz" + else "" + ; + +let println = fun (a) -> (); +println(fizz(5)); \ No newline at end of file diff --git a/ir/src/lib.rs b/ir/src/lib.rs index 6216aaf..40861b2 100644 --- a/ir/src/lib.rs +++ b/ir/src/lib.rs @@ -4,9 +4,14 @@ use typing::typed::TExpr; #[derive(Clone, Debug)] pub enum IExpr<'src> { + BoolAnd, IntPush(i64), IntAdd, IntSub, + IntRem, + IntEq, + StrPush(&'src str), + Branch(Vec, Vec), VarLoad(&'src str), VarStore(&'src str), FnPush(Vec), @@ -27,10 +32,10 @@ impl Lowerer { use IExpr::*; match e { TExpr::Lit(l) => match l { - Lit::Unit => todo!(), + Lit::Unit => vec![], Lit::Bool(_) => todo!(), Lit::Int(n) => vec![IntPush(n)], - Lit::Str(_) => todo!(), + Lit::Str(s) => vec![StrPush(s)], } TExpr::Ident(s) => vec![VarLoad(s)], TExpr::Unary { op, expr, .. } => { @@ -55,14 +60,14 @@ impl Lowerer { BinaryOp::Sub => IExpr::IntSub, BinaryOp::Mul => todo!(), BinaryOp::Div => todo!(), - BinaryOp::Rem => todo!(), - BinaryOp::Eq => todo!(), + BinaryOp::Rem => IExpr::IntRem, + BinaryOp::Eq => IExpr::IntEq, BinaryOp::Ne => todo!(), BinaryOp::Lt => todo!(), BinaryOp::Gt => todo!(), BinaryOp::Le => todo!(), BinaryOp::Ge => todo!(), - BinaryOp::And => todo!(), + BinaryOp::And => IExpr::BoolAnd, BinaryOp::Or => todo!(), BinaryOp::Pipe => unreachable!(), }); @@ -82,12 +87,22 @@ impl Lowerer { es.push(IExpr::Call); es }, + + TExpr::If { cond, t, f, .. } => { + let mut es = self.lower_texpr(*cond.0); + es.push(IExpr::Branch( + self.lower_texpr(*t.0), + self.lower_texpr(*f.0), + )); + es + }, TExpr::Define { name, value, .. } => { let mut es = self.lower_texpr(*value.0); es.push(IExpr::VarStore(name)); es }, + e => unimplemented!("{:?}", e) } } diff --git a/ref.hlm b/ref.hlm index 4539473..0e211c6 100644 --- a/ref.hlm +++ b/ref.hlm @@ -1,2 +1,2 @@ -let by_ref = fn (&x: int) = *x + 1; -let by_value = fn (x: int) = x + 1; \ No newline at end of file +let by_ref = fun (&x int) -> *x + 1; +let by_value = fun (x: int) -> x + 1; \ No newline at end of file diff --git a/simple.hlm b/simple.hlm index 9b197c1..ebfb7d8 100644 --- a/simple.hlm +++ b/simple.hlm @@ -1,5 +1,2 @@ -let a = fun (x Int, y) Int -> x + y; -let b = fun (x, y) -> x + y; -a(34, 35); - -fun (x Int, y) Int -> x + y; \ No newline at end of file +let f = fun (x Int, y) Int -> x + y; +f(34, 35); \ No newline at end of file diff --git a/syntax/src/parser.rs b/syntax/src/parser.rs index c327ab8..0b84d36 100644 --- a/syntax/src/parser.rs +++ b/syntax/src/parser.rs @@ -145,14 +145,15 @@ pub fn expr_parser<'tokens, 'src: 'tokens>() -> impl Parser< let lambda = just(Token::Func) .ignore_then( - symbol + (symbol .then(type_parser().or_not()) .separated_by(just(Token::Comma)) .collect::>() .delimited_by( just(Token::Open(Delim::Paren)), just(Token::Close(Delim::Paren)), - ) + )) + .or(just(Token::Unit).to(Vec::new())) ) .then(type_parser().or_not()) .then_ignore(just(Token::Arrow)) @@ -262,6 +263,7 @@ pub fn expr_parser<'tokens, 'src: 'tokens>() -> impl Parser< let op = choice(( just(Token::Mul).to(BinaryOp::Mul), just(Token::Div).to(BinaryOp::Div), + just(Token::Rem).to(BinaryOp::Rem), )); let product = unary.clone() .foldl(