λ Support functions! #5

Open
acw wants to merge 59 commits from awick/functions into develop
2 changed files with 57 additions and 2 deletions
Showing only changes of commit 4c53419fc0 - Show all commits

View File

@@ -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
<stmts:Statements> => Program {
<stmts:ProgramTopLevel> => Program {
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> = {
// 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.
<ls: @L> "print" <name_start: @L> <v:"<var>"> <name_end: @L> ";" <le: @L> =>
Statement::Print(
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()),
// 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)),
// this expression could actually be a block!
"{" <stmts:Statements> "}" => unimplemented!(),
// finally, let people parenthesize expressions and get back to a
// lower precedence
"(" <e:Expression> ")" => e,

View File

@@ -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)),