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

View File

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

View File

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