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