Make operators live in a submodule of ast

Starting with PrefixOp, BinOp happens next
This commit is contained in:
greg 2019-08-14 07:25:45 -07:00
parent 6e92b03f81
commit fde169b623
6 changed files with 59 additions and 35 deletions

View File

@ -1,10 +1,12 @@
use std::rc::Rc;
use std::convert::From;
use std::str::FromStr;
use crate::builtin::{BinOp, Builtin};
use crate::builtin::{BinOp};
use crate::typechecking::TypeData;
mod operators;
pub use operators::*;
#[derive(Clone, Debug, PartialEq)]
pub struct Meta<T> {
n: T,
@ -242,30 +244,3 @@ pub enum ForBody {
MonadicReturn(Meta<Expression>),
StatementBlock(Block),
}
#[derive(Debug, PartialEq, Clone)]
pub struct PrefixOp {
pub sigil: Rc<String>,
pub builtin: Option<Builtin>,
}
impl PrefixOp {
pub fn from_sigil(sigil: &str) -> PrefixOp {
PrefixOp {
sigil: Rc::new(sigil.to_string()),
builtin: Builtin::from_str(sigil).ok(),
}
}
pub fn sigil(&self) -> &Rc<String> {
&self.sigil
}
pub fn is_prefix(op: &str) -> bool {
match op {
"+" => true,
"-" => true,
"!" => true,
_ => false
}
}
}

View File

@ -0,0 +1,41 @@
use std::rc::Rc;
use std::str::FromStr;
use crate::builtin::Builtin;
#[derive(Debug, PartialEq, Clone)]
pub struct PrefixOp {
pub sigil: Rc<String>,
pub builtin: Option<Builtin>,
}
impl PrefixOp {
pub fn sigil(&self) -> &Rc<String> {
&self.sigil
}
pub fn is_prefix(op: &str) -> bool {
match op {
"+" => true,
"-" => true,
"!" => true,
_ => false
}
}
}
impl FromStr for PrefixOp {
type Err = ();
fn from_str(s: &str) -> Result<Self, Self::Err> {
use Builtin::*;
let builtin = match s {
"+" => Ok(Increment),
"-" => Ok(Negate),
"!" => Ok(BooleanNot),
_ => Err(())
};
builtin.map(|builtin| PrefixOp { sigil: Rc::new(s.to_string()), builtin: Some(builtin) })
}
}

View File

@ -8,7 +8,9 @@ use crate::typechecking::{TypeConst, Type};
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum Builtin {
Add,
Increment,
Subtract,
Negate,
Multiply,
Divide,
Quotient,
@ -61,6 +63,8 @@ impl Builtin {
IOGetLine => ty!(StringT),
Assignment => ty!(Unit),
Concatenate => ty!(StringT -> StringT -> StringT),
Increment => ty!(Nat -> Int),
Negate => ty!(Nat -> Int)
}
}
}

View File

@ -327,10 +327,10 @@ impl<'a> State<'a> {
/* prefix ops */
(BooleanNot, &[Lit(Bool(true))]) => Lit(Bool(false)),
(BooleanNot, &[Lit(Bool(false))]) => Lit(Bool(true)),
(Subtract, &[Lit(Nat(n))]) => Lit(Int(-1*(n as i64))),
(Subtract, &[Lit(Int(n))]) => Lit(Int(-1*(n as i64))),
(Add, &[Lit(Int(n))]) => Lit(Int(n)),
(Add, &[Lit(Nat(n))]) => Lit(Nat(n)),
(Negate, &[Lit(Nat(n))]) => Lit(Int(-1*(n as i64))),
(Negate, &[Lit(Int(n))]) => Lit(Int(-1*(n as i64))),
(Increment, &[Lit(Int(n))]) => Lit(Int(n)),
(Increment, &[Lit(Nat(n))]) => Lit(Nat(n)),
/* builtin functions */

View File

@ -145,6 +145,7 @@
mod test;
use std::rc::Rc;
use std::str::FromStr;
use crate::tokenizing::*;
use crate::tokenizing::Kw::*;
@ -625,8 +626,9 @@ impl Parser {
_ => unreachable!(),
};
let expr = self.primary()?;
let prefix_op = PrefixOp::from_str(sigil.as_str()).unwrap();
Ok(Expression::new(
ExpressionKind::PrefixExp(PrefixOp::from_sigil(sigil.as_str()), bx!(expr.into()))
ExpressionKind::PrefixExp(prefix_op, bx!(expr.into()))
))
},
_ => self.call_expr()

View File

@ -1,5 +1,7 @@
#![cfg(test)]
use ::std::rc::Rc;
use std::str::FromStr;
use super::tokenize;
use super::ParseResult;
use crate::builtin::{BinOp};
@ -59,7 +61,7 @@ macro_rules! binexp {
($op:expr, $lhs:expr, $rhs:expr) => { BinExp(BinOp::from_sigil($op), bx!(Expression::new($lhs).into()), bx!(Expression::new($rhs).into())) }
}
macro_rules! prefexp {
($op:expr, $lhs:expr) => { PrefixExp(PrefixOp::from_sigil($op), bx!(Expression::new($lhs).into())) }
($op:expr, $lhs:expr) => { PrefixExp(PrefixOp::from_str($op).unwrap(), bx!(Expression::new($lhs).into())) }
}
macro_rules! exst {
($expr_type:expr) => { Meta::new(Statement::ExpressionStatement(Expression::new($expr_type).into())) };