Skip to content

Commit 57a59d6

Browse files
Claude/add academic proofs mg s2z (#29)
Signed-off-by: Jonathan D.A. Jewell <6759885+hyperpolymath@users.noreply.github.com> Co-authored-by: Claude <noreply@anthropic.com>
1 parent abac6fb commit 57a59d6

9 files changed

Lines changed: 1216 additions & 241 deletions

File tree

Cargo.lock

Lines changed: 360 additions & 9 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ path = "src/main.rs"
1818
logos = "0.14"
1919
thiserror = "1.0"
2020
miette = { version = "7.0", features = ["fancy"] }
21+
rustyline = { version = "14.0", features = ["derive"] }
22+
dirs = "5.0"
2123

2224
[dev-dependencies]
2325
pretty_assertions = "1.4"

src/ast/mod.rs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,11 +52,19 @@ pub struct QualifiedName {
5252
pub span: Span,
5353
}
5454

55+
/// Generic type parameter: `<T: Trait>` or just `<T>`
56+
#[derive(Debug, Clone)]
57+
pub struct TypeParam {
58+
pub name: String,
59+
pub bounds: Vec<String>, // Trait bounds (future use)
60+
}
61+
5562
/// Function definition
5663
#[derive(Debug, Clone)]
5764
pub struct FunctionDef {
5865
pub emote: Option<EmoteTag>,
5966
pub name: String,
67+
pub type_params: Vec<TypeParam>, // Generic type parameters: <T, U>
6068
pub params: Vec<Parameter>,
6169
pub return_type: Option<Type>,
6270
pub hello: Option<String>,
@@ -290,6 +298,24 @@ pub enum Literal {
290298
Float(f64),
291299
String(String),
292300
Bool(bool),
301+
Unit, // The () value
302+
}
303+
304+
/// Lambda expression body
305+
#[derive(Debug, Clone)]
306+
pub enum LambdaBody {
307+
/// Expression body: `|x| -> x + 1`
308+
Expr(Box<Spanned<Expr>>),
309+
/// Block body: `|x| { give back x + 1; }`
310+
Block(Vec<Statement>),
311+
}
312+
313+
/// Lambda/closure expression: `|x, y| -> expr` or `|x, y| { ... }`
314+
#[derive(Debug, Clone)]
315+
pub struct LambdaExpr {
316+
pub params: Vec<Parameter>,
317+
pub return_type: Option<Type>,
318+
pub body: LambdaBody,
293319
}
294320

295321
/// Lambda expression body
@@ -384,6 +410,10 @@ pub enum Type {
384410
Reference(Box<Type>),
385411
/// Function type: (T1, T2) -> R
386412
Function(Vec<Type>, Box<Type>),
413+
/// Generic/parameterized type: Result<T, E>, Map<K, V>
414+
Generic(String, Vec<Type>),
415+
/// Type parameter reference: T (used inside generic functions)
416+
TypeVar(String),
387417
}
388418

389419
/// Type definition: `type Name = ...;`

src/interpreter/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -401,6 +401,7 @@ impl Interpreter {
401401
Literal::Float(n) => Value::Float(*n),
402402
Literal::String(s) => Value::String(s.clone()),
403403
Literal::Bool(b) => Value::Bool(*b),
404+
Literal::Unit => Value::Unit,
404405
}
405406
}
406407

src/lib.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,12 @@ pub mod ast;
22
pub mod interpreter;
33
pub mod lexer;
44
pub mod parser;
5+
pub mod repl;
6+
pub mod typechecker;
57

68
pub use ast::Program;
79
pub use interpreter::Interpreter;
810
pub use lexer::Lexer;
911
pub use parser::Parser;
12+
pub use repl::Repl;
13+
pub use typechecker::TypeChecker;

src/main.rs

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use miette::Result;
22
use std::env;
33
use std::fs;
4-
use wokelang::{Interpreter, Lexer, Parser};
4+
use wokelang::{Interpreter, Lexer, Parser, Repl, TypeChecker};
55

66
fn main() -> Result<()> {
77
let args: Vec<String> = env::args().collect();
@@ -10,14 +10,24 @@ fn main() -> Result<()> {
1010
println!("WokeLang v0.1.0 - A human-centered, consent-driven programming language");
1111
println!();
1212
println!("Usage: woke <file.woke> Run a WokeLang program");
13+
println!(" woke repl Start interactive REPL");
1314
println!(" woke --tokenize <file> Show lexer tokens");
1415
println!(" woke --parse <file> Show parsed AST");
16+
println!(" woke --typecheck <file> Type-check without running");
17+
return Ok(());
18+
}
19+
20+
// Check for REPL mode first
21+
if args.get(1).map(|s| s.as_str()) == Some("repl") {
22+
let mut repl = Repl::new().expect("Failed to create REPL");
23+
repl.run().expect("REPL error");
1524
return Ok(());
1625
}
1726

1827
let (mode, file_path) = match args.get(1).map(|s| s.as_str()) {
1928
Some("--tokenize") => ("tokenize", args.get(2)),
2029
Some("--parse") => ("parse", args.get(2)),
30+
Some("--typecheck") => ("typecheck", args.get(2)),
2131
Some(_) => ("run", Some(&args[1])),
2232
None => {
2333
eprintln!("Expected file path");
@@ -63,10 +73,38 @@ fn main() -> Result<()> {
6373
}
6474
}
6575
}
76+
"typecheck" => {
77+
let mut parser = Parser::new(tokens, &source);
78+
match parser.parse() {
79+
Ok(program) => {
80+
let mut typechecker = TypeChecker::new();
81+
match typechecker.check_program(&program) {
82+
Ok(()) => {
83+
println!("Type check passed!");
84+
}
85+
Err(e) => {
86+
eprintln!("Type error: {}", e);
87+
}
88+
}
89+
}
90+
Err(e) => {
91+
eprintln!("{:?}", miette::Report::new(e));
92+
}
93+
}
94+
}
6695
"run" => {
6796
let mut parser = Parser::new(tokens, &source);
6897
match parser.parse() {
6998
Ok(program) => {
99+
// Type check first
100+
let mut typechecker = TypeChecker::new();
101+
if let Err(e) = typechecker.check_program(&program) {
102+
eprintln!("Type error: {}", e);
103+
eprintln!("\nType checking failed. Not running.");
104+
return Ok(());
105+
}
106+
107+
// Run the program
70108
let mut interpreter = Interpreter::new();
71109
if let Err(e) = interpreter.run(&program) {
72110
eprintln!("Runtime error: {}", e);

src/parser/mod.rs

Lines changed: 81 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,14 @@ impl<'src> Parser<'src> {
8888
}
8989

9090
let name = self.expect_identifier()?;
91+
92+
// Parse optional type parameters: <T, U>
93+
let type_params = if self.check(&Token::Less) {
94+
self.parse_type_params()?
95+
} else {
96+
Vec::new()
97+
};
98+
9199
self.expect(Token::LParen)?;
92100
let params = self.parse_parameter_list()?;
93101
self.expect(Token::RParen)?;
@@ -130,6 +138,7 @@ impl<'src> Parser<'src> {
130138
Ok(FunctionDef {
131139
emote,
132140
name,
141+
type_params,
133142
params,
134143
return_type,
135144
hello,
@@ -171,6 +180,45 @@ impl<'src> Parser<'src> {
171180
})
172181
}
173182

183+
/// Parse type parameters: <T, U: Bound>
184+
fn parse_type_params(&mut self) -> Result<Vec<TypeParam>, ParseError> {
185+
self.expect(Token::Less)?; // Consume '<'
186+
let mut params = Vec::new();
187+
188+
if self.check(&Token::Greater) {
189+
self.advance();
190+
return Ok(params);
191+
}
192+
193+
params.push(self.parse_type_param()?);
194+
while self.check(&Token::Comma) {
195+
self.advance();
196+
params.push(self.parse_type_param()?);
197+
}
198+
199+
self.expect(Token::Greater)?; // Consume '>'
200+
Ok(params)
201+
}
202+
203+
/// Parse a single type parameter: T or T: Bound
204+
fn parse_type_param(&mut self) -> Result<TypeParam, ParseError> {
205+
let name = self.expect_identifier()?;
206+
let bounds = if self.check(&Token::Colon) {
207+
self.advance();
208+
// Parse bounds separated by +
209+
let mut bounds = Vec::new();
210+
bounds.push(self.expect_identifier()?);
211+
while self.check(&Token::Plus) {
212+
self.advance();
213+
bounds.push(self.expect_identifier()?);
214+
}
215+
bounds
216+
} else {
217+
Vec::new()
218+
};
219+
Ok(TypeParam { name, bounds })
220+
}
221+
174222
// === Consent Block ===
175223

176224
fn parse_consent_block(&mut self) -> Result<ConsentBlock, ParseError> {
@@ -515,12 +563,38 @@ impl<'src> Parser<'src> {
515563
Some(Token::Identifier(name)) => {
516564
let name = name.clone();
517565
self.advance();
518-
Ok(Type::Basic(name))
566+
// Check for generic type arguments: Result<T, E>
567+
if self.check(&Token::Less) {
568+
let args = self.parse_type_args()?;
569+
Ok(Type::Generic(name, args))
570+
} else {
571+
Ok(Type::Basic(name))
572+
}
519573
}
520574
_ => Err(self.error("Expected type")),
521575
}
522576
}
523577

578+
/// Parse type arguments: <Int, String>
579+
fn parse_type_args(&mut self) -> Result<Vec<Type>, ParseError> {
580+
self.expect(Token::Less)?;
581+
let mut args = Vec::new();
582+
583+
if self.check(&Token::Greater) {
584+
self.advance();
585+
return Ok(args);
586+
}
587+
588+
args.push(self.parse_type()?);
589+
while self.check(&Token::Comma) {
590+
self.advance();
591+
args.push(self.parse_type()?);
592+
}
593+
594+
self.expect(Token::Greater)?;
595+
Ok(args)
596+
}
597+
524598
// === Statement Parsing ===
525599

526600
fn parse_statement_list(&mut self) -> Result<Vec<Statement>, ParseError> {
@@ -1118,6 +1192,12 @@ impl<'src> Parser<'src> {
11181192
}
11191193
Some(Token::LParen) => {
11201194
self.advance();
1195+
// Check for Unit literal: ()
1196+
if self.check(&Token::RParen) {
1197+
self.advance();
1198+
let end = self.previous_span().end;
1199+
return Ok(Spanned::new(Expr::Literal(Literal::Unit), start..end));
1200+
}
11211201
let expr = self.parse_expression()?;
11221202
self.expect(Token::RParen)?;
11231203
Ok(expr)

0 commit comments

Comments
 (0)