// Copyright ⓒ 2017 David Li. // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. use std::ops::Deref; #[derive(Debug)] pub struct WithLocation { pub value: T, pub start: usize, pub end: usize, } impl WithLocation { pub fn new(value: T, start: usize, end: usize) -> WithLocation { WithLocation { value: value, start: start, end: end, } } pub fn map U>(self, f: F) -> WithLocation { WithLocation { value: f(self.value), start: self.start, end: self.end, } } pub fn join_map(self, other: WithLocation, f: F) -> WithLocation where F: FnOnce(WithLocation, WithLocation) -> V { let start = self.start; let end = other.end; WithLocation { value: f(self, other), start: start, end: end, } } } impl Deref for WithLocation { type Target = T; fn deref(&self) -> &Self::Target { &self.value } } #[derive(Debug)] pub struct Program(pub Box>); #[derive(Debug)] pub enum UnaryOp { Pos, Neg, Not, } #[derive(Debug)] pub enum BinOp { Add, Sub, Mul, Div, FloorDiv, Eq, Neq, Gt, Lt, Ge, Le, And, Or, } #[derive(Debug)] pub enum Expression { Let(Vec>, Box>), UnaryOp(UnaryOp, Box>), BinOp(BinOp, Box>, Box>), Number(u64), String(String), Name(String), Call(String, Vec>), Nil, } #[derive(Debug)] pub struct RecordField { pub name: WithLocation, pub ty: WithLocation, } impl RecordField { pub fn new(name: WithLocation, ty: WithLocation) -> RecordField { RecordField { name, ty } } } #[derive(Debug)] pub enum Ty { Name(String), Array(Box>), Record(Vec>), } #[derive(Debug)] pub struct Declaration { pub name: WithLocation, pub declaration: DeclarationBody, } #[derive(Debug)] pub enum DeclarationBody { Var { ty: Option>, value: Box>, }, Ty { ty: WithLocation, }, Fun { ty: Option>, params: Vec>, body: Box>, }, } impl Declaration { pub fn new_var(name: WithLocation, type_: Option>, value: Box>) -> Declaration { Declaration { name: name, declaration: DeclarationBody::Var { ty: type_, value: value, } } } pub fn new_ty(name: WithLocation, type_: WithLocation) -> Declaration { Declaration { name: name, declaration: DeclarationBody::Ty { ty: type_, } } } pub fn new_fun(name: WithLocation, params: Vec>, type_: Option>, body: Box>) -> Declaration { Declaration { name: name, declaration: DeclarationBody::Fun { ty: type_, params: params, body: body, } } } }