Skip to content
Snippets Groups Projects
lang.y 5.67 KiB
Newer Older
  • Learn to ignore specific revisions
  • Aaron Councilman's avatar
    Aaron Councilman committed
    %avoid_insert "ID" "INT" "STRING"
    
    %expect-unused Unmatched 'UNMATCHED'
    
    
    %left '\\'
    %left '|'
    %left '&'
    %left '.' '@'
    
    
    Aaron Councilman's avatar
    Aaron Councilman committed
    Schedule -> OperationList
      :               { OperationList::NilStmt() }
      | Expr          { OperationList::FinalExpr($1) }
      | Stmt Schedule { OperationList::ConsStmt($1, Box::new($2)) }
      ;
    
    Aaron Councilman's avatar
    Aaron Councilman committed
    Stmt -> Stmt
      : 'let' 'ID' '=' Expr ';'
          { Stmt::LetStmt { span: $span, var: span_of_tok($2), expr: $4 } }
    
    Aaron Councilman's avatar
    Aaron Councilman committed
      | 'let' '(' Ids ')' '=' Expr ';'
          { Stmt::LetsStmt { span: $span, vars: rev($3), expr: $6 } }
    
    Aaron Councilman's avatar
    Aaron Councilman committed
      | 'ID' '=' Expr ';'
          { Stmt::AssignStmt { span: $span, var: span_of_tok($1), rhs: $3 } }
      | Expr ';'
          { Stmt::ExprStmt { span: $span, exp: $1 } }
      | 'fixpoint' FixpointLimit '{' Schedule '}'
          { Stmt::Fixpoint { span: $span, limit: $2, body: Box::new($4) } }
      | MacroDecl
          { Stmt::MacroDecl { span: $span, def: $1 } }
    
    Aaron Councilman's avatar
    Aaron Councilman committed
    FixpointLimit -> FixpointLimit
      : { FixpointLimit::NoLimit { span: $span } }
      | 'stop_after' 'INT'
          { FixpointLimit::StopAfter { span: $span, limit: span_of_tok($2) } }
      | 'panic_after' 'INT'
          { FixpointLimit::PanicAfter { span: $span, limit: span_of_tok($2) } }
      | 'print_iter'
          { FixpointLimit::PrintIter { span: $span } }
      ;
    
    Aaron Councilman's avatar
    Aaron Councilman committed
    Expr -> Expr
      : 'ID' Args Selector
          { Expr::Function { span: $span, name: span_of_tok($1), args: $2, selection: $3 } }
      | 'MACRO' Args Selector
          { Expr::Macro { span: $span, name: span_of_tok($1), args: $2, selection: $3 } }
      | 'ID'
          { Expr::Variable { span: span_of_tok($1) } }
      | 'INT'
          { Expr::Integer { span: span_of_tok($1) } }
      | 'true'
          { Expr::Boolean { span: $span, val: true } }
      | 'false'
          { Expr::Boolean { span: $span, val: false } }
    
    Aaron Councilman's avatar
    Aaron Councilman committed
      | 'STRING'
          { Expr::String { span: $span } }
    
    Aaron Councilman's avatar
    Aaron Councilman committed
      | Expr '.' 'ID'
          { Expr::Field { span: $span, lhs: Box::new($1), field: span_of_tok($3) } }
    
    Aaron Councilman's avatar
    Aaron Councilman committed
      | Expr '.' 'INT'
          { Expr::TupleField { span: $span, lhs: Box::new($1), field: span_of_tok($3) } }
    
    Aaron Councilman's avatar
    Aaron Councilman committed
      | Expr '@' 'ID'
          { Expr::Field { span: $span, lhs: Box::new($1), field: span_of_tok($3) } }
    
    Aaron Councilman's avatar
    Aaron Councilman committed
      | '(' Exprs ')'
          { Expr::Tuple { span: $span, exps: $2 } }
      | '[' Exprs ']'
          { Expr::Tuple { span: $span, exps: $2 } }
    
    Aaron Councilman's avatar
    Aaron Councilman committed
      | '{' Schedule '}'
          { Expr::BlockExpr { span: $span, body: Box::new($2) } }
      | '<' Fields '>'
          { Expr::Record { span: $span, fields: rev($2) } }
    
      | Expr '\\' Expr
          { Expr::SetOp { span: $span, op: SetOp::Difference, lhs: Box::new($1), rhs: Box::new($3) } }
      | Expr '|' Expr
          { Expr::SetOp { span: $span, op: SetOp::Union, lhs: Box::new($1), rhs: Box::new($3) } }
      | Expr '&' Expr
          { Expr::SetOp { span: $span, op: SetOp::Intersection, lhs: Box::new($1), rhs: Box::new($3) } }
    
    Aaron Councilman's avatar
    Aaron Councilman committed
    Args -> Vec<Expr>
    
    Aaron Councilman's avatar
    Aaron Councilman committed
      :                { vec![] }
      | '[' RExprs ']' { rev($2) }
    
    Aaron Councilman's avatar
    Aaron Councilman committed
    Exprs -> Vec<Expr>
    
    Aaron Councilman's avatar
    Aaron Councilman committed
      : RExprs  { rev($1) }
      ;
    
    RExprs -> Vec<Expr>
      :                  { vec![] }
      | Expr             { vec![$1] }
      | Expr ',' RExprs  { snoc($1, $3) }
    
    Aaron Councilman's avatar
    Aaron Councilman committed
    Fields -> Vec<(Span, Expr)>
      :                           { vec![] }
      | 'ID' '=' Expr             { vec![(span_of_tok($1), $3)] }
      | 'ID' '=' Expr ',' Fields  { snoc((span_of_tok($1), $3), $5) }
    
    Aaron Councilman's avatar
    Aaron Councilman committed
    
    Selector -> Selector
      : '(' '*' ')'
          { Selector::SelectAll { span: $span } }
      | '(' Exprs ')'
          { Selector::SelectExprs { span: $span, exprs: $2 } }
    
    Aaron Councilman's avatar
    Aaron Councilman committed
    MacroDecl -> MacroDecl
      : 'macro_keyword' 'MACRO' Params '(' 'ID' ')' MacroDef
          { MacroDecl {
              name: span_of_tok($2),
              params: rev($3),
              selection_name: span_of_tok($5),
              def: Box::new($7),
            }
          }
    
    Aaron Councilman's avatar
    Aaron Councilman committed
    
    Params -> Vec<Span>
      :                  { vec![] }
      | '[' Ids ']'      { $2 }
    
    Aaron Councilman's avatar
    Aaron Councilman committed
    Ids -> Vec<Span>
      :               { vec![] }
      | 'ID'          { vec![span_of_tok($1)] }
      | 'ID' ',' Ids  { snoc(span_of_tok($1), $3) }
    
    Aaron Councilman's avatar
    Aaron Councilman committed
    MacroDef -> OperationList : '{' Schedule '}' { $2 };
    
    
    Unmatched -> () : 'UNMATCHED' {};
    
    %%
    
    use cfgrammar::Span;
    use lrlex::DefaultLexeme;
    
    
    Aaron Councilman's avatar
    Aaron Councilman committed
    fn snoc<T>(x: T, mut xs: Vec<T>) -> Vec<T> {
      xs.push(x);
      xs
    }
    
    fn rev<T>(mut xs: Vec<T>) -> Vec<T> {
      xs.reverse();
      xs
    }
    
    
    fn span_of_tok(t : Result<DefaultLexeme, DefaultLexeme>) -> Span {
      t.map_err(|_| ()).map(|l| l.span()).unwrap()
    }
    
    
    Aaron Councilman's avatar
    Aaron Councilman committed
    pub enum OperationList {
      NilStmt(),
      FinalExpr(Expr),
      ConsStmt(Stmt, Box<OperationList>),
    
    Aaron Councilman's avatar
    Aaron Councilman committed
    pub enum Stmt {
      LetStmt    { span: Span, var: Span, expr: Expr },
    
    Aaron Councilman's avatar
    Aaron Councilman committed
      LetsStmt   { span: Span, vars: Vec<Span>, expr: Expr },
    
    Aaron Councilman's avatar
    Aaron Councilman committed
      AssignStmt { span: Span, var: Span, rhs: Expr },
      ExprStmt   { span: Span, exp: Expr },
      Fixpoint   { span: Span, limit: FixpointLimit, body: Box<OperationList> },
      MacroDecl  { span: Span, def: MacroDecl },
    
    Aaron Councilman's avatar
    Aaron Councilman committed
    pub enum FixpointLimit {
      NoLimit    { span: Span },
      StopAfter  { span: Span, limit: Span },
      PanicAfter { span: Span, limit: Span },
      PrintIter  { span: Span },
    
    #[derive(Copy, Clone, Debug)]
    pub enum SetOp {
      Difference,
      Union,
      Intersection,
    }
    
    
    Aaron Councilman's avatar
    Aaron Councilman committed
    pub enum Expr {
      Function    { span: Span, name: Span, args: Vec<Expr>, selection: Selector },
      Macro       { span: Span, name: Span, args: Vec<Expr>, selection: Selector },
      Variable    { span: Span },
      Integer     { span: Span },
      Boolean     { span: Span, val: bool },
    
    Aaron Councilman's avatar
    Aaron Councilman committed
      String      { span: Span },
    
    Aaron Councilman's avatar
    Aaron Councilman committed
      Field       { span: Span, lhs: Box<Expr>, field: Span },
      BlockExpr   { span: Span, body: Box<OperationList> },
      Record      { span: Span, fields: Vec<(Span, Expr)> },
    
      SetOp       { span: Span, op: SetOp, lhs: Box<Expr>, rhs: Box<Expr> },
    
    Aaron Councilman's avatar
    Aaron Councilman committed
      Tuple       { span: Span, exps: Vec<Expr> },
      TupleField  { span: Span, lhs: Box<Expr>, field: Span },
    
    Aaron Councilman's avatar
    Aaron Councilman committed
    }
    
    Aaron Councilman's avatar
    Aaron Councilman committed
    pub enum Selector {
      SelectAll   { span: Span },
      SelectExprs { span: Span, exprs: Vec<Expr> },
    }
    
    Aaron Councilman's avatar
    Aaron Councilman committed
    pub struct MacroDecl {
      pub name: Span,
      pub params: Vec<Span>,
      pub selection_name: Span,
      pub def: Box<OperationList>,