Let and let mut syntax

This commit is contained in:
greg 2018-07-11 16:44:15 -07:00
parent 43ff08b04c
commit f7dbbddad1
3 changed files with 25 additions and 16 deletions

View File

@ -340,8 +340,8 @@ mod eval_tests {
#[test] #[test]
fn test_basic_eval() { fn test_basic_eval() {
fresh_env!("1 + 2", "3"); fresh_env!("1 + 2", "3");
fresh_env!("var a = 1; a = 2", "Unit"); fresh_env!("let mut a = 1; a = 2", "Unit");
fresh_env!("var a = 1; a = 2; a", "2"); fresh_env!("let mut a = 1; a = 2; a", "2");
fresh_env!(r#"("a", 1 + 2)"#, r#"("a", 3)"#); fresh_env!(r#"("a", 1 + 2)"#, r#"("a", 3)"#);
} }
@ -354,18 +354,18 @@ mod eval_tests {
#[test] #[test]
fn scopes() { fn scopes() {
let scope_ok = r#" let scope_ok = r#"
const a = 20 let a = 20
fn haha() { fn haha() {
const a = 10 let a = 10
a a
} }
haha() haha()
"#; "#;
fresh_env!(scope_ok, "10"); fresh_env!(scope_ok, "10");
let scope_ok = r#" let scope_ok = r#"
const a = 20 let a = 20
fn haha() { fn haha() {
const a = 10 let a = 10
a a
} }
a a

View File

@ -44,8 +44,12 @@ formal_param := IDENTIFIER type_anno+
/* Declaration - Variable bindings */ /* Declaration - Variable bindings */
/* OLD */
binding_declaration: 'var' IDENTIFIER '=' expression | 'const' IDENTIFIER '=' expression binding_declaration: 'var' IDENTIFIER '=' expression | 'const' IDENTIFIER '=' expression
/* NEW */
binding_declaration := 'let' 'mut'? IDENTIFIER '=' expresion
/* Declaration - Interface */ /* Declaration - Interface */
interface_declaration := 'interface' interface_name signature_block interface_declaration := 'interface' interface_name signature_block
@ -296,7 +300,7 @@ impl Parser {
match self.peek() { match self.peek() {
Keyword(Type) => self.type_declaration().map(|decl| { Statement::Declaration(decl) }), Keyword(Type) => self.type_declaration().map(|decl| { Statement::Declaration(decl) }),
Keyword(Func)=> self.func_declaration().map(|func| { Statement::Declaration(func) }), Keyword(Func)=> self.func_declaration().map(|func| { Statement::Declaration(func) }),
Keyword(Var) | Keyword(Const) => self.binding_declaration().map(|decl| Statement::Declaration(decl)), Keyword(Let) => self.binding_declaration().map(|decl| Statement::Declaration(decl)),
Keyword(Interface) => self.interface_declaration().map(|decl| Statement::Declaration(decl)), Keyword(Interface) => self.interface_declaration().map(|decl| Statement::Declaration(decl)),
Keyword(Impl) => self.impl_declaration().map(|decl| Statement::Declaration(decl)), Keyword(Impl) => self.impl_declaration().map(|decl| Statement::Declaration(decl)),
_ => self.expression().map(|expr| { Statement::ExpressionStatement(expr) } ), _ => self.expression().map(|expr| { Statement::ExpressionStatement(expr) } ),
@ -396,10 +400,14 @@ impl Parser {
}); });
parse_method!(binding_declaration(&mut self) -> ParseResult<Declaration> { parse_method!(binding_declaration(&mut self) -> ParseResult<Declaration> {
let constant = match self.next() {
Keyword(Var) => false, expect!(self, Keyword(Kw::Let));
Keyword(Const) => true, let constant = match self.peek() {
_ => return ParseError::new("Expected 'var' or 'const'"), Keyword(Kw::Mut) => {
self.next();
false
}
_ => true
}; };
let name = self.identifier()?; let name = self.identifier()?;
expect!(self, Operator(ref o) if **o == "="); expect!(self, Operator(ref o) if **o == "=");
@ -1178,8 +1186,8 @@ fn a(x) {
#[test] #[test]
fn parsing_bindings() { fn parsing_bindings() {
parse_test!("var a = 10", AST(vec![Declaration(Binding { name: rc!(a), constant: false, expr: ex!(NatLiteral(10)) } )])); parse_test!("let mut a = 10", AST(vec![Declaration(Binding { name: rc!(a), constant: false, expr: ex!(NatLiteral(10)) } )]));
parse_test!("const a = 2 + 2", AST(vec![Declaration(Binding { name: rc!(a), constant: true, expr: ex!(binexp!("+", NatLiteral(2), NatLiteral(2))) }) ])); parse_test!("let a = 2 + 2", AST(vec![Declaration(Binding { name: rc!(a), constant: true, expr: ex!(binexp!("+", NatLiteral(2), NatLiteral(2))) }) ]));
} }
#[test] #[test]
@ -1294,7 +1302,7 @@ fn a(x) {
#[test] #[test]
fn parsing_type_annotations() { fn parsing_type_annotations() {
parse_test!("const a = b : Int", AST(vec![ parse_test!("let a = b : Int", AST(vec![
Declaration(Binding { name: rc!(a), constant: true, expr: Declaration(Binding { name: rc!(a), constant: true, expr:
Expression(val!("b"), Some(ty!("Int"))) })])); Expression(val!("b"), Some(ty!("Int"))) })]));

View File

@ -50,7 +50,8 @@ pub enum Kw {
Func, Func,
For, While, For, While,
Match, Match,
Var, Const, Let, In, Const, Let, In,
Mut,
Return, Return,
Alias, Type, SelfType, SelfIdent, Alias, Type, SelfType, SelfIdent,
Interface, Impl, Interface, Impl,
@ -68,10 +69,10 @@ lazy_static! {
"fn" => Kw::Func, "fn" => Kw::Func,
"for" => Kw::For, "for" => Kw::For,
"while" => Kw::While, "while" => Kw::While,
"var" => Kw::Var,
"const" => Kw::Const, "const" => Kw::Const,
"let" => Kw::Let, "let" => Kw::Let,
"in" => Kw::In, "in" => Kw::In,
"mut" => Kw::Mut,
"return" => Kw::Return, "return" => Kw::Return,
"alias" => Kw::Alias, "alias" => Kw::Alias,
"type" => Kw::Type, "type" => Kw::Type,