cxgraph/libcxgraph/src/language/syntax.lalrpop

125 lines
3.1 KiB
Plaintext

use crate::language::ast::*;
use crate::language::token::*;
grammar<'input>(input: &'input str);
extern {
type Location = usize;
type Error = LexerError;
enum Token<'input> {
"(" => Token::LParen,
")" => Token::RParen,
"{" => Token::LBrace,
"}" => Token::RBrace,
"+" => Token::Plus,
"-" => Token::Minus,
"*" => Token::Star,
"/" => Token::Slash,
"^" => Token::Caret,
"," => Token::Comma,
"->" => Token::Arrow,
"=" => Token::Equal,
":" => Token::Colon,
"\n" => Token::Newline,
"sum" => Token::Sum,
"prod" => Token::Prod,
"iter" => Token::Iter,
Float => Token::Float(<f64>),
Int => Token::Int(<i32>),
Name => Token::Name(<&'input str>),
}
}
// Definitions
pub Program: Vec<Definition<'input>> = Definitions;
Definitions: Vec<Definition<'input>> = {
"\n"* <defs:(<Definition> "\n"+)*> <last:Definition?> => defs.into_iter().chain(last).collect(),
}
Definition: Definition<'input> = {
<n:Name> "(" <args:(<Name> ",")*> <last:Name?> ")" "=" <exs:Exprs> => Definition::Function {
name: n,
args: args.into_iter().chain(last).collect(),
value: exs,
},
<n:Name> "=" <exs:Exprs> => Definition::Constant {
name: n,
value: exs,
},
}
// Expressions
Exprs: Vec<Expression<'input>> = {
<args:(<Expr> ",")*> <last:Expr> ","? => args.into_iter().chain(std::iter::once(last)).collect(),
}
Expr: Expression<'input> = Store;
Store: Expression<'input> = {
<a:Store> "->" <n:Name> => Expression::new_store(a, n),
Sum,
}
Sum: Expression<'input> = {
<a:Sum> "+" <b:Product> => Expression::new_binary(BinaryOp::Add, a, b),
<a:Sum> "-" <b:Product> => Expression::new_binary(BinaryOp::Sub, a, b),
Product,
}
Product: Expression<'input> = {
<a:Product> "*" <b:Unary> => Expression::new_binary(BinaryOp::Mul, a, b),
<a:Product> "/" <b:Unary> => Expression::new_binary(BinaryOp::Div, a, b),
Unary,
}
Unary: Expression<'input> = {
"+" <a:Unary> => Expression::new_unary(UnaryOp::Pos, a),
"-" <a:Unary> => Expression::new_unary(UnaryOp::Neg, a),
"*" <a:Unary> => Expression::new_unary(UnaryOp::Conj, a),
<a:Juxtapose> <b:Power> => Expression::new_binary(BinaryOp::Mul, a, b),
Power,
}
Juxtapose: Expression<'input> = {
<a:Juxtapose> <b:PreJuxtapose> => Expression::new_binary(BinaryOp::Mul, a, b),
PreJuxtapose,
}
Power: Expression<'input> = {
<a:FnCall> "^" <b:Unary> => Expression::new_binary(BinaryOp::Pow, a, b),
FnCall,
}
FnCall: Expression<'input> = {
<n:Name> "(" <args:Exprs> ")"
=> Expression::new_fncall(n, args),
<Item>
}
PreJuxtapose: Expression<'input> = {
Number,
"(" <Expr> ")",
}
Item: Expression<'input> = {
Number,
<n:Name> => Expression::new_name(n),
"(" <Expr> ")",
"{" <exs:Exprs> "}" => Expression::new_block(exs),
"sum" "(" <name:Name> ":" <min:Int> "," <max:Int> ")" "{" <exs:Exprs> "}"
=> Expression::new_sum(name, min, max, exs),
"prod" "(" <name:Name> ":" <min:Int> "," <max:Int> ")" "{" <exs:Exprs> "}"
=> Expression::new_prod(name, min, max, exs),
"iter" "(" <count:Int> "," <name:Name> ":" <init:Expr> ")" "{" <exs:Exprs> "}"
=> Expression::new_iter(name, count, init, exs),
}
Number: Expression<'input> = {
<n:Float> => Expression::new_number(n),
<n:Int> => Expression::new_number(n as f64),
}