From 5fa27330ebb0443fe9cc8fff7821ebfb23b49cf4 Mon Sep 17 00:00:00 2001 From: Stephen D <webmaster@scd31.com> Date: Tue, 11 Mar 2025 14:54:58 -0400 Subject: [PATCH] fixes and some examples --- Cargo.lock | 7 +++++++ Cargo.toml | 1 + examples/1.sos | 4 ---- examples/hello_world.sos | 20 ++++++++++++++++++ examples/reverse.sos | 4 ++++ examples/sort.sos | 2 ++ src/main.rs | 44 +++++++++++++++++++++++----------------- src/parser.rs | 8 -------- src/scanner.rs | 20 +++++++++--------- 9 files changed, 69 insertions(+), 41 deletions(-) delete mode 100644 examples/1.sos create mode 100644 examples/hello_world.sos create mode 100644 examples/reverse.sos create mode 100644 examples/sort.sos diff --git a/Cargo.lock b/Cargo.lock index 3a7cae6..ecfa198 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,12 @@ # It is not intended for manual editing. version = 4 +[[package]] +name = "anyhow" +version = "1.0.97" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcfed56ad506cb2c684a14971b8861fdc3baaaae314b9e5f9bb532cbe3ba7a4f" + [[package]] name = "bitvec" version = "1.0.1" @@ -30,6 +36,7 @@ checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" name = "sophiescript" version = "0.1.0" dependencies = [ + "anyhow", "bitvec", ] diff --git a/Cargo.toml b/Cargo.toml index 10f50da..ea3fae6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,4 +4,5 @@ version = "0.1.0" edition = "2021" [dependencies] +anyhow = "1.0.97" bitvec = "1.0.1" diff --git a/examples/1.sos b/examples/1.sos deleted file mode 100644 index 7a02f76..0000000 --- a/examples/1.sos +++ /dev/null @@ -1,4 +0,0 @@ -$false = λtf.f -$true = λtf.t - -λa.(a $true) diff --git a/examples/hello_world.sos b/examples/hello_world.sos new file mode 100644 index 0000000..8c1630f --- /dev/null +++ b/examples/hello_world.sos @@ -0,0 +1,20 @@ +$true = λtf.t; +$false = λtf.f; + +# λλλ [[0 2] 1] +$pair = λabc.cab; +$0 = $pair $true; +$1 = $pair $false; +$H = ($pair ($0 ($1 ($0 ($0 ($1 ($0 ($0 ($0 $false))))))))); +$e = ($pair ($0 ($1 ($1 ($0 ($0 ($1 ($0 ($1 $false))))))))); +$l = ($pair ($0 ($1 ($1 ($0 ($1 ($1 ($0 ($0 $false))))))))); +$o = ($pair ($0 ($1 ($1 ($0 ($1 ($1 ($1 ($1 $false))))))))); +$sp = ($pair ($0 ($0 ($1 ($0 ($0 ($0 ($0 ($0 $false))))))))); +$W = ($pair ($0 ($1 ($0 ($1 ($0 ($1 ($1 ($1 $false))))))))); +$r = ($pair ($0 ($1 ($1 ($1 ($0 ($0 ($1 ($0 $false))))))))); +$d = ($pair ($0 ($1 ($1 ($0 ($0 ($1 ($0 ($0 $false))))))))); +$nl = ($pair ($0 ($0 ($0 ($0 ($1 ($0 ($1 ($0 $false))))))))); +$exc = ($pair ($0 ($0 ($1 ($0 ($0 ($0 ($0 ($1 $false))))))))); + + +λa. $H ($e ($l ($l ($o ($sp ($W ($o ($r ($l ($d ($exc ($nl $false)))))))))))); \ No newline at end of file diff --git a/examples/reverse.sos b/examples/reverse.sos new file mode 100644 index 0000000..4b3842c --- /dev/null +++ b/examples/reverse.sos @@ -0,0 +1,4 @@ +$false=λtf.f; +$omega=λa. (a a); + +λa.a($omega(λbcde.d(bb)(λf.fce)))$false; diff --git a/examples/sort.sos b/examples/sort.sos new file mode 100644 index 0000000..1dfba58 --- /dev/null +++ b/examples/sort.sos @@ -0,0 +1,2 @@ + λa.(λb.bb)(λb.(λcde.e(λfg.(λh.hh)(λhi.i(λjkl.hhk(λm.j(λnopqrs.sm(n(λu.uoq)q)(nr(λu.uor)))(λnop.p(λqr.mq(λs.sqr))no)))(λj.(λk.jkkk)(λkl.l)))e(λhijk.(λl.h(d(λmn.n))(c(l(λmn.m))i(c(l(λmn.n))jk)))(λlm.d(λn.nlm)))))(bb))(λb.b)a(λbc.c); + \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index bc62b3c..965b63f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,3 +1,5 @@ +use std::{fs, io::Write}; + use bitvec::vec::BitVec; use flatten::Flattener; use parser::Parser; @@ -10,34 +12,38 @@ mod scanner; mod stmt; mod token; -fn main() { - let scanner = Scanner::new( - " - $false=λtf.f; - $omega=λa. (a a); +fn main() -> anyhow::Result<()> { + let args: Vec<_> = std::env::args().collect(); + if args.len() != 2 { + println!("Usage: {} filename.sos", args[0]); + return Ok(()); + } + + let code = fs::read_to_string(&args[1])?; + + run(&code); + Ok(()) +} - (λa.a($omega(λbcde.d(bb)(λf.fce)))$false); - #(λabc.cb(ab)); - #(λabc.cba); - ", - // "((λab.ba)(λa.a))", - ); +fn run(code: &str) -> Option<()> { + let scanner = Scanner::new(code); - let tokens = scanner.scan_tokens().unwrap(); + let tokens = scanner.scan_tokens()?; let mut parser = Parser::new(tokens); - let (funcs, main) = parser.parse().unwrap(); + let (funcs, main) = parser.parse()?; let mut flattener = Flattener::new(funcs); - let flat = flattener.flatten(&main).unwrap(); - - println!("{flat}"); + let flat = flattener.flatten(&main)?; - /*let mut bv = BitVec::new(); + let mut bv = BitVec::new(); flat.to_blc(&mut bv); + let mut stdout = std::io::stdout(); for x in bv.as_raw_slice() { - print!("{}", *x as char); - }*/ + stdout.write_all(&[*x]).unwrap(); + } + + Some(()) } diff --git a/src/parser.rs b/src/parser.rs index 035258c..6a35c47 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -87,8 +87,6 @@ impl Parser { fn expr(&mut self) -> Option<Expr> { let mut expr = self.expr_once()?; - dbg!(&expr); - while !self.is_at_end_of_expr() { let right = self.expr_once()?; expr = Expr::App(Box::new(expr), Box::new(right)); @@ -113,8 +111,6 @@ impl Parser { let expr = self.expr()?; - dbg!(&self.peek().token_type); - if self.peek().token_type != TokenType::RightParen { self.print_error("Expected ')'"); return None; @@ -133,8 +129,6 @@ impl Parser { } _ => { - dbg!(&self.peek().token_type); - self.print_error( "Unexpected token. Expected one of 'λ', '/', '\\', '$', '(', or a variable", ); @@ -169,8 +163,6 @@ impl Parser { } fn find_variable(&self, name: char) -> Option<usize> { - dbg!(name, &self.env); - let ret = self .env .iter() diff --git a/src/scanner.rs b/src/scanner.rs index 94a5581..ff24357 100644 --- a/src/scanner.rs +++ b/src/scanner.rs @@ -20,7 +20,7 @@ impl Scanner { } } - pub fn scan_tokens(mut self) -> Result<Vec<Token>, ()> { + pub fn scan_tokens(mut self) -> Option<Vec<Token>> { while !self.is_at_end() { self.start = self.current; self.scan_token()?; @@ -28,10 +28,10 @@ impl Scanner { self.add_token(TokenType::Eof); - Ok(self.tokens) + Some(self.tokens) } - pub fn scan_token(&mut self) -> Result<(), ()> { + pub fn scan_token(&mut self) -> Option<()> { use TokenType::*; let c = self.advance(); @@ -51,7 +51,7 @@ impl Scanner { } '#' => { // comment - while self.peek() != '\n' { + while !self.is_at_end() && self.peek() != '\n' { self.advance(); } @@ -61,31 +61,31 @@ impl Scanner { _ => { self.print_error(&format!("Unexpected character '{}'.", c)); - return Err(()); + return None; } }; self.add_token(token_type); - Ok(()) + Some(()) } - fn definition(&mut self) -> Result<(), ()> { - while self.peek().is_alphanumeric() { + fn definition(&mut self) -> Option<()> { + while !self.is_at_end() && self.peek().is_alphanumeric() { self.advance(); } if self.start + 1 == self.current { self.print_error("Missing function name after $"); - return Err(()); + return None; } self.add_token(TokenType::DefinitionName( self.chars[(self.start + 1)..self.current].iter().collect(), )); - Ok(()) + Some(()) } fn add_token(&mut self, token_type: TokenType) { -- GitLab