Move where PrefixOp lives
This commit is contained in:
parent
a3bb3ee514
commit
0dd6b26e5a
@ -1,7 +1,8 @@
|
||||
use std::rc::Rc;
|
||||
use std::convert::From;
|
||||
use std::str::FromStr;
|
||||
|
||||
use crate::builtin::{BinOp, PrefixOp};
|
||||
use crate::builtin::{BinOp, Builtin};
|
||||
use crate::typechecking::TypeData;
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
@ -241,3 +242,30 @@ 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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5,7 +5,7 @@ use std::str::FromStr;
|
||||
use crate::tokenizing::TokenKind;
|
||||
use crate::typechecking::{TypeConst, Type};
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||
pub enum Builtin {
|
||||
Add,
|
||||
Subtract,
|
||||
@ -33,6 +33,12 @@ pub enum Builtin {
|
||||
Concatenate,
|
||||
}
|
||||
|
||||
impl Builtin {
|
||||
pub fn get_type(&self) -> Type {
|
||||
ty!(Nat -> Nat -> Nat)
|
||||
}
|
||||
}
|
||||
|
||||
impl FromStr for Builtin {
|
||||
type Err = ();
|
||||
|
||||
@ -130,36 +136,9 @@ impl BinOp {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Clone)]
|
||||
pub struct PrefixOp {
|
||||
sigil: Rc<String>
|
||||
}
|
||||
|
||||
impl PrefixOp {
|
||||
pub fn from_sigil(sigil: &str) -> PrefixOp {
|
||||
PrefixOp { sigil: Rc::new(sigil.to_string()) }
|
||||
}
|
||||
pub fn sigil(&self) -> &Rc<String> {
|
||||
&self.sigil
|
||||
}
|
||||
pub fn is_prefix(op: &str) -> bool {
|
||||
PREFIX_OPS.get(op).is_some()
|
||||
}
|
||||
pub fn get_type(&self) -> Result<Type, String> {
|
||||
let s = self.sigil.as_str();
|
||||
PREFIX_OPS.get(s).map(|x| x.0.clone()).ok_or(format!("Prefix op {} not found", s))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
lazy_static! {
|
||||
static ref PREFIX_OPS: HashMap<&'static str, (Type, ())> =
|
||||
hashmap! {
|
||||
"+" => (ty!(Nat -> Int), ()),
|
||||
"-" => (ty!(Nat -> Int), ()),
|
||||
"!" => (ty!(Bool -> Bool), ()),
|
||||
};
|
||||
}
|
||||
//TODO mapping between sigil string and precedence should live in ast.rs
|
||||
//mapping between operation and type should live here in builtins.rs
|
||||
|
||||
/* the second tuple member is a placeholder for when I want to make evaluation rules tied to the
|
||||
* binop definition */
|
||||
|
@ -152,7 +152,7 @@ use crate::tokenizing::TokenKind::*;
|
||||
|
||||
use crate::ast::*;
|
||||
|
||||
use crate::builtin::{BinOp, PrefixOp};
|
||||
use crate::builtin::{BinOp};
|
||||
|
||||
/// Represents a parsing error
|
||||
#[derive(Debug)]
|
||||
|
@ -2,8 +2,8 @@
|
||||
use ::std::rc::Rc;
|
||||
use super::tokenize;
|
||||
use super::ParseResult;
|
||||
use crate::builtin::{PrefixOp, BinOp};
|
||||
use crate::ast::{AST, Meta, Expression, Statement, IfExpressionBody, Discriminator, Pattern, PatternLiteral, TypeBody, Enumerator, ForBody, InvocationArgument, FormalParam};
|
||||
use crate::builtin::{BinOp};
|
||||
use crate::ast::{AST, Meta, Expression, Statement, IfExpressionBody, Discriminator, Pattern, PatternLiteral, TypeBody, Enumerator, ForBody, InvocationArgument, FormalParam, PrefixOp};
|
||||
use super::Statement::*;
|
||||
use super::Declaration::*;
|
||||
use super::Signature;
|
||||
|
@ -17,7 +17,7 @@ use std::str::FromStr;
|
||||
|
||||
use crate::ast::*;
|
||||
use crate::symbol_table::{Symbol, SymbolSpec, SymbolTable};
|
||||
use crate::builtin::{BinOp, PrefixOp, Builtin};
|
||||
use crate::builtin::{BinOp, Builtin};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct ReducedAST(pub Vec<Stmt>);
|
||||
|
@ -5,7 +5,7 @@ use ena::unify::{UnifyKey, InPlaceUnificationTable, UnificationTable, EqUnifyVal
|
||||
|
||||
use crate::ast::*;
|
||||
use crate::util::ScopeStack;
|
||||
use crate::builtin::{PrefixOp, BinOp};
|
||||
use crate::builtin::{BinOp};
|
||||
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
@ -326,9 +326,9 @@ impl<'a> TypeContext<'a> {
|
||||
}
|
||||
|
||||
fn prefix(&mut self, op: &PrefixOp, expr: &Expression) -> InferResult<Type> {
|
||||
let tf = match op.get_type() {
|
||||
Ok(ty) => ty,
|
||||
Err(e) => return TypeError::new(e)
|
||||
let tf = match op.builtin.map(|b| b.get_type()) {
|
||||
Some(ty) => ty,
|
||||
None => return TypeError::new("no type found")
|
||||
};
|
||||
|
||||
let tx = self.expr(expr)?;
|
||||
@ -468,13 +468,16 @@ mod typechecking_tests {
|
||||
assert_type_in_fresh_context!("1", ty!(Nat));
|
||||
assert_type_in_fresh_context!(r#""drugs""#, ty!(StringT));
|
||||
assert_type_in_fresh_context!("true", ty!(Bool));
|
||||
assert_type_in_fresh_context!("-1", ty!(Int));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn operators() {
|
||||
//TODO fix these with new operator regime
|
||||
/*
|
||||
assert_type_in_fresh_context!("-1", ty!(Int));
|
||||
assert_type_in_fresh_context!("1 + 2", ty!(Nat));
|
||||
assert_type_in_fresh_context!("-2", ty!(Int));
|
||||
assert_type_in_fresh_context!("!true", ty!(Bool));
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user