diff --git a/schala-lang/language/src/ast.rs b/schala-lang/language/src/ast.rs index e0ccc79..a8e73a5 100644 --- a/schala-lang/language/src/ast.rs +++ b/schala-lang/language/src/ast.rs @@ -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 { n: T, @@ -242,30 +244,3 @@ pub enum ForBody { MonadicReturn(Meta), StatementBlock(Block), } - -#[derive(Debug, PartialEq, Clone)] -pub struct PrefixOp { - pub sigil: Rc, - pub builtin: Option, -} - -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 { - &self.sigil - } - pub fn is_prefix(op: &str) -> bool { - match op { - "+" => true, - "-" => true, - "!" => true, - _ => false - } - } -} - diff --git a/schala-lang/language/src/ast/operators.rs b/schala-lang/language/src/ast/operators.rs new file mode 100644 index 0000000..64f4e2c --- /dev/null +++ b/schala-lang/language/src/ast/operators.rs @@ -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, + pub builtin: Option, +} + +impl PrefixOp { + pub fn sigil(&self) -> &Rc { + &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 { + 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) }) + } +} diff --git a/schala-lang/language/src/builtin.rs b/schala-lang/language/src/builtin.rs index 2d8c080..fcbf97d 100644 --- a/schala-lang/language/src/builtin.rs +++ b/schala-lang/language/src/builtin.rs @@ -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) } } } diff --git a/schala-lang/language/src/eval.rs b/schala-lang/language/src/eval.rs index 73bd769..d78ab62 100644 --- a/schala-lang/language/src/eval.rs +++ b/schala-lang/language/src/eval.rs @@ -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 */ diff --git a/schala-lang/language/src/parsing.rs b/schala-lang/language/src/parsing.rs index f446746..0b4e557 100644 --- a/schala-lang/language/src/parsing.rs +++ b/schala-lang/language/src/parsing.rs @@ -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() diff --git a/schala-lang/language/src/parsing/test.rs b/schala-lang/language/src/parsing/test.rs index 9e6d4a9..85806a5 100644 --- a/schala-lang/language/src/parsing/test.rs +++ b/schala-lang/language/src/parsing/test.rs @@ -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())) };