variable bindings
This commit is contained in:
parent
1981b74d89
commit
b920fae93b
@ -327,7 +327,7 @@ program := (statement delimiter)* EOF
|
|||||||
delimiter := NEWLINE | ';'
|
delimiter := NEWLINE | ';'
|
||||||
statement := expression | declaration
|
statement := expression | declaration
|
||||||
|
|
||||||
declaration := type_alias | type_declaration | func_declaration
|
declaration := type_alias | type_declaration | func_declaration | binding_declaration
|
||||||
|
|
||||||
type_alias := 'alias' IDENTIFIER '=' IDENTIFIER
|
type_alias := 'alias' IDENTIFIER '=' IDENTIFIER
|
||||||
type_declaration := 'type' IDENTIFIER '=' type_body
|
type_declaration := 'type' IDENTIFIER '=' type_body
|
||||||
@ -338,6 +338,9 @@ member_list := (IDENTIFIER type_anno)*
|
|||||||
func_declaration := 'fn' IDENTIFIER '(' param_list ')'
|
func_declaration := 'fn' IDENTIFIER '(' param_list ')'
|
||||||
param_list := (IDENTIFIER type_anno+ ',')*
|
param_list := (IDENTIFIER type_anno+ ',')*
|
||||||
|
|
||||||
|
binding_declaration: 'var' IDENTIFIER '=' expression
|
||||||
|
| 'const' IDENTIFIER '=' expression
|
||||||
|
|
||||||
type_anno := ':' type
|
type_anno := ':' type
|
||||||
|
|
||||||
expression := precedence_expr
|
expression := precedence_expr
|
||||||
@ -435,7 +438,12 @@ pub enum Declaration {
|
|||||||
params: FormalParamList,
|
params: FormalParamList,
|
||||||
},
|
},
|
||||||
TypeDecl(Rc<String>, TypeBody),
|
TypeDecl(Rc<String>, TypeBody),
|
||||||
TypeAlias(Rc<String>, Rc<String>)
|
TypeAlias(Rc<String>, Rc<String>),
|
||||||
|
Binding {
|
||||||
|
name: Rc<String>,
|
||||||
|
constant: bool,
|
||||||
|
expr: Expression,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq)]
|
||||||
@ -522,6 +530,7 @@ impl Parser {
|
|||||||
Keyword(Alias) => self.type_alias().map(|alias| { Statement::Declaration(alias) }),
|
Keyword(Alias) => self.type_alias().map(|alias| { Statement::Declaration(alias) }),
|
||||||
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)),
|
||||||
_ => self.expression().map(|expr| { Statement::Expression(expr) } ),
|
_ => self.expression().map(|expr| { Statement::Expression(expr) } ),
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -564,6 +573,19 @@ impl Parser {
|
|||||||
Ok(vec!())
|
Ok(vec!())
|
||||||
});
|
});
|
||||||
|
|
||||||
|
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'"),
|
||||||
|
};
|
||||||
|
let name = self.identifier()?;
|
||||||
|
expect!(self, Operator(ref o) if **o == "=", "Expected '='");
|
||||||
|
let expr = self.expression()?;
|
||||||
|
|
||||||
|
Ok(Declaration::Binding { name, constant, expr })
|
||||||
|
});
|
||||||
|
|
||||||
parse_method!(expression(&mut self) -> ParseResult<Expression> {
|
parse_method!(expression(&mut self) -> ParseResult<Expression> {
|
||||||
self.precedence_expr(Operation::min_precedence())
|
self.precedence_expr(Operation::min_precedence())
|
||||||
});
|
});
|
||||||
@ -846,7 +868,7 @@ mod parse_tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn parse_complicated_operators() {
|
fn parsing_complicated_operators() {
|
||||||
parse_test!("a <- b", AST(vec![Expression(binexp!(op!("<-"), var!("a"), var!("b")))]));
|
parse_test!("a <- b", AST(vec![Expression(binexp!(op!("<-"), var!("a"), var!("b")))]));
|
||||||
parse_test!("a || b", AST(vec![Expression(binexp!(op!("||"), var!("a"), var!("b")))]));
|
parse_test!("a || b", AST(vec![Expression(binexp!(op!("||"), var!("a"), var!("b")))]));
|
||||||
parse_test!("a<>b", AST(vec![Expression(binexp!(op!("<>"), var!("a"), var!("b")))]));
|
parse_test!("a<>b", AST(vec![Expression(binexp!(op!("<>"), var!("a"), var!("b")))]));
|
||||||
@ -868,7 +890,7 @@ mod parse_tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn parse_bools() {
|
fn parsing_bools() {
|
||||||
parse_test!("false", AST(vec![Expression(BoolLiteral(false))]));
|
parse_test!("false", AST(vec![Expression(BoolLiteral(false))]));
|
||||||
parse_test!("true", AST(vec![Expression(BoolLiteral(true))]));
|
parse_test!("true", AST(vec![Expression(BoolLiteral(true))]));
|
||||||
}
|
}
|
||||||
@ -883,4 +905,10 @@ mod parse_tests {
|
|||||||
parse_test!("type Yolo = Yolo", AST(vec![Declaration(TypeDecl(rc!(Yolo), TypeBody(vec![Variant::Singleton(rc!(Yolo))])))]));
|
parse_test!("type Yolo = Yolo", AST(vec![Declaration(TypeDecl(rc!(Yolo), TypeBody(vec![Variant::Singleton(rc!(Yolo))])))]));
|
||||||
parse_test!("alias Sex = Drugs", AST(vec![Declaration(TypeAlias(rc!(Sex), rc!(Drugs)))]));
|
parse_test!("alias Sex = Drugs", AST(vec![Declaration(TypeAlias(rc!(Sex), rc!(Drugs)))]));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn parsing_bindings() {
|
||||||
|
parse_test!("var a = 10", AST(vec![Declaration(Binding { name: rc!(a), constant: false, expr: IntLiteral(10) } )]));
|
||||||
|
parse_test!("const a = 2 + 2", AST(vec![Declaration(Binding { name: rc!(a), constant: true, expr: binexp!(op!("+"), IntLiteral(2), IntLiteral(2)) }) ]));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user