summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorElizabeth Alexander Hunt <lizhunt@amazon.com>2026-08-14 15:22:49 -0700
committerElizabeth Alexander Hunt <lizhunt@amazon.com>2026-08-14 15:22:49 -0700
commitb38ce2a67114cab3e3416d602a58a17f58e27c96 (patch)
treefa72ad1f6f096231c325301ab2dedd288d091df0 /src
parentca16123c89f5731e2a3096d3780e641d071280d6 (diff)
downloadgock-main.tar.gz
gock-main.zip
Stuffv2HEADmain
Diffstat (limited to 'src')
-rw-r--r--src/main.rs140
1 files changed, 100 insertions, 40 deletions
diff --git a/src/main.rs b/src/main.rs
index 7736a08..48ccbe3 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -17,6 +17,27 @@ enum TokenType {
Eof,
}
+impl fmt::Display for TokenType {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ let chars = match self {
+ TokenType::Lparen => "(",
+ TokenType::Rparen => ")",
+ TokenType::Lbracket => "[",
+ TokenType::Rbracket => "]",
+ TokenType::Lbrace => "{",
+ TokenType::Rbrace => "}",
+ TokenType::Colon => ":",
+ TokenType::Semicolon => ";",
+ TokenType::Arrow => "->",
+ TokenType::Comma => ",",
+ TokenType::Equals => "=",
+ TokenType::Identifier(name) => name,
+ TokenType::Eof => "",
+ };
+ write!(f, "{}", chars)
+ }
+}
+
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
struct Blame {
line: usize,
@@ -65,6 +86,11 @@ impl Lexer {
};
for (i, c) in text.char_indices() {
+ // HACK for two-char type shi
+ if c == '>' {
+ continue;
+ }
+
let lookahead = text.chars().nth(i.saturating_add(1));
let singlechar = match c {
'(' => Some(TokenType::Lparen),
@@ -107,17 +133,6 @@ impl Lexer {
}
}
-enum Atomic {
- Unit,
- Bool,
- Int,
-}
-
-enum SimpleType {
- Arrow(Box<(SimpleType, SimpleType)>),
- Atom(Atomic),
-}
-
type Identifier = String;
struct Binding {
@@ -164,7 +179,7 @@ impl fmt::Display for Arguments {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "Arguments(")?;
for v in &self.0 {
- write!(f, "\t{}", v)?;
+ write!(f, "{} ", v)?;
}
write!(f, ")")
}
@@ -180,7 +195,7 @@ impl fmt::Display for Assignments {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "Assignments(")?;
for v in &self.0 {
- write!(f, "\t{}", v)?;
+ write!(f, "{} ", v)?;
}
write!(f, ")")
}
@@ -188,7 +203,14 @@ impl fmt::Display for Assignments {
impl fmt::Display for Binding {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- write!(f, "Binding({}, {})", self.name, "TYPE TODO")
+ write!(
+ f,
+ "Binding({}, {})",
+ self.name,
+ self.arg_type
+ .as_ref()
+ .unwrap_or(&TypeDeclaration::BaseType(String::from("None")))
+ )
}
}
@@ -237,6 +259,23 @@ enum ParsingFailure {
PastTokens,
}
+impl fmt::Display for Blame {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ write!(f, "Blame({}, {})", self.line, self.char)
+ }
+}
+
+impl fmt::Display for ParsingFailure {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ match self {
+ ParsingFailure::Blame(blame, reason) => {
+ write!(f, "ParsingFailure({}, {})", blame, reason)
+ }
+ ParsingFailure::PastTokens => write!(f, "ParsingFailure(PastTokens)"),
+ }
+ }
+}
+
impl Parser {
fn peek(&mut self) -> Result<&Token, ParsingFailure> {
return self
@@ -282,33 +321,21 @@ impl Parser {
fn parse_type_declaration(&mut self) -> Result<TypeDeclaration, ParsingFailure> {
self.consume_if_match_nomsg(|it| (*it).token == TokenType::Lparen)?;
- let my_type = self.consume_if_and_map(
- |it| match ((*it).token).clone() {
- // unfortunately, gotta clone to make the borrow checker happy. maybe i'll come back to this :3
- TokenType::Identifier(name) => Some(name.clone()),
- _ => None,
- },
- String::from("BWA"),
- );
- if let Ok(name) = my_type {
- return Ok(TypeDeclaration::BaseType(name as Identifier));
+ let type_name = self.parse_identifier();
+ if let Ok(name) = type_name {
+ self.consume_if_match_nomsg(|it| (*it).token == TokenType::Rparen)?;
+ println!("{}", name);
+ return Ok(TypeDeclaration::BaseType(name));
}
let left = self.parse_type_declaration()?;
self.consume_if_match_nomsg(|it| (*it).token == TokenType::Arrow)?;
let right = self.parse_type_declaration()?;
+ self.consume_if_match_nomsg(|it| (*it).token == TokenType::Rparen)?;
return Ok(TypeDeclaration::Arrow(Box::new((left, right))));
}
fn parse_binding(&mut self) -> Result<Binding, ParsingFailure> {
- let name = self.consume_if_and_map(
- |it| match ((*it).token).clone() {
- // unfortunately, gotta clone to make the borrow checker happy. maybe i'll come back to this :3
- TokenType::Identifier(name) => Some(name),
- _ => None,
- },
- String::from("Expected identifier"),
- )?;
-
+ let name = self.parse_identifier()?;
let val = self.consume_if_match_nomsg(|it| (*it).token == TokenType::Colon);
if val.is_ok() {
let blame = val.unwrap().blame;
@@ -373,9 +400,13 @@ impl Parser {
}
}
self.consume_if_match_nomsg(|it| (*it).token == TokenType::Rbracket)?;
+ self.consume_if_match_nomsg(|it| (*it).token == TokenType::Lbrace)?;
+ let body = self.parse_computation()?;
+ println!("{}", self.peek()?.token);
+ self.consume_if_match_nomsg(|it| (*it).token == TokenType::Rbrace)?;
return Ok(Abstraction {
arguments: Arguments(arguments),
- body: Box::new(self.parse_computation()?),
+ body: Box::new(body),
});
}
@@ -389,6 +420,17 @@ impl Parser {
});
}
+ fn parse_identifier(&mut self) -> Result<Identifier, ParsingFailure> {
+ self.consume_if_and_map(
+ |it| match ((*it).token).clone() {
+ // unfortunately, gotta clone to make the borrow checker happy. maybe i'll come back to this :3
+ TokenType::Identifier(name) => Some(name),
+ _ => None,
+ },
+ String::from("Expected identifier"),
+ )
+ }
+
fn parse_computation(&mut self) -> Result<Computation, ParsingFailure> {
let next = self.peek()?.clone();
return match next.token {
@@ -396,10 +438,10 @@ impl Parser {
if identifier == String::from("let") {
Ok(Computation::LetStatement(self.parse_let_statement()?))
} else {
- Ok(Computation::Identifier(identifier))
+ Ok(Computation::Identifier(self.parse_identifier()?))
}
}
- TokenType::Lbrace => Ok(Computation::Abstraction(self.parse_abstraction()?)),
+ TokenType::Lbracket => Ok(Computation::Abstraction(self.parse_abstraction()?)),
TokenType::Lparen => Ok(Computation::Application(self.parse_application()?)),
_ => Err(ParsingFailure::Blame(
next.blame,
@@ -514,7 +556,21 @@ mod tests {
}
);
assert_eq!(
- analysis[21],
+ analysis[8],
+ Token {
+ token: TokenType::Lparen,
+ blame: Blame { line: 1, char: 3 }
+ }
+ );
+ assert_eq!(
+ analysis[18],
+ Token {
+ token: TokenType::Rbrace,
+ blame: Blame { line: 1, char: 20 }
+ }
+ );
+ assert_eq!(
+ analysis[20],
Token {
token: TokenType::Eof,
blame: Blame { line: 2, char: 0 }
@@ -524,10 +580,14 @@ mod tests {
#[test]
fn test_parse() {
- let prog = "let Identity: ((Int) -> (Int)) = [a] { a }; in Identity";
+ let prog = "let Identity: ((Int) -> (Int)) =\n[a] { a }; in Identity";
let tokens = Lexer::analyze(prog);
let mut parser = Parser::new(tokens);
- let ast = parser.parse_computation().ok();
- println!("{}", ast.unwrap());
+ match parser.parse_computation() {
+ Ok(parsed) => println!("{}", parsed),
+ Err(err) => println!("err {}", err),
+ };
+ // let ast = parser.parse_computation().ok();
+ // println!("{}", ast.unwrap());
}
}