diff --git a/Cargo.lock b/Cargo.lock
index 3a7cae61da2977ab8ef52d13b116ad8d243b6331..ecfa1980fa392ed213e7baffa5f334361d7e89cc 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 10f50da99380834144df0e284d460302ffb8673e..ea3fae68452965fa4e44aaddc76cb53243296a80 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 7a02f76115b0c2d39d0fa3bbc151bdf1997d4ea2..0000000000000000000000000000000000000000
--- 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 0000000000000000000000000000000000000000..8c1630f2ad616a2792dadd69b2351c9a98b13d3b
--- /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 0000000000000000000000000000000000000000..4b3842ce7c76ff9d0b2603e98ecdbedcc37e0c1d
--- /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 0000000000000000000000000000000000000000..1dfba58608ce212df78ffbb6f6835e9d36fa4fd8
--- /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 bc62b3cd25fd61b6071579d3fe7a7ce6e56e9ad5..965b63f2286e1b0260a8929f150b156f590e65b4 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 035258c47c3eedc5c67469910bf45e397bde35b7..6a35c473eefb44c9fe9afb63b7ebe0b81879116a 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 94a5581120491da0e6d6f285128980282c6dce7a..ff24357d21633e5bdba157f5d9849efc2cc54bbc 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) {