Change where Builtin is calculated from operators

This commit is contained in:
Greg Shuflin 2021-10-16 20:21:08 -07:00
parent 25bffa339c
commit 2fe4109296
7 changed files with 48 additions and 34 deletions

View File

@ -6,7 +6,7 @@ mod walker;
mod visitor; mod visitor;
mod visitor_test; mod visitor_test;
mod operators; mod operators;
pub use operators::*; pub use operators::{PrefixOp, BinOp};
pub use visitor::ASTVisitor; pub use visitor::ASTVisitor;
pub use walker::walk_ast; pub use walker::walk_ast;
use crate::tokenizing::Location; use crate::tokenizing::Location;

View File

@ -1,20 +1,21 @@
use std::rc::Rc; use std::rc::Rc;
use std::str::FromStr;
use crate::tokenizing::TokenKind; use crate::tokenizing::TokenKind;
use crate::builtin::Builtin;
#[derive(Debug, PartialEq, Clone)] #[derive(Debug, PartialEq, Clone)]
pub struct PrefixOp { pub struct PrefixOp {
sigil: Rc<String>, sigil: Rc<String>,
pub builtin: Option<Builtin>,
} }
impl PrefixOp { impl PrefixOp {
#[allow(dead_code)] pub fn from_sigil(sigil: &str) -> PrefixOp {
pub fn sigil(&self) -> &Rc<String> { PrefixOp { sigil: Rc::new(sigil.to_string()) }
}
pub fn sigil(&self) -> &str {
&self.sigil &self.sigil
} }
pub fn is_prefix(op: &str) -> bool { pub fn is_prefix(op: &str) -> bool {
match op { match op {
"+" => true, "+" => true,
@ -25,37 +26,20 @@ impl PrefixOp {
} }
} }
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) })
}
}
#[derive(Debug, PartialEq, Clone)] #[derive(Debug, PartialEq, Clone)]
pub struct BinOp { pub struct BinOp {
sigil: Rc<String>, sigil: Rc<String>,
pub builtin: Option<Builtin>,
} }
impl BinOp { impl BinOp {
pub fn from_sigil(sigil: &str) -> BinOp { pub fn from_sigil(sigil: &str) -> BinOp {
let builtin = Builtin::from_str(sigil).ok(); BinOp { sigil: Rc::new(sigil.to_string()) }
BinOp { sigil: Rc::new(sigil.to_string()), builtin }
} }
pub fn sigil(&self) -> &Rc<String> {
pub fn sigil(&self) -> &str {
&self.sigil &self.sigil
} }
pub fn from_sigil_token(tok: &TokenKind) -> Option<BinOp> { pub fn from_sigil_token(tok: &TokenKind) -> Option<BinOp> {
let s = token_kind_to_sigil(tok)?; let s = token_kind_to_sigil(tok)?;
Some(BinOp::from_sigil(s)) Some(BinOp::from_sigil(s))

View File

@ -1,7 +1,10 @@
use std::str::FromStr; use std::str::FromStr;
use std::convert::TryFrom;
use crate::typechecking::{TypeConst, Type}; use crate::typechecking::{TypeConst, Type};
use crate::ast::{BinOp, PrefixOp};
/// "Builtin" computational operations with some kind of semantics, mostly mathematical operations.
#[derive(Debug, Clone, Copy, PartialEq)] #[derive(Debug, Clone, Copy, PartialEq)]
pub enum Builtin { pub enum Builtin {
Add, Add,
@ -66,6 +69,29 @@ impl Builtin {
} }
} }
impl TryFrom<&BinOp> for Builtin {
type Error = ();
fn try_from(binop: &BinOp) -> Result<Self, Self::Error> {
FromStr::from_str(binop.sigil())
}
}
impl TryFrom<&PrefixOp> for Builtin {
type Error = ();
fn try_from(prefix_op: &PrefixOp) -> Result<Self, Self::Error> {
use Builtin::*;
match prefix_op.sigil() {
"+" => Ok(Increment),
"-" => Ok(Negate),
"!" => Ok(BooleanNot),
_ => Err(())
}
}
}
impl FromStr for Builtin { impl FromStr for Builtin {
type Err = (); type Err = ();

View File

@ -161,7 +161,6 @@
mod test; mod test;
use std::rc::Rc; use std::rc::Rc;
use std::str::FromStr;
use crate::tokenizing::*; use crate::tokenizing::*;
use crate::tokenizing::Kw::*; use crate::tokenizing::Kw::*;
@ -658,7 +657,7 @@ impl Parser {
_ => unreachable!(), _ => unreachable!(),
}; };
let expr = self.primary()?; let expr = self.primary()?;
let prefix_op = PrefixOp::from_str(sigil.as_str()).unwrap(); let prefix_op = PrefixOp::from_sigil(sigil.as_str());
Ok(Expression::new( Ok(Expression::new(
self.id_store.fresh(), self.id_store.fresh(),
ExpressionKind::PrefixExp(prefix_op, Box::new(expr)) ExpressionKind::PrefixExp(prefix_op, Box::new(expr))

View File

@ -1,6 +1,5 @@
#![cfg(test)] #![cfg(test)]
use std::rc::Rc; use std::rc::Rc;
use std::str::FromStr;
use crate::tokenizing::Location; use crate::tokenizing::Location;
use super::{Parser, ParseResult, tokenize}; use super::{Parser, ParseResult, tokenize};
@ -109,7 +108,7 @@ macro_rules! binexp {
($op:expr, $lhs:expr, $rhs:expr) => { BinExp(BinOp::from_sigil($op), bx!(Expression::new(ItemIdStore::new_id(), $lhs).into()), bx!(Expression::new(ItemIdStore::new_id(), $rhs).into())) } ($op:expr, $lhs:expr, $rhs:expr) => { BinExp(BinOp::from_sigil($op), bx!(Expression::new(ItemIdStore::new_id(), $lhs).into()), bx!(Expression::new(ItemIdStore::new_id(), $rhs).into())) }
} }
macro_rules! prefexp { macro_rules! prefexp {
($op:expr, $lhs:expr) => { PrefixExp(PrefixOp::from_str($op).unwrap(), bx!(Expression::new(ItemIdStore::new_id(), $lhs).into())) } ($op:expr, $lhs:expr) => { PrefixExp(PrefixOp::from_sigil($op), bx!(Expression::new(ItemIdStore::new_id(), $lhs).into())) }
} }
macro_rules! exst { macro_rules! exst {
($expr_type:expr) => { make_statement(StatementKind::Expression(Expression::new(ItemIdStore::new_id(), $expr_type).into())) }; ($expr_type:expr) => { make_statement(StatementKind::Expression(Expression::new(ItemIdStore::new_id(), $expr_type).into())) };

View File

@ -14,6 +14,7 @@
//! built from the ReducedAST. //! built from the ReducedAST.
use std::rc::Rc; use std::rc::Rc;
use std::str::FromStr; use std::str::FromStr;
use std::convert::TryFrom;
use crate::ast::*; use crate::ast::*;
use crate::symbol_table::{Symbol, SymbolSpec, SymbolTable, FullyQualifiedSymbolName}; use crate::symbol_table::{Symbol, SymbolSpec, SymbolTable, FullyQualifiedSymbolName};
@ -337,7 +338,8 @@ impl<'a> Reducer<'a> {
} }
fn prefix(&mut self, prefix: &PrefixOp, arg: &Box<Expression>) -> Expr { fn prefix(&mut self, prefix: &PrefixOp, arg: &Box<Expression>) -> Expr {
match prefix.builtin { let builtin: Option<Builtin> = TryFrom::try_from(prefix).ok();
match builtin {
Some(op) => { Some(op) => {
let f = Box::new(Expr::Func(Func::BuiltIn(op))); let f = Box::new(Expr::Func(Func::BuiltIn(op)));
Expr::Call { f, args: vec![self.expression(arg)] } Expr::Call { f, args: vec![self.expression(arg)] }

View File

@ -1,8 +1,10 @@
use std::rc::Rc; use std::rc::Rc;
use std::fmt::Write; use std::fmt::Write;
use std::convert::TryFrom;
use ena::unify::{UnifyKey, InPlaceUnificationTable, UnificationTable, EqUnifyValue}; use ena::unify::{UnifyKey, InPlaceUnificationTable, UnificationTable, EqUnifyValue};
use crate::builtin::Builtin;
use crate::ast::*; use crate::ast::*;
use crate::util::ScopeStack; use crate::util::ScopeStack;
use crate::util::deref_optional_box; use crate::util::deref_optional_box;
@ -332,7 +334,8 @@ impl<'a> TypeContext<'a> {
} }
fn prefix(&mut self, op: &PrefixOp, expr: &Expression) -> InferResult<Type> { fn prefix(&mut self, op: &PrefixOp, expr: &Expression) -> InferResult<Type> {
let tf = match op.builtin.map(|b| b.get_type()) { let builtin: Option<Builtin> = TryFrom::try_from(op).ok();
let tf = match builtin.map(|b| b.get_type()) {
Some(ty) => ty, Some(ty) => ty,
None => return TypeError::new("no type found") None => return TypeError::new("no type found")
}; };
@ -342,7 +345,8 @@ impl<'a> TypeContext<'a> {
} }
fn binexp(&mut self, op: &BinOp, lhs: &Expression, rhs: &Expression) -> InferResult<Type> { fn binexp(&mut self, op: &BinOp, lhs: &Expression, rhs: &Expression) -> InferResult<Type> {
let tf = match op.builtin.map(|b| b.get_type()) { let builtin: Option<Builtin> = TryFrom::try_from(op).ok();
let tf = match builtin.map(|b| b.get_type()) {
Some(ty) => ty, Some(ty) => ty,
None => return TypeError::new("no type found"), None => return TypeError::new("no type found"),
}; };