diff --git a/src/syntax/parser.lalrpop b/src/syntax/parser.lalrpop index fc6a0c6..3c1d7f8 100644 --- a/src/syntax/parser.lalrpop +++ b/src/syntax/parser.lalrpop @@ -30,11 +30,15 @@ extern { enum Token { "=" => Token::Equals, ";" => Token::Semi, + "," => Token::Comma, "(" => Token::LeftParen, ")" => Token::RightParen, "<" => Token::LessThan, ">" => Token::GreaterThan, + "{" => Token::OpenBrace, + "}" => Token::CloseBrace, + "function" => Token::Function, "print" => Token::Print, "+" => Token::Operator('+'), @@ -53,11 +57,43 @@ extern { pub Program: Program = { // a program is just a set of statements - => Program { + => Program { statements: stmts } } +ProgramTopLevel: Vec = { + Function => unimplemented!(), + => { + rest.push(next); + rest + }, + => Vec::new(), +} + +Function: () = { + "function" "(" Arguments OptionalComma ")" Expression => unimplemented!(), +} + +Arguments: Vec = { + => { + args.push(arg); + args + }, + + => Vec::new(), +} + +Argument: Name = { + "> => + Name::new(v, Location::new(file_idx, name_start..name_end)), +} + +OptionalComma: () = { + => (), + "," => (), +} + Statements: Vec = { // a statement is either a set of statements followed by another // statement (note, here, that you can name the result of a sub-parse @@ -98,7 +134,7 @@ pub Statement: Statement = { e, ), - // Alternatively, a statement can just be a print statement. + // A statement can just be a print statement. "print" "> ";" => Statement::Print( Location::new(file_idx, ls..le), @@ -166,6 +202,8 @@ AtomicExpression: Expression = { "> => Expression::Reference(Location::new(file_idx, l..end), v.to_string()), // just a number "> => Expression::Value(Location::new(file_idx, l..end), Value::Number(n.0, n.1, n.2)), + // this expression could actually be a block! + "{" "}" => unimplemented!(), // finally, let people parenthesize expressions and get back to a // lower precedence "(" ")" => e, diff --git a/src/syntax/tokens.rs b/src/syntax/tokens.rs index e521987..f6da79e 100644 --- a/src/syntax/tokens.rs +++ b/src/syntax/tokens.rs @@ -34,6 +34,9 @@ pub enum Token { #[token(";")] Semi, + #[token(",")] + Comma, + #[token("(")] LeftParen, @@ -46,6 +49,16 @@ pub enum Token { #[token(">")] GreaterThan, + #[token("{")] + OpenBrace, + + #[token("}")] + CloseBrace, + + #[token("lambda")] + #[token("function")] + Function, + // Next we take of any reserved words; I always like to put // these before we start recognizing more complicated regular // expressions. I don't think it matters, but it works for me. @@ -93,10 +106,14 @@ impl fmt::Display for Token { match self { Token::Equals => write!(f, "'='"), Token::Semi => write!(f, "';'"), + Token::Comma => write!(f, "','"), Token::LeftParen => write!(f, "'('"), Token::RightParen => write!(f, "')'"), Token::LessThan => write!(f, "<"), Token::GreaterThan => write!(f, ">"), + Token::OpenBrace => write!(f, "{{"), + Token::CloseBrace => write!(f, "}}"), + Token::Function => write!(f, "function"), Token::Print => write!(f, "'print'"), Token::Operator(c) => write!(f, "'{}'", c), Token::Number((None, otype, v)) => write!(f, "'{}{}'", v, display_optional_type(otype)),