diff --git a/libconlang/src/ast.rs b/libconlang/src/ast.rs index 5780ad8..c1a2e14 100644 --- a/libconlang/src/ast.rs +++ b/libconlang/src/ast.rs @@ -241,6 +241,7 @@ pub enum StmtKind { pub struct Let { pub mutable: Mutability, pub name: Identifier, + pub ty: Option>, pub init: Option>, } diff --git a/libconlang/src/ast/ast_impl.rs b/libconlang/src/ast/ast_impl.rs index c0cbcc9..da533aa 100644 --- a/libconlang/src/ast/ast_impl.rs +++ b/libconlang/src/ast/ast_impl.rs @@ -252,8 +252,11 @@ mod display { } impl Display for Let { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - let Self { mutable, name, init } = self; + let Self { mutable, name, ty, init } = self; write!(f, "let {mutable}{name}")?; + if let Some(value) = ty { + write!(f, ": {value}")?; + } if let Some(value) = init { write!(f, " = {value}")?; } diff --git a/libconlang/src/interpreter.rs b/libconlang/src/interpreter.rs index cc6271d..a41f26a 100644 --- a/libconlang/src/interpreter.rs +++ b/libconlang/src/interpreter.rs @@ -398,13 +398,9 @@ pub mod interpret { } impl Interpret for Let { fn interpret(&self, env: &mut Environment) -> IResult { - let Let { mutable: _, name: Identifier(name), init } = self; - if let Some(init) = init { - let init = init.interpret(env)?; - env.insert(name, Some(init)); - } else { - env.insert(name, None); - } + let Let { mutable: _, name: Identifier(name), ty: _, init } = self; + let init = init.as_ref().map(|i| i.interpret(env)).transpose()?; + env.insert(name, init); Ok(ConValue::Empty) } } diff --git a/libconlang/src/parser.rs b/libconlang/src/parser.rs index ac1e966..b1c0dd0 100644 --- a/libconlang/src/parser.rs +++ b/libconlang/src/parser.rs @@ -785,7 +785,13 @@ impl<'t> Parser<'t> { Ok(Let { mutable: self.mutability()?, name: self.identifier()?, - init: if Type::Eq == self.peek_type(Parsing::Let)? { + ty: if Ok(Type::Colon) == self.peek_type(Parsing::Let) { + self.consume_peeked(); + Some(self.ty()?.into()) + } else { + None + }, + init: if Ok(Type::Eq) == self.peek_type(Parsing::Let) { self.consume_peeked(); Some(self.expr()?.into()) } else {